[MOBY-guts] biomoby commit

Paul Gordon gordonp at dev.open-bio.org
Tue Jun 9 19:15:56 UTC 2009


gordonp
Tue Jun  9 15:15:56 EDT 2009
Update of /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util
In directory dev.open-bio.org:/tmp/cvs-serv20439/src/main/ca/ucalgary/services/util

Modified Files:
	SourceMap.java 
Log Message:
Added support for nesting of tags
moby-live/Java/src/main/ca/ucalgary/services/util SourceMap.java,1.2,1.3
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/SourceMap.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/services/util/SourceMap.java	2008/10/30 02:33:24	1.2
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/SourceMap.java	2009/06/09 19:15:56	1.3
@@ -8,18 +8,29 @@
 /**
  * Converts a Map of Strings into a Source for the Java SOAP libraries.
  * The Map should be of the form (SOAP input param name -> XML Schema Instance data).
+ * This class assumes that all of the elements being put into the map are of the same 
+ * namespace as the message name given in the constructor.  Nesting of elements is 
+ * achieved using a colon, e.g. given "a:b" and "a:c" keys, a two level map is created 
+ * with one entry at the first level (a), and two at the second level (b, c).  MEMBER_REF_PREFIX
+ * as the entry value denotes the nesting of maps.
  */
