[MOBY-guts] biomoby commit

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


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

Modified Files:
	WSDLConfig.java 
Log Message:
Added support for all styles of encoding doc/lit etc.
moby-live/Java/src/main/ca/ucalgary/services/util WSDLConfig.java,1.5,1.6
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/WSDLConfig.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/WSDLConfig.java	2008/10/30 02:33:24	1.5
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/WSDLConfig.java	2009/06/09 19:14:52	1.6
@@ -1,5 +1,7 @@
 package ca.ucalgary.services.util;
 
+import ca.ucalgary.services.SoapServlet;
+
 import org.biomoby.shared.LSIDResolver;
 import org.biomoby.shared.MobyPrefixResolver;
 import org.biomoby.shared.NamespaceContextImpl;
@@ -39,7 +41,8 @@
 
     private final String ARRAY_SENTINEL = "applyToEachXSIArrayItem";
     private final String SERVICENAME_ATTR_XPATH = "//sawsdl:attrExtensions"; 
-    // note that XPath //@moby:"+SERVICE_NAME_ATTR doesn't work, not sure why at the moment, so we don't support WSDL2.0 yet...
+    // private final String SERVICENAME_ATTR_XPATH = "//*[@moby:"+SERVICE_NAME_ATTR+"]"; 
+    // note that the XPath above doesn't work, not sure why at the moment, so we don't support WSDL2.0 yet...
 
     private static XPath xPath;
     private static DocumentBuilder docBuilder;
@@ -48,18 +51,24 @@
 
     private Map<String,QName> mobyServiceName2Service;
     private Map<String,QName> mobyServiceName2Port;
-    private Map<String,String> mobyServiceName2TargetNamespaceURI;
     private Map<String,QName> mobyServiceName2OpInput;
     private Map<String,QName> mobyServiceName2OpOutput;
     private Map<String,String> mobyServiceName2Op;
+    private Map<String,String> mobyServiceName2SoapAction;
+    private Map<String,String> mobyServiceName2TargetNamespaceURI;
+    private Map<String,String> mobyServiceName2Style;    //document or rpc
+    private Map<String,String> mobyServiceName2Encoding; //literal or encoded
     private Map<String,Map<String,String>> mobyServiceName2InputXSDTypes;
     private Map<String,Map<String,String>> mobyServiceName2OutputXSDTypes;
+    private Map<String,Map<String,String>> mobyServiceName2MobyXPathMap;
     private LSIDResolver lsidResolver;
 
     private static Logger logger = Logger.getLogger("ca.ucalgary.services.util.WSDLConfig");
 
     static{
-        XPathFactory xPathFactory = XPathFactory.newInstance();
+        // Commented out generic factory due to Google App Engine bug
+	// XPathFactory xPathFactory = XPathFactory.newInstance();
+	XPathFactory xPathFactory = new org.apache.xpath.jaxp.XPathFactoryImpl();
 	try{
 	    xPath = xPathFactory.newXPath();
 	    xPath.setNamespaceContext(new NamespaceContextImpl());
@@ -76,19 +85,31 @@
         }
     }
 
