KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > webservice > deployment > ServiceDescription


1 /**
2  * JBoss, the OpenSource J2EE webOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7 package org.jboss.webservice.deployment;
8
9 // $Id: ServiceDescription.java,v 1.40.2.22 2005/06/19 10:07:15 bill Exp $
10

11 import org.jboss.axis.Constants;
12 import org.jboss.axis.encoding.DefaultTypeMappingImpl;
13 import org.jboss.axis.encoding.TypeMapping;
14 import org.jboss.axis.enums.Style;
15 import org.jboss.axis.enums.Use;
16 import org.jboss.logging.Logger;
17 import org.jboss.webservice.metadata.jaxrpcmapping.ExceptionMapping;
18 import org.jboss.webservice.metadata.jaxrpcmapping.JavaWsdlMapping;
19 import org.jboss.webservice.metadata.jaxrpcmapping.JavaWsdlMappingFactory;
20 import org.jboss.webservice.metadata.jaxrpcmapping.JavaXmlTypeMapping;
21 import org.jboss.webservice.metadata.jaxrpcmapping.MethodParamPartsMapping;
22 import org.jboss.webservice.metadata.jaxrpcmapping.ServiceEndpointInterfaceMapping;
23 import org.jboss.webservice.metadata.jaxrpcmapping.ServiceEndpointMethodMapping;
24 import org.jboss.webservice.metadata.jaxrpcmapping.WsdlMessageMapping;
25 import org.jboss.webservice.metadata.wsdl.WSDL11DefinitionFactory;
26 import org.jboss.webservice.util.DOMUtils;
27 import org.jboss.xb.binding.NamespaceRegistry;
28 import org.w3c.dom.Element JavaDoc;
29 import org.w3c.dom.NodeList JavaDoc;
30
31 import javax.wsdl.Binding;
32 import javax.wsdl.BindingInput;
33 import javax.wsdl.BindingOperation;
34 import javax.wsdl.BindingOutput;
35 import javax.wsdl.Definition;
36 import javax.wsdl.Input;
37 import javax.wsdl.Message;
38 import javax.wsdl.Output;
39 import javax.wsdl.Part;
40 import javax.wsdl.Port;
41 import javax.wsdl.PortType;
42 import javax.wsdl.Service;
43 import javax.wsdl.WSDLException;
44 import javax.wsdl.extensions.ExtensibilityElement;
45 import javax.wsdl.extensions.soap.SOAPBinding;
46 import javax.wsdl.extensions.soap.SOAPBody;
47 import javax.wsdl.extensions.soap.SOAPHeader;
48 import javax.wsdl.factory.WSDLFactory;
49 import javax.wsdl.xml.WSDLWriter;
50 import javax.xml.namespace.QName JavaDoc;
51 import javax.xml.parsers.DocumentBuilder JavaDoc;
52 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
53 import javax.xml.rpc.ServiceException JavaDoc;
54 import java.io.IOException JavaDoc;
55 import java.io.InputStream JavaDoc;
56 import java.io.OutputStream JavaDoc;
57 import java.net.URI JavaDoc;
58 import java.net.URISyntaxException JavaDoc;
59 import java.net.URL JavaDoc;
60 import java.util.ArrayList JavaDoc;
61 import java.util.HashMap JavaDoc;
62 import java.util.HashSet JavaDoc;
63 import java.util.Iterator JavaDoc;
64 import java.util.List JavaDoc;
65 import java.util.Properties JavaDoc;
66 import java.util.StringTokenizer JavaDoc;
67
68 /**
69  * Abstracts an Axis service description
70  *
71  * @author thomas.diesler@jboss.org
72  * @since 08-June-2004
73  */

