[MOBY-guts] biomoby commit

Paul Gordon gordonp at dev.open-bio.org
Sun Apr 8 17:26:25 UTC 2007


gordonp
Sun Apr  8 13:26:25 EDT 2007
Update of /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/services
In directory dev.open-bio.org:/tmp/cvs-serv21020/src/main/ca/ucalgary/seahawk/services

Modified Files:
	MobyClient.java MobyComplexBuilder.java 
Log Message:
Refactored rule evaluation code for reuse, and added support for assigning an article name to created objects
moby-live/Java/src/main/ca/ucalgary/seahawk/services MobyClient.java,1.9,1.10 MobyComplexBuilder.java,1.4,1.5
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/services/MobyClient.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/services/MobyClient.java	2007/04/04 01:31:38	1.9
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/services/MobyClient.java	2007/04/08 17:26:24	1.10
@@ -41,6 +41,7 @@
     public static final String RULE_SET_TAG = "object";
     public static final String PREFIX_TAG = "prefix";
     public static final String PREFIX_ATTR = "value";
+    public static final String ARTICLENAME_RULE_TAG = "articlename";
     public static final String NAMESPACE_RULE_TAG = "namespace";
     public static final String NAMESPACE_VALUE_TAG = "ns";
     public static final String NAMESPACE_VALUE_ATTR = "value";
@@ -195,9 +196,10 @@
 	    Vector regexStrings = new Vector();
 	    Vector urlRegexStrings = new Vector();
 	    Vector xpathStrings = new Vector();
-	    Map namespaceMap = new HashMap();
-	    Map memberMap = new HashMap();
+	    Map<String,String> namespaceMap = new HashMap<String,String>();
+	    Map<String,String[]> memberMap = new HashMap<String,String[]>();
 	    String dataTypeString = null;
+	    String articleNameString = null;
 
 	    NodeList ruleMembers = ruleSet.getChildNodes();
 	    for(int j = 0; j < ruleMembers.getLength(); j++){
@@ -221,6 +223,15 @@
 		else if(isNamespaceRule(ruleMember)){
 		    addNamespaceMapping(ruleMember, namespaceMap);
 		}
+		else if(isArticleNameRule(ruleMember)){
+		    if(articleNameString != null && articleNameString.length() != 0){
+			System.err.println("Skipping unexpected article name definition node, " +
+					   "a valid article name rule has already been " +
+					   "created for this ruleset");
+			continue;
+		    }
+		    articleNameString = ruleMember.getTextContent();
+		}
 		else if(isDataTypeRule(ruleMember)){
 		    if(dataTypeString != null && dataTypeString.length() != 0){
 			System.err.println("Skipping unexpected datatype definition node, " +
@@ -257,13 +268,13 @@
 		}
 
 		for(int j = 0; j < xpathStrings.size(); j++){
-		    addXPathMapping((String) xpathStrings.elementAt(j), namespaceMap);
+		    addXPathMapping((String) xpathStrings.elementAt(j), namespaceMap, articleNameString);
 		}
 		for(int j = 0; j < regexStrings.size(); j++){
-		    addRegexMapping((String) regexStrings.elementAt(j), namespaceMap);
+		    addRegexMapping((String) regexStrings.elementAt(j), namespaceMap, articleNameString);
 		}
 		for(int j = 0; j < urlRegexStrings.size(); j++){
-		    addURLRegexMapping((String) urlRegexStrings.elementAt(j), namespaceMap);
+		    addURLRegexMapping((String) urlRegexStrings.elementAt(j), namespaceMap, articleNameString);
 		}
 	    }
 	    // Build complex object
@@ -274,13 +285,13 @@
 		}
 
 		for(int j = 0; j < xpathStrings.size(); j++){
-		    addXPathMapping((String) xpathStrings.elementAt(j), namespaceMap, dataTypeString, memberMap);
+		    addXPathMapping((String) xpathStrings.elementAt(j), namespaceMap, dataTypeString, memberMap, articleNameString);
 		}
 		for(int j = 0; j < regexStrings.size(); j++){
-		    addRegexMapping((String) regexStrings.elementAt(j), namespaceMap, dataTypeString, memberMap);
+		    addRegexMapping((String) regexStrings.elementAt(j), namespaceMap, dataTypeString, memberMap, articleNameString);
 		}
 		for(int j = 0; j < urlRegexStrings.size(); j++){
-		    addURLRegexMapping((String) urlRegexStrings.elementAt(j), namespaceMap, dataTypeString, memberMap);
+		    addURLRegexMapping((String) urlRegexStrings.elementAt(j), namespaceMap, dataTypeString, memberMap, articleNameString);
 		}
 	    }
 
