[MOBY-guts] biomoby commit

Paul Gordon gordonp at dev.open-bio.org
Mon Mar 12 14:38:38 UTC 2007


gordonp
Mon Mar 12 10:38:38 EDT 2007
Update of /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/services
In directory dev.open-bio.org:/tmp/cvs-serv3481/src/main/ca/ucalgary/seahawk/services

Modified Files:
	MobyComplexBuilder.java 
Log Message:
Added XPath evaluation to regex rules, and added function to get the returned data type from the rule
moby-live/Java/src/main/ca/ucalgary/seahawk/services MobyComplexBuilder.java,1.2,1.3
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/services/MobyComplexBuilder.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/services/MobyComplexBuilder.java	2007/02/08 16:59:58	1.2
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/services/MobyComplexBuilder.java	2007/03/12 14:38:38	1.3
@@ -1,13 +1,13 @@
 package ca.ucalgary.seahawk.services;
 
-import org.biomoby.shared.MobyDataType;
-import org.biomoby.shared.MobyException;
-import org.biomoby.shared.MobyNamespace;
-import org.biomoby.shared.MobyRelationship;
+import org.biomoby.shared.*;
 import org.biomoby.shared.data.MobyDataObject;
 import org.biomoby.shared.data.MobyDataComposite;
 
+import org.w3c.dom.Document;
+
 import javax.xml.xpath.*;
+import javax.xml.parsers.*;
 import javax.xml.namespace.NamespaceContext;
 
 import java.util.Iterator;
