[MOBY-guts] biomoby commit

Paul Gordon gordonp at dev.open-bio.org
Thu Jul 3 16:29:26 UTC 2008


gordonp
Thu Jul  3 12:29:25 EDT 2008
Update of /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util
In directory dev.open-bio.org:/tmp/cvs-serv24943/src/main/ca/ucalgary/services/util

Modified Files:
	WSDLConfig.java 
Log Message:
Refactored and added implicit collection support
moby-live/Java/src/main/ca/ucalgary/services/util WSDLConfig.java,1.3,1.4
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/WSDLConfig.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/WSDLConfig.java	2008/06/30 17:42:29	1.3
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/WSDLConfig.java	2008/07/03 16:29:25	1.4
@@ -157,6 +157,7 @@
 	    }
 	    String modelReference = partElement.getAttributeNS(MobyPrefixResolver.SAWSDL_NAMESPACE, SAWSDL_MODEL_ATTR);
 	    if(modelReference == null || modelReference.length() == 0){
+		// TODO deal with schema-only level SAWSDL annotation
 		throw new Exception("Part element " + partName + " of WSDL message " + 
 				    messageName + " has no SAWSDL " + SAWSDL_MODEL_ATTR + " attribute defined");
 	    }
@@ -167,10 +168,10 @@
 		    throw new Exception("Part element " + partName + " of WSDL message " + 
 					messageName + " has no SAWSDL " + SAWSDL_INMAP_ATTR + " attribute defined");
 		}
-		String mobyParam = wsdlParam2MobyParam(partName, partType, modelReference);
+		String mobyParam = wsdlParam2MobyParam(partElement, partName, partType, modelReference);
 		if(mobyParam == null){
 		    // Check if it's a secondary
-		    mobyParam = wsdlParam2MobySecondaryParam(partName, partType, modelReference, partElement);
+		    mobyParam = wsdlParam2MobySecondaryParam(partElement, partName, partType, modelReference);
 		    if(mobyParam == null){
 			throw new Exception("The LSID '" + modelReference + 
 					    "' is not a properly formed Moby primary or secondary param LSID as required");
@@ -189,7 +190,7 @@
 		    throw new Exception("Part element " + partName + " of WSDL message " + 
 					messageName + " has no SAWSDL " + SAWSDL_OUTMAP_ATTR + " attribute defined");
 		}
-		outputs.put(partName, wsdlParam2MobyParam(partName, partType, modelReference));
+		outputs.put(partName, wsdlParam2MobyParam(partElement, partName, partType, modelReference));
 		outputTypes.put(partName, partType);
 		outputMappings.put(partName, schemaMapping);	    
 	    }
@@ -207,7 +208,8 @@
 	}
     }
 