74 public class ServiceDescription
75 {
76    // provide logging
77
private final Logger log = Logger.getLogger(ServiceDescription.class);
78
79    private Definition wsdlDefinition;
80    private Service wsdlService;
81    private Binding wsdlBinding;
82    private JavaWsdlMapping javaWsdlMapping;
83
84    private Style style;
85    private Use use;
86    private HashMap JavaDoc operations = new HashMap JavaDoc();
87    private HashMap JavaDoc typeMappings = new HashMap JavaDoc();
88
89    // Maps namespace uri to prefix
90
private NamespaceRegistry nsRegistry = new NamespaceRegistry();
91
92    // Set<QName> user type qnames
93
private HashSet JavaDoc userTypes = new HashSet JavaDoc();
94
95    private Properties JavaDoc callProperties;
96
97    /**
98     * Construct the service description from a given wsdl and jaxrpc-mapping.xml
99     */

100    public ServiceDescription(Definition wsdlDefinition, JavaWsdlMapping javaMapping, URL JavaDoc ws4eeMetaData, String JavaDoc portName) throws ServiceException JavaDoc
101    {
102       this.wsdlDefinition = wsdlDefinition;
103       this.wsdlService = getWsdlService(wsdlDefinition, portName);
104       this.wsdlBinding = getWsdlBinding(wsdlService, portName);
105
106       this.javaWsdlMapping = javaMapping;
107
108       initServiceDescription();
109
110       mergeDeploymentMetaData(ws4eeMetaData, portName);
111    }
112
113    /**
114     * This is mainly for testing, the WSDDGenerator has a main entry
115     */

116    public ServiceDescription(URL JavaDoc wsdlLocation, URL JavaDoc jaxrpcLocation, String JavaDoc portName) throws Exception JavaDoc
117    {
118       WSDL11DefinitionFactory wsdlFactory = WSDL11DefinitionFactory.newInstance();
119       wsdlFactory.setFeature(WSDL11DefinitionFactory.FEATURE_VERBOSE, true);
120
121       this.wsdlDefinition = wsdlFactory.parse(wsdlLocation);
122       this.wsdlService = getWsdlService(wsdlDefinition, portName);
123       this.wsdlBinding = getWsdlBinding(wsdlService, portName);
124
125       if (jaxrpcLocation != null)
126       {
127          JavaWsdlMappingFactory mappingFactory = JavaWsdlMappingFactory.newInstance();
128          this.javaWsdlMapping = mappingFactory.parse(jaxrpcLocation);
129       }
130       initServiceDescription();
131    }
132
133    /**
134     * Initialize this service description
135     */

136    private void initServiceDescription() throws ServiceException JavaDoc
137    {
138       initServiceStyle();
139       initServiceUse();
140       initOperations();
141       initTypeMappings();
142    }
143
144    public Definition getWsdlDefinition()
145    {
146       return wsdlDefinition;
147    }
148
149    public JavaWsdlMapping getJavaWsdlMapping()
150    {
151       return javaWsdlMapping;
152    }
153
154    public Service getWsdlService()
155    {
156       return wsdlService;
157    }
158
159    public Binding getWsdlBinding()
160    {
161       return wsdlBinding;
162    }
163
164    public NamespaceRegistry getNamespaceRegistry()
165    {
166       return nsRegistry;
167    }
168
169    public Style getStyle()
170    {
171       return style;
172    }
173
174    public Use getUse()
175    {
176       return use;
177    }
178
179    public String JavaDoc[] getOperationNames()
180    {
181       String JavaDoc[] names = new String JavaDoc[operations.size()];
182       return (String JavaDoc[])operations.keySet().toArray(names);
183    }
184
185    public OperationDescription getOperation(String JavaDoc name)
186    {
187       return (OperationDescription)operations.get(name);
188    }
189
190    public Iterator JavaDoc getOperations()
191    {
192       return operations.values().iterator();
193    }
194
195    public QName JavaDoc[] getTypMappingNames()
196    {
197       QName JavaDoc[] names = new QName JavaDoc[typeMappings.size()];
198       return (QName JavaDoc[])typeMappings.keySet().toArray(names);
199    }
200
201    public Iterator JavaDoc getTypMappings()
202    {
203       return typeMappings.values().iterator();
204    }
205
206    public TypeMappingDescription getTypMapping(QName JavaDoc qname)
207    {
208       return (TypeMappingDescription)typeMappings.get(qname);
209    }
210
211    public void dumpWsdlDefinition(OutputStream JavaDoc out) throws WSDLException, IOException JavaDoc
212    {
213       WSDLFactory wsdlFactory = WSDLFactory.newInstance();
214       WSDLWriter wsdlWriter = wsdlFactory.newWSDLWriter();
215       wsdlWriter.writeWSDL(wsdlDefinition, out);
216    }
217
218    public Properties JavaDoc getCallProperties()
219    {
220       return callProperties;
221    }
222
223    public void setCallProperties(Properties JavaDoc callProperties)
224    {
225       this.callProperties = callProperties;
226    }
227
228    /**
229     * Merge an axis style wsdd with this service description
230     */

231    private void mergeDeploymentMetaData(URL JavaDoc ws4eeMetaData, String JavaDoc portName) throws ServiceException JavaDoc
232    {
233       if (ws4eeMetaData == null)
234       {
235          log.debug("No ws4ee deployment meta data available");
236          return;
237       }
238
239       log.debug("Merging with ws4ee deployment meta data: " + ws4eeMetaData);
240
241       try
242       {
243          DocumentBuilderFactory JavaDoc factory = DocumentBuilderFactory.newInstance();
244          factory.setNamespaceAware(true);
245          DocumentBuilder JavaDoc builder = factory.newDocumentBuilder();
246
247          Element JavaDoc rootElement = null;
248          InputStream JavaDoc is = ws4eeMetaData.openStream();
249          try
250          {
251             rootElement = builder.parse(is).getDocumentElement();
252          }
253          finally
254          {
255             is.close();
256          }
257
258          // The root element can have zero ore more port elements
259
Element JavaDoc portElement = null;
260          NodeList JavaDoc nlistRoot = rootElement.getElementsByTagName("port");
261          for (int i = 0; portElement == null && i < nlistRoot.getLength(); i++)
262          {
263             Element JavaDoc el = (Element JavaDoc)nlistRoot.item(i);
264             String JavaDoc name = el.getAttribute("name");
265             if (name.equals(portName))
266                portElement = el;
267          }
268
269          // Check if we have an import
270
if (portElement != null)
271          {
272             log.debug("Using port element: " + portName);
273             Element JavaDoc importElement = DOMUtils.getFirstChildElement(portElement);
274             if (importElement.getLocalName().equals("import"))
275             {
276                String JavaDoc importFile = importElement.getFirstChild().getNodeValue();
277                log.debug("Using import: " + importFile);
278
279                String JavaDoc resource = ws4eeMetaData.toExternalForm();
280                resource = resource.substring(0, resource.lastIndexOf("/")) + "/" + importFile;
281                InputStream JavaDoc isImport = new URL JavaDoc(resource).openStream();
282                try
283                {
284                   portElement = builder.parse(isImport).getDocumentElement();
285                }
286                finally
287                {
288                   is.close();
289                }
290             }
291          }
292
293          // There was no port element, so use the root
294
if (portElement == null)
295             portElement = rootElement;
296
297          mergeTypeMappings(portElement);
298
299          mergeOperations(portElement);
300
301       }
302       catch (Exception JavaDoc e)
303       {
304          throw new ServiceException JavaDoc(e);
305       }
306    }
307
308    private void mergeTypeMappings(Element JavaDoc portElement)
309    {
310       ArrayList JavaDoc mergedTypeMappings = new ArrayList JavaDoc();
311
312       NodeList JavaDoc nlistPort = portElement.getElementsByTagName("typeMapping");
313       for (int i = 0; i < nlistPort.getLength(); i++)
314       {
315          Element JavaDoc el = (Element JavaDoc)nlistPort.item(i);
316          QName JavaDoc qname = DOMUtils.getAttributeValueAsQName(el, "qname");
317          String JavaDoc javaType = DOMUtils.getAttributeValue(el, "type");
318
319          if (mergedTypeMappings.contains(qname))
320             throw new IllegalArgumentException JavaDoc("Cannot add/replace the same type mapping twice: " + qname);
321
322          mergedTypeMappings.add(qname);
323
324          if (javaType.startsWith("java:"))
325             javaType = javaType.substring(5);
326
327          TypeMappingDescription tm = (TypeMappingDescription)typeMappings.get(qname);
328          if (tm != null)
329             log.debug("Replacing typeMapping: " + qname);
330          else
331             log.debug("Addinging typeMapping: " + qname);
332
333          tm = new TypeMappingDescription(qname, null, javaType, use, null);
334          tm.setEncodingURI(el.getAttribute("encodingStyle"));
335          tm.setSerializerFactoryName(el.getAttribute("serializer"));
336          tm.setDeserializerFactoryName(el.getAttribute("deserializer"));
337          tm.setUserDefined(true);
338
339          typeMappings.put(qname, tm);
340
341          BeanXMLMetaData metaData = BeanXMLMetaData.parse(DOMUtils.getFirstChildElement(el));
342          tm.setMetaData(metaData);
343       }
344    }
345
346    private void mergeOperations(Element JavaDoc portElement)
347    {
348       ArrayList JavaDoc mergedOperations = new ArrayList JavaDoc();
349
350       NodeList JavaDoc nlistOperation = portElement.getElementsByTagName("operation");
351       for (int i = 0; i < nlistOperation.getLength(); i++)
352       {
353          Element JavaDoc elOp = (Element JavaDoc)nlistOperation.item(i);
354          String JavaDoc opName = elOp.getAttribute("name");
355          QName JavaDoc opQName = DOMUtils.getAttributeValueAsQName(elOp, "qname");
356          QName JavaDoc returnQName = DOMUtils.getAttributeValueAsQName(elOp, "returnQName");
357          QName JavaDoc returnType = DOMUtils.getAttributeValueAsQName(elOp, "returnType");
358
359          if (mergedOperations.contains(opName))
360             throw new IllegalArgumentException JavaDoc("Cannot add/replace the same operation twice: " + opName);
361
362          mergedOperations.add(opName);
363
364          OperationDescription op = (OperationDescription)operations.get(opName);
365          if (op != null)
366             log.debug("Replacing operation: " + opName);
367          else
368             log.debug("Addinging operation: " + opName);
369
370
371          if (opQName == null)
372             opQName = new QName JavaDoc(opName);
373
374          op = new OperationDescription(opName, opQName);
375          op.setReturnQName(returnQName);
376          op.setReturnType(returnType);
377          operations.put(opName, op);
378
379          NodeList JavaDoc paramList = elOp.getElementsByTagName("parameter");
380          for (int j = 0; j < paramList.getLength(); j++)
381          {
382             Element JavaDoc elParam = (Element JavaDoc)paramList.item(j);
383             String JavaDoc paramName = elParam.getAttribute("name");
384             QName JavaDoc paramQName = DOMUtils.getAttributeValueAsQName(elParam, "qname");
385             String JavaDoc mode = elParam.getAttribute("mode");
386             QName JavaDoc type = DOMUtils.getAttributeValueAsQName(elParam, "type");
387             boolean inHeader = DOMUtils.getAttributeValueAsBoolean(elParam, "inHeader");
388             boolean outHeader = DOMUtils.getAttributeValueAsBoolean(elParam, "outHeader");
389
390             if (paramQName == null)
391                paramQName = new QName JavaDoc(paramName);
392
393             OperationDescription.Parameter param = new OperationDescription.Parameter(paramName, paramQName, mode, type);
394             param.setInHeader(inHeader);
395             param.setOutHeader(outHeader);
396             op.addParameter(param);
397          }
398
399          NodeList JavaDoc faultList = elOp.getElementsByTagName("fault");
400          for (int j = 0; j < faultList.getLength(); j++)
401          {
402             Element JavaDoc elFault = (Element JavaDoc)faultList.item(j);
403             String JavaDoc faultName = DOMUtils.getAttributeValue(elFault, "name");
404             QName JavaDoc faultQName = DOMUtils.getAttributeValueAsQName(elFault, "qname");
405             String JavaDoc javaType = DOMUtils.getAttributeValue(elFault, "class");
406             QName JavaDoc faultType = DOMUtils.getAttributeValueAsQName(elFault, "type");
407
408             OperationDescription.Fault fault = new OperationDescription.Fault(faultName, faultQName, javaType, faultType);
409             op.addFault(fault);
410          }
411       }
412    }
413
414    /**
415     * Get the service style, should be 'rpc' or 'document'
416     */

417    private void initServiceStyle()
418    {
419       Iterator JavaDoc itBinding = wsdlBinding.getExtensibilityElements().iterator();
420       while (itBinding.hasNext())
421       {
422          ExtensibilityElement exElement = (ExtensibilityElement)itBinding.next();
423          if (exElement instanceof SOAPBinding)
424          {
425             SOAPBinding soapBinding = (SOAPBinding)exElement;
426             Style bindingStyle = Style.getStyle(soapBinding.getStyle());
427             if (style == null && bindingStyle != null)
428                style = bindingStyle;
429
430             if (style != null && bindingStyle != null && style.equals(bindingStyle) == false)
431                throw new IllegalArgumentException JavaDoc("Unsupported mix of style attributes " + style + "/" + bindingStyle);
432          }
433       }
434
435       if (style == null)
436       {
437          log.warn("Cannot find any style attribute for binding: " + wsdlBinding.getQName());
438          style = Style.RPC;
439       }
440    }
441
442    /**
443     * Get the service use, should be 'encoded' or 'literal'
444     */

445    private void initServiceUse()
446    {
447       Iterator JavaDoc itOp = wsdlBinding.getBindingOperations().iterator();
448       while (itOp.hasNext())
449       {
450          BindingOperation wsdlBindingOperation = (BindingOperation)itOp.next();
451
452          BindingInput wsdlBindingInput = wsdlBindingOperation.getBindingInput();
453          if (wsdlBindingInput != null)
454          {
455             Iterator JavaDoc itIn = wsdlBindingInput.getExtensibilityElements().iterator();
456             while (itIn.hasNext())
457             {
458                Object JavaDoc obj = itIn.next();
459                if (obj instanceof SOAPBody)
460                {
461                   SOAPBody soapBody = (SOAPBody)obj;
462                   Use soapBodyUse = Use.getUse(soapBody.getUse());
463                   if (use == null)
464                   {
465                      if (soapBodyUse != null)
466                      {
467                         use = soapBodyUse;
468                      }
469                      else
470                      {
471                         use = Use.getUse("literal");
472                      }
473                   }
474                   if (use != null && soapBodyUse != null && use.equals(soapBodyUse) == false)
475                      throw new IllegalArgumentException JavaDoc("Unsupported mix of use attributes " + use + "/" + soapBodyUse);
476                }
477             }
478          }
479
480          BindingOutput wsdlBindingOutput = wsdlBindingOperation.getBindingOutput();
481          if (wsdlBindingOutput != null)
482          {
483             Iterator JavaDoc itOut = wsdlBindingOutput.getExtensibilityElements().iterator();
484             while (itOut.hasNext())
485             {
486                Object JavaDoc obj = itOut.next();
487                if (obj instanceof SOAPBody)
488                {
489                   SOAPBody soapBody = (SOAPBody)obj;
490                   Use soapBodyUse = Use.getUse(soapBody.getUse());
491                   if (use == null)
492                   {
493                      if (soapBodyUse != null)
494                      {
495                         use = soapBodyUse;
496                      }
497                      else
498                      {
499                         use = Use.getUse("literal");
500                      }
501                   }
502                   if (use != null && soapBodyUse != null && use.equals(soapBodyUse) == false)
503                      throw new IllegalArgumentException JavaDoc("Unsupported mix of use attributes " + use + "/" + soapBodyUse);
504                }
505             }
506          }
507       }
508
509       if (use == null)
510       {
511          log.warn("Cannot find any use attribute for binding: " + wsdlBinding.getQName());
512          use = Use.LITERAL;
513       }
514    }
515
516    /**
517     * Init the Service operations
518     */

519    private void initOperations() throws ServiceException JavaDoc
520    {
521       PortType wsdlPortType = wsdlBinding.getPortType();
522       QName JavaDoc portTypeQName = wsdlPortType.getQName();
523
524       Iterator JavaDoc itOp = wsdlPortType.getOperations().iterator();
525       while (itOp.hasNext())
526       {
527          javax.wsdl.Operation wsdlOperation = (javax.wsdl.Operation)itOp.next();
528          String JavaDoc opWsdlName = wsdlOperation.getName();
529          String JavaDoc opJavaName = opWsdlName;
530
531          QName JavaDoc opQName = null;
532
533          // Use the namespace uri from the port type
534
if (portTypeQName.getNamespaceURI().length() > 0)
535          {
536             opQName = new QName JavaDoc(portTypeQName.getNamespaceURI(), opWsdlName);
537             opQName = nsRegistry.registerQName(opQName);
538          }
539          else
540          {
541             opQName = new QName JavaDoc(opWsdlName);
542          }
543
544          // Replace the opName with the java method name from jaxrpc-mapping.xml
545
ServiceEndpointMethodMapping seMethodMapping = getServiceEndpointMethodMapping(wsdlPortType, opWsdlName);
546          if (seMethodMapping != null)
547          {
548             opJavaName = seMethodMapping.getJavaMethodName();
549          }
550
551          OperationDescription opDesc = new OperationDescription(opJavaName, opQName);
552          operations.put(opJavaName, opDesc);
553
554          Output wsdlOutput = wsdlOperation.getOutput();
555          Input wsdlInput = wsdlOperation.getInput();
556
557          if (wsdlInput != null && wsdlOutput == null)
558          {
559             log.debug("Using one-way call semantics: " + opWsdlName);
560             opDesc.setOneWay(true);
561          }
562
563          // [TDI] Workaround for document style operations that don't have a parameter
564
// http://jira.jboss.com/jira/browse/JBWS-70
565
if (style == Style.DOCUMENT && seMethodMapping != null)
566          {
567             boolean inParams = seMethodMapping.getMethodParamPartsMappings().length > 0;
568             if (wsdlInput != null && wsdlInput.getMessage().getParts().size() > 0 && inParams == false)
569             {
570                log.debug("jaxrpc-mapping does not have any <method-param-parts-mapping>, ignoring wsdl parts");
571                wsdlInput = null;
572             }
573
574             boolean outParams = seMethodMapping.getWsdlReturnValueMapping() != null;
575             if (wsdlOutput != null && wsdlOutput.getMessage().getParts().size() > 0 && outParams == false)
576             {
577                log.debug("jaxrpc-mapping does not have any <wsdl-return-value-mapping>, ignoring wsdl parts");
578                wsdlOutput = null;
579             }
580          }
581
582          if (wsdlOutput != null)
583          {
584             Message wsdlMessageOut = wsdlOutput.getMessage();
585             Iterator JavaDoc outParts = wsdlMessageOut.getOrderedParts(null).iterator();
586             while (outParts.hasNext())
587             {
588                Part wsdlPart = (Part)outParts.next();
589                String JavaDoc paramName = wsdlPart.getName();
590                QName JavaDoc typeQName = wsdlPart.getTypeName();
591
592                boolean outHeader = isHeaderParam(opWsdlName, paramName);
593
594                QName JavaDoc element = wsdlPart.getElementName();
595                if (typeQName == null && element != null)
596                   typeQName = element;
597
598                if (typeQName != null)
599                {
600                   typeQName = nsRegistry.registerQName(typeQName);
601                   userTypes.add(typeQName);
602                }
603
604                // Get the param mode from jaxrpc-mapping
605
String JavaDoc paramMode = null;
606                if (seMethodMapping != null)
607                {
608                   MethodParamPartsMapping[] mppMappings = seMethodMapping.getMethodParamPartsMappings();
609                   for (int i = 0; paramMode == null && i < mppMappings.length; i++)
610                   {
611                      WsdlMessageMapping wmMapping = mppMappings[i].getWsdlMessageMapping();
612                      if (paramName.equals(wmMapping.getWsdlMessagePartName()))
613                      {
614                         paramMode = wmMapping.getParameterMode();
615                      }
616                   }
617                }
618
619                // The first out part is the return if it is not also an input
620
// and if there is no parameter mode given for it in jaxrpc-mapping
621
if (opDesc.getReturnType() == null && wsdlOperation.getInput().getMessage().getPart(paramName) == null && paramMode == null)
622                {
623                   QName JavaDoc returnQName = getParameterQName(wsdlPart);
624                   opDesc.setReturnQName(returnQName);
625                   opDesc.setReturnType(typeQName);
626                }
627
628                // If this was not the return parameter, add it as operation parameter
629
else
630                {
631                   if (paramMode == null)
632                      paramMode = "OUT";
633
634                   QName JavaDoc paramQName = getParameterQName(wsdlPart);
635                   OperationDescription.Parameter param = new OperationDescription.Parameter(paramName, paramQName, paramMode, typeQName);
636                   param.setOutHeader(outHeader);
637                   opDesc.addParameter(param);
638                }
639             }
640          }
641
642          // Process the IN parts
643
if (wsdlInput != null)
644          {
645             Message wsdlMessageIn = wsdlInput.getMessage();
646             Iterator JavaDoc inParts = wsdlMessageIn.getOrderedParts(null).iterator();
647             while (inParts.hasNext())
648             {
649                Part wsdlPart = (Part)inParts.next();
650                String JavaDoc paramName = wsdlPart.getName();
651                QName JavaDoc typeQName = wsdlPart.getTypeName();
652
653                boolean inHeader = isHeaderParam(opWsdlName, paramName);
654
655                if (typeQName == null && wsdlPart.getElementName() != null)
656                   typeQName = wsdlPart.getElementName();
657
658                if (typeQName != null)
659                {
660                   typeQName = nsRegistry.registerQName(typeQName);
661                   userTypes.add(typeQName);
662                }
663
664                OperationDescription.Parameter param = opDesc.getParameterForName(paramName);
665                if (param != null)
666                {
667                   param.setMode("INOUT");
668                   param.setInHeader(inHeader);
669                }
670                else
671                {
672                   QName JavaDoc paramQName = getParameterQName(wsdlPart);
673                   param = new OperationDescription.Parameter(paramName, paramQName, "IN", typeQName);
674                   param.setInHeader(inHeader);
675                   opDesc.addParameter(param);
676                }
677             }
678          }
679
680          // Reorder the parameters
681
reorderOperationParameters(opDesc, wsdlOperation);
682
683          // Process the fault parts
684
Iterator JavaDoc inFaults = wsdlOperation.getFaults().values().iterator();
685          while (inFaults.hasNext())
686          {
687             javax.wsdl.Fault wsdlFault = (javax.wsdl.Fault)inFaults.next();
688             Part wsdlPart = (Part)wsdlFault.getMessage().getParts().values().iterator().next();
689             String JavaDoc partName = wsdlPart.getName();
690             QName JavaDoc typeQName = wsdlPart.getTypeName();
691             QName JavaDoc faultQName = wsdlPart.getElementName();
692
693             if (typeQName == null && faultQName != null)
694                typeQName = faultQName;
695
696             if (typeQName != null)
697                typeQName = nsRegistry.registerQName(typeQName);
698
699             if (faultQName != null)
700                faultQName = nsRegistry.registerQName(faultQName);
701
702             String JavaDoc javaType = null;
703             if (javaWsdlMapping != null)
704             {
705                // Try exception mapping first
706
QName JavaDoc wsdlMessageName = wsdlFault.getMessage().getQName();
707                ExceptionMapping exceptionMapping = javaWsdlMapping.getExceptionMappingForMessageQName(wsdlMessageName);
708                if (exceptionMapping != null)
709                {
710                   javaType = exceptionMapping.getExceptionType();
711                }
712                // Try type mapping next
713
else
714                {
715                   JavaXmlTypeMapping javaMapping = javaWsdlMapping.getTypeMappingForQName(typeQName);
716                   if (javaMapping != null)
717                      javaType = javaMapping.getJavaType();
718                }
719             }
720
721             // Try axis default type mapping
722
if (javaType == null)
723             {
724                TypeMapping defMapping = DefaultTypeMappingImpl.getSingleton();
725                Class JavaDoc typeClass = defMapping.getClassForQName(typeQName);
726                if (typeClass != null)
727                   javaType = typeClass.getName();
728             }
729
730             if (javaType == null)
731             {
732                String JavaDoc packageName = getPackageName(typeQName);
733                javaType = packageName + "." + typeQName.getLocalPart();
734                log.warn("Guessing fault java type from qname: " + javaType);
735             }
736
737             OperationDescription.Fault fault = new OperationDescription.Fault(partName, faultQName, javaType, typeQName);
738             opDesc.addFault(fault);
739          }
740       }
741
742       if (operations.size() == 0)
743          log.warn("Cannot find any operations for portType: " + wsdlPortType.getQName());
744    }
745
746    /** Reorder the parameters */
747    private void reorderOperationParameters(OperationDescription opDesc, javax.wsdl.Operation wsdlOperation)
748    {
749       // Order according to the parameterOrder from the wsdl portType operation
750
List JavaDoc wsdlParamOrder = wsdlOperation.getParameterOrdering();
751       if (wsdlParamOrder != null && wsdlParamOrder.size() > 0)
752       {
753          ArrayList JavaDoc orderedParams = new ArrayList JavaDoc();
754          Iterator JavaDoc it = wsdlParamOrder.iterator();
755          while (it.hasNext())
756          {
757             String JavaDoc paramName = (String JavaDoc)it.next();
758             OperationDescription.Parameter opParam = opDesc.getParameterForName(paramName);
759             if (opParam == null)
760             {
761                throw new IllegalArgumentException JavaDoc("Operation paramerter appears in wsdl paramOrder, " +
762                        "but not in operation: " + paramName);
763             }
764             orderedParams.add(opParam);
765          }
766          opDesc.setParameters(orderedParams);
767       }
768    }
769
770    /** Get the paramter QName
771     * @param wsdlPart
772     */

773    private QName JavaDoc getParameterQName(Part wsdlPart)
774    {
775       String JavaDoc partName = wsdlPart.getName();
776       QName JavaDoc elementName = wsdlPart.getElementName();
777       QName JavaDoc paramQName = (elementName != null ? elementName : new QName JavaDoc(partName));
778
779       if (paramQName.getNamespaceURI().equals("") == false)
780          paramQName = nsRegistry.registerQName(paramQName);
781
782       return paramQName;
783    }
784
785    /**
786     * Get the service endpoint method mapping from jaxrpc-mapping.xml for a given port type and operation name.
787     */

788    private ServiceEndpointMethodMapping getServiceEndpointMethodMapping(PortType wsdlPortType, String JavaDoc opWsdlName)
789    {
790       ServiceEndpointMethodMapping seiMethodMapping = null;
791       if (javaWsdlMapping != null)
792       {
793          ServiceEndpointInterfaceMapping seiMapping = javaWsdlMapping.getServiceEndpointInterfaceMappingByPortType(wsdlPortType.getQName());
794          if (seiMapping != null)
795          {
796             seiMethodMapping = seiMapping.getServiceEndpointMethodMappingByWsdlOperation(opWsdlName);
797          }
798       }
799       return seiMethodMapping;
800    }
801
802    private boolean isHeaderParam(String JavaDoc opName, String JavaDoc paramName)
803    {
804       boolean inHeader = false;
805
806       BindingOperation wsdlBindingOperation = wsdlBinding.getBindingOperation(opName, null, null);
807       if (wsdlBindingOperation != null)
808       {
809          BindingInput bindingInput = wsdlBindingOperation.getBindingInput();
810          if (bindingInput != null)
811          {
812             Iterator JavaDoc itIn = bindingInput.getExtensibilityElements().iterator();
813             while (inHeader == false && itIn.hasNext())
814             {
815                ExtensibilityElement exElement = (ExtensibilityElement)itIn.next();
816                if (exElement instanceof SOAPHeader)
817                {
818                   SOAPHeader soapHeader = (SOAPHeader)exElement;
819                   inHeader = soapHeader.getPart().equals(paramName);
820                }
821             }
822          }
823
824          BindingOutput bindingOutput = wsdlBindingOperation.getBindingOutput();
825          if (bindingOutput != null)
826          {
827             Iterator JavaDoc itOut = bindingOutput.getExtensibilityElements().iterator();
828             while (inHeader == false && itOut.hasNext())
829             {
830                ExtensibilityElement exElement = (ExtensibilityElement)itOut.next();
831                if (exElement instanceof SOAPHeader)
832                {
833                   SOAPHeader soapHeader = (SOAPHeader)exElement;
834                   inHeader = soapHeader.getPart().equals(paramName);
835                }
836             }
837          }
838       }
839       else
840       {
841          log.warn("Cannot obtain binding operation for: " + opName);
842       }
843
844       return inHeader;
845    }
846
847    /**
848     * Append the typeMapping information, which is taken from the jaxrpc-mapping.xml
849     */

850    private void initTypeMappings() throws ServiceException JavaDoc
851    {
852       // Remove the QNames for which we don't need an explicit type mapping
853
Iterator JavaDoc itRem = userTypes.iterator();
854       while (itRem.hasNext())
855       {
856          QName JavaDoc typeQName = (QName JavaDoc)itRem.next();
857          String JavaDoc typeURI = typeQName.getNamespaceURI();
858
859          // No typeMapping for xsd:foo and soap:bar
860
if (typeURI.equals(Constants.URI_DEFAULT_SCHEMA_XSD) || typeURI.equals(Constants.URI_SOAP11_ENC))
861             itRem.remove();
862       }
863
864       // There is a chance that the custom type is not expicitly mapped in jaxrpc-mapping.xml
865
// Walk through all the remaining userTypes and try to find the corresponding class
866
Iterator JavaDoc it = userTypes.iterator();
867       while (it.hasNext())
868       {
869          QName JavaDoc typeQName = (QName JavaDoc)it.next();
870          String JavaDoc typeURI = typeQName.getNamespaceURI();
871
872          String JavaDoc prefix = (String JavaDoc)nsRegistry.getPrefix(typeURI);
873          if (prefix == null)
874             throw new IllegalStateException JavaDoc("Cannot find uri in registry: " + typeURI);
875
876          QName JavaDoc anonymousQName = null;
877          String JavaDoc javaType = null;
878
879          // Lookup the java type from jaxrpc-mapping
880
JavaXmlTypeMapping javaTypeMapping = null;
881          if (javaWsdlMapping != null)
882          {
883             javaTypeMapping = javaWsdlMapping.getTypeMappingForQName(typeQName);
884             if (javaTypeMapping != null)
885             {
886                anonymousQName = javaTypeMapping.getAnonymousTypeQName();
887                javaType = javaTypeMapping.getJavaType();
888             }
889          }
890
891          if (javaType == null)
892          {
893             // Guess the java type from the qname
894
String JavaDoc packageName = getPackageName(typeQName);
895             String JavaDoc localPart = typeQName.getLocalPart();
896             javaType = packageName + "." + localPart;
897             log.debug("Guessing the javaType from typeQName: " + typeQName + " -> " + javaType);
898          }
899
900          TypeMappingDescription typeMapping = new TypeMappingDescription(typeQName, anonymousQName, javaType, use, javaTypeMapping);
901          typeMappings.put(typeQName, typeMapping);
902          it.remove();
903       }
904
905       // Add the type mappings from jaxrpc-mapping that are not top level types
906
if (javaWsdlMapping != null)
907       {
908          JavaXmlTypeMapping[] javaXmlTypeMappings = javaWsdlMapping.getJavaXmlTypeMappings();
909          for (int i = 0; i < javaXmlTypeMappings.length; i++)
910          {
911             JavaXmlTypeMapping javaTypeMapping = javaXmlTypeMappings[i];
912             QName JavaDoc anonymousQName = javaTypeMapping.getAnonymousTypeQName();
913             String JavaDoc javaType = javaTypeMapping.getJavaType();
914             QName JavaDoc typeQName = javaTypeMapping.getRootTypeQName();
915
916             // If the RootTypeQName is not given, try the AnonymousTypeQName
917
if (typeQName == null && anonymousQName != null)
918                typeQName = anonymousQName;
919
920             typeQName = nsRegistry.registerQName(typeQName);
921             TypeMapping defaultTm = DefaultTypeMappingImpl.getSingleton();
922             if (typeQName != null && typeMappings.get(typeQName) == null && defaultTm.getClassForQName(typeQName) == null)
923             {
924                TypeMappingDescription typeMapping = new TypeMappingDescription(typeQName, anonymousQName, javaType, use, javaTypeMapping);
925                typeMappings.put(typeQName, typeMapping);
926             }
927          }
928       }
929    }
930
931    private String JavaDoc getPackageName(QName JavaDoc typeQName) throws ServiceException JavaDoc
932    {
933       String JavaDoc packageName = null;
934
935       if (javaWsdlMapping != null)
936       {
937          packageName = javaWsdlMapping.getPackageTypeForURI(typeQName.getNamespaceURI());
938          if (packageName == null)
939             throw new IllegalArgumentException JavaDoc("Cannot find package type for: " + typeQName);
940       }
941       else
942       {
943          try
944          {
945             URI JavaDoc uri = new URI JavaDoc(typeQName.getNamespaceURI());
946             String JavaDoc reverse = uri.getHost();
947             StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(reverse, ".");
948
949             while (st.hasMoreTokens())
950             {
951                if (packageName == null)
952                   packageName = st.nextToken();
953                else
954                   packageName = st.nextToken() + "." + packageName;
955             }
956
957             log.debug("Using type uri to obtain package: " + uri + " -> " + packageName);
958          }
959          catch (URISyntaxException JavaDoc e)
960          {
961             throw new ServiceException JavaDoc(e);
962          }
963       }
964
965       return packageName;
966    }
967
968
969    /**
970     * Get the wsdl service that corresponds to the portName
971     * If portName is null, it assumes there is only one service.
972     */

973    private Service getWsdlService(Definition wsdlDefinition, String JavaDoc portName)
974    {
975       Service wsdlService = null;
976
977       if (portName == null)
978       {
979          if (wsdlDefinition.getServices().values().size() != 1)
980             throw new IllegalArgumentException JavaDoc("Unsupported number of service elements");
981
982          wsdlService = (Service)wsdlDefinition.getServices().values().iterator().next();
983       }
984       else
985       {
986          Iterator JavaDoc it = wsdlDefinition.getServices().values().iterator();
987          while (wsdlService == null && it.hasNext())
988          {
989             Service service = (Service)it.next();
990             if (service.getPort(portName) != null)
991                wsdlService = service;
992          }
993       }
994
995       if (wsdlService == null)
996          throw new IllegalArgumentException JavaDoc("Cannot find wsdl service for port: " + portName);
997
998       return wsdlService;
999    }
1000
1001
1002   /**
1003    * Get the wsdl binding with for the given service and portName
1004    * If portName is null, it iterates over the available bindings and checks that their are not multiple
1005    * definitions.
1006    */

1007   private Binding getWsdlBinding(Service wsdlService, String JavaDoc portName)
1008   {
1009      Binding wsdlBinding = null;
1010
1011      if (portName != null)
1012      {
1013         Port port = wsdlService.getPort(portName);
1014         if (port == null)
1015            throw new IllegalArgumentException JavaDoc("Cannot find wsdl port for: " + portName);
1016
1017         wsdlBinding = port.getBinding();
1018      }
1019      else
1020      {
1021         Iterator JavaDoc it = wsdlService.getPorts().values().iterator();
1022         while (it.hasNext())
1023         {
1024            Port port = (Port)it.next();
1025            Binding binding = port.getBinding();
1026
1027            if (wsdlBinding != null && wsdlBinding.getQName().equals(binding.getQName()) == false)
1028               throw new IllegalArgumentException JavaDoc("Multiple bindings not supported for service: " + wsdlService.getQName());
1029
1030            if (wsdlBinding == null)
1031               wsdlBinding = binding;
1032         }
1033      }
1034
1035      if (wsdlBinding == null)
1036         throw new IllegalArgumentException JavaDoc("Cannot find wsdl binding for: " + wsdlService.getQName());
1037
1038      return wsdlBinding;
1039   }
1040}
1041
Popular Tags