-    public WSDLConfig(URL url) throws Exception{
-	wsdlURL = url;	
-
+    /**
+     * C-tor to use when you'll programmatically set the values rarther than getting them from a SAWSDL file.
+     */
+    public WSDLConfig(){
 	mobyServiceName2Service = new HashMap<String,QName>();
 	mobyServiceName2Port = new HashMap<String,QName>();
-	mobyServiceName2TargetNamespaceURI = new HashMap<String,String>();
+	mobyServiceName2SoapAction = new HashMap<String,String>();
+	mobyServiceName2Style = new HashMap<String,String>();     //document or rpc
+	mobyServiceName2Encoding = new HashMap<String,String>();  //literal or encoded
 	mobyServiceName2Op = new HashMap<String,String>();
 	mobyServiceName2OpInput = new HashMap<String,QName>();
 	mobyServiceName2OpOutput = new HashMap<String,QName>();
 	mobyServiceName2InputXSDTypes = new HashMap<String,Map<String,String>>();
 	mobyServiceName2OutputXSDTypes = new HashMap<String,Map<String,String>>();
+	mobyServiceName2MobyXPathMap = new HashMap<String,Map<String,String>>();
+	mobyServiceName2TargetNamespaceURI = new HashMap<String,String>();
+
+	lsidResolver = new LSIDResolver();	
+    }
 
-	lsidResolver = new LSIDResolver();
+    public WSDLConfig(URL url) throws Exception{
+	this();
+	wsdlURL = url;
+
+	setSpecURL(wsdlURL);
 	parse(wsdlURL.openStream());
     }
 
@@ -105,8 +126,9 @@
      */
     protected void parse(InputStream is) throws Exception{
 	wsdlDoc = docBuilder.parse(is);
-	// TODO: put wsdl imports in-place as pertinent parts of the definition 
+	// put wsdl imports in-place as pertinent parts of the definition 
 	// of the service maybe spread over multiple files.
+	SoapServlet.doImports(wsdlDoc, wsdlURL);
 
 	// Find the moby:serviceName attributes
 	parseMobyServiceSpecs();
@@ -152,49 +174,50 @@
 		throw new Exception("A part element has no name in the definition of the WSDL message named " + messageName);
 	    }
 	    String partType = partElement.getAttribute("type");
+	    // Here RPC/Encoded and Document Literal start to differ, as Doc/Lit will refer the element definitions, 
+	    // whereas RPC/Encoded will define the types right here.
 	    if(partType == null || partType.length() == 0){
-		throw new Exception("Part element " + partName + " of WSDL message " + 
-				    messageName + " has no type attribute defined");
-	    }
-	    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");
-	    }
-	    String schemaMapping = null;
-	    if(isInputMessage){
-		schemaMapping = partElement.getAttributeNS(MobyPrefixResolver.SAWSDL_NAMESPACE, SAWSDL_INMAP_ATTR);
-		if(schemaMapping == null || schemaMapping.length() == 0){
+		String elementType = partElement.getAttribute("element");
+		if(elementType == null || elementType.trim().length() == 0){
 		    throw new Exception("Part element " + partName + " of WSDL message " + 
-					messageName + " has no SAWSDL " + SAWSDL_INMAP_ATTR + " attribute defined");
+					messageName + " has no type (rpc/encoded) or element (doc/lit) attribute defined");
 		}
-		String mobyParam = wsdlParam2MobyParam(partElement, partName, partType, modelReference);
-		if(mobyParam == null){
-		    // Check if it's a secondary
-		    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");
-		    }
-		    secondaryInputs.put(partName, mobyParam);
-		    secondaryMappings.put(partName, schemaMapping);
+		// A qualified name?
+		if(elementType.indexOf(":") != -1){
+		    elementType = elementType.substring(elementType.indexOf(":")+1);
 		}
-		else{
-		    inputs.put(partName, mobyParam);
-		    inputTypes.put(partName, partType);
-		    inputMappings.put(partName, schemaMapping);
+		// Find the definition, it should have the sawsdl stuff in it
+		NodeList elementDefs = (NodeList) xPath.evaluate("//xsd:element[@name='"+elementType+"']",
+								  wsdlDoc,
+								  XPathConstants.NODESET);
+		if(elementDefs == null || elementDefs.getLength() == 0){
+		    throw new Exception("The definition of the element '" + elementType + 
+					"' (for message " + messageName + ", part " + partName + 
+					") could not be found in the WSDL file.");		    
+		}		
+		if(elementDefs.getLength() != 1){
+		    throw new Exception("Found more than one definition for element " + 
+					elementType + " in the WSDL file");		    
+		}
+		// Find the sub elements that make up the document element contents, each should have its one
+		// schema mapping (we don't yet support 1:n moby:xmlschema mappings, or "deep" mappings of nested subelements).
+		NodeList subElements = ((Element) elementDefs.item(0)).getElementsByTagName("element");
+		for(int j = 0; j < subElements.getLength(); j++){
+		    Element subElement = (Element) subElements.item(j);
+		    String subPartName = subElement.getAttribute("name");
+		    String subPartType = subElement.getAttribute("type");
+		    if(subPartType == null || subPartType.trim().length() == 0){
+			throw new Exception("No type attribute was found for " + elementType + " subelement " + subPartName);
+		    }
+		    addIOMapping(subElement, messageName, subPartType, subPartName,
+				 inputs, inputMappings, secondaryMappings, inputTypes, 
+				 secondaryInputs, outputs, outputMappings, outputTypes, isInputMessage);
 		}
 	    }
 	    else{
-		schemaMapping = partElement.getAttributeNS(MobyPrefixResolver.SAWSDL_NAMESPACE, SAWSDL_OUTMAP_ATTR);
-		if(schemaMapping == null || schemaMapping.length() == 0){
-		    throw new Exception("Part element " + partName + " of WSDL message " + 
-					messageName + " has no SAWSDL " + SAWSDL_OUTMAP_ATTR + " attribute defined");
-		}
-		outputs.put(partName, wsdlParam2MobyParam(partElement, partName, partType, modelReference));
-		outputTypes.put(partName, partType);
-		outputMappings.put(partName, schemaMapping);	    
+		addIOMapping(partElement, messageName, partType, partName, 
+			     inputs, inputMappings, secondaryMappings, inputTypes, 
+			     secondaryInputs, outputs, outputMappings, outputTypes, isInputMessage);
 	    }
 	}
 	if(isInputMessage){
@@ -211,17 +234,61 @@
 	}
     }
 