@@ -20,12 +20,26 @@
 
 public class MobyComplexBuilder{
 
+    private static XPathFactory xPathFactory;
+    private static DocumentBuilder docBuilder;
+
     private Map namespaceRules;
     private Map memberRules;
     private MobyDataType mobyDataType;
     private MobyNamespace[] mobyNS;
     private MobyRelationship[] children;
 
+    static{
+	xPathFactory = XPathFactory.newInstance();
+	DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+	dbf.setNamespaceAware(true);
+	try{
+	    docBuilder = dbf.newDocumentBuilder();
+	} catch(Exception e){
+	    e.printStackTrace();
+	}
+    }
+
     public MobyComplexBuilder(String dataType, Map members, Map nameSpaces) throws Exception{
 	mobyDataType = MobyDataType.getDataType(dataType);
 	// Not an existing Ontology data type
@@ -87,6 +101,10 @@
     }
 
     public MobyDataObject apply(Matcher matcher) throws MobyException{
+	return apply(matcher, null);
+    }
+
+    public MobyDataObject apply(Matcher matcher, byte[] data) throws MobyException{
 	MobyDataObject mobyObj = null;
 	
 	if(mobyDataType.getName().equals("Object")){
@@ -123,16 +141,87 @@
 	    }
 	}
 
+	Document doc = docBuilder.newDocument();
 	// Set members if available and required
 	if(mobyObj instanceof MobyDataComposite){
 	    if(children != null){
 		for(int i = 0; i < children.length; i++){
 		    String memberName = children[i].getName();
-		    String result = (String) memberRules.get(memberName);
+		    String[] resultSpec = (String[]) memberRules.get(memberName);
+		    String result = resultSpec[0];
+		    byte[] resultBytes = result.getBytes();
+		    String whitespaceMode = resultSpec[1];
+		    String encodingMode = resultSpec[2];
+
+		    boolean nonBasic = result.length() != 2 || result.indexOf("$") != 0;
+		    MobyPrefixResolver.MobyNodeList nodeList = new MobyPrefixResolver.MobyNodeList();
 		    // Replace any $0, $1, etc. in the replacement string with the values found in the matcher
+		    // Note that this is not perfect: if you had "$1 $2", and $1 had value "$250", you'd get $250$2,
+		    // then you'd substitute $2's value of "per metre", you'd get "per metre50 per metre" instead of
+		    // "$250 per metre".  Not sure of a good way around this yet (i.e. when varValue had $k in it where k > j)...
 		    for(int j = 0; j <= matcher.groupCount(); j++){
-			result = result.replaceAll("\\$"+j, matcher.group(j));
+			// A replaceAll() for binary data
+			if(data != null){
+			    (new Exception("Binary replaceAll()")).printStackTrace();
+			    int srcPos = 0;
+			    for(int varIndex = result.indexOf("\\$"+j, srcPos); 
+				varIndex != -1; 
+				varIndex = result.indexOf("\\$"+j, srcPos)){
+				int varValueLength = matcher.end(j)-matcher.start(j)+1;
+
+				byte[] newResultBytes = new byte[resultBytes.length+varValueLength];
+			        if(varIndex > 0){
+				    System.arraycopy(resultBytes, 0, newResultBytes, 0, varIndex);
+				}
+			        System.arraycopy(data, matcher.start(j), newResultBytes, varIndex, varValueLength);
+				int remaining = result.length()-varIndex-2;
+				if(remaining > 0){
+				    System.arraycopy(resultBytes, varIndex+2, newResultBytes, varIndex+varValueLength, 
+						     result.length()-varIndex-2);
+				}
+				srcPos += varIndex + varValueLength + 1;
+				resultBytes = newResultBytes;
+			    }
+			}
+			// $# substitution in a string, considerably simpler!
+			else{
+			    String varValue = matcher.group(j);
+			    if(whitespaceMode.equals(MobyClient.WHITESPACE_ATTR_NORMALIZE_VAL)){
+				varValue = varValue.replaceAll("\\s+"," ");
+			    }
+			    else if(whitespaceMode.equals(MobyClient.WHITESPACE_ATTR_STRIP_VAL)){
+				varValue = varValue.replaceAll("\\s+","");
+			    }
+			    result = result.replaceAll("\\$"+j, varValue);
+
+			    // Binary data and XPath are incompatible, since many bytes are not allowed in XML
+			    // so only create the node list if not Base64 encoding
+			    nodeList.add(doc.createTextNode(result));
+			}
 		    }
+
+		    if(encodingMode.equals(MobyClient.ENCODING_ATTR_BASE64_VAL)){
+			(new Exception("Base 64 encoding")).printStackTrace();
+			result = org.apache.axis.encoding.Base64.encode(data == null ? result.getBytes() : resultBytes);
+		    }
+		    else{
+			System.err.println("NO BASE64 (" + MobyClient.ENCODING_ATTR_BASE64_VAL + 
+					   ") ENCODING for " +memberName+": " + encodingMode);
+		    }
+
+		    // If the value contains anything other than $#, treat it as a XPath expression 
+		    // to be evaluated on a text node containing the result value 
+		    if(nonBasic && data == null){
+			XPath xpath = xPathFactory.newXPath();
+			try{
+			    result = xpath.evaluate(result, nodeList);
+			}catch(Exception e){
+			    e.printStackTrace();
+			    throw new MobyException("Could not evaluate result of XPath expression for object member " + 
+						    memberName + " (" + result + "): " + e);
+			}
+		    }
+
 		    ((MobyDataComposite) mobyObj).put(memberName, 
 						      MobyDataObject.createInstanceFromString(children[i].getDataTypeName(), result));
 		}
@@ -143,7 +232,7 @@
     }
 
     public MobyDataObject applyXPath(Object result, NamespaceContext nsContext) throws MobyException, XPathExpressionException{
-	XPath xpath = XPathFactory.newInstance().newXPath();
+	XPath xpath = xPathFactory.newXPath();
 	xpath.setNamespaceContext(nsContext);
 	MobyDataObject mobyObj = null;
 	
@@ -184,7 +273,7 @@
 	    if(children != null){
 		for(int i = 0; i < children.length; i++){
 		    String memberName = children[i].getName();
-		    String expr = (String) memberRules.get(memberName);
+		    String expr = ((String[]) memberRules.get(memberName))[0];
 		    String value = xpath.evaluate(expr, result);
 
 		    ((MobyDataComposite) mobyObj).put(memberName, 
@@ -195,4 +284,12 @@
 
 	return mobyObj;
     }
+
+    /**
+     * Reports the data type of the objects returned by matched rules.
+     */
+    public MobyDataType getDataType(){
+	//System.err.println("Returning data type of " + mobyDataType.getName());
+	return mobyDataType;
+    }
 }




More information about the MOBY-guts mailing list