[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