+    private void addIOMapping(Element partElement, String messageName, String partType, String partName, 
+			      Map<String,String> inputs,
+			      Map<String,String> inputMappings,
+			      Map<String,String> secondaryMappings, 
+			      Map<String,String> inputTypes,
+			      Map<String,String> secondaryInputs, 
+			      Map<String,String> outputs, 
+			      Map<String,String> outputMappings, 
+			      Map<String,String> outputTypes,
+			      boolean isInputMessage) throws Exception{
+	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");
+	}
+	String schemaMapping = null;
+	if(isInputMessage){
+	    schemaMapping = partElement.getAttributeNS(MobyPrefixResolver.SAWSDL_NAMESPACE, SAWSDL_INMAP_ATTR);
+	    if(schemaMapping == null || schemaMapping.length() == 0){
+		throw new Exception("Part element " + partName + " of WSDL message " + 
+				    messageName + " has no SAWSDL " + SAWSDL_INMAP_ATTR + " attribute defined");
+	    }
+	    String mobyParam = wsdlParam2MobyParam(partElement, partName, partType, modelReference);
+	    if(mobyParam == null){
+		// Check if it's a secondary
+		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");
+		}
+		secondaryInputs.put(partName, mobyParam);
+		secondaryMappings.put(partName, schemaMapping);
+	    }
+	    else{
+		inputs.put(partName, mobyParam);
+		inputTypes.put(partName, partType);
+		inputMappings.put(partName, schemaMapping);
+	    }
+	}
+	else{
+	    schemaMapping = partElement.getAttributeNS(MobyPrefixResolver.SAWSDL_NAMESPACE, SAWSDL_OUTMAP_ATTR);
+	    if(schemaMapping == null || schemaMapping.length() == 0){
+		throw new Exception("Part element " + partName + " of WSDL message " + 
+				    messageName + " has no SAWSDL " + SAWSDL_OUTMAP_ATTR + " attribute defined");
+	    }
+	    outputs.put(partName, wsdlParam2MobyParam(partElement, partName, partType, modelReference));
+	    outputTypes.put(partName, partType);
+	    outputMappings.put(partName, schemaMapping);	    
+	}
+    }
+
     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") ||
-	   (!dataTypeLSIDFields[3].equals("objectclass") && !dataTypeLSIDFields[3].equals("namespacetype"))){
-	    return null;
-	}
-	// 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(":")){
@@ -231,24 +298,55 @@
 	}
 	Element schemaDataTypeElement = isBasicType(paramXSDType) ? null : 
 	    getSchemaElement(element.getOwnerDocument(), nsURI, paramXSDType);	    
