KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > wsif > providers > soap > soaprmi > WSIFOperation_SoapRMI


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2002 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "WSIF" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 2001, 2002, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package org.apache.wsif.providers.soap.soaprmi;
59
60 import java.io.BufferedWriter JavaDoc;
61 import java.io.IOException JavaDoc;
62 import java.io.Reader JavaDoc;
63 import java.io.StringWriter JavaDoc;
64 import java.io.Writer JavaDoc;
65 import java.net.URL JavaDoc;
66 import java.util.HashMap JavaDoc;
67 import java.util.Iterator JavaDoc;
68 import java.util.List JavaDoc;
69 import java.util.Map JavaDoc;
70 import java.util.Vector JavaDoc;
71
72 import javax.wsdl.Definition;
73 import javax.wsdl.Input;
74 import javax.wsdl.Operation;
75 import javax.wsdl.Output;
76 import javax.wsdl.Part;
77 import javax.xml.namespace.QName JavaDoc;
78
79 import org.apache.wsif.WSIFException;
80 import org.apache.wsif.WSIFMessage;
81 import org.apache.wsif.WSIFOperation;
82 import org.apache.wsif.WSIFPort;
83 import org.apache.wsif.base.WSIFDefaultOperation;
84 import org.apache.wsif.logging.Trc;
85 import org.apache.wsif.providers.WSIFDynamicTypeMap;
86 import org.apache.wsif.providers.WSIFDynamicTypeMapping;
87 import soaprmi.mapping.XmlJavaMapping;
88 import soaprmi.mapping.XmlJavaTypeMap;
89 import soaprmi.mapping.XmlMapException;
90 import soaprmi.soap.Soap;
91 import soaprmi.soaprpc.MethodInvoker;
92 import soaprmi.util.HTTPUtils;
93
94 /**
95  * Provide concrete implementation of WSDL operation with SoapRMI
96  * RPC method invocation.
97  *
98  * @author Alekander Slominski
99  */

