[MOBY-guts] biomoby commit
Paul Gordon
gordonp at dev.open-bio.org
Wed Apr 14 22:02:05 UTC 2010
gordonp
Wed Apr 14 18:02:04 EDT 2010
Update of /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util
In directory dev.open-bio.org:/tmp/cvs-serv7013/src/main/ca/ucalgary/seahawk/util
Modified Files:
DataUtils.java FilterSearch.java
Added Files:
MobyPayloadRequestListener.java MutableNodeList.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/util MobyPayloadRequestListener.java,NONE,1.1 MutableNodeList.java,NONE,1.1 DataUtils.java,1.4,1.5 FilterSearch.java,1.4,1.5
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util/DataUtils.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util/DataUtils.java 2010/04/11 20:15:28 1.4
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util/DataUtils.java 2010/04/14 22:02:04 1.5
@@ -4,6 +4,7 @@
import java.net.URL;
import java.util.*;
import java.util.logging.*;
+import java.util.regex.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
@@ -34,8 +35,12 @@
public static final String TEMP_FILE_PREFIX = "seahawk";
private static final String OUTPUT_SUFFIX = ".out.xml";
private static final String INPUT_SUFFIX = ".in.xml";
- private static DocumentBuilder docBuilder;
+ public static DocumentBuilder docBuilder;
private static Transformer identityTransform;
+ public static XPathFactory xPathFactory;
+
+ public static final String ARTICLE_PEERS_MODE = "article_peers";
+ public static final String DATATYPE_PEERS_MODE = "datatype_peers";
private static Logger logger = Logger.getLogger(DataUtils.class.getName());
@@ -54,6 +59,8 @@
} catch(Exception e){
logger.log(Level.SEVERE, "Cannot get identity XSLT transform from configuration", e);
}
+
+ xPathFactory = XPathFactory.newInstance();
}
/**
@@ -176,7 +183,7 @@
// User data has the form srcURL#XpathSelectCriteria <tab> xptrActualDataSubmitted <tab> regexFilter
// where the filter is optional
String[] data = sampleData.getUserData().toString().split("\t");
- System.err.println("Forward user data is " + sampleData.getUserData().toString());
+ //System.err.println("Forward user data is " + sampleData.getUserData().toString());
URL dataSrcURL = null;
try{
dataSrcURL = new URL(data[0]);
@@ -437,7 +444,7 @@
"sync: the instance job '" + jobName +
"' has no parameter '" + paramName + "'");
}
- System.err.println("Setting user data val to " + attrValue + " for " + paramName);
+ //System.err.println("Setting user data val to " + attrValue + " for " + paramName);
contentInstance.get(jobName).get(paramName).setUserData(attrValue);
}
else{
@@ -451,24 +458,47 @@
}
/**
- * Get the data instance object associated with a given XPointer into a Moby XML doc
+ * Loads targetURL, minus the nodes specified by the xpath keys in filteredXPtrs (map values are not currently used).
+ */
+ public static void filterDoc(Document domDoc, Map<String,String> filteredXPtrs){
+
+ if(domDoc == null){
+ logger.log(Level.SEVERE, "Error: Could not get MOBY document as DOM (empty or malformed document?)");
+ return;
+ }
+
+ // Remove the filtered data from the doc before deserializing to a moby data instance
+ // That way the request actually reflects what is shown on the screen to the user.
+ if(filteredXPtrs != null){
+ // Mark and sweep (if we just deleted as we found nodes, the XPointers could be
+ // wrong as they refer to ordinality)
+ Vector<Node> nodesToDelete = new Vector<Node>();
+ for(String xptr: filteredXPtrs.keySet()){
+ nodesToDelete.add(XPointerResolver.getNodeFromXPointer(domDoc, xptr));
+ }
+
+ // Delete
+ for(Node nodeToDelete: nodesToDelete){
+ Node parent = nodeToDelete.getParentNode();
+ parent.removeChild(nodeToDelete);
+ // Get rid of Simple parents of deleted nodes, because empty Simple
+ // tags are not okay in Moby (causes parsing error)
+ if(MobyTags.SIMPLE.equals(parent.getLocalName())){
+ parent.getParentNode().removeChild(parent);
+ }
+ }
+ }
+ }
+
+ /**
+ * Get the data instance object associated with a given XPointer in a Moby XML doc.
*
* @param targetURL of the form URLpath#/1/1/2/1 where /1/1/2/1 is an XPointer, or an standard xpath, to the part of the Moby XML doc to deserialize
* @param filteredXPtrs a map of the xpointers to data that should NOT be deserialized if children of the targetURL XPointer
* @param docFilter the current filter applied to the document in targetURL
*/
public static MobyDataInstance loadMobyDataFromXPointer(URL targetURL, Map<String,String> filteredXPtrs, FilterSearch docFilter){
- // Are we dealing with a simple object or a complex one?
- MobyDataInstance mobyData = null;
-
- // Find the DOM fragment corresponding to the MOBY ID anchor specified
- // in the link URL by using an XPath statement on the source MOBY doc
- //System.err.println("Retrieving complex object from XPointer " + targetURL);
-
- // A child Xpointer is of the form /1/2/1/1, specifying the DOM child
- // descent path from the root node to get to the target node. The
- // equivalent XPath is /*[1]/*[2]/*[1]/*[1]
- String childXPath = targetURL.getRef().replaceAll("/(\\d+)", "/*[$1]");
+
URL currentURL = null;
try{currentURL = new URL(targetURL.toString().replaceAll("#"+targetURL.getRef(), ""));}
catch(Exception e){
@@ -476,7 +506,6 @@
}
// Build the DOM
- Element mobyDOMRoot = null;
Document domDoc = null;
try{
domDoc = docBuilder.parse(targetURL.openStream());
@@ -489,46 +518,29 @@
" could not be read (from " + targetURL + ")", ioe);
return null;
}
+ // Does an in-place edit of domDoc
+ filterDoc(domDoc, filteredXPtrs);
+
+ // Are we dealing with a simple object or a complex one?
+ MobyDataInstance mobyData = null;
- if(domDoc != null){
- mobyDOMRoot = domDoc.getDocumentElement();
- }
- if(mobyDOMRoot == null){
- logger.log(Level.SEVERE, "Error: Could not get MOBY document as DOM from source URL " +
- targetURL + " (empty or malformed document?)");
- return null;
- }
+ // Find the DOM fragment corresponding to the MOBY ID anchor specified
+ // in the link URL by using an XPath statement on the source MOBY doc
+ //System.err.println("Retrieving complex object from XPointer " + targetURL);
- // Remove the filtered data from the doc before deserializing to a moby data instance
- // That way the request actually reflects what is shown on the screen to the user.
- if(filteredXPtrs != null){
- // Mark and sweep (if we just deleted as we found node, the XPointers could be
- // wrong as they refer to ordinality)
- Vector<Node> nodesToDelete = new Vector<Node>();
- for(String xptr: filteredXPtrs.keySet()){
- nodesToDelete.add(XPointerResolver.getNodeFromXPointer(domDoc, xptr));
- }
-
- // Delete
- for(Node nodeToDelete: nodesToDelete){
- Node parent = nodeToDelete.getParentNode();
- parent.removeChild(nodeToDelete);
- // Get rid of Simple parents of deleted nodes, because empty Simple
- // tags are not okay in Moby (causes parsing error)
- if(MobyTags.SIMPLE.equals(parent.getLocalName())){
- parent.getParentNode().removeChild(parent);
- }
- }
- }
+ // A child Xpointer is of the form /1/2/1/1, specifying the DOM child
+ // descent path from the root node to get to the target node. The
+ // equivalent XPath is /*[1]/*[2]/*[1]/*[1]
+ String childXPath = targetURL.getRef().replaceAll("/(\\d+)", "/*[$1]");
// Build and run the XPath statement
Element mobyObject = null;
NodeList idSearchResult = null;
Object xobject = null;
try{
- xobject = XPathFactory.newInstance().newXPath().evaluate(childXPath,
- domDoc,
- XPathConstants.NODESET);
+ xobject = xPathFactory.newXPath().evaluate(childXPath,
+ domDoc,
+ XPathConstants.NODESET);
// Check the results
if(xobject != null){
@@ -603,7 +615,7 @@
* Generalizes the element instance into an XPath retrieving it and all
* similarly nested elements (based on traversing the parent nodes and prepending their names)
*/
- protected static String elementInContextToNameBasedXPath(Element targetElement){
+ public static String elementInContextToNameBasedXPath(Element targetElement){
String xpath = "";
for(Element currentElement = targetElement;
@@ -630,22 +642,20 @@
xpath = "/*[@"+MobyTags.OBJ_NAMESPACE + " = '" +
currentElement.getAttribute(MobyTags.OBJ_NAMESPACE)+"']" + xpath;
}
- else if(elName.equals(MobyTags.MOBYFLOAT) ||
- elName.equals(MobyTags.MOBYSTRING) ||
- elName.equals(MobyTags.MOBYBOOLEAN) ||
- elName.equals(MobyTags.MOBYINTEGER) ||
- elName.equals(MobyTags.MOBYDATETIME)){
+// else if(elName.equals(MobyTags.MOBYFLOAT) ||
+// elName.equals(MobyTags.MOBYSTRING) ||
+// elName.equals(MobyTags.MOBYBOOLEAN) ||
+// elName.equals(MobyTags.MOBYINTEGER) ||
+// elName.equals(MobyTags.MOBYDATETIME)){
// Assume that it isn't the primitive type, but rather the articleName
// that makes it appropriate to use.
- xpath = "/*[@"+MobyTags.ARTICLENAME + " = '" +
- articleName+"']" + xpath;
- }
+// xpath = "/*[@"+MobyTags.ARTICLENAME + " = '" +
+// articleName+"']" + xpath;
+// }
else{
// It's a complex type. Assume the type is why we are picking it.
// TODO: In future we may want to check if a parent type is allowed in
- // this slot, and generalize to that. May also want to check that there isn't more
- // than one member of this type at this level in a HAS relationship...
- // in that case we probably want to go by articleName to catch the full semantics
+ // this slot, and generalize to that.
xpath = "/"+elName + xpath;
}
if(!(currentElement.getParentNode() instanceof Element)){
@@ -696,6 +706,12 @@
}
/**
+ * Replace the selection xpath info in the data instance
+ */
+ public static void replaceUserData(MobyDataInstance mdi, String selectionXPath){
+ }
+
+ /**
* Retrieves processing instructions embedded in Moby XML docs if they have the for <?seahawk attr="val"?>
*/
public static String getSeahawkAttrFromDoc(URL docURL, String attrName) throws Exception{
@@ -777,4 +793,328 @@
"any_namespace");
}
+ // Recursively ascend the DOM tree and find out our place in its branching structure
+ public static 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;
+ }
+
+ /**
+ * If any moby object member is in a HAS relationship, add it to the list of filterable items
+ */
+ public static 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.log(Level.WARNING,
+ "Found datatype unknown to the registry ("+object.getLocalName()+")");
+ return Boolean.FALSE;
+ }
+ }
+
+ 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;
+ }
+ }
+ }
+ }
+ return hasHAS;
+ }
+
+ /**
+ * For one-off filtering of a doc. Populates xPtrsToFilter, and returns the
+ * whole doc which you can manipulate yourself (e.g. removing the nodes identified).
+ */
+ public static Document findFilteredNodes(URL targetURL, FilterSearch filter,
+ Map<String,String> xPtrsToFilter){
+ Document unfilteredDoc = null;
+ try{
+ unfilteredDoc = docBuilder.parse(targetURL.openStream());
+ } catch(Exception e){
+ logger.log(Level.SEVERE,
+ "Could not parse Moby document " + targetURL, e);
+ return null;
+ }
+ findFilteredNodes(unfilteredDoc, filter, null, xPtrsToFilter, null, null, null, true);
+ return unfilteredDoc;
+ }
+
+ /**
+ * Returns a list of xptrs to filterable nodes in the targetDoc, an populates the list of
+ * xptrs that should be filtered according to the provided filter. In-place edited fields are
+ * xPtrsToFilter, jobXPtrs, currentSelectedData, and currentSelectionXPath
+ * (for caching efficiency on multiple consecutive
+ * calls to this method, such as a live typed search in the UI). The latter three can be null if no caching is desired.
+ */
+ public static List<String> findFilteredNodes(Document targetDoc, FilterSearch filter, List<String> filterableXPtrs,
+ Map<String,String> xPtrsToFilter, Map<String,Boolean> jobXPtrs,
+ MutableNodeList currentSelectedData, StringBuffer currentSelectionXPath,
+ boolean apply){
+ xPtrsToFilter.clear();
+
+ // Filter out any moby jobs, parameters, collection members or HAS members that aren't in the matchingNodes
+ if(filterableXPtrs == null){
+ if(jobXPtrs == null){
+ jobXPtrs = new HashMap<String,Boolean>();
+ }
+ else{
+ jobXPtrs.clear();
+ }
+ filterableXPtrs = new Vector<String>();
+ NodeList nodes = targetDoc.getElementsByTagNameNS(MobyTags.MOBY_XML_NS, MobyTags.MOBYDATA);
+ for(int i = 0; i < nodes.getLength(); i++){
+ String jobXPtr = getXPtr(nodes.item(i));
+ filterableXPtrs.add(jobXPtr);
+ jobXPtrs.put(jobXPtr, addHASXPtrs(filterableXPtrs, (Element) nodes.item(i)));
+ }
+
+ // Collections
+ nodes = targetDoc.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;
+ }
+ filterableXPtrs.add(collectionXPtr+"/"+(j-nonElementCnt+1)+"/1");
+ }
+ }
+ }
+
+ if(!apply || filter == null || filter.getFilterRegex().toString().length() == 0){
+ return filterableXPtrs;
+ }
+ // Otherwise make a list of xpointers to data that should be filtered
+ XPathOption xsel = filter.getSelectedXPath();
+
+ // Find the applicable DOM nodes if not yet found, or if selection criteria have changed
+ if(currentSelectedData == null || currentSelectedData.isEmpty() ||
+ currentSelectionXPath == null || !currentSelectionXPath.toString().equals(xsel.getXPath())){
+ if(currentSelectionXPath == null){
+ currentSelectionXPath = new StringBuffer(xsel.getXPath());
+ }
+ else{
+ currentSelectionXPath.replace(0, currentSelectionXPath.length(), xsel.getXPath());
+ }
+ try{
+ if(currentSelectedData == null){
+ currentSelectedData = new MutableNodeList();
+ }
+ else{
+ currentSelectedData.clear();
+ }
+ currentSelectedData.addAll((NodeList) xPathFactory.newXPath().evaluate(currentSelectionXPath.toString(),
+ targetDoc,
+ XPathConstants.NODESET));
+ } catch(Exception e){
+ logger.log(Level.SEVERE,
+ "Could not evaluate XPath (" + xsel.getXPath() + ")", e);
+ return filterableXPtrs;
+ }
+ // 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(filter.getFilterRegex().toString(),
+ Pattern.MULTILINE | Pattern.DOTALL |
+ (filter.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.log(Level.WARNING,
+ "Found filter xpath result item that was not an Element or Attribute as expected ("+
+ node.getClass().getName()+")");
+ }
+ }
+
+ boolean inversed = filter.getSelectionInversed();
+ Map<String,Boolean> parentMatchingXPtrs = new LinkedHashMap<String,Boolean>();
+ for(String currXPtr: filterableXPtrs){
+ 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.toString().equals(FilterSearch.SELECT_ALL_XPATH) || jobXPtrs.containsKey(currXPtr))){
+ shouldFilter = true;
+ }
+ if(!inversed && shouldFilter ||
+ inversed && !shouldFilter){
+ xPtrsToFilter.put(currXPtr, "todo");
+ }
+ }
+
+ //todo: filter objects without the HAS field at all...
+ return filterableXPtrs;
+ }
+ // We need to enumerate the possible peer-sets for the selected data item. Is the user interested in
+ // items in the same namespace, same data type, or same article name?
+ public static NodeList getPeerElements(Document doc, MobyDataInstance mobyData, String peerMode){
+ if(!(mobyData instanceof MobyPrimaryData)){
+ logger.log(Level.WARNING, "Tried to get peers of data that was not an instanceof MobyPrimaryData (was " +
+ mobyData.getClass().getName()+ ")");
+ return null;
+ }
+ MobyDataType dataTypeTemplate = ((MobyPrimaryData) mobyData).getDataType();
+
+ NodeList peerElements = null;
+ String peerGroupXPath = null;
+ if(mobyData.getUserData() != null){
+ String[] userData = ((String) mobyData.getUserData()).split("\t");
+ // first arg is url#nameBasedXPath
+ peerGroupXPath = userData[0].split("#", 2)[1];
+ }
+ else{
+ // Fallback is to get all nodes with the same name...
+ // warning: need to set this in the userdata sent to the job, to jibe with taverna workflow export selection of nodes!
+ logger.log(Level.WARNING, "No UserData for data instance, falling back to all peer elements of the same datatype");
+ peerGroupXPath = "//"+dataTypeTemplate.getName();
+ }
+
+ // just look at data type tag, regardless of nesting
+ if(DATATYPE_PEERS_MODE.equals(peerMode)){
+ peerGroupXPath = peerGroupXPath.replaceFirst("^.+/", "//");
+ }
+ else if(ARTICLE_PEERS_MODE.equals(peerMode)){
+ String xpathArticleCondition = "[@"+MobyTags.ARTICLENAME + "='" + mobyData.getName() +"']";
+ // Pass back modified selection xpath for userdata (enables PBE to capture the additonal semantics)
+ // This is done by replacing first tab delimited field url#selectionXPath with url#newXPath
+ String newUserData = mobyData.getUserData().toString().replaceFirst("^(.*?)#.*?(?=\\t)",
+ "$1#"+peerGroupXPath+xpathArticleCondition);
+ mobyData.setUserData(newUserData);
+
+ // keep from job article name down
+ peerGroupXPath = peerGroupXPath.replaceFirst("^.*/(Collection|Simple)", "//*");
+ // we want to go by articleName too to catch the full semantics of the peer group definition
+ peerGroupXPath += xpathArticleCondition;
+ }
+ else{
+ logger.log(Level.SEVERE, "Got unknown mode for peer selection, aborting (mode was "+peerMode+")");
+ return null;
+ }
+ // For xpaths given above, MOBY namespace is problem in XPath evaluation.
+ // solution: eliminate Moby envelope path parts: full path doesn't resolve in xpath for unknown reasons
+ //.replaceAll("/(MOBY|mobyContent|mobyData|Collection|Simple)","/moby:$1"); //attempt 1
+ //.replaceAll("/([a-zA-Z_0-9\\-]+)(?=/|$)", "/*[local-name() = '$1']") //attempt 2
+ //.replaceAll("/([a-zA-Z_0-9\\-]+)\\[", "/*[local-name() = '$1' and "); //attempt 2 cont'd
+
+ try{
+ peerElements = (NodeList) xPathFactory.newXPath().evaluate(peerGroupXPath,
+ doc,
+ XPathConstants.NODESET);
+ } catch(Exception e){
+ logger.log(Level.SEVERE, "Could not evaluate UserData XPath "+peerGroupXPath, e);
+ }
+ System.err.println("Got " + peerElements.getLength() + " peers for " + peerGroupXPath);
+
+ return peerElements;
+ }
+
+ // given a node from a Moby XML dom, find the name of the mobyData job that's its parent
+ public static String findMobyJobName(Node n){
+ while(n != null && !n.getLocalName().equals(MobyTags.MOBYDATA)){
+ n = n.getParentNode();
+ }
+ if(n == null){
+ return null; // no mobyData parent
+ }
+ else{
+ return MobyPrefixResolver.getAttr((Element) n, MobyTags.QUERYID);
+ }
+ }
}
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util/FilterSearch.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util/FilterSearch.java 2010/04/10 00:40:17 1.4
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util/FilterSearch.java 2010/04/14 22:02:04 1.5
@@ -28,6 +28,20 @@
public static final String SELECT_ALL_XPATH = "//* | //*/@*";
/**
+ * A c-tor to manually populate the filter with a specific set of filter criteria.
+ * No autopoulation of options is done.
+ */
+ public FilterSearch(String regex, XPathOption xpath, boolean case_sensitive, boolean inverse_selection){
+ filterRegex = new StringBuffer(regex);
+ xpathOptions = new Vector<XPathOption>();
+ xpathOptions.add(xpath);
+ setCaseSensitivity(case_sensitive);
+ setSelectionInversed(inverse_selection);
+ }
+
+ /**
+ * Autopopulates the possible search field values based on the incoming doc
+ *
* @param docToFilter the document that will be used to determine what XPaths can be suggested
* @param docBuilder the xml parser to use on the document
*
@@ -106,4 +120,15 @@
public Vector<XPathOption> getXPathOptions(){
return xpathOptions;
}
+
+ public boolean equals(Object o){
+ if(o == null || !(o instanceof FilterSearch)){
+ return false;
+ }
+ FilterSearch other = (FilterSearch) o;
+ return filterRegex.toString().equals(other.filterRegex.toString()) &&
+ getSelectedXPath().getXPath().equals(other.getSelectedXPath().getXPath()) &&
+ caseSensitivity == other.caseSensitivity &&
+ inverseSelection == other.inverseSelection;
+ }
}
More information about the MOBY-guts
mailing list