-	if(getArrayType(schemaDataTypeElement) != null){
-	    // Special case, if the LSID is a namespace, spec out a base object in the given namespace
+	boolean isArray = getArrayType(schemaDataTypeElement) != null;
+
+	// The reference may include multiple values, separated by spaces
+	String[] dataTypeLSIDs = dataTypeLSID.split(" ");
+	String returnDataType = null;
+        String returnNamespaces = null;
+
+	for(String lsid: dataTypeLSIDs){
+	    String[] dataTypeLSIDFields = lsid.split(":");
+	    if(dataTypeLSIDFields.length != 5 && dataTypeLSIDFields.length != 6 ||
+	       !dataTypeLSIDFields[0].equals("urn") || !dataTypeLSIDFields[1].equals("lsid") ||
+	       (!dataTypeLSIDFields[3].equals("objectclass") && !dataTypeLSIDFields[3].equals("namespacetype"))){
+		// silently ignore secondaries...we'll catch them later in the code
+		if(!dataTypeLSIDFields[3].equals("secondaryParamClass")){
+		    logger.log(Level.WARNING, "Ignoring '" + lsid + "' annotation as it does not appear to be a Moby LSID");
+		}
+		continue;
+	    }
+	    
 	    if(dataTypeLSIDFields[3].equals("namespacetype")){
-		return paramName+":Collection("+MobyTags.MOBYOBJECT+"):"+dataTypeLSIDFields[4];
+		returnNamespaces = returnNamespaces == null ? dataTypeLSIDFields[4] : 
+		                                              returnNamespaces + "," + dataTypeLSIDFields[4];
+	    }
+	    else if(returnDataType == null){
+		if(isArray){
+		    // Deal with the case where the output XSD data type is an array: 
+		    // implicitly make the return data type Collection(Thing)
+		    returnDataType = "Collection("+dataTypeLSIDFields[4]+")";
+		}
+		else{
+		    returnDataType = dataTypeLSIDFields[4];
+		}
 	    }
 	    else{
-		return paramName+":Collection("+dataTypeLSIDFields[4]+")";
+		Exception e = new IllegalArgumentException("The annotation for " + paramName + 
+							   " contains more than one datatype (" + returnDataType + " and " +
+							   lsid + "), please remove one.  Multiple namespaces, but not " +
+							   "multiple datatypes are allowed.");
+		logger.log(Level.SEVERE, "While parsing annotation for " + paramName, e);
+		throw e;
 	    }
 	}
-	else{
-	    if(dataTypeLSIDFields[3].equals("namespacetype")){
-		return paramName+":"+MobyTags.MOBYOBJECT+":"+dataTypeLSIDFields[4];
-	    }
-	    else{
-		return paramName+":"+dataTypeLSIDFields[4];
+	if(returnDataType == null){
+	    if(returnNamespaces == null){
+		return null; // No moby annotation found
 	    }
+	    returnDataType = isArray ? "Collection("+MobyTags.MOBYOBJECT+")" : MobyTags.MOBYOBJECT;
 	}
-	
+	return paramName+":"+returnDataType+(returnNamespaces == null ? "" : ":"+returnNamespaces);
     }
 
     private boolean isBasicType(String xsdType){
@@ -358,7 +456,7 @@
 	}
 
 	// we expect the method to have a nullary signature, so we just create a blank input map
-	SourceMap source = new SourceMap(new QName(specs[0].getNamespaceURI(), opName)); 
+	SourceMap source = new SourceMap(new QName(specs[0].getNamespaceURI(), opName), specs[2].getLocalPart()); 
 
 	Source resultSource = dispatch.invoke(source);
 	// Parse the results into the datatype required
@@ -382,7 +480,8 @@
     }
 
     /**
-     * Goes from an operation, determines the output datatype, then sees if that datatype has a lifting schema
+     * Goes from an operation, determines the output datatype (THERE SHOULD BE JUST ONE), 
+     * then sees if that datatype has a lifting schema
      * that'll turn the response into a moby secondary param format.
      */
     protected URL getLiftingSchemaFromOperation(Element opElement, String opName) throws Exception{
@@ -422,10 +521,17 @@
 	}
 
 	String partType = partElement.getAttribute("type");
-	if(partType == null || partType.length() == 0){
-	    throw new Exception("The WSDL message (" + targetMessageName+") containing the values " +
-				"for a Moby secondary param (operation "+opName+") has a part element " +
-				"as expected, but no defined data type (type attribute missing)");
+	if(partType == null || partType.trim().length() == 0){
+	    // See if it's document/literal, in which case we need the element reference
+	    String elementType = partElement.getAttribute("element");
+	    if(elementType == null || elementType.trim().length() == 0){
+		throw new Exception("The WSDL message (" + targetMessageName+") containing the values " +
+				    "for a Moby secondary param (operation "+opName+") has a part element " +
+				    "as expected, but no defined data type ('type' or 'element' attribute " +
+				    "missing, for rpc/encoded or doc/lit respectively)");
+	    }
+	    // Track back to the element xml schema definition for doc/lit: it should have the SAWSDL
+	    partType = elementType;
 	}
 	// See if the name is namespace qualified, and separate the local part if so
 	String partTypeNamespaceURI = "";
@@ -436,8 +542,20 @@
 	}
 
 	// 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"/>
+	// Usually, <xsd:schema> -> <xsd:complexType name="partType"/> for rpc/encoded, 
+	//       or <element name="partType"><xsd:complexType><sequence><element> for doc/lit, in which case we need to dig further
 	Element schemaDefElement = getSchemaElement(opElement.getOwnerDocument(), partTypeNamespaceURI, partType);
+	schemaMapping = schemaDefElement.getAttributeNS(MobyPrefixResolver.SAWSDL_NAMESPACE, SAWSDL_OUTMAP_ATTR);
+	if((schemaMapping == null || schemaMapping.length() == 0) &&
+	   "element".equals(schemaDefElement.getNodeName())){
+	    NodeList subElements = schemaDefElement.getElementsByTagNameNS(MobyPrefixResolver.XSD_NAMESPACE, "element");
+	    if(subElements == null || subElements.getLength() == 0){
+		throw new Exception("The definition of XML Schema type " + partType + " used as the output of " + 
+				    opName + " has no child elements, nor a SAWSDL " + SAWSDL_OUTMAP_ATTR + 
+				    " attribute");
+	    }
+	    schemaDefElement = (Element) subElements.item(0);
+	}
 
 	// 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
@@ -445,7 +563,7 @@
 	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
+	    // we will take care of the array iteration part of the transformation
 	    String arrayType = getArrayType(schemaDefElement);
 	    if(arrayType == null){
 		throw new Exception("The definition of XML Schema type " + partType + " used as the output of " + 
@@ -763,12 +881,30 @@
 				"of Moby service " + currentService + " is missing or blank");
 	}
 	soapOpName = soapOpName.trim();
+
+	String soapAction = null;
+	NodeList soapOps =
+	    opElement.getElementsByTagNameNS("http://schemas.xmlsoap.org/wsdl/soap/",
+					     "operation");
+	for(int n = 0; n < soapOps.getLength(); n++){
+	    Element soapOp = (Element) soapOps.item(n);
+	    soapAction = soapOp.getAttribute("soapAction");
+	    if(soapAction != null && soapAction.trim().length() > 0){					
+		break;
+	    }
+	}
+
 	QName[] names = getServiceAndPortFromOperation(opElement, soapOpName);
 	QName[] ioMsgNames = getInputAndOutputMessageNamesFromOperation(opElement);
 
+	String style = names[2].getNamespaceURI(); //we abused the QName structure to pass back op style/encoding info
+	String encoding = names[2].getLocalPart(); //we abused the QName structure to pass back op style/encoding info
+
 	setServiceQName(names[0]);
 	setPortQName(names[1]);
-	setTargetNamespaceURI(names[0].getNamespaceURI());
+	setSoapAction(soapAction);
+	setOperationStyle(style);
+	setOperationEncoding(encoding);
 	setOperationName(soapOpName);
 	setOperationInputQName(ioMsgNames[0]);
 	setOperationOutputQName(ioMsgNames[1]);
@@ -842,7 +978,7 @@
     }
 
     /**
-     * @return a two element array, with service, then port
+     * @return a two element array, with service, then port, then style
      */
     protected QName[] getServiceAndPortFromOperation(Element opElement, String soapOpName) throws Exception{
 
@@ -877,6 +1013,8 @@
 	    throw new Exception("Could not find any WSDL binding elements in the WSDL");
 	}
 	String bindingName = null;