100 public class WSIFOperation_SoapRMI
101     extends WSIFDefaultOperation
102     implements WSIFOperation {
103
104     private static final long serialVersionUID = 1L;
105
106     protected WSIFPort_SoapRMI portInstance;
107     protected Operation operation;
108     protected Definition definition;
109
110     // cached information to allow efficinet operation calls
111
protected List JavaDoc partNames;
112     protected String JavaDoc[] names;
113     protected Class JavaDoc[] types;
114     protected String JavaDoc inputEncodingStyle = Soap.SOAP_ENC_NS;
115     protected String JavaDoc inputNamespace;
116
117     protected String JavaDoc returnName;
118     protected Class JavaDoc returnType;
119     protected String JavaDoc outputEncodingStyle = Soap.SOAP_ENC_NS;
120     protected String JavaDoc actionUri;
121     protected WSIFDynamicTypeMap typeMap;
122     protected XmlJavaMapping soaprmiMapping;
123
124     /**
125      * Create Apache SOAP operation instance that encapsultes all necessary
126      * information required to create and execute Apache SOAP Call.
127      */

128     public WSIFOperation_SoapRMI(
129         WSIFPort_SoapRMI pi,
130         Operation op,
131         WSIFDynamicTypeMap typeMap)
132         throws WSIFException {
133         this.typeMap = typeMap;
134         setDynamicWSIFPort(pi);
135         setOperation(op);
136         setDefintion(pi.getDefinition());
137         prepare();
138     }
139
140     /**
141      * Create a new copy of this object. This is not a clone, since
142      * it does not copy the referenced objects as well.
143      */

144     public WSIFOperation_SoapRMI copy() throws WSIFException {
145
146         WSIFOperation_SoapRMI op =
147             new WSIFOperation_SoapRMI(portInstance, operation, typeMap);
148
149         op.setSoapActionURI(getSoapActionURI());
150         op.setInputNamespace(getInputNamespace());
151         op.setInputEncodingStyle(getInputEncodingStyle());
152         op.setOutputEncodingStyle(getOutputEncodingStyle());
153         op.setPartNames(getPartNames());
154         op.setReturnName(getReturnName());
155
156         return op;
157     }
158
159     /**
160      * This is utility method that when called initializes operation
161      * (including reconstruction of method signature).
162      */

163     private void prepare() throws WSIFException {
164         soaprmiMapping = new XmlJavaMapping();
165         try {
166             XmlJavaMapping defaultMapping = soaprmi.soap.Soap.getDefault().getMapping();
167             soaprmiMapping.connectTo(defaultMapping);
168             // disable SoapRMI auto mapping
169
soaprmiMapping.setDefaultStructNsPrefix(null);
170
171             for (Iterator JavaDoc i = typeMap.iterator(); i.hasNext();) {
172                 WSIFDynamicTypeMapping mapping = (WSIFDynamicTypeMapping) i.next();
173
174                 // map SOAPStruct into namespace:http://soapinterop.org/ : SOAPStruct
175
soaprmiMapping.mapStruct(
176                     "http://schemas.xmlsoap.org/soap/encoding/",
177                     mapping.getXmlType().getNamespaceURI(),
178                     mapping.getXmlType().getLocalPart(),
179                     mapping.getJavaType());
180
181             }
182         } catch (XmlMapException ex) {
183             throw new WSIFException("Could not initialize mapping.", ex);
184         }
185
186         // first determine list of arguments
187
Input input = operation.getInput();
188         if (input != null) {
189             List JavaDoc parts;
190             if (partNames != null) {
191                 parts = new Vector JavaDoc();
192                 for (Iterator JavaDoc i = partNames.iterator(); i.hasNext();) {
193                     String JavaDoc partName = (String JavaDoc) i.next();
194                     Part part = input.getMessage().getPart(partName);
195                     if (part == null) {
196                         throw new WSIFException(
197                             "no input part named " + partName + " for bining operation " + getName());
198                     }
199                     parts.add(part);
200                 }
201             } else {
202                 parts = input.getMessage().getOrderedParts(null);
203             }
204             int count = parts.size();
205             names = new String JavaDoc[count];
206             types = new Class JavaDoc[count];
207
208             // get parts in correct order
209
for (int i = 0; i < count; ++i) {
210                 Part part = (Part) parts.get(i);
211                 names[i] = part.getName();
212                 QName JavaDoc partType = part.getTypeName();
213                 if (partType == null) {
214                     throw new WSIFException("part " + names[i] + " must have type name declared");
215                 }
216                 try {
217                     XmlJavaTypeMap typeMap =
218                         soaprmiMapping.queryTypeMap(
219                             inputEncodingStyle,
220                             partType.getNamespaceURI(),
221                             partType.getLocalPart());
222                     types[i] = typeMap.javaClass();
223                 } catch (XmlMapException ex) {
224                     throw new WSIFException(
225                         "Could not determine local java type for "
226                             + partType.getNamespaceURI()
227                             + ":"
228                             + partType.getLocalPart(),
229                         ex);
230                 }
231
232             }
233         } else {
234             names = new String JavaDoc[0];
235             types = new Class JavaDoc[0];
236         }
237
238         // now prepare return value
239
Output output = operation.getOutput();
240         if (output != null) {
241             Part returnPart = null;
242             if (returnName != null) {
243                 returnPart = output.getMessage().getPart(returnName);
244                 if (returnPart == null) {
245                     throw new WSIFException(
246                         "no output part named " + returnName + " for bining operation " + getName());
247                 }
248             } else {
249                 List JavaDoc parts = output.getMessage().getOrderedParts(null);
250                 if (parts.size() > 0) {
251                     returnPart = (Part) parts.get(0);
252                     returnName = returnPart.getName();
253                 }
254             }
255             if (returnPart != null) {
256                 QName JavaDoc partType = returnPart.getTypeName();
257                 try {
258                     XmlJavaTypeMap typeMap =
259                         soaprmiMapping.queryTypeMap(
260                             outputEncodingStyle,
261                             partType.getNamespaceURI(),
262                             partType.getLocalPart());
263                     returnType = typeMap.javaClass();
264                 } catch (XmlMapException ex) {
265                     throw new WSIFException(
266                         "Could not determine local java type for "
267                             + partType.getNamespaceURI()
268                             + ":"
269                             + partType.getLocalPart(),
270                         ex);
271                 }
272             } else {
273                 returnType = Void.TYPE;
274             }
275         }
276
277     }
278
279     public boolean executeRequestResponseOperation(
280         WSIFMessage input,
281         WSIFMessage output,
282         WSIFMessage fault)
283         throws WSIFException {
284         return invokeRequestResponseOperation(input, output, fault);
285     }
286
287     public void executeInputOnlyOperation(WSIFMessage input) throws WSIFException {
288         invokeInputOnlyOperation(input);
289     }
290
291     /**
292      * Invoke RPC operation using ApacheSOAP
293      */

294     public boolean invokeRequestResponseOperation(
295         WSIFMessage input,
296         WSIFMessage output,
297         WSIFMessage fault)
298         throws WSIFException {
299         if (names == null)
300             prepare();
301
302         try {
303
304             // prepare parameters
305

306             Object JavaDoc[] params = new Object JavaDoc[types.length];
307
308             Object JavaDoc partInst;
309             for (int i = 0; i < names.length; ++i) {
310                 partInst = input.getObjectPart(names[i]);
311                 if (partInst == null) {
312                     boolean foundInputParameter = false;
313                     String JavaDoc paramName = names[i];
314                     Iterator JavaDoc partsIterator = input.getPartNames();
315                     while (partsIterator.hasNext()) {
316                         String JavaDoc partName = (String JavaDoc) partsIterator.next();
317                         if (partName == null || paramName == null)
318                             break;
319                         if (partName.equals(paramName)) {
320                             foundInputParameter = true;
321                         }
322                     }
323                     if (!foundInputParameter)
324                         throw new WSIFException(
325                             "expected input message to have part with name '" + names[i] + "'");
326                 }
327                 Object JavaDoc value = partInst;
328                 // some runtime param validity check
329
if (value != null
330                     && !types[i].isPrimitive()
331                     && !(types[i].isAssignableFrom(value.getClass()))) {
332                     throw new WSIFException(
333                         "value "
334                             + value
335                             + " has unexpected type "
336                             + value.getClass()
337                             + " instead of "
338                             + types[i]);
339                 }
340                 params[i] = value;
341             }
342
343             MethodInvoker mi = null; //newCall(m);
344
// prepare this method invoker
345
// try {
346
mi =
347                 MethodInvoker.makeMethodInvoker(
348                     getInputNamespace(),
349                     returnType,
350                     getName(),
351                     types,
352                     names,
353                     getSoapActionURI(),
354                     soaprmiMapping);
355             // } catch(soaprmi.RemoteException ex) {
356
// throw new WSIFException(
357
// "Could not prepare method invoker for operation "+getName(), ex);
358
// }
359

360             Map JavaDoc requestHeaders = new HashMap JavaDoc();
361
362             requestHeaders.put("SOAPAction", getSoapActionURI());
363
364             StringWriter JavaDoc sw = new StringWriter JavaDoc();
365             Writer JavaDoc writer = new BufferedWriter JavaDoc(sw);
366
367             String JavaDoc locationUri = portInstance.getLocation();
368
369             if (Trc.ON)
370                 Trc.event(
371                     this,
372                     "invoking SoapRMI operation "
373                         + getName()
374                         + " on "
375                         + locationUri);
376
377             mi.sendRequest(params, writer);
378
379             String JavaDoc requestContent = sw.toString();
380
381             String JavaDoc httpProxyHost = null;
382             int httpProxyPort = -1;
383
384             URL JavaDoc url = new URL JavaDoc(locationUri);
385
386             Reader JavaDoc reader =
387                 HTTPUtils.post(url, requestContent, requestHeaders, "text/xml; charset=utf-8",
388                 //NOTE putting "" around utf-8 is crashing Tomcat 3.2.1
389
60 * 1000, //timeout,
390
httpProxyHost, httpProxyPort);
391
392             Object JavaDoc result = mi.receiveResponse(reader);
393
394             if (returnType != null) {
395                 if (result != null
396                     && !returnType.isPrimitive()
397                     && !(returnType.isAssignableFrom(result.getClass()))) {
398                     throw new WSIFException(
399                         "return value "
400                             + result
401                             + " has unexpected type "
402                             + result.getClass()
403                             + " instead of "
404                             + returnType);
405                 }
406                 output.setObjectPart(returnName, result);
407             }
408
409             // TOOD keep pool of method invokers - good for performance
410
//returnCallToPool(mi);
411

412         } catch (IOException JavaDoc ex) {
413             //ex.printStackTrace();
414
throw new WSIFException("IO Exception", ex);
415         } catch (soaprmi.RemoteException ex) {
416             ex.printStackTrace();
417             throw new WSIFException("SoapRMI exception", ex);
418         } catch (soaprmi.soap.SoapException ex) {
419             throw new WSIFException("SOAP exception", ex);
420         } catch (xpp.XmlPullParserException ex) {
421             throw new WSIFException("SOAP exception", ex);
422         }
423
424         return true;
425     }
426
427     /**
428      * Invoke only operation are not yet supported.
429      */

430     public void invokeInputOnlyOperation(WSIFMessage input) throws WSIFException {
431         throw new WSIFException("not implemented");
432     }
433
434     /**
435      * Return name of operation.
436      */

437     public String JavaDoc getName() {
438         return operation.getName();
439     }
440
441     public String JavaDoc getSoapActionURI() {
442         return actionUri;
443     }
444     public void setSoapActionURI(String JavaDoc value) {
445         actionUri = value;
446     }
447
448     public String JavaDoc getInputNamespace() {
449         return inputNamespace;
450     }
451     public void setInputNamespace(String JavaDoc value) {
452         inputNamespace = value;
453     }
454
455     public String JavaDoc getInputEncodingStyle() {
456         return inputEncodingStyle;
457     }
458     
459     public void setInputEncodingStyle(String JavaDoc value) {
460         inputEncodingStyle = value;
461     }
462     
463     public String JavaDoc getOutputEncodingStyle() {
464         return outputEncodingStyle;
465     }
466     
467     public void setOutputEncodingStyle(String JavaDoc value) {
468         outputEncodingStyle = value;
469     }
470     
471     public List JavaDoc getPartNames() {
472         return partNames;
473     }
474     
475     public void setPartNames(List JavaDoc value) {
476         partNames = value;
477     }
478     
479     public String JavaDoc getReturnName() {
480         return returnName;
481     }
482     
483     public void setReturnName(String JavaDoc value) {
484         returnName = value;
485     }
486
487     // where is WSDL defining this abstract mesage
488
public Operation getOperation() {
489         return operation;
490     }
491     
492     public void setOperation(Operation value) {
493         operation = value;
494     }
495     
496     public Definition getDefinition() {
497         return definition;
498     }
499     
500     public void setDefintion(Definition value) {
501         definition = value;
502     }
503
504     // WSIF related
505
public WSIFPort_SoapRMI getDynamicWSIFPort() {
506         return portInstance;
507     }
508     
509     public void setDynamicWSIFPort(WSIFPort_SoapRMI value) {
510         portInstance = value;
511     }
512
513     public WSIFPort getWSIFPort() {
514         Trc.entry(this);
515         Trc.exit(portInstance);
516         return portInstance;
517     }
518     
519 }
Popular Tags