1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 package uk.ac.soton.itinnovation.wsdlutils;
52
53
54 import java.io.InputStream;
55 import java.io.ByteArrayInputStream;
56 import java.util.Iterator;
57 import java.util.Vector;
58
59 import javax.xml.namespace.QName;
60 import javax.xml.soap.SOAPElement;
61 import javax.xml.soap.SOAPException;
62 import javax.xml.parsers.DocumentBuilderFactory;
63
64 import org.apache.axis.client.Call;
65 import org.apache.axis.constants.Style;
66 import org.apache.axis.message.MessageElement;
67 import org.w3c.dom.Document;
68 import org.w3c.dom.Element;
69 import org.apache.axis.message.SOAPBodyElement;
70 import org.apache.axis.message.SOAPEnvelope;
71 import org.apache.axis.message.SOAPHeaderElement;
72 import org.w3c.dom.Node;
73 import org.w3c.dom.NodeList;
74
75
76 import uk.ac.soton.itinnovation.utils.URIUtils;
77
78 public class WSDLOperation {
79 public static boolean DEBUG = true;
80
81 private WSDLService service = null;
82 private Call call = null;
83 private Vector inputs = new Vector();
84 private Vector outputs = new Vector();
85 private String operationName;
86 private String inputMessageName;
87 private String outputMessageName;
88 private String portName;
89 private String documentation;
90 private Element secToken;
91 private Document requestDocument=null;
92 private SOAPHeaderElement slaHeader;
93
94 public WSDLOperation(Call c) {
95 this.call = c;
96 }
97
98
99 public WSDLParameter getInput(int i) {
100 return (WSDLParameter) getInputs().elementAt(i);
101 }
102 public WSDLParameter getInput(String name) {
103 for(int i = 0; i < inputs.size(); i++) {
104 WSDLParameter in = (WSDLParameter) inputs.get(i);
105 String paramName = in.getName();
106 if(paramName.equals(name) || URIUtils.getLocalName(paramName).equals(name))
107 return in;
108 }
109
110 return null;
111 }
112 public WSDLParameter getOutput(int i) {
113 return (WSDLParameter) getOutputs().elementAt(i);
114 }
115 public WSDLParameter getOutput(String name) {
116 for(int i = 0; i < outputs.size(); i++) {
117 WSDLParameter out = (WSDLParameter) outputs.get(i);
118 String paramName = out.getName();
119 if( URIUtils.relaxedMatch(paramName, name) )
120 return out;
121 }
122
123 return null;
124 }
125 public Vector getInputs() { return inputs; }
126 public Vector getOutputs() { return outputs; }
127 void addInput(String name, QName type) { inputs.add(new WSDLParameter(name, type)); }
128 void addOutput(String name, QName type) { outputs.add(new WSDLParameter(name, type)); }
129
130 public String getName() { return call.getOperationName().getLocalPart(); }
131
132 public String getOperationName() { return operationName; }
133 public void setOperationName(String s) { operationName = s; }
134 public String getPortName() { return portName; }
135 public void setPortName(String s) { portName = s; }
136 public String getInputMessageName() { return inputMessageName; }
137 public void setInputMessageName(String s) { inputMessageName = s; }
138 public String getOutputMessageName() { return outputMessageName; }
139 public void setOutputMessageName(String s) { outputMessageName = s; }
140 public WSDLService getService() { return service; }
141 public void setService(WSDLService s) { service = s; }
142 public String getDocumentation() { return documentation; }
143 public void setDocumentation(String s) { documentation = s; }
144 public void setRequestDocument(Document doc){ this.requestDocument=doc; }
145
146 public void addHeader(SOAPHeaderElement param){ call.addHeader(param);}
147 public void setOperationStyle(Style style){ call.setOperationStyle(style);}
148
149 public String toString() {
150 return getName();
151 }
152
153 public String getDescription() {
154 String s = getName() + "(";
155
156 for(Iterator i = inputs.
157 WSDLParameter param = (WSDLParameter) i.next();
158 s += param.getName() + ":" + param.getType().getLocalPart();
159 if(i.hasNext()) s += ", ";
160 }
161 s += ") -> (";
162
163 for(Iterator i = outputs.
164 WSDLParameter param = (WSDLParameter) i.next();
165 s += param.getName() + ":" + param.getType().getLocalPart();
166 if(i.hasNext()) s += ", ";
167 }
168 s += ")";
169
170 return s;
171 }
172
173
174 public void setSecToken(Element token){
175 secToken=token;
176 }
177
178 public void setSLAHeader(SOAPHeaderElement header ){
179 slaHeader=header;
180 }
181
182 public void invoke() throws Exception {
183 SOAPEnvelope request = createRequest();
184 if (secToken!=null){
185 request.addHeader(new SOAPHeaderElement(secToken));
186 }
187 if (slaHeader!=null){
188 request.addHeader(slaHeader);
189 }
190
191
192 if(DEBUG) {
193 System.out.println("Invoke operation " + getDescription());
194 System.out.println(request);
195 }
196
197 SOAPEnvelope reply = call.invoke(request);
198
199
200
201
202 processResult(reply);
203 }
204
205 private SOAPElement response=null;
206 public Iterator getResponse(){
207 return response.getChildElements();
208 }
209 private void processResult(SOAPEnvelope reply) throws SOAPException {
210 SOAPElement soapBody = reply.getBody();
211 response = (SOAPElement) soapBody.getChildElements().next();
212 Iterator messageParts = response.getChildElements();
213
214 for(int i = 0; i < outputs.size(); i++) {
215 WSDLParameter output = (WSDLParameter) outputs.elementAt(i);
216
217 SOAPElement e = (SOAPElement) messageParts.next();
218 output.setTextValue(e.toString());
219
220 if(DEBUG) {
221 System.out.println("processResult " + e);
222 System.out.println("getValue " + e.getValue());
223 System.out.println("getType " + (e.getNodeType() == Node.ELEMENT_NODE));
224 System.out.println("getValue is null? " + (e.getValue() == null));
225 System.out.println("result has children? " + e.getChildElements().hasNext());
226 if(e.getChildElements().hasNext()) {
227 Node child = (Node) e.getChildElements().next();
228 System.out.println("result first child " + child);
229 }
230 }
231
232 Iterator children = e.getChildElements();
233 if( children.hasNext() ) {
234 Node child = (Node) e.getChildElements().next();
235 if( child.getNodeType() == Node.TEXT_NODE )
236 output.setValue( child.toString() );
237 else
238 output.setValue( e.toString() );
239 }
240 else
241 output.setValue( e.toString() );
242 }
243 }
244
245
246 private SOAPEnvelope createRequest() throws SOAPException {
247 String targetNamespace = call.getOperationName().getNamespaceURI();
248 String opName = call.getOperationName().getLocalPart();
249 SOAPEnvelope envelope = new SOAPEnvelope();
250
251 if(DEBUG) {
252 System.out.println("Get opName = " + call.getOperationName());
253 System.out.println("SOAP opName = " +opName);
254 System.out.println("SOAP Action = " +call.getSOAPActionURI());
255 System.out.println("SOAP Action used = " + call.useSOAPAction());
256 }
257
258 envelope.addNamespaceDeclaration("xsi", WSDLConsts.xsiURI);
259 envelope.addNamespaceDeclaration("xsd",WSDLConsts. xsdURI);
260
261
262 String inputEncodingStyle = "http://schemas.xmlsoap.org/soap/encoding/";
263 if(inputEncodingStyle != null) {
264 envelope.setEncodingStyle(inputEncodingStyle);
265 envelope.addAttribute(WSDLConsts.soapURI, "encodingStyle", inputEncodingStyle);
266 }
267
268
269 SOAPBodyElement soapBody =null;
270 if (call.getOperationStyle().equals(Style.RPC)){
271 String nsOp = "u" ;
272 soapBody = new SOAPBodyElement(
273 envelope.createName(opName, nsOp, targetNamespace));
274 }
275 else {
276 setOperationStyle(Style.DOCUMENT);
277 if(requestDocument!=null)soapBody = new SOAPBodyElement((Element)requestDocument.getDocumentElement());
278 else soapBody = new SOAPBodyElement(envelope.createName(opName));
279 }
280
281 envelope.addBodyElement(soapBody);
282
283 for(Iterator i = inputs.iterator(); i.hasNext(); ) {
284 WSDLParameter param = (WSDLParameter) i.next();
285 Object paramValue = param.getValue();
286
287 if(paramValue == null) continue;
288
289 SOAPElement soapElement = soapBody.addChildElement(URIUtils.getLocalName(param.getName()), "");
290
291
292 if(((String)paramValue).startsWith("<") ) {
293 if(DEBUG)
294 System.out.println("Case 1");
295 InputStream in=new ByteArrayInputStream(((String)paramValue).getBytes());
296 try{
297 DocumentBuilderFactory dbf= new org.apache.xerces.jaxp.DocumentBuilderFactoryImpl();
298 Document doc=dbf.newDocumentBuilder().parse(in);
299 System.out.println("GOT DOCUMENT\n"+doc);
300
301 Node inputNode=doc.getDocumentElement();
302 createSOAPElement(soapElement, inputNode);
303 }catch(Exception pe){
304 throw new SOAPException(pe);
305 }
306 if(soapElement.getAttributeValue(WSDLConsts.xsiType) == null) {
307 if(DEBUG) System.out.println("Case 1a");
308 soapElement.addAttribute(WSDLConsts.xsiType,
309 "u:" + param.getType().getLocalPart());
310 }
311 }
312 else {
313 if(DEBUG){
314 System.out.println("Case 2 " + param.getType());
315 System.out.println("Case 2 " + paramValue.toString());
316 }
317 soapElement.addAttribute(WSDLConsts.xsiType, "xsd:" + param.getType().getLocalPart());
318 soapElement.addTextNode(paramValue.toString());
319 }
320
321 }
322
323 return envelope;
324 }
325
326 public void createSOAPElement(SOAPElement parent, Node node) throws SOAPException {
327 int type = node.getNodeType();
328
329 if(type == Node.TEXT_NODE) {
330 if(DEBUG)
331 System.out.println("Case 3");
332
333 parent.addAttribute(WSDLConsts.xsiType, "xsd:string");
334 parent.addTextNode(node.getNodeValue());
335 }
336 else if(type == Node.ELEMENT_NODE) {
337 SOAPElement soapElement;
338
339 if(!(node.getParentNode() instanceof org.w3c.dom.Document)) {
340 if(DEBUG)
341 System.out.println("Case 4");
342
343 soapElement = parent.addChildElement(node.getNodeName());
344 }
345 else {
346 if(DEBUG)
347 System.out.println("Case 5");
348
349 soapElement = parent;
350 }
351
352
353
354 NodeList children = node.getChildNodes();
355 if (children != null) {
356 int len = children.getLength();
357 for (int i = 0; i < len; i++) {
358 createSOAPElement(soapElement, children.item(i));
359 }
360 }
361 }
362 }
363
364
365 }