+	String style = null;
+	String encoding = null;
 	for(int i = 0; i < bindingElements.getLength(); i++){
 	    Element bindingElement = (Element) bindingElements.item(i);
 	    String bindingPortType = bindingElement.getAttribute("type");
@@ -888,7 +1026,49 @@
 		    throw new Exception("The WSDL binding element that uses the " + portTypeName + 
 					" port type does not have a name attribute.");
 		}
-		break;
+
+		// find the style of the soap op (document or rpc)
+		NodeList opElements = bindingElement.getElementsByTagNameNS("http://schemas.xmlsoap.org/wsdl/soap/",
+									    "binding");
+		for(int j = 0; j < opElements.getLength(); j++){
+		    Element op = (Element) opElements.item(j);
+		    style = op.getAttribute("style");
+		    if(style != null && style.length() > 0){
+			break;
+		    }
+		}
+
+		// find the encoding type (encoded or literal) for the soap op
+		opElements = bindingElement.getElementsByTagNameNS(MobyPrefixResolver.WSDL_NAMESPACE,
+								   "operation");
+		for(int j = 0; j < opElements.getLength(); j++){
+		    Element op = (Element) opElements.item(j);
+		    String opName = op.getAttribute("name");
+		    if(soapOpName.equals(opName)){
+			NodeList inputs =
+			    op.getElementsByTagNameNS(MobyPrefixResolver.WSDL_NAMESPACE,
+						      "input");
+			String inputMsgName = null;
+			QName inputMsgQName = null;
+			for(int n = 0; n < inputs.getLength(); n++){
+			    Element input = (Element) inputs.item(n);
+			    inputMsgName = input.getAttribute("name");
+			    
+			    NodeList soapInputs =
+				input.getElementsByTagNameNS("http://schemas.xmlsoap.org/wsdl/soap/",
+							     "body");
+			    if(soapInputs == null || soapInputs.getLength() == 0){
+				throw new Exception("Could not find a SOAP body definition for operation " + opName + "\n");
+			    }
+			    Element bodyDef = (Element) soapInputs.item(0);
+			    encoding = bodyDef.getAttribute("use");
+			    if(encoding != null && encoding.length() != 0){
+				break;
+			    }
+			}
+			break;
+		    }
+		}
 	    }
 	}
 	if(bindingName == null){
@@ -951,9 +1131,12 @@
 	    throw new Exception("No targetNamespace attribute was found in the root element of the WSDL document");
 	}
 
