WSDLOperation.java revision 6
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen// The MIT License
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen//
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen// Copyright (c) 2004 Evren Sirin
bdd36cfdba3ff66d25570a9ff568d69e1eb543cfTimo Sirainen//
1299f2c3723ca9ccf8f9e563ec23ee1a1721fe4cTimo Sirainen// Permission is hereby granted, free of charge, to any person obtaining a copy
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen// of this software and associated documentation files (the "Software"), to
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen// deal in the Software without restriction, including without limitation the
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen// sell copies of the Software, and to permit persons to whom the Software is
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen// furnished to do so, subject to the following conditions:
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen//
d8702d15ee7721ed1fcfc8f00a589970bd6b3598Timo Sirainen// The above copyright notice and this permission notice shall be included in
d8702d15ee7721ed1fcfc8f00a589970bd6b3598Timo Sirainen// all copies or substantial portions of the Software.
38505846b6d083e19f0a7d1373761bdda5d9a5a9Timo Sirainen//
38505846b6d083e19f0a7d1373761bdda5d9a5a9Timo Sirainen// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2087543679f0b35a8f70e1277b234e66ffdf96edTimo Sirainen// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2087543679f0b35a8f70e1277b234e66ffdf96edTimo Sirainen// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
ff2f20bbc039ad8e362ead199366e21bc41f18edAki Tuomi// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
ff2f20bbc039ad8e362ead199366e21bc41f18edAki Tuomi// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
ff2f20bbc039ad8e362ead199366e21bc41f18edAki Tuomi// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen// IN THE SOFTWARE.
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainenpackage org.mindswap.wsdl;
7c849dbc7be089175c1a83a84ee7249ed695810dTimo Sirainen
7c849dbc7be089175c1a83a84ee7249ed695810dTimo Sirainen
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainenimport java.util.Iterator;
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainenimport java.util.Vector;
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainenimport javax.xml.namespace.QName;
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainenimport javax.xml.soap.SOAPElement;
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainenimport javax.xml.soap.SOAPException;
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainenimport org.apache.axis.client.Call;
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainenimport org.apache.axis.constants.Style;
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainenimport org.apache.axis.message.SOAPBodyElement;
8eea67470c1bd8562a62e7445d930bb2079b1a43Timo Sirainenimport org.apache.axis.message.SOAPEnvelope;
8eea67470c1bd8562a62e7445d930bb2079b1a43Timo Sirainenimport org.mindswap.utils.URIUtils;
8eea67470c1bd8562a62e7445d930bb2079b1a43Timo Sirainenimport org.mindswap.utils.Utils;
8eea67470c1bd8562a62e7445d930bb2079b1a43Timo Sirainenimport org.w3c.dom.Node;
8eea67470c1bd8562a62e7445d930bb2079b1a43Timo Sirainenimport org.w3c.dom.NodeList;
64e244defe74f513ce94f33d000a048ddbe2ea23Timo Sirainen
64e244defe74f513ce94f33d000a048ddbe2ea23Timo Sirainenpublic class WSDLOperation {
87cc5e9025e7fb6408f0de64c48d2d2897773ba5Timo Sirainen public static boolean DEBUG = false;
f016dec9837e6a41867708e4b89ca5308dedab05Timo Sirainen
939451389b8e0ad529277b84fe51dab38a8cf77cTimo Sirainen private WSDLService service = null;
fe791e96fdf796f7d8997ee0515b163dc5eddd72Aki Tuomi private Call call = null;
a8dac1be6a0c3adbbce5887ca395f418194c6c06Aki Tuomi private Vector inputs = new Vector();
53f97800b16ab3a8d263c5331132dec1e8fea9a0Aki Tuomi private Vector outputs = new Vector();
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen private String operationName;
64e244defe74f513ce94f33d000a048ddbe2ea23Timo Sirainen private String inputMessageName;
325d17cdbb7a338f7c413788f5e8e42d2e80a7f8Timo Sirainen private String outputMessageName;
009217abb57a24a4076092e8e4e165545747839eStephan Bosch private String portName;
64e244defe74f513ce94f33d000a048ddbe2ea23Timo Sirainen private String documentation;
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen
64e244defe74f513ce94f33d000a048ddbe2ea23Timo Sirainen public WSDLOperation(Call c) {
64e244defe74f513ce94f33d000a048ddbe2ea23Timo Sirainen this.call = c;
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen }
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen public WSDLParameter getInput(int i) {
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen return (WSDLParameter) getInputs().elementAt(i);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen }
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen public WSDLParameter getInput(String name) {
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen for(int i = 0; i < inputs.size(); i++) {
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen WSDLParameter in = (WSDLParameter) inputs.get(i);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen String paramName = in.getName();
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen if(paramName.equals(name) || URIUtils.getLocalName(paramName).equals(name))
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen return in;
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen }
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen
18ddd4fba186b1b407cae98bb388fa8add7db48dTimo Sirainen return null;
90ed03ab289947f5576d2c616ada27724f50e9cdTimo Sirainen }
9ddd3d7d8651985e373a6c48e0ddc76b8a4ef1c7Timo Sirainen public WSDLParameter getOutput(int i) {
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen return (WSDLParameter) getOutputs().elementAt(i);
05817ffe09295892e1aa5c4a7f91d060e249563cTimo Sirainen }
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen public WSDLParameter getOutput(String name) {
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen for(int i = 0; i < outputs.size(); i++) {
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen WSDLParameter out = (WSDLParameter) outputs.get(i);
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen String paramName = out.getName();
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen if( URIUtils.relaxedMatch(paramName, name) )
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen return out;
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen }
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen return null;
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen }
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen public Vector getInputs() { return inputs; }
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen public Vector getOutputs() { return outputs; }
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen void addInput(String name, QName type) { inputs.add(new WSDLParameter(name, type)); }
8eea67470c1bd8562a62e7445d930bb2079b1a43Timo Sirainen void addOutput(String name, QName type) { outputs.add(new WSDLParameter(name, type)); }
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen public String getName() { return call.getOperationName().getLocalPart(); }
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen public String getOperationName() { return operationName; }
64e244defe74f513ce94f33d000a048ddbe2ea23Timo Sirainen public void setOperationName(String s) { operationName = s; }
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen public String getPortName() { return portName; }
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen public void setPortName(String s) { portName = s; }
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen public String getInputMessageName() { return inputMessageName; }
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen public void setInputMessageName(String s) { inputMessageName = s; }
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen public String getOutputMessageName() { return outputMessageName; }
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen public void setOutputMessageName(String s) { outputMessageName = s; }
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen public WSDLService getService() { return service; }
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen public void setService(WSDLService s) { service = s; }
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen public String getDocumentation() { return documentation; }
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen public void setDocumentation(String s) { documentation = s; }
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen public String toString() {
9137c55411aa39d41c1e705ddc34d5bd26c65021Timo Sirainen return getName();
66c3f635f2f33905af527d49b27f95322aa7dfa7Timo Sirainen }
66c3f635f2f33905af527d49b27f95322aa7dfa7Timo Sirainen
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen public String getDescription() {
3b8d05391336c0e4d24c8ddcc962f350409ffbd3Timo Sirainen String s = getName() + "(";
3b8d05391336c0e4d24c8ddcc962f350409ffbd3Timo Sirainen
3b8d05391336c0e4d24c8ddcc962f350409ffbd3Timo Sirainen for(Iterator i = inputs./*values().*/iterator(); i.hasNext(); ) {
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen WSDLParameter param = (WSDLParameter) i.next();
s += param.getName() + ":" + param.getType().getLocalPart();
if(i.hasNext()) s += ", ";
}
s += ") -> (";
for(Iterator i = outputs./*values().*/iterator(); i.hasNext(); ) {
WSDLParameter param = (WSDLParameter) i.next();
s += param.getName() + ":" + param.getType().getLocalPart();
if(i.hasNext()) s += ", ";
}
s += ")";
return s;
}
public void invoke() throws Exception {
SOAPEnvelope request = createRequest();
if(DEBUG) {
System.out.println("Invoke operation " + getDescription());
System.out.println(request);
}
SOAPEnvelope reply = call.invoke(request);
if(DEBUG)
System.out.println(Utils.formatXML(reply));
// TODO Handle SOAPFault message
processResult(reply);
}
private void processResult(SOAPEnvelope reply) throws SOAPException {
SOAPElement soapBody = reply.getBody();
SOAPElement response = (SOAPElement) soapBody.getChildElements().next();
Iterator messageParts = response.getChildElements();
for(int i = 0; i < outputs.size(); i++) {
WSDLParameter output = (WSDLParameter) outputs.elementAt(i);
SOAPElement e = (SOAPElement) messageParts.next();
output.setTextValue(e.toString());
if(DEBUG) {
System.out.println("processResult " + e);
System.out.println("getValue " + e.getValue());
System.out.println("getType " + (e.getNodeType() == Node.ELEMENT_NODE));
System.out.println("getValue is null? " + (e.getValue() == null));
System.out.println("result has children? " + e.getChildElements().hasNext());
if(e.getChildElements().hasNext()) {
Node child = (Node) e.getChildElements().next();
System.out.println("result first child " + child);
}
}
Iterator children = e.getChildElements();
if( children.hasNext() ) {
Node child = (Node) e.getChildElements().next();
if( child.getNodeType() == Node.TEXT_NODE )
output.setValue( child.toString() );
else
output.setValue( e.toString() );
}
else
output.setValue( e.toString() );
}
}
private SOAPEnvelope createRequest() throws SOAPException {
String targetNamespace = call.getOperationName().getNamespaceURI();
String opName = call.getOperationName().getLocalPart();
SOAPEnvelope envelope = new SOAPEnvelope();
if(DEBUG) {
System.out.println("SOAP Action = " +call.getSOAPActionURI());
System.out.println("SOAP Action used = " + call.useSOAPAction());
}
envelope.addNamespaceDeclaration("xsi", WSDLConsts.xsiURI);
envelope.addNamespaceDeclaration("xsd",WSDLConsts. xsdURI);
//envelope.addNamespaceDeclaration("ns0", targetNamespace);
String inputEncodingStyle = "http://schemas.xmlsoap.org/soap/encoding/";
if(inputEncodingStyle != null) {
envelope.setEncodingStyle(inputEncodingStyle);
envelope.addAttribute(WSDLConsts.soapURI, "encodingStyle", inputEncodingStyle);
}
// FIXME test this feature
String nsOp = call.getOperationStyle().equals(Style.RPC) ? "u" : "";
SOAPBodyElement soapBody = new SOAPBodyElement(
envelope.createName(opName, nsOp, targetNamespace));
envelope.addBodyElement(soapBody);
for(Iterator i = inputs.iterator(); i.hasNext(); ) {
WSDLParameter param = (WSDLParameter) i.next();
Object paramValue = param.getValue();
if(paramValue == null) continue;
SOAPElement soapElement = soapBody.addChildElement(URIUtils.getLocalName(param.getName()), "");
// TODO treat string, int, float differently
if(paramValue instanceof Node) {
if(DEBUG)
System.out.println("Case 1");
createSOAPElement(soapElement, (Node) paramValue);
if(soapElement.getAttributeValue(WSDLConsts.xsiType) == null) {
if(DEBUG) System.out.println("Case 1a");
soapElement.addAttribute(WSDLConsts.xsiType,
"u:" + param.getType().getLocalPart());
}
}
else {
if(DEBUG)
System.out.println("Case 2 " + param.getType());
soapElement.addAttribute(WSDLConsts.xsiType, "xsd:" + param.getType().getLocalPart());
soapElement.addTextNode(paramValue.toString());
}
}
return envelope;
}
public void createSOAPElement(SOAPElement parent, Node node) throws SOAPException {
int type = node.getNodeType();
if(type == Node.TEXT_NODE) {
if(DEBUG)
System.out.println("Case 3");
parent.addAttribute(WSDLConsts.xsiType, "xsd:string");
parent.addTextNode(node.getNodeValue());
}
else if(type == Node.ELEMENT_NODE) {
SOAPElement soapElement;
if(!(node.getParentNode() instanceof org.w3c.dom.Document)) {
if(DEBUG)
System.out.println("Case 4");
soapElement = parent.addChildElement(node.getNodeName());
}
else {
if(DEBUG)
System.out.println("Case 5");
soapElement = parent;
}
//NamedNodeMap attrs = node.getAttributes();
NodeList children = node.getChildNodes();
if (children != null) {
int len = children.getLength();
for (int i = 0; i < len; i++) {
createSOAPElement(soapElement, children.item(i));
}
}
}
}
}