@@ -307,6 +318,10 @@
 	return e != null && DATATYPE_RULE_TAG.equals(e.getLocalName());
     }
 
+    public boolean isArticleNameRule(Element e){
+	return e != null && ARTICLENAME_RULE_TAG.equals(e.getLocalName());
+    }
+
     public boolean isMemberRule(Element e){
 	return e != null && MEMBER_RULE_TAG.equals(e.getLocalName());
     }
@@ -379,7 +394,7 @@
 	return str;
     }
 
-    protected void addMemberMapping(Element memTag, Map membersMap) throws Exception{
+    protected void addMemberMapping(Element memTag, Map<String,String[]> membersMap) throws Exception{
 	if(!isMemberRule(memTag)){
 	    throw new Exception("Element provided to addMemberMapping (" +
 				(memTag == null ? null : memTag.getLocalName()) + 
@@ -432,7 +447,7 @@
 						   memberEncodingSetting});
     }
 
-    protected void addNamespaceMapping(Element nsTag, Map namespaceStrings) throws Exception{
+    protected void addNamespaceMapping(Element nsTag, Map<String,String> namespaceStrings) throws Exception{
 	if(!isNamespaceRule(nsTag)){
 	    throw new Exception("Element provided to createNamespaceMapping (" +
 				(nsTag == null ? null : nsTag.getLocalName()) + 
@@ -945,20 +960,24 @@
     }
 
     public void addRegexMapping(String regexp, String[] mobyObj){ //mobyObj<--mobyNamespaces
+	addRegexMapping(regexp, mobyObj, null);
+    }
+
+    public void addRegexMapping(String regexp, String[] mobyObj, String articleName){ //mobyObj<--mobyNamespaces
 	if(mobyObj == null){
 	    System.err.println("Ignoring empty namespace-only regex rule mappings");
 	    return;
 	}
 
-	Map nsRules = new HashMap();
+	Map<String,String> nsRules = new HashMap<String,String>();
 	// Default the rule to taking the whole matched expression ($0)
 	for(int i = 0; i < mobyObj.length; i++){
 	    nsRules.put(mobyObj[i], "$0");
 	}
-	addRegexMapping(regexp, nsRules);
+	addRegexMapping(regexp, nsRules, articleName);
     }
 
-    public void addURLRegexMapping(String url_regexp, String[] mobyObj){ //mobyObj<--mobyNamespaces
+    public void addURLRegexMapping(String url_regexp, String[] mobyObj, String articleName){ //mobyObj<--mobyNamespaces
 	if(mobyObj == null){
 	    System.err.println("Ignoring empty namespace-only url regex rule mappings");
 	    return;
@@ -969,7 +988,7 @@
 	for(int i = 0; i < mobyObj.length; i++){
 	    url_nsRules.put(mobyObj[i], "$1");
 	}
-	addURLRegexMapping(url_regexp, url_nsRules);
+	addURLRegexMapping(url_regexp, url_nsRules, articleName);
     }
 
     /**
@@ -999,25 +1018,30 @@
 	return url_regex_flexible;
     }
 
-    protected void addRegexMapping(String regexp, Map nsRules){ //nsRules = Map<String ns, String regex_replacement>
+    protected void addRegexMapping(String regexp, Map<String,String> nsRules, String articleName){ //nsRules = Map<String ns, String regex_replacement>
 	if(nsRules == null || nsRules.size() == 0){
 	    System.err.println("Ignoring empty namespace-only regex rule mappings");
 	    return;
 	}
 
-	addRegexMapping(regexp, nsRules, (String) null, (Map) null);
+	addRegexMapping(regexp, nsRules, (String) null, (Map<String,String[]>) null, articleName);
     }
 
-    protected void addURLRegexMapping(String url_regexp, Map url_nsRules){ //nsRules = Map<String ns, String regex_replacement>
+    protected void addURLRegexMapping(String url_regexp, Map url_nsRules, String articleName){ //nsRules = Map<String ns, String regex_replacement>
 	if(url_nsRules == null || url_nsRules.size() == 0){
 	    System.err.println("Ignoring empty namespace-only url regex rule mappings");
 	    return;
 	}
 
-	addURLRegexMapping(url_regexp, url_nsRules, (String) null, (Map) null);
+	addURLRegexMapping(url_regexp, url_nsRules, (String) null, (Map) null, articleName);
+    }
+
+    public void addRegexMapping(String regexp, Map<String,String> nsRules, 
+				String mobyDataType, Map<String,String[]> membersMap){
+	addRegexMapping(regexp, nsRules, mobyDataType, membersMap, null);
     }
 
-    public void addRegexMapping(String regexp, Map nsRules, String mobyDataType, Map membersMap){ //mobyObj<--mobyNamespaces
+    public void addRegexMapping(String regexp, Map<String,String> nsRules, String mobyDataType, Map<String,String[]> membersMap, String articleName){ 
 	try{
 	    // Pattern.DOTALL to allow ".*" to span multiple lines, also allow comments (# to EOL) and whitespace
 	    // for better readability in the rules file.
@@ -1027,14 +1051,16 @@
 	    if(mobyDataType == null || mobyDataType.length() == 0){
 		regexMap.put(pattern, new MobyComplexBuilder("Object", 
 							     membersMap, 
-							     nsRules));
+							     nsRules,
+							     articleName));
 		return;
 	    }
 
 	    // Complex Object
 	    regexMap.put(pattern, new MobyComplexBuilder(mobyDataType, 
 							 membersMap, 
-							 nsRules));
+							 nsRules,
+							 articleName));
 	}catch(Exception e){
 	    System.err.println("Could not create regular expression statement from '" +
 			       regexp + "': " + e);
@@ -1043,7 +1069,7 @@
     }
 
     public void addURLRegexMapping(String url_regexp, Map url_nsRules, 
-				String mobyDataType, Map membersMap){ //mobyObj<--mobyNamespaces
+				   String mobyDataType, Map<String,String[]> membersMap, String articleName){ //mobyObj<--mobyNamespaces
 	//System.out.println("url regex addMapping: " + url_regexp);
 	try{
 	    Pattern pattern = Pattern.compile(processURLRegExp(url_regexp));	
@@ -1052,14 +1078,16 @@
 	    if(mobyDataType == null || mobyDataType.length() == 0){
 		urlRegexMap.put(pattern, new MobyComplexBuilder("Object", 
 								membersMap, 
-								url_nsRules));
+								url_nsRules,
+								articleName));
 		return;
 	    }
 
 	    // Complex Object
 	    urlRegexMap.put(pattern, new MobyComplexBuilder(mobyDataType, 
 							    membersMap, 
-							    url_nsRules));
+							    url_nsRules,
+							    articleName));
 	}catch(Exception e){
 	    System.err.println("Could not create URL regular expression statement from '" +
 			       url_regexp + "': " + e);
@@ -1078,14 +1106,15 @@
 	for(int i = 0; i < mobyObj.length; i++){
 	    nsRules.put(mobyObj[i], ".");
 	}
-	addXPathMapping(xpath, nsRules);
+	addXPathMapping(xpath, nsRules, null);
     }
 
-    public void addXPathMapping(String xpath_exp, Map nsRules){ //mobyObj<--mobyNamespaces
-	addXPathMapping(xpath_exp, nsRules, (String) null, (Map) null);
+    public void addXPathMapping(String xpath_exp, Map nsRules, String articleName){ //mobyObj<--mobyNamespaces
+	addXPathMapping(xpath_exp, nsRules, (String) null, (Map) null, articleName);
     }
 
-    public void addXPathMapping(String xpath_exp, Map nsRules, String mobyDataType, Map membersMap){ //mobyObj<--mobyNamespaces
+    public void addXPathMapping(String xpath_exp, Map nsRules, String mobyDataType, 
+				Map<String,String[]> membersMap, String articleName){ //mobyObj<--mobyNamespaces
 	//System.out.println("xpath addMapping: " + xpath_exp);
 	try{
 	    XPath xpath = new XPath(xpath_exp,
@@ -1097,14 +1126,16 @@
 	    if(mobyDataType == null || mobyDataType.length() == 0){
 		xpathMap.put(xpath, new MobyComplexBuilder("Object", 
 							   membersMap, 
-							   nsRules));
+							   nsRules,
+							   articleName));
 		return;
 	    }
 
 	    // Complex Object
 	    xpathMap.put(xpath, new MobyComplexBuilder(mobyDataType, 
 						       membersMap, 
-						       nsRules));	    
+						       nsRules,
+						       articleName));
 
 	}catch(Exception e){
 	    logger.warn("Could not create XPath select statement from '" +

===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/services/MobyComplexBuilder.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/services/MobyComplexBuilder.java	2007/04/03 02:30:36	1.4
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/services/MobyComplexBuilder.java	2007/04/08 17:26:24	1.5
@@ -19,12 +19,13 @@
  */
 
 public class MobyComplexBuilder{
-
+    public static final String ANON_ARTICLE = "_seahawk_data";
     private static XPathFactory xPathFactory;
     private static DocumentBuilder docBuilder;
 
-    private Map namespaceRules;
-    private Map memberRules;
+    private Map<String,String> namespaceRules; // ns, template
+    private Map<String,String[]> memberRules;  // member name, [template, whitespace rule, encoding rule]
+    private String articleNameRule;
     private MobyDataType mobyDataType;
     private MobyNamespace[] mobyNS;
     private MobyRelationship[] children;
@@ -40,13 +41,18 @@
 	}
     }
 
-    public MobyComplexBuilder(String dataType, Map members, Map nameSpaces) throws Exception{
+    public MobyComplexBuilder(String dataType, Map<String,String[]> members, Map<String,String> nameSpaces) throws Exception{
+	this(dataType, members, nameSpaces, ANON_ARTICLE);
+    }
+
+    public MobyComplexBuilder(String dataType, Map<String,String[]> members, Map<String,String> nameSpaces, String articleName) throws Exception{
 	mobyDataType = MobyDataType.getDataType(dataType);
 	// Not an existing Ontology data type
 	if(mobyDataType == null){
 	    mobyDataType = new MobyDataType(dataType);
 	}
 
+	articleNameRule = articleName;
 	memberRules = members;
 
 	if(mobyDataType != null && mobyDataType.getName() != null && 
@@ -115,15 +121,26 @@
 	    mobyObj = new MobyDataComposite(mobyDataType);
 	}
 
+	// Set article name, if available
+	if(articleNameRule != null && articleNameRule.length() > 0){
+	    mobyObj.setName(evaluateRule(matcher, 
+					 articleNameRule, 
+					 MobyClient.WHITESPACE_ATTR_STRIP_FLANKING_VAL,
+					 null, 
+					 data));
+	}
+
 	// Set namespaces if available
 	if(namespaceRules != null && namespaceRules.size() > 0){
 	    boolean haveID = false;
 	    for(int i = 0; mobyNS != null && i < mobyNS.length; i++){	    
-		String result = (String) namespaceRules.get(mobyNS[i].getName());
-		// Replace any $0, $1, etc. in the replacement string with the values found in the matcher
-		for(int j = 0; j <= matcher.groupCount(); j++){
-		    result = result.replaceAll("\\$"+j, matcher.group(j));
-		}
+		String resultSpec = namespaceRules.get(mobyNS[i].getName());
+		String result = evaluateRule(matcher, 
+					     resultSpec, 
+					     MobyClient.WHITESPACE_ATTR_STRIP_FLANKING_VAL, 
+					     null, 
+					     data);
+
 		// A non-blank value was the result of the evaluation
 		if(result.length() > 0){
 		    if(!haveID){
@@ -141,19 +158,14 @@
 	    }
 	}
 
-	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[] resultSpec = (String[]) memberRules.get(memberName);
+		    String[] resultSpec = memberRules.get(memberName);
+
 		    MobyRelationship memberRelationship = mobyDataType.getChild(memberName);
-		    String result = resultSpec[0];
-		    byte[] resultBytes = result.getBytes();
-		    String whitespaceMode = resultSpec[1];
-		    String encodingMode = resultSpec[2];
-		    
 		    // Is the field a list rather than a single value?  If so,
 		    // we will need to reinterpret the member value specification
 		    // as many times as the regex capture group matched...
@@ -161,88 +173,109 @@
 			
 		    }
 		    // else is iHASA, scalar context
-
-		    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++){
-			// 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+","");
-			    }
-			    else if(whitespaceMode.equals(MobyClient.WHITESPACE_ATTR_STRIP_FLANKING_VAL)){
-				varValue = varValue.trim(); // removes leading and trailing whitespace
-			    }
-			    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);
-		    }
+			String result = evaluateRule(matcher, resultSpec[0], resultSpec[1], resultSpec[2], data);
 
-		    // 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));
 		    }
-
-		    ((MobyDataComposite) mobyObj).put(memberName, 
-						      MobyDataObject.createInstanceFromString(children[i].getDataTypeName(), result));
 		}
 	    }
 	}
-
 	return mobyObj;
     }
 