-	QName[] specs = new QName[2];
+	QName[] specs = new QName[3];
 	specs[0] = new QName(targetNamespace, serviceName);
 	specs[1] = new QName(targetNamespace, portName);
+	// not really a QName, but pass it back as such for simplicity (will be either 
+	// "document" or "rpc", and "literal" or "encoded")
+	specs[2] = new QName(style, encoding);  
 	return specs;
     }
 
@@ -965,14 +1148,6 @@
 	mobyServiceName2Op.put(currentService, opName);
     }
 
-    public String getTargetNamespaceURI(){
-	return mobyServiceName2TargetNamespaceURI.get(currentService);
-    }
-
-    public void setTargetNamespaceURI(String nsURI){
-	mobyServiceName2TargetNamespaceURI.put(currentService, nsURI);
-    }
-
     public QName getPortQName(){
 	return mobyServiceName2Port.get(currentService);
     }
@@ -997,6 +1172,41 @@
 	mobyServiceName2OpInput.put(currentService, inputName);
     }
 
+    /**
+     * If style is not explicitly available, literal is the default
+     */
+    public String getOperationEncoding(){
+	String encoding = mobyServiceName2Encoding.get(currentService);
+	if(encoding == null){
+	    return "literal";
+	}
+	return encoding;
+    }
+
+    public void setOperationEncoding(String encoding){
+	mobyServiceName2Encoding.put(currentService, encoding);
+    }
+
+    public String getOperationStyle(){
+	String style = mobyServiceName2Style.get(currentService);
+	if(style == null){
+	    return "document";
+	}
+	return style;
+    }
+
+    public void setOperationStyle(String style){
+	mobyServiceName2Style.put(currentService, style);
+    }
+
+    public String getSoapAction(){
+	return mobyServiceName2SoapAction.get(currentService);
+    }
+
+    public void setSoapAction(String soapAction){
+	mobyServiceName2SoapAction.put(currentService, soapAction);
+    }
+
     public QName getOperationOutputQName(){
 	return mobyServiceName2OpOutput.get(currentService);
     }
@@ -1019,5 +1229,25 @@
     public void setOutputXSDTypes(Map<String,String> types){
 	mobyServiceName2OutputXSDTypes.put(currentService, types);
     }
+
+    public Map<String,String> getMobyParams2DocXPaths(){
+	return mobyServiceName2MobyXPathMap.get(currentService);
+    }
+
+    /**
+     * Primarily for use by systems that allow renaming of params, since SAWSDL doesn't directly
+     */
+    public void setMobyParams2DocXPaths(Map<String,String> moby2xpaths){
+	mobyServiceName2MobyXPathMap.put(currentService, moby2xpaths);
+    }
+
+    public String getTargetNamespaceURI(){
+	return mobyServiceName2TargetNamespaceURI.get(currentService);
+    }
+
+    public void setTargetNamespaceURI(String nsURI){
+	mobyServiceName2TargetNamespaceURI.put(currentService, nsURI);
+    }
+
 }
 




More information about the MOBY-guts mailing list