-    public String wsdlParam2MobyParam(String paramName, String paramXSDType, String dataTypeLSID){
+    public String wsdlParam2MobyParam(Element element, String paramName, String paramXSDType, String dataTypeLSID) 
+	throws Exception{
 	String[] dataTypeLSIDFields = dataTypeLSID.split(":");
 	if(dataTypeLSIDFields.length != 5 && dataTypeLSIDFields.length != 6 ||
 	   !dataTypeLSIDFields[0].equals("urn") || !dataTypeLSIDFields[1].equals("lsid") ||
@@ -219,11 +221,29 @@
 	    return paramName+":"+MobyTags.MOBYOBJECT+":"+dataTypeLSIDFields[4];
 	}
 	else{
-	    return paramName+":"+dataTypeLSIDFields[4];
+	    // Deal with the case where the output XSD data type is an array: 
+	    // implicitly make the return data type Collection(Thing)
+
+	    // See if the name is namespace qualified, and separate the local part if so
+	    String nsURI = "";
+	    if(paramXSDType.contains(":")){
+		String nsPrefix = paramXSDType.substring(0, paramXSDType.indexOf(":"));  //XML NS prefix
+		paramXSDType = paramXSDType.substring(paramXSDType.indexOf(":")+1); //local part
+		nsURI = element.lookupNamespaceURI(nsPrefix);  //prefix->URI
+	    }
+	    Element schemaDataTypeElement = getSchemaElement(element.getOwnerDocument(), nsURI, paramXSDType);	    
+	    if(getArrayType(schemaDataTypeElement) != null){
+		return paramName+":Collection("+dataTypeLSIDFields[4]+")";
+	    }
+	    else{
+		return paramName+":"+dataTypeLSIDFields[4];
+	    }
 	}
+	
     }
 
-    public String wsdlParam2MobySecondaryParam(String paramName, String paramXSDType, String dataTypeLSID, Element partElement) throws Exception{
+    public String wsdlParam2MobySecondaryParam(Element partElement, String paramName, 
+					       String paramXSDType, String dataTypeLSID) throws Exception{
 	String[] dataTypeLSIDFields = dataTypeLSID.split(":");
 	if(dataTypeLSIDFields.length != 5 && dataTypeLSIDFields.length != 6 ||
 	   !dataTypeLSIDFields[0].equals("urn") || !dataTypeLSIDFields[1].equals("lsid") ||
@@ -381,7 +401,7 @@
 	    throw new Exception("Could not find a message definition (" + targetMessageName + 
 				") for operation "+ opName);
 	}
-	// The lifting may be defijned at the "part" tag level, as it is for services
+	// The lifting may be defined at the "part" tag level, as it is for services
 	String schemaMapping = partElement.getAttributeNS(MobyPrefixResolver.SAWSDL_NAMESPACE, SAWSDL_OUTMAP_ATTR);
 	if(schemaMapping != null && schemaMapping.length() != 0){
 	    return new URL(schemaMapping);
@@ -403,105 +423,119 @@
 
 	// Now find the definition of the part's data type, and see if it has a schema lifting mapping
 	// Usually, <xsd:schema> -> <xsd:complexType name="partType"/>
-	NodeList schemaElements = wsdlRoot.getElementsByTagNameNS(MobyPrefixResolver.XSD_NAMESPACE, 
-								  "schema");
+	Element schemaDefElement = getSchemaElement(opElement.getOwnerDocument(), partTypeNamespaceURI, partType);
+
+	// If it's an XML Schema definition element with the same name as our part type, we're good to go...
+	// See if the SAWSDL lifting schema attribute is defined
+	schemaMapping = schemaDefElement.getAttributeNS(MobyPrefixResolver.SAWSDL_NAMESPACE, SAWSDL_OUTMAP_ATTR);
+	if(schemaMapping == null || schemaMapping.length() == 0){
+	    // As a last-ditch effort, if the data type is just an array of another datatype, 
+	    // look up the other data type to see if it has a lifting schema mapping, and
+	    // we will take care of the array iteration part opf the transformation
+	    String arrayType = getArrayType(schemaDefElement);
+	    if(arrayType == null){
+		throw new Exception("The definition of XML Schema type " + partType + " used as the output of " + 
+				    opName + " has no SAWSDL " + SAWSDL_OUTMAP_ATTR + " attribute defined, nor is" +
+				    "it simply an array of a type with a lifting schema");
+	    }
+
+	    // We're at the array's data type.  This is the last chance to find a schema lifting mapping
+	    Element sde = getSchemaElement(opElement.getOwnerDocument(), partTypeNamespaceURI, arrayType);
+	    schemaMapping = sde.getAttributeNS(MobyPrefixResolver.SAWSDL_NAMESPACE, SAWSDL_OUTMAP_ATTR);
+
+	    if(schemaMapping != null && schemaMapping.length() != 0){
+		// The ARRAY_SENTINEL as a ref part of the URL indicates the rule should be
+		// applied to each members of the incoming array, not the once to the whole array
+		if(lsidResolver.isLSID(schemaMapping)){
+		    return new URL(lsidResolver.resolveDataURL(schemaMapping).toString()+
+				   "#"+ARRAY_SENTINEL);
+		}
+		else{
+		    return new URL(schemaMapping+"#"+ARRAY_SENTINEL);
+		}
+	    }
+	    throw new Exception("Neither the array datatype ("+partType + ") nor the datatype " +
+				"it stores (" + arrayType + ") has a SAWSDL " + SAWSDL_OUTMAP_ATTR +
+				" attribute");
+	}
+	else{
+	    if(lsidResolver.isLSID(schemaMapping)){
+		return lsidResolver.resolveDataURL(schemaMapping);
+	    }
+	    else{
+		return new URL(schemaMapping);
+	    } 
+	}
+    }
+
+    /**
+     * @return the data type of the array, or null if the data type is not an array
+     */
+    protected String getArrayType(Element schemaDefElement){
+	// The XML must look something like:
+	//<xsd:complexType name="ArrayOfThing">
+	// <xsd:complexContent>
+	//  <xsd:restriction base="soapenc:Array">
+	//   <xsd:attribute ref="soapenc:arrayType" wsdl:arrayType="typens:Thing[]"/>
+	// </xsd:restriction></xsd:complexContent></xsd:complexType>
+	NodeList contentElements = schemaDefElement.getElementsByTagNameNS(MobyPrefixResolver.XSD_NAMESPACE, 
+									   "complexContent");
+	if(contentElements.getLength() == 1){
+	    NodeList restrictionElements = 
+		((Element) contentElements.item(0)).getElementsByTagNameNS(MobyPrefixResolver.XSD_NAMESPACE, 
+									   "restriction");
+	    if(restrictionElements.getLength() == 1){
+		NodeList attributeElements = ((Element) restrictionElements.item(0)).getElementsByTagNameNS(MobyPrefixResolver.XSD_NAMESPACE, 
+													    "attribute");
+		if(attributeElements.getLength() == 1){
+		    // NOTE: WSDL 1.1 only for now
+		    String arrayType = ((Element) attributeElements.item(0)).getAttributeNS(MobyPrefixResolver.WSDL_NAMESPACE, 
+											    "arrayType");
+		    if(arrayType.contains(":")){
+			arrayType = arrayType.substring(arrayType.indexOf(":")+1); //local part
+		    }
+		    if(arrayType.endsWith("[]")){
+			return arrayType.substring(0, arrayType.length()-2); // remove the array square brackets
+		    }
+		}
+	    }
+	}
+	return null;
+    }
+
+    /**
+     * Returns the XML DOM element containing the definition of an XML Schema data type, 
+     * unless that datatype or namespace doesn't exist, in which case an exception is thrown.
+     */
+    protected Element getSchemaElement(Document wsdlDoc, String nsUri, String name) throws Exception{
+	NodeList schemaElements = wsdlDoc.getDocumentElement().getElementsByTagNameNS(MobyPrefixResolver.XSD_NAMESPACE, 
+										      "schema");
+	if(schemaElements.getLength() == 0){
+	    throw new Exception("Could not find XML Schema type definition for " + name + 
+				", cannot find the schema section of the WSDL document");
+	}
+
 	for(int i = 0; i < schemaElements.getLength(); i++){
-	    if(!partTypeNamespaceURI.equals(((Element) schemaElements.item(i)).getAttribute("targetNamespace"))){
+	    if(!nsUri.equals(((Element) schemaElements.item(i)).getAttribute("targetNamespace"))){
 		continue; // only look as schema definitions in the correct namespace
 	    }
-
+	    
 	    NodeList schemaDefElements = ((Element) schemaElements.item(i)).getChildNodes();
 	    for(int j = 0; j < schemaDefElements.getLength(); j++){
-
 		if(!(schemaDefElements.item(j) instanceof Element)){
 		    continue;
 		}
-
-		Element schemaDefElement = (Element) schemaDefElements.item(j);
-		// If it's an XML Schema definition element with the same name as our part type, we're good to go...
-		if((MobyPrefixResolver.XSD_NAMESPACE.equals(schemaDefElement.getNamespaceURI())) &&
-		   partType.equals(schemaDefElement.getAttribute("name"))){
-		    // See if the SAWSDL lifting schema attribute is defined
-		    schemaMapping = partElement.getAttributeNS(MobyPrefixResolver.SAWSDL_NAMESPACE, SAWSDL_OUTMAP_ATTR);
-		    if(schemaMapping == null || schemaMapping.length() == 0){
-			// As a last-ditch effort, if the data type is just an array of another datatype, 
-			// look up the other data type to see if it has a lifting schema mapping, and
-			// we will take care of the array iteration part opf the transformation
-			// The XML must look something like:
-			//<xsd:complexType name="ArrayOfThing">
-			// <xsd:complexContent>
-			//  <xsd:restriction base="soapenc:Array">
-			//   <xsd:attribute ref="soapenc:arrayType" wsdl:arrayType="typens:Thing[]"/>
-			// </xsd:restriction></xsd:complexContent></xsd:complexType>
-			NodeList contentElements = schemaDefElement.getElementsByTagNameNS(MobyPrefixResolver.XSD_NAMESPACE, 
-											   "complexContent");
-			if(contentElements.getLength() == 1){
-			    NodeList restrictionElements = 
-				((Element) contentElements.item(0)).getElementsByTagNameNS(MobyPrefixResolver.XSD_NAMESPACE, 
-											   "restriction");
-			    if(restrictionElements.getLength() == 1){
-				NodeList attributeElements = ((Element) restrictionElements.item(0)).getElementsByTagNameNS(MobyPrefixResolver.XSD_NAMESPACE, 
-															    "attribute");
-				if(attributeElements.getLength() == 1){
-				    // NOTE: WSDL 1.1 only for now
-				    String arrayType = ((Element) attributeElements.item(0)).getAttributeNS(MobyPrefixResolver.WSDL_NAMESPACE, 
-													    "arrayType");
-				    if(arrayType.contains(":")){
-					arrayType = arrayType.substring(arrayType.indexOf(":")+1); //local part
-				    }
-				    if(!arrayType.endsWith("[]")){
-					throw new Exception("The definition of XML Schema type " + partType + 
-							    " used as the output of " + 
-							    opName + " has no SAWSDL " + SAWSDL_OUTMAP_ATTR + 
-							    " attribute defined, nor is" +
-							    "it simply an array of a type with a lifting schema");
-				    }
-				    arrayType = arrayType.substring(0, arrayType.length()-2); // remove the array square brackets
-				    for(int k = 0; k < schemaDefElements.getLength(); k++){
-					if(!(schemaDefElements.item(k) instanceof Element)){
-					    continue;
-					}
-					Element sde = (Element) schemaDefElements.item(k);
-					if((MobyPrefixResolver.XSD_NAMESPACE.equals(sde.getNamespaceURI())) &&
-					   arrayType.equals(sde.getAttribute("name"))){
-					    // We're at the array's data type.  This is the last chance to find a schema lifting mapping
-					    schemaMapping = sde.getAttributeNS(MobyPrefixResolver.SAWSDL_NAMESPACE, SAWSDL_OUTMAP_ATTR);
-					    if(schemaMapping != null && schemaMapping.length() != 0){
-						// The ARRAY_SENTINEL as a ref part of the URL indicates the rule should be
-						// applied to each members of the incoming array, not the once to the whole array
-						if(lsidResolver.isLSID(schemaMapping)){
-						    return new URL(lsidResolver.resolveDataURL(schemaMapping).toString()+
-								   "#"+ARRAY_SENTINEL);
-						}
-						else{
-						    return new URL(schemaMapping+"#"+ARRAY_SENTINEL);
-						}
-					    }
-					    throw new Exception("Neither the array datatype ("+partType + ") nor the datatype " +
-								"it stores (" + arrayType + ") has a SAWSDL " + SAWSDL_OUTMAP_ATTR +
-								" attribute");
-					}
-				    }
-				    throw new Exception("Could not find XML Schema type definition for " + arrayType);
-				}
-			    }
-			}
-
-			throw new Exception("The definition of XML Schema type " + partType + " used as the output of " + 
-					    opName + " has no SAWSDL " + SAWSDL_OUTMAP_ATTR + " attribute defined, nor is" +
-					    "it simply an array of a type with a lifting schema");
-		    }
-		    if(lsidResolver.isLSID(schemaMapping)){
-			return lsidResolver.resolveDataURL(schemaMapping);
-		    }
-		    else{
-			return new URL(schemaMapping);
-		    } 
+		Element e = (Element) schemaDefElements.item(j);
+		if((MobyPrefixResolver.XSD_NAMESPACE.equals(e.getNamespaceURI())) &&
+		   name.equals(e.getAttribute("name"))){
+		    return e;
 		}
 	    }
+	    throw new Exception("Could not find XML Schema type definition for " + name + ", namespace " +
+				nsUri + " exists, but schema element " + name + " does not");
 	}
-	throw new Exception("Could not find the data type definition for " + partType + " in the WSDL");
-	    
+	throw new Exception("Could not find XML Schema type definition for " + name + ", namespace " +
+			    nsUri + " does not exist");
     }
 
     protected String convertSourceToMobySecondaryValues(Source source, URL liftingSchema, boolean arrayRule) throws Exception{




More information about the MOBY-guts mailing list