[MOBY-guts] biomoby commit
Paul Gordon
gordonp at dev.open-bio.org
Wed Apr 14 22:02:04 UTC 2010
gordonp
Wed Apr 14 18:02:04 EDT 2010
Update of /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/gui
In directory dev.open-bio.org:/tmp/cvs-serv7013/src/main/ca/ucalgary/seahawk/gui
Modified Files:
MobyContentPane.java MobyServicesGUI.java
Added Files:
MobyPayloadCreator.java
Log Message:
Changes to implement explicit 'for each' loops over Seahawk data lists (not quite functional yet, but compiles)
moby-live/Java/src/main/ca/ucalgary/seahawk/gui MobyPayloadCreator.java,NONE,1.1 MobyContentPane.java,1.26,1.27 MobyServicesGUI.java,1.17,1.18
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/gui/MobyContentPane.java,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/gui/MobyContentPane.java 2010/04/11 20:15:28 1.26
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/gui/MobyContentPane.java 2010/04/14 22:02:04 1.27
@@ -1,4 +1,3 @@
-
package ca.ucalgary.seahawk.gui;
// For external links
@@ -72,8 +71,8 @@
public static final String SERVICE_CREATION_MSG = "Create a service returning this datatype";
private static final int TAB_ICON_SPACER = 2;
- private static String SEARCH_VISIBLE = "Search visible";
- private static String SEARCH_HIDDEN = "Search hidden";
+ private static final String SEARCH_VISIBLE = "Search visible";
+ private static final String SEARCH_HIDDEN = "Search hidden";
private static ImageIcon hourglassIcon;
private static ImageIcon failedIcon;
@@ -105,10 +104,10 @@
private Map<String,String> filteredData; //Map<xptrOfFilteredData,>
private boolean filterChanged;
private Document currentDoc; //the doc DOM being actively filtered
- private NodeList currentSelectedData = null;
- private String currentSelectionXPath = null;
- private Map<String,Boolean> jobXPtrs = null; // Map<xptr,has a HAS member>
+ private MutableNodeList currentSelectedData = null;
+ private StringBuffer currentSelectionXPath = null;
private List<String> filterableNodes = null; // List<xptr>
+ private Map<String,Boolean> jobXPtrs = null; // Map<xptr,has a HAS member>
private List<AttributeSet> origStyles = null;
private boolean firstDocRendering = true;
@@ -141,20 +140,6 @@
private final static String wsServletPath = "/SOAPServlet";
private static Acme.Serve.Serve servletContainer;
private static Map<String,MobyContentGUI> id2GuiMap;
- private static DocumentBuilder docBuilder;
- private static XPathFactory xPathFactory;
-
- static{
- xPathFactory = XPathFactory.newInstance();
-
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware(true);
- try{
- docBuilder = dbf.newDocumentBuilder();
- } catch(Exception e){
- logger.warn("Cannot get XML parser from configuration", e);
- }
- }
public MobyContentPane(MobyContentGUI cGUI, MobyServicesGUI sGUI, JTabbedPane parentComponent, DataFlowRecorder recorder, JLabel statusBar){
tabbedPane = parentComponent;
@@ -200,7 +185,9 @@
filterHistory = new HashMap<URL,FilterSearch>();
deletedFilters = new HashMap<URL,FilterSearch>();
xPtrsReferencedInNextService = new Vector<String>();
+ currentSelectedData = new MutableNodeList();
filteredData = new HashMap<String,String>();
+ jobXPtrs = new HashMap<String,Boolean>();
ClassLoader cl = getClass().getClassLoader();
if(cl == null){
@@ -738,9 +725,8 @@
// If this page has a filter associated with it before reload it
try{
currentDoc = null; // get rid of previous in-memory doc use for interactive filtering, if any
- currentSelectedData = null;
- currentSelectionXPath = null;
- jobXPtrs = null;
+ currentSelectedData.clear();
+ currentSelectionXPath = new StringBuffer();
filterableNodes = null;
origStyles = null;
firstDocRendering = true;
@@ -1209,14 +1195,54 @@
"not extract MOBY Data Object from " +targetURL);
return;
}
+ if(!(mobyData instanceof MobyPrimaryData)){
+ logger.warn("Cannot create MOBY service list for non-primary " +
+ "MOBY Data (was " +mobyData.getClass().getName()+")");
+ return;
+ }
JPopupMenu popup = new DynamicJPopupMenu();
popup.setName(MOBY_SERVICE_POPUP_NAME);
addExtraMobyOptions(popup, mobyData, targetURL);
- JMenuItem checkingLinksPopupItem = new JMenuItem("Check for services...");
+ JMenuItem checkingLinksPopupItem = new JMenuItem("Checking for services...");
popup.add(checkingLinksPopupItem);
popup.show(this, lastClickX+editorPane.getX(), lastClickY+editorPane.getY());
servicesGUI.addPopupOptions(mobyData, popup, true, getDefaultHandler()); // true = asynchronous
+
+ // It's possible that the current node clicked has peers that could also be submitted at the same time.
+ // In this case, create a "for each" option to submit all peers to the service. We don't actually build
+ // the input data, but provde a callback listener to create the full submission envelope if the user
+ // chooses the for each option. The Moby data instance's userData gives us the current context, enabling us
+ // to construct the correct payload in MobyPayloadCreator.createPayload() at any point in the future.
+ String origUserData = (String) mobyData.getUserData();
+ MobyPayloadRequestListener payloadCreator = new MobyPayloadCreator(this);
+ for(String peerMode: new String[]{DataUtils.ARTICLE_PEERS_MODE, DataUtils.DATATYPE_PEERS_MODE}){
+ // note that getPeerElements() will modify the userData to reflect the semantic of the requested peer mode
+ mobyData.setUserData(origUserData);
+ NodeList peerElements = DataUtils.getPeerElements(getCurrentDoc(), mobyData, peerMode);
+ if(peerElements.getLength() <= 1){
+ continue; // no 'for each' option if only one to process...
+ }
+ String each = "each <i>(" + peerElements.getLength() + " total)</i>";
+ if(peerMode.equals(DataUtils.ARTICLE_PEERS_MODE)){
+ each += " '"+mobyData.getName()+"'";
+ }
+ MobyDataType dataType = ((MobyPrimaryData) mobyData).getDataType();
+ if(mobyData instanceof MobyPrimaryDataSet){ // Collection
+ servicesGUI.addPopupOptions((MobyPrimaryDataSet) mobyData, popup, true, getDefaultHandler(), payloadCreator,
+ (String) mobyData.getUserData(), each);
+ }
+ else if(MobyTags.MOBYOBJECT.equals(dataType.getName())){
+ MobyNamespace namespace = null;
+ servicesGUI.addPopupOptions(namespace, popup, true, getDefaultHandler(), payloadCreator,
+ (String) mobyData.getUserData(), each);
+ }
+ else{
+ servicesGUI.addPopupOptions(dataType, popup, true, getDefaultHandler(), payloadCreator,
+ (String) mobyData.getUserData(), each);
+ }
+ }
+
status.setText("Shift+Click=Service in new tab, Ctrl+Click=Use default 2nd params");
if(popup.getSubElements().length > 0){
popup.setSelected(null);
@@ -1228,6 +1254,15 @@
}
}
+ Map<String,String> getFilteredData(){
+ return filteredData;
+ }
+
+ Map<String,Boolean> getJobXPtrs(){
+ return jobXPtrs;
+ }
+
+
/**
* Subclasses can use this method to expand the popup menu. Be sure to call super.addExtraMobyOptions()
*/
@@ -1252,7 +1287,7 @@
//System.err.println("Should create a previous input menu item for " + mdi.getUserData());
try{
- Document srcDoc = docBuilder.parse(srcURL.openStream());
+ Document srcDoc = DataUtils.docBuilder.parse(srcURL.openStream());
// Get the input data for the *previous* service
MobyDataJob inputData = DataUtils.getInputSample(srcDoc, SeahawkOptions.getRegistry());
@@ -1262,7 +1297,7 @@
return;
}
for(MobyDataInstance previousMDI: inputData.getPrimaryData()){
- // add conditional of the current service as a criteria in user data for each previousMDI,
+ // add conditional of the current service as a criteria in user data for each previousMDI,
// so PbE will properly reflect the logic of if(f1(x) matches filter){f2(x)}
DataUtils.addUserData(previousMDI, srcURL, getFilter());
@@ -1271,6 +1306,7 @@
} catch(Exception e){
logger.warn("Could not load previous service info, 'previous input' option will not be displayed", e);
}
+
}
/**
@@ -1392,231 +1428,41 @@
return null;
}
- /**
- * Determine the parts of the XML document matching the FilterSearch criteria, and filter the view accordingly.
- */
- public void applyFilter(boolean apply){
- if(!filterChanged){
- filterChanged = true;
- }
- filteredData.clear();
-
+ protected Document getCurrentDoc(){
if(currentDoc == null){ // parse the doc into memory if not already there
try{
- currentDoc = docBuilder.parse(getCurrentURL().openStream());
+ currentDoc = DataUtils.docBuilder.parse(getCurrentURL().openStream());
} catch(Exception e){
logger.error("Could not parse Moby document " + getCurrentURL(), e);
- return;
- }
- }
- // Filter out any moby jobs, parameters, collection members or HAS members that aren't in the matchingNodes
- if(filterableNodes == null){
- jobXPtrs = new HashMap<String,Boolean>();
- filterableNodes = new Vector<String>();
- NodeList nodes = currentDoc.getElementsByTagNameNS(MobyTags.MOBY_XML_NS, MobyTags.MOBYDATA);
- for(int i = 0; i < nodes.getLength(); i++){
- String jobXPtr = getXPtr(nodes.item(i));
- filterableNodes.add(jobXPtr);
- jobXPtrs.put(jobXPtr, addHASXPtrs(filterableNodes, (Element) nodes.item(i)));
- }
-
- // Collections
- nodes = currentDoc.getElementsByTagNameNS(MobyTags.MOBY_XML_NS, MobyTags.COLLECTION);
- for(int i = 0; i < nodes.getLength(); i++){
- String collectionXPtr = getXPtr(nodes.item(i));
- NodeList collectionMembers = nodes.item(i).getChildNodes();
- int nonElementCnt = 0;
- for(int j = 0; j < collectionMembers.getLength(); j++){
- if(!(collectionMembers.item(j) instanceof Element)){
- nonElementCnt++;
- continue;
- }
- filterableNodes.add(collectionXPtr+"/"+(j-nonElementCnt+1)+"/1");
- }
+ return null;
}
}
-
- if(!apply || !filterHistory.containsKey(getCurrentURL()) ||
- (filterHistory.containsKey(getCurrentURL()) &&
- filterHistory.get(getCurrentURL()).getFilterRegex().toString().length() == 0)){
- // Show whole doc if no filter or if filter is blank, so nothing to do here
- if(firstDocRendering){
- firstDocRendering = false;
- }
- else{
- displayFilterEffect(); //need to cleanup previous state
- }
- return;
- }
- // Otherwise make a list of xpointers to data that should be grayed out
- FilterSearch fs = filterHistory.get(getCurrentURL());
- XPathOption xsel = fs.getSelectedXPath();
-
- // Find all the matching data
- XPath xpath = xPathFactory.newXPath();
- // Find the applicable DOM nodes if not yet found, or if selection criteria have changed
- if(currentSelectedData == null || currentSelectionXPath == null || !currentSelectionXPath.equals(xsel.getXPath())){
- currentSelectionXPath = xsel.getXPath();
- try{
- currentSelectedData = (NodeList) xpath.evaluate(currentSelectionXPath, currentDoc, XPathConstants.NODESET);
- } catch(Exception e){
- logger.error("Could not evaluate XPath (" + xsel.getXPath() + ") over " + getCurrentURL(), e);
- return;
- }
- // System.err.println("There are " + currentSelectedData.getLength() +
- // " items selected in the document using XPath " + currentSelectionXPath);
- }
-
- // Find just the data subset also matching the regex
- Map<String,Boolean> matchingXPtrs = new LinkedHashMap<String,Boolean>();
- // Build the FSA only once, for efficiency
- Pattern regex = Pattern.compile(fs.getFilterRegex().toString(),
- Pattern.MULTILINE | Pattern.DOTALL |
- (fs.getCaseSensitivity() ? 0 : Pattern.CASE_INSENSITIVE));
- for(int i = 0; i < currentSelectedData.getLength(); i++){
- Node node = currentSelectedData.item(i);
- if(node instanceof Element){
- String elementXPtr = getXPtr(node);
- if(matchingXPtrs.containsKey(elementXPtr) &&
- matchingXPtrs.get(elementXPtr).booleanValue()){
- continue; // already true, no
- }
- else if(regex.matcher(((Element) node).getTextContent()).find()){
- matchingXPtrs.put(elementXPtr, Boolean.TRUE);
- //System.err.println("Adding " + elementXPtr + " as " + matchingXPtrs.get(elementXPtr));
- }
- else{
- matchingXPtrs.put(elementXPtr, Boolean.FALSE);
- //System.err.println("Adding " + elementXPtr + " as " + matchingXPtrs.get(elementXPtr));
- }
- }
- else if(node instanceof Attr){
- String attrParentXPtr = getXPtr(((Attr) node).getOwnerElement());
- if(matchingXPtrs.containsKey(attrParentXPtr) &&
- matchingXPtrs.get(attrParentXPtr).booleanValue()){
- continue;
- }
- else if(regex.matcher(((Attr) node).getValue()).find()){
- // Mark the element to which the attribute belongs
- matchingXPtrs.put(attrParentXPtr, Boolean.TRUE);
- //System.err.println("Adding " + attrParentXPtr + " attr parent as " + matchingXPtrs.get(attrParentXPtr));
- }
- // so false doesn't override true for multi-attr elements
- else if(!matchingXPtrs.containsKey(attrParentXPtr)){
- matchingXPtrs.put(attrParentXPtr, Boolean.FALSE);
- //System.err.println("Adding " + attrParentXPtr + " attr parent as " + matchingXPtrs.get(attrParentXPtr));
- }
-
- }
- else{
- logger.warn("Found filter xpath result item that was not an Element or Attribute as expected ("+
- node.getClass().getName()+")");
- }
- }
-
- boolean inversed = fs.getSelectionInversed();
- Map<String,Boolean> parentMatchingXPtrs = new LinkedHashMap<String,Boolean>();
- for(String currXPtr: filterableNodes){
- for(Map.Entry<String,Boolean> matchingXPtr: matchingXPtrs.entrySet()){
- if(matchingXPtr.getKey().startsWith(currXPtr+"/")){ // a parent of the matching data
- // No positive example yet?
- if(!parentMatchingXPtrs.containsKey(currXPtr) ||
- !inversed && !parentMatchingXPtrs.get(currXPtr).booleanValue() ||
- inversed && parentMatchingXPtrs.get(currXPtr).booleanValue()){
- //System.err.println("Adding "+ matchingXPtr.getValue() + " for " + currXPtr);
- parentMatchingXPtrs.put(currXPtr, matchingXPtr.getValue());
- }
- }
- }
- }
-
- matchingXPtrs.putAll(parentMatchingXPtrs);
- for(String currXPtr: matchingXPtrs.keySet()){
- // Is part of the selection criteria, but doesn't match the regex
- boolean shouldFilter = false;
- if(!matchingXPtrs.get(currXPtr).booleanValue() &&
- // special condition: if "entire response" xpath is given, filter only at the job level
- (!currentSelectionXPath.equals(FilterSearch.SELECT_ALL_XPATH) || jobXPtrs.containsKey(currXPtr))){
- shouldFilter = true;
- }
- if(!inversed && shouldFilter ||
- inversed && !shouldFilter){
- filteredData.put(currXPtr, "todo");
- }
- }
-
- //todo: filter objects without the HAS field at all...
-
- // apply gray out in the document display
- displayFilterEffect();
+ return currentDoc;
}
- // If any moby object member is in a HAS relationship, add it to the list of filterable items
- private Boolean addHASXPtrs(List<String> filterList, Element object){
- String tagName = object.getLocalName();
- boolean isContainer = false;
- MobyDataType mobyDataType = null;
- if(tagName.equals(MobyTags.MOBYDATA) || tagName.equals(MobyTags.COLLECTION) || tagName.equals(MobyTags.SIMPLE) ||
- tagName.equals(MobyTags.CROSSREFERENCE)){
- isContainer = true;
- }
- else{
- mobyDataType = MobyDataType.getDataType(tagName, SeahawkOptions.getRegistry());
- if(mobyDataType == null){
- logger.warn("Found datatype unknown to the registry ("+object.getLocalName()+")");
- return Boolean.FALSE;
- }
+ /**
+ * Determine the parts of the XML document matching the FilterSearch criteria for the current doc,
+ * and filter the view accordingly. Used for interactive filtering in the display.
+ */
+ protected void applyFilter(boolean apply){
+ if(!filterChanged){
+ filterChanged = true;
}
- Boolean hasHAS = Boolean.FALSE; // does the object have a member with a HAS relationship?
- NodeList members = object.getChildNodes();
- for(int i = 0; i < members.getLength(); i++){
- if(!(members.item(i) instanceof Element)){
- continue;
- }
-
- Element member = (Element) members.item(i);
- addHASXPtrs(filterList, member);
-
- if(!isContainer){
- String memberName = member.getAttribute(MobyTags.ARTICLENAME);
- MobyRelationship membership = mobyDataType.getChild(memberName);
- //System.err.println("Relationship for " + tagName + " member " + memberName +
- // " is " + (membership == null ? null : membership.getRelationshipType()));
- if(membership != null && membership.getRelationshipType() == Central.iHAS){
- filterList.add(getXPtr(member));
- if(!hasHAS){
- hasHAS = Boolean.TRUE;
- }
- }
- }
+ FilterSearch filter = filterHistory.get(getCurrentURL());
+ filterableNodes = DataUtils.findFilteredNodes(getCurrentDoc(), filter, filterableNodes, filteredData, jobXPtrs,
+ currentSelectedData, currentSelectionXPath, apply);
+
+ if((!apply || filter == null || filter.getFilterRegex().toString().length() == 0) && firstDocRendering){
+ // Show whole doc if no filter or if filter is blank, so nothing to do here
+ firstDocRendering = false;
}
- return hasHAS;
+ // apply gray out in the document display, or need to cleanup previous state even if no filter now
+ else{
+ displayFilterEffect();
+ }
}
- // Recursively ascend the DOM tree and find out our place in its branching structure
- private String getXPtr(Node n){
- if(n == null || n instanceof Document){
- return "";
- }
- Node parent = n.getParentNode();
- if(parent == null && n instanceof Attr){
- parent = ((Attr) n).getOwnerElement();
- }
-
- NodeList children = parent.getChildNodes();
- int nonElementCnt = 0;
- for(int i = 0; i < children.getLength(); i++){
- if(!(children.item(i) instanceof Element)){
- nonElementCnt++;
- continue;
- }
- if(n == children.item(i)){
- return getXPtr(parent)+"/"+(i-nonElementCnt+1);
- }
- }
- return null;
- }
/**
* Gray out parts of the HTML view if they are part of the filtered data.
@@ -1681,7 +1527,7 @@
// Gray out the mismatched textual data
for(Map.Entry<String,String> dataToFilter: filteredData.entrySet()){
- //System.err.println("Filtering "+dataToFilter.getKey());
+ System.err.println("Filtering "+dataToFilter.getKey());
javax.swing.text.AbstractDocument.AbstractElement htmlDiv =
(javax.swing.text.AbstractDocument.AbstractElement) d.getElement(dataToFilter.getKey());
if(htmlDiv == null){
@@ -1998,4 +1844,5 @@
public void lostOwnership(Clipboard clipboard, Transferable contents){
//System.err.println("Lost clipboard ownership");
}
+
}
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/gui/MobyServicesGUI.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/gui/MobyServicesGUI.java 2010/04/09 15:55:48 1.17
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/gui/MobyServicesGUI.java 2010/04/14 22:02:04 1.18
@@ -1,11 +1,11 @@
package ca.ucalgary.seahawk.gui;
import ca.ucalgary.seahawk.services.MobyClient;
-import ca.ucalgary.seahawk.util.HTMLUtils;
-import ca.ucalgary.seahawk.util.SeahawkOptions;
+import ca.ucalgary.seahawk.util.*;
import org.biomoby.shared.*;
import org.biomoby.shared.data.*;
+import org.biomoby.shared.parser.MobyTags;
import org.biomoby.client.CentralImpl;
import org.biomoby.client.MobyRequest;
import org.biomoby.client.MobyRequestEventHandler;
@@ -182,6 +182,7 @@
return handler;
}
+ // synchronized so simultaneous requests don't get their input data mixed up
public void setupServiceSecondaryData(MobyRequestEventHandler handler){
MobyDataInstance[] castInputs = new MobyDataInstance[primaryInput.length];
for(int i = 0; i < primaryInput.length; i++){
@@ -194,14 +195,17 @@
castInputs[i] = (MobyDataInstance) primaryInput[i];
}
- try{
- mobyRequest.setInput(castInputs);
- mobyRequest.setSecondaryInput(secondaryInputInstances);
- } catch(MobyException me){
- me.printStackTrace();
- logger.warn("Error while trying to set service input: " + me);
- }
- executeService(handler);
+ // code from mobyRequest.setInput() to executeService() should always be synced to avoid input mixup between requests
+ synchronized(mobyRequest){
+ try{
+ mobyRequest.setInput(castInputs);
+ mobyRequest.setSecondaryInput(secondaryInputInstances);
+ } catch(MobyException me){
+ me.printStackTrace();
+ logger.warn("Error while trying to set service input: " + me);
+ }
+ executeService(handler);
+ }
}
protected void setupService(MobyService mobyService, MobyDataInstance mdi, int handlerHashCode, boolean useDefaultSecondaries){
@@ -217,18 +221,21 @@
System.arraycopy(primaryInputTemplate, 0, primaryInput, 0, primaryInput.length);
if(!hasSecondaryInput(mobyService)){
- try{
- // Implement simple input (i.e. only one input argument)
- mobyRequest.setInput(mdi, "");
- }
- catch(MobyException me){
- logger.error("Failure in MOBY input, was not acceptable:" + me);
- return;
- }
+ // code from mobyRequest.setInput() to executeService() should always be synced to avoid input mixup between requests
+ synchronized(mobyRequest){
+ try{
+ // Implement simple input (i.e. only one input argument)
+ mobyRequest.setInput(mdi, "");
+ }
+ catch(MobyException me){
+ logger.error("Failure in MOBY input, was not acceptable:" + me);
+ return;
+ }
- // No need for further info, just launch the request
- removePopupOptions();
- executeService(getHandlerByHashCode(handlerHashCode));
+ // No need for further info, just launch the request
+ removePopupOptions();
+ executeService(getHandlerByHashCode(handlerHashCode));
+ }
}
else{
// We need more info from the user to launch this service
@@ -502,7 +509,8 @@
class OptionLoaderThread extends Thread{
Node targetNode = null;
MobyRequestEventHandler handler = null;
- MobyDataInstance mobyData = null;
+ MobyPayloadRequestListener payloadCreator = null;
+ Object mobyData = null;
String extraMenuText = null;
JPopupMenu popupList;
@@ -513,11 +521,13 @@
this.handler = handler;
}
- public OptionLoaderThread(MobyDataInstance mobyData, JPopupMenu popupList, MobyRequestEventHandler handler, String extraMenuText){
+ public OptionLoaderThread(Object mobyData, JPopupMenu popupList, MobyRequestEventHandler handler,
+ MobyPayloadRequestListener payloadCreator, String extraMenuText){
super();
this.mobyData = mobyData;
this.popupList = popupList;
this.handler = handler;
+ this.payloadCreator = payloadCreator;
this.extraMenuText = extraMenuText;
}
@@ -526,7 +536,7 @@
addPopupOptions(targetNode, popupList, false, handler);
}
else if(mobyData != null){
- addPopupOptions(mobyData, popupList, false, handler, extraMenuText);
+ addPopupOptions(mobyData, popupList, false, handler, payloadCreator, extraMenuText);
}
else{
logger.warn("Warning: OptionLoaderThread has no data to work with");
@@ -576,6 +586,30 @@
}
/**
+ * Creates a menu item based on the provided data type. If a service is selected from here,
+ * a callback will be made to the MobyPayloadRequestListener for the actual submission data.
+ *
+ * @param payloadKey a key that will be used in the callback so the listener knows what payload the create
+ */
+ public void addPopupOptions(MobyDataType mobyDataType, JPopupMenu popupList, boolean asynchronous,
+ MobyRequestEventHandler handler, MobyPayloadRequestListener payloadCreator,
+ String payloadKey, String extraMenuText){
+ addPopupOptions(mobyDataType, popupList, asynchronous, handler, payloadCreator, extraMenuText);
+ }
+
+ public void addPopupOptions(MobyNamespace mobyNamespace, JPopupMenu popupList, boolean asynchronous,
+ MobyRequestEventHandler handler, MobyPayloadRequestListener payloadCreator,
+ String payloadKey, String extraMenuText){
+ addPopupOptions(mobyNamespace, popupList, asynchronous, handler, payloadCreator, extraMenuText);
+ }
+
+ public void addPopupOptions(MobyPrimaryDataSet collection, JPopupMenu popupList, boolean asynchronous,
+ MobyRequestEventHandler handler, MobyPayloadRequestListener payloadCreator,
+ String payloadKey, String extraMenuText){
+ addPopupOptions(collection, popupList, asynchronous, handler, payloadCreator, extraMenuText);
+ }
+
+ /**
* Same as three arg addPopupOptions, but uses default response handler
*/
public void addPopupOptions(MobyDataInstance mobyData, JPopupMenu popupList, boolean asynchronous){
@@ -586,13 +620,16 @@
* Find the list of available services querying MobyCentral directly with a piece of data.
*/
public void addPopupOptions(MobyDataInstance mobyData, JPopupMenu popupList, boolean asynchronous, MobyRequestEventHandler handler){
- addPopupOptions(mobyData, popupList, asynchronous, handler, null);
+ addPopupOptions(mobyData, popupList, asynchronous, handler, null, null);
}
/**
* Find the list of available services querying MobyCentral directly with a piece of data.
+ *
+ * @param mobyData a MobyDataInstance, or in the case of deferred data to be created by payloadCreator, a MobyDataType, MobyNamespace, or MobyPrimaryDataSet
*/
- public void addPopupOptions(MobyDataInstance mobyData, JPopupMenu popupList, boolean asynchronous, MobyRequestEventHandler handler, String extraMenuText){
+ public void addPopupOptions(Object mobyData, JPopupMenu popupList, boolean asynchronous,
+ MobyRequestEventHandler handler, MobyPayloadRequestListener payloadCreator, String extraMenuText){
if(asynchronous){
//Show the user that we're doing something...
@@ -605,7 +642,7 @@
}
// Call this method synchronously in a different thread
- OptionLoaderThread lt = new OptionLoaderThread(mobyData, popupList, handler, extraMenuText);
+ OptionLoaderThread lt = new OptionLoaderThread(mobyData, popupList, handler, payloadCreator, extraMenuText);
lt.start();
return;
}
@@ -625,7 +662,9 @@
popupList.setVisible(true);
}
- addClipboardItem(submenu, mobyData);
+ if(mobyData instanceof MobyDataInstance){
+ addClipboardItem(submenu, (MobyDataInstance) mobyData);
+ }
submenu.add(getWaitItem(submenu));
MobyDataServiceAssocInstance serviceAssocObject = null;
@@ -637,6 +676,15 @@
else if(mobyData instanceof MobyDataObject){
serviceAssocObject = mobyClient.getServices((MobyDataObject) mobyData);
}
+ // The data will be loaded later
+ else if(payloadCreator != null){
+ if(mobyData instanceof MobyPrimaryDataSet){
+ //serviceAssocObject = mobyClient.getServices(new MobyDataObjectSetDeferred(mobyData, payloadCreator, requestKey));
+ }
+ else{
+ //serviceAssocObject = mobyClient.getServices(new MobyDataObjectDeferred(mobyData, payloadCreator, requestKey));
+ }
+ }
else{
logger.warn("Service options for objects other than MobyDataObject " +
"and MobyDataObjectSet are not yet supported.");
@@ -1136,51 +1184,50 @@
return menu;
}
- public JMenu createObjectSubMenu(MobyDataInstance mdi, String extraMenuText){
- if(!(mdi instanceof MobyPrimaryData)){
- logger.warn("Ignoring non-primary data object submitted to menu creation: " + mdi);
- return null;
- }
-
- MobyPrimaryData targetData = (MobyPrimaryData) mdi;
- String id = targetData.getId();
- if(id == null){
- id = "";
- }
- else if(id.length() > MAX_ID_LEN+3){
- id = id.substring(0, MAX_ID_LEN)+"...";
- }
-
- MobyDataType mobyDataType = targetData.getDataType();
- String name = null;
- if(mobyDataType == null){
- logger.warn("PG: Warning: no datatype associated with service " +
- targetData.getName());
- }
- else{
- name = mobyDataType.getName();
- }
- if("Object".equals(name)){
- MobyNamespace namespaces[] = targetData.getNamespaces();
- //System.err.println("Got base object with namespaces numbering " + namespaces.length);
- if(namespaces != null && namespaces.length > 0 && namespaces[0] != null){
- //System.err.println("Checking namespace "+ namespaces[0].getName());
- name = namespaces[0].getName();
+ /**
+ * Template object may be one of MobyPrimaryData, or in case of deferred content loading a
+ * MobyNamespace, MobyDataType, or MobyPrimaryDataSet.
+ */
+ public JMenu createObjectSubMenu(Object templateObject, String extraMenuText){
+ String id = null;
+ MobyDataType mobyDataType = null;
+ String name = null;
+ MobyNamespace[] namespaces = null;
+ if(templateObject instanceof MobyPrimaryData){
+ MobyPrimaryData targetData = (MobyPrimaryData) templateObject;
+ mobyDataType = targetData.getDataType();
+ namespaces = targetData.getNamespaces();
+ id = targetData.getId();
+ if(id == null){
+ id = "";
}
- }
- else{
- //System.err.println("Got complex object with datatype name " + name);
- }
+ else if(id.length() > MAX_ID_LEN+3){
+ id = id.substring(0, MAX_ID_LEN)+"...";
+ }
+ if(MobyTags.MOBYOBJECT.equals(mobyDataType.getName()) &&
+ namespaces != null && namespaces.length > 0 && namespaces[0] != null){
+ name = namespaces[0].getName();
+ }
+ else{
+ name = mobyDataType.getName();
+ }
+ }
+ else if(templateObject instanceof MobyNamespace){
+ namespaces = new MobyNamespace[]{(MobyNamespace) templateObject};
+ mobyDataType = MobyDataType.getDataType(MobyTags.MOBYOBJECT, SeahawkOptions.getRegistry());
+ name = ((MobyNamespace) templateObject).getName();
+ }
+ else if(templateObject instanceof MobyDataType){
+ mobyDataType = (MobyDataType) templateObject;
+ name = ((MobyDataType) templateObject).getName();
+ }
+ else{
+ logger.error("Could not create submenu for object of unaccepted type "+templateObject.getClass().getName());
+ }
- // Make sure we have a fully documented data type object
- mobyDataType = MobyDataType.getDataType(targetData.getDataType().getName(), SeahawkOptions.getRegistry());
String desc = null;
String datatype = null;
- if(mobyDataType == null){
- logger.warn("PG: Warning (submenu): no datatype associated with service " +
- targetData.getName());
- }
- else{
+ if(mobyDataType != null){
datatype = mobyDataType.getName();
desc = mobyDataType.getDescription();
if(desc == null || desc.length() == 0){
@@ -1189,19 +1236,12 @@
}
if(datatype != null && datatype.indexOf("objectclass:") != -1){
//LSID type URN, truncate the prefix and keep the part a user would care about (last part, the class name)
-
datatype = datatype.substring(datatype.indexOf("objectclass:")+12);
}
JMenu submenu = null;
- MobyNamespace[] namespaces = targetData.getNamespaces();
// If not defined, derive a description from the Data Namespace
- if(mobyDataType == null){
- desc = "Unknown datatype";
- submenu = new JMenu("Services for unknown datatype");
- assignMenuDataIndex(submenu);
- }
- else if("Object".equals(mobyDataType.getName())){
+ if(MobyTags.MOBYOBJECT.equals(mobyDataType.getName())){
String mobydesc = "?";
if(namespaces != null){
// Take the longest description
@@ -1214,20 +1254,30 @@
}
}
desc = "Record Identifier - " + mobydesc;
- submenu = new JMenu("Services for " + (extraMenuText == null ? "" : extraMenuText+" ")+datatype + ":" + id);
+ if(templateObject instanceof MobyDataObjectSet){
+ datatype += " collection";
+ }
+ submenu = new JMenu("<html>Services for " + (extraMenuText == null ? "" : extraMenuText+" ") +
+ datatype + (id == null ? "" : ":" + id)+"</html>");
assignMenuDataIndex(submenu);
}
- else if("String".equals(mobyDataType.getName())){
- String sample = targetData.getName();
- if(sample == null){
- sample = targetData.toString();
+ else if(MobyTags.MOBYSTRING.equals(mobyDataType.getName())){
+ String sample = "";
+ if(templateObject instanceof MobyDataInstance){
+ sample = ((MobyDataInstance) templateObject).getName();
+ if(sample == null){
+ sample = "\""+((MobyDataInstance) templateObject).toString()+"\"";
+ }
+ }
+ if(templateObject instanceof MobyDataObjectSet){
+ sample += " collection";
}
if(sample.length() > MAX_ID_LEN+3){
- sample = sample.substring(0, MAX_ID_LEN)+"...";
+ sample = "\""+sample.substring(0, MAX_ID_LEN)+"...\"";
}
desc = "A piece of text";
- submenu = new JMenu("Services for "+(extraMenuText == null ? "" : extraMenuText+" ")+
- "String \"" + sample + "\"");
+ submenu = new JMenu("<html>Services for "+(extraMenuText == null ? "" : extraMenuText+" ")+
+ "String " + sample+"</html>");
assignMenuDataIndex(submenu);
}
// Complex object
@@ -1240,17 +1290,18 @@
desc += "["+namespaceDesc+"]";
}
}
- if(targetData instanceof MobyDataObject && id != null && id.length() > 0){
+ if(templateObject instanceof MobyDataObject && id != null && id.length() > 0){
objectLabel += ":" + id;
}
- else if(targetData instanceof MobyDataObjectSet){
+ else if(templateObject instanceof MobyDataObjectSet){
objectLabel += " collection";
}
- submenu = new JMenu("Services for " + (extraMenuText == null ? "" : extraMenuText+" ")+objectLabel);
+ submenu = new JMenu("<html>Services for " + (extraMenuText == null ? "" : extraMenuText+" ")+objectLabel+"</html>");
assignMenuDataIndex(submenu);
}
desc = "Input data: " + desc;
desc = HTMLUtils.htmlifyToolTipText(desc, MAX_SERVICE_DESC_LEN);
+ System.err.println("New submenu has label " + submenu.getText());
submenu.setToolTipText(desc);
submenu.setName(SERVICE_SUBMENU_NAME);
return submenu;
More information about the MOBY-guts
mailing list