+    // takes a rule and evaluates $# variables and XPath expressions
+    private String evaluateRule(Matcher matcher, String result, String whitespaceMode, String encodingMode, byte[] data)
+	throws MobyException{
+	byte[] resultBytes = result.getBytes();
+	boolean nonBasic = result.length() != 2 || result.indexOf("$") != 0;
+
+	MobyPrefixResolver.MobyNodeList nodeList = new MobyPrefixResolver.MobyNodeList();
+
+	Document doc = null;
+	// Only get a DOM instance (for text node creation) if we're going to evaluate an XPath in the end
+	if(nonBasic){
+	    doc = docBuilder.newDocument();
+	}
+
+	// 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++){
+	    // 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 == null){
+		    // do nothing
+		}
+		else 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+","");
+		}
+		else if(whitespaceMode.equals(MobyClient.WHITESPACE_ATTR_STRIP_FLANKING_VAL)){
+		    varValue = varValue.trim(); // removes leading and trailing whitespace
+		}
+		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
+		if(nonBasic){
+		    nodeList.add(doc.createTextNode(result));
+		}
+	    }
+	}
+	
+	if(encodingMode != null && 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 " + 
+					"('" + result + "'): " + e);
+	    }
+	}
+	return result;
+    }
+
     public MobyDataObject applyXPath(Object result, NamespaceContext nsContext) throws MobyException, XPathExpressionException{
 	XPath xpath = xPathFactory.newXPath();
 	xpath.setNamespaceContext(nsContext);
@@ -260,7 +293,7 @@
 	if(namespaceRules != null && namespaceRules.size() > 0){
 	    boolean haveID = false;
 	    for(int i = 0; mobyNS != null && i < mobyNS.length; i++){	    
-		String expr = (String) namespaceRules.get(mobyNS[i].getName());
+		String expr = namespaceRules.get(mobyNS[i].getName());
 		String value = xpath.evaluate(expr, result);
 
 		// A non-blank value was the result of the evaluation
@@ -285,7 +318,7 @@
 	    if(children != null){
 		for(int i = 0; i < children.length; i++){
 		    String memberName = children[i].getName();
-		    String expr = ((String[]) memberRules.get(memberName))[0];
+		    String expr = memberRules.get(memberName)[0];
 		    String value = xpath.evaluate(expr, result);
 
 		    ((MobyDataComposite) mobyObj).put(memberName, 




More information about the MOBY-guts mailing list