[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