[kepler-dev] type conversion for the web services actor

Matt Jones jones at nceas.ucsb.edu
Mon Feb 9 17:43:07 PST 2004


Hi Ilkay,

I started looking into the changes needed to make the web services actor 
support non-string data types.  Here's a diff (below) showing my changes 
to start to get this to work (against WebServiceInterface.java, which I 
later learned is out-of-date code still hanging around in CVS -- sorry).

The atomic types (e.g., xsd:int) will be pretty easy to map and cast, 
but the more complex types (e.g., arrays such as xsd:string[] and 
user-defined object types) will be more complex because the WSDL has to 
be parsed for complexType defs that can be fairly arbitrary. 
Nevertheless, I think both are tractable.

The code diff below sets the right Ptolemy type on the actor, but I 
didn't get to the part where input and output values are propoerly 
casted when the data is being emitted on the port.  That was going to be 
more confusing.

Also, it seemed like your current code used a single return value port 
rather than setting up the response message output ports.  So I was 
confused about the correct usage of Call.getResponseMessage(), 
Call.getOutputParams(), Call.getOutputValues(), and 
Call.getReturnType().  What's your view of the appropriate mapping of 
the WSDL requestMessage, responseMessage, and returnMessage to Ptolemy 
ports?  I felt like there were multiple options here and wasn't sure how 
to proceed.

Finally, web services can be deployed using several different SOAP 
message parsing schemes.   Axis defines these as "RPC", "Document", 
"Wrapped", and "Message" (see 
http://ws.apache.org/axis/java/user-guide.html).  Each has a different 
way of interpreting the SOAP body.  Do you think this needs to be 
exposed through Kepler's WS interface, or can we treat them all 
uniformly? That is, does the client care at all how the service is deployed?

I'd like to continue discussing this design with you, so let me know as 
you start to work on this.  Cheers,

Matt


Index: src/org/sdm/spa/WebServiceInterface.java
===================================================================
RCS file: /cvs/kepler/src/org/sdm/spa/Attic/WebServiceInterface.java,v
retrieving revision 1.21
diff -r1.21 WebServiceInterface.java
40a41
 > import ptolemy.data.type.ArrayType;
484d484
<
503a504,526
 >             // Get a hash of all of the array type definitions
 >             Hashtable arrayTypes = new Hashtable();
 >             //xPath = 
"//wsdl:types/schema/complexType/complexContent/restriction/attribute[@ref=\"soapenc:arrayType\"]";
 >             xPath = "//types/schema/complexType";
 >             System.out.println("Searching for: " + xPath);
 >             contextNode = doc.getDocumentElement();
 >             i = XPathAPI.selectNodeIterator(contextNode, xPath);
 >             // For each node
 >             while ( (node = i.nextNode()) != null) {
 >               String arrayName = ( (Element) node).getAttribute("name");
 >               System.out.println("Processing a complexType element: " 
+ arrayName);
 >               //xPath = 
"//complexContent/restriction/attribute[@ref=\"soapenc:arrayType\"]";
 >               xPath = "//complexContent/restriction/attribute";
 >               NodeIterator typeIterator = 
XPathAPI.selectNodeIterator(node, xPath);
 >               Node subnode = typeIterator.nextNode();
 >               if (subnode != null) {
 >                   System.out.println("Processing subnode...");
 >                   String arrayType = ( (Element) 
subnode).getAttribute("wsdl:arrayType");
 >                   System.out.println("Found array type: " + arrayName 
+ " (" + arrayType + ")");
 >                   arrayTypes.put(arrayName, arrayType);
 >               }
 >             }
 >
526a550
 > 	          System.out.println("Input port: " + partName + " [" + 
typeStr + "]");
529c553
<               pin.setTypeEquals(BaseType.STRING);
---
 >               setPortType(arrayTypes, pin, typeStr);
542a567
 > 	          System.out.println("Output port: " + partName + " [" + 
typeStr + "]");
545c570
<               pout.setTypeEquals(BaseType.STRING);
---
 >               setPortType(arrayTypes, pout, typeStr);
601a627,654
 >   /**
 >    * Set the type of a port based on a string representation of that type
 >    * that was extracted from the WSDL description.
 >    *
 >    * @param arrayTypes a hash of defined array types by name
 >    * @param port the port whose type is to be set
 >    * @param typeStr the string representation of the type to be set
 >    */
 >   private void setPortType(Hashtable arrayTypes, TypedIOPort port, 
String typeStr) {
 >   	      if (typeStr.equals("xsd:int")) {
 > 		      port.setTypeEquals(BaseType.INT);
 > 	      } else if (typeStr.equals("xsd:long")) {
 > 		      port.setTypeEquals(BaseType.LONG);
 >           } else if (typeStr.equals("xsd:double")) {
 > 		      port.setTypeEquals(BaseType.DOUBLE);
 > 	      } else if (typeStr.equals("xsd:string")) {
 >               port.setTypeEquals(BaseType.STRING);
 > 	      } else if (typeStr.startsWith("impl:")) {
 >               String match = typeStr.substring(5);
 >               String matchedType = (String)arrayTypes.get(match);
 >               System.out.println("Setting type to: " + matchedType);
 >               // FIXME: need to actually set the type to the right 
array type!
 >               port.setTypeEquals(new ArrayType(BaseType.STRING));
 > 	      } else {
 > 		      port.setTypeEquals(BaseType.STRING);
 > 	      }
 >   }
 >





More information about the Kepler-dev mailing list