-public class SourceMap extends javax.xml.transform.stream.StreamSource implements Map<String,String>{
-
-    private TreeMap<String,String> members;
+public class SourceMap extends javax.xml.transform.stream.StreamSource implements Map<String,String[]>{
+    private static final String SINGLE_VAL_PREFIX = "_seahawkSingleValuePrefix09";
+    private static final String MEMBER_REF_PREFIX = "_thisIsARefNotanActualvalue";
+    private Map<String,String[]> members;
+    private Map<String,SourceMap> submaps;
     private QName messageName;
+    private String use;
 
     /**
      * @param msgName the name of the operation message (WSDL 1.1) or operation element (WSDL 2.0) that is being encapsulated
+     * @param style "literal" or "encoded", the WSDL data encoding style, or "raw", so the wrapping tag is already assumed to be present
      */
-    public SourceMap(QName msgName){
-	members = new TreeMap<String,String>();
+    public SourceMap(QName msgName, String encoding){
+	members = new LinkedHashMap<String,String[]>();
+	submaps = new LinkedHashMap<String,SourceMap>();
 	messageName = msgName;
+	use = encoding;
     }
 
     /**
@@ -27,25 +38,78 @@
      * Map set to date.
      */
     public InputStream getInputStream(){
-	setInputStream(new ByteArrayInputStream(serializeMapContents().getBytes()));
+	setInputStream(new ByteArrayInputStream(toString().getBytes()));
 	return super.getInputStream();
     }
 
+    public String toString(){
+	return //"<?xml version='1.0'?>\n"+
+	       "<"+messageName.getLocalPart()+" xmlns=\""+messageName.getNamespaceURI()+"\">"+
+	       serializeMapContents()+
+               "</"+messageName.getLocalPart()+">";
+    }
+
     private String serializeMapContents(){
 	StringBuffer xmlContents = new StringBuffer();
-	xmlContents.append("<?xml version='1.0'?>\n");
-	xmlContents.append("<m:"+messageName.getLocalPart()+" xmlns:m=\""+messageName.getNamespaceURI()+"\">");
 
 	// Serialize map members 
-	for(String value: values()){
-	    xmlContents.append(value);
+	for(Map.Entry<String,String[]> member: members.entrySet()){
+	    SourceMap submembers = getSubMap(member.getKey());
+	    if(submembers != null){
+		// nested elements
+		xmlContents.append(createXML(member.getKey(), submembers.serializeMapContents()));
+	    }
+	    else{
+		// process the whole bunch of values at once
+		xmlContents.append(createXML(member.getKey(), member.getValue()));
+	    }
 	}
 
-	xmlContents.append("</m:"+messageName.getLocalPart()+">");
+	return xmlContents.toString();
+    }
 
-	//System.err.println("SOAP payload:\n"+xmlContents.toString());
+    private String createXML(String name, String[] values){
+	String valuesXML = "";
+	if(use.equals("literal") || use.equals("raw")){
+	    for(String value: values){
+		valuesXML += createXML(name, value);
+	    }
+	}
+	// encoded: todo get data type dynamically
+	else{
+	    if(values.length == 1 && values[0].indexOf(SINGLE_VAL_PREFIX) == 0){
+		return createXML(name, values[0]);
+	    }
+	    else{ //an array
+		valuesXML = "<"+name+" xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:string[" +
+		    values.length+"]\" xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\" " +
+		    "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " + 
+		    "xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\">";
+		for(String value: values){
+		    valuesXML += "<item xsi:type=\"xsd:string\">"+value+"</item>";
+		}
+		valuesXML += "</"+name+">";
+	    }
+	}
+	return valuesXML;
+    }
 
-	return xmlContents.toString();
+    private String createXML(String name, String value){
+	if(value.indexOf(SINGLE_VAL_PREFIX) == 0){
+	    value = value.substring(SINGLE_VAL_PREFIX.length());
+	}
+	if(use.equals("raw")){
+	    return value;
+	}
+	else if(use.equals("literal")){
+	    return "<"+name+">"+value+"</"+name+">";
+	}
+	else{
+	    return "<"+name+" xsi:type=\"xsd:string\" " +
+		"xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\" "+
+		"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
+		value+"</"+name+">"; //encoded: todo get data type dynamically
+	}
     }
 
     /**
@@ -55,7 +119,7 @@
 	members.clear();
     }
 
-    public Collection<String> values(){
+    public Collection<String[]> values(){
 	return members.values();
     }
 
@@ -76,7 +140,7 @@
     /**
      * Retrieves each field name/value pair for the members of the composite object
      */
-    public Set<Map.Entry<String,String>> entrySet(){
+    public Set<Map.Entry<String,String[]>> entrySet(){
 	return members.entrySet();
     }
 
@@ -90,7 +154,7 @@
     /**
      * Retrieves a member of the composite with a given field name.
      */
-    public String get(Object fieldName){
+    public String[] get(Object fieldName){
 	return members.get(fieldName);
     }
 
@@ -112,14 +176,72 @@
 	return members.keySet();
     }
 
-    public String put(String fieldName, String value){
-	return members.put(fieldName, value);
+    /**
+     * To be used if a sequence is expected for a member.  fieldName can have the 
+     * form a or a:b for nested tags to be represented.
+     */
+    public String[] put(String fieldName, String[] values){
+	if(fieldName.indexOf(":") != -1){
+	    // Nested member, so delegate
+	    SourceMap subMap = getSubMap(fieldName);
+	    if(subMap == null){
+		subMap = createSubMap(fieldName);
+	    }
+	    String subfield = fieldName.substring(fieldName.indexOf(":") + 1);
+	    return subMap.put(subfield, values);
+	}
+	else{
+	    return members.put(fieldName, values);
+	}
+    }
+
+    public String[] put(String fieldName, String value){
+	if(fieldName.indexOf(":") != -1){
+	    // Nested member, so delegate
+	    SourceMap subMap = getSubMap(fieldName);
+	    if(subMap == null){
+		subMap = createSubMap(fieldName);
+	    }
+	    String subfield = fieldName.substring(fieldName.indexOf(":") + 1);	
+	    return subMap.put(subfield, value);
+	}
+	else{
+	    return members.put(fieldName, new String[]{SINGLE_VAL_PREFIX+value});
+	}
+    }
+
+    private SourceMap createSubMap(String fieldName){
+	if(fieldName.indexOf(":") != -1){  // chop off any nested names
+	    fieldName = fieldName.substring(0, fieldName.indexOf(":"));
+	}
+	members.put(fieldName, new String[]{MEMBER_REF_PREFIX+submaps.size()});
+	SourceMap newMap = new SourceMap(new QName(""), use);
+	submaps.put(""+submaps.size(), newMap);
+	return newMap;
+    }
+
+    // Essential the data structure is Map<field,string(ref)> -> Map<string(ref),SourceMap>
+    // to allow any value to be either a literal string or pointer to nested elements
+    private SourceMap getSubMap(String fieldName){
+	if(fieldName.indexOf(":") != -1){  // chop off any nested names
+	    fieldName = fieldName.substring(0, fieldName.indexOf(":"));
+	}
+	String vals[] = members.get(fieldName);
+	if(vals == null || vals.length != 1){
+	    return null;  //must be an array of more than one literal value
+	}
+	String submapRef = vals[0];
+	if(submapRef.indexOf(MEMBER_REF_PREFIX) != 0){
+	    return null;
+	}
+	submapRef = submapRef.substring(MEMBER_REF_PREFIX.length());
+	return submaps.get(submapRef);
     }
 
     /**
      * Sets a number of object fields at once.
      */
-    public void putAll(Map<? extends String,? extends String> map){
+    public void putAll(Map<? extends String,? extends String[]> map){
 	members.putAll(map);
     }
 
@@ -128,7 +250,7 @@
      *
      * @return the data field removed
      */
-    public String remove(Object fieldName){
+    public String[] remove(Object fieldName){
 	return members.remove(fieldName);
     }
 




More information about the MOBY-guts mailing list