View Javadoc

1   package org.codehaus.xfire.xmlbeans.generator;
2   
3   import java.net.URL;
4   import java.util.ArrayList;
5   import java.util.HashSet;
6   import java.util.Iterator;
7   import java.util.List;
8   import java.util.Set;
9   
10  import javax.xml.namespace.QName;
11  
12  import org.apache.xmlbeans.SchemaType;
13  import org.apache.xmlbeans.SchemaTypeLoader;
14  import org.apache.xmlbeans.XmlAnySimpleType;
15  import org.apache.xmlbeans.XmlBeans;
16  import org.apache.xmlbeans.XmlObject;
17  import org.apache.xmlbeans.XmlOptions;
18  import org.w3c.dom.Node;
19  import org.xml.sax.EntityResolver;
20  import org.xmlsoap.schemas.wsdl.DefinitionsDocument;
21  import org.xmlsoap.schemas.wsdl.TBinding;
22  import org.xmlsoap.schemas.wsdl.TBindingOperation;
23  import org.xmlsoap.schemas.wsdl.TDefinitions;
24  import org.xmlsoap.schemas.wsdl.TMessage;
25  import org.xmlsoap.schemas.wsdl.TOperation;
26  import org.xmlsoap.schemas.wsdl.TParam;
27  import org.xmlsoap.schemas.wsdl.TPart;
28  import org.xmlsoap.schemas.wsdl.TPortType;
29  import org.xmlsoap.schemas.wsdl.TService;
30  
31  /***
32   * Inspects WSDL documents and provide handy classes to examine the 
33   * content.
34   * 
35   * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
36   * @since Oct 27, 2004
37   */
38  public class WSDLInspector
39  {
40      public final static String schemaNS = 
41          "declare namespace xs=\"http://www.w3.org/2001/XMLSchema\"";
42      public final static String wsdlNS = 
43          "declare namespace wsdl=\"http://schemas.xmlsoap.org/wsdl/\"";
44      public final static String wsdlSoapNS = 
45          "declare namespace soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"";
46      public final static String httpNS = 
47          "declare namespace http=\"http://schemas.xmlsoap.org/wsdl/http/";
48      
49      SchemaTypeLoader loader = 
50          XmlBeans.typeLoaderForClassLoader(XmlObject.class.getClassLoader());
51      
52      public List generateServices(URL document) throws Exception
53      {
54          EntityResolver entResolver = null;
55  
56          XmlOptions options = new XmlOptions();
57          options.setLoadLineNumbers();
58  
59          options.setEntityResolver(entResolver);
60  
61          SchemaTypeLoader wloader = 
62              XmlBeans.typeLoaderForClassLoader(TDefinitions.class.getClassLoader());
63          XmlObject wsdldoc = wloader.parse(document, null, options);
64          
65          TDefinitions defs = ((DefinitionsDocument)wsdldoc).getDefinitions();
66          XmlObject[] types = defs.getTypesArray();
67          
68          ArrayList services = new ArrayList();
69          
70          TService[] xServices = defs.getServiceArray();
71          for ( int i = 0; i < xServices.length; i++ )
72          {
73              TService xService = xServices[i];
74              
75              Service service = new Service();
76              
77              XmlObject[] xAddresses = xService.selectPath(wsdlSoapNS + " $this//soap:address");
78              if (xAddresses == null || xAddresses.length == 0)
79              {
80                  xAddresses = xService.selectPath(httpNS + " $this//http:address");
81                  if (xAddresses == null || xAddresses.length == 0)
82                      break;
83                  
84                  service.setRest(true);
85                  break;
86              }
87  
88              service.setName(xService.getName());
89              service.setUrl(xAddresses[0].selectAttribute("","location").newCursor().getTextValue());
90              service.setXmlObject(xService);
91              service.setBinding(xService.getPortArray(0).getBinding());
92  
93              TBinding xBinding = getBinding( defs, service.getBinding() );
94              if ( xBinding  == null )
95                  throw new RuntimeException("Couldn't find binding!");
96              
97              service.setPortType(xBinding.getType());
98              
99              TPortType xPortType = getPortType( defs, service.getPortType() );
100             if ( xPortType  == null )
101                 throw new RuntimeException("Couldn't find port type!");
102             
103             TBindingOperation[] xOperations = xBinding.getOperationArray();
104             
105             for ( int j = 0; j < xOperations.length; j++ )
106             {
107                 ServiceMethod m = createMethod( xOperations[j], xPortType, defs );
108                 
109                 service.addMethod(m);
110             }
111             
112             services.add(service);
113         }
114         
115         return services;
116     }
117 
118     private ServiceMethod createMethod(TBindingOperation xOperation, TPortType portType, TDefinitions defs)
119     {
120         ServiceMethod m = new ServiceMethod();
121         m.setName(xOperation.getName());
122         
123         TOperation abstractOp = getAbstractOperation( m.getName(), portType );
124         TParam input = abstractOp.getInput();
125         TMessage message = getMessage( input.getMessage().getLocalPart(), defs );
126 
127         TPart[] xParts = message.getPartArray();
128         for ( int i = 0; i < xParts.length; i++ )
129         {
130             Parameter p = new Parameter();
131             p.setName(xParts[i].getName());
132             SchemaType type = loader.findDocumentType(xParts[i].getElement());
133             if ( type == null )
134             {
135                 System.out.println("Couldn't find type " + xParts[i].getElement().toString());
136                 type = XmlAnySimpleType.type;
137             }
138             p.setType( type );
139             
140             m.addRequestParameter(p);
141         }
142         
143         XmlObject[] xHeaders = xOperation.getInput().selectPath(wsdlSoapNS + " $this//soap:header");
144         if ( xHeaders != null )
145         {
146             QName partQ = new QName("part");
147             QName messageQ = new QName("message");
148             
149             for ( int i = 0; i < xHeaders.length; i++ )
150             {
151                 String msgName = xHeaders[i].newCursor().getAttributeText(messageQ);
152                 msgName = msgName.substring(msgName.indexOf(":")+1);
153                 
154                 String partName = xHeaders[i].newCursor().getAttributeText(partQ);
155                 TMessage hMessage = getMessage( msgName, defs );
156                 TPart part = getPart(hMessage, partName);
157                 
158                 Parameter p = new Parameter();
159                 p.setName(part.getName() + "Header");
160                 SchemaType type = loader.findDocumentType(part.getElement());
161                 if ( type == null )
162                 {
163                     System.out.println("Couldn't find type " + xParts[i].getElement().toString());
164                     type = XmlAnySimpleType.type;
165                 }
166                 p.setType( type );
167                 
168                 m.addRequestHeader(p);
169             }
170         }
171         
172         XmlObject[] soapOp = xOperation.selectPath(wsdlSoapNS + " $this//soap:operation");
173         if (soapOp != null && soapOp.length > 0)
174         {
175             Node actionNode = soapOp[0].getDomNode().getAttributes().getNamedItem("soapAction");
176             
177             if (actionNode != null)
178             {
179                 m.setSoapAction(actionNode.getNodeValue());
180             }
181         }
182 
183         TParam output = abstractOp.getOutput();
184         message = getMessage( output.getMessage().getLocalPart(), defs );
185         
186         xParts = message.getPartArray();
187         for ( int i = 0; i < xParts.length; i++ )
188         {
189             Parameter p = new Parameter();
190             p.setName(xParts[i].getName());
191             p.setType( loader.findDocumentType(xParts[i].getElement()) );
192             
193             m.addResponseParameter(p);
194         }
195         
196         // todo get soap action
197         return m;
198     }
199 
200     private TPart getPart(TMessage message, String partName)
201     {
202         TPart[] parts = message.getPartArray();
203         for ( int i = 0; i < parts.length; i ++ )
204         {
205             if ( parts[i].getName().equals(partName) )
206                 return parts[i];
207         }
208         return null;
209     }
210 
211     private TMessage getMessage(String name, TDefinitions defs)
212     {
213         TMessage[] xMessages = defs.getMessageArray();
214         for ( int i = 0; i < xMessages.length; i ++ )
215         {
216             if ( xMessages[i].getName().equals(name) )
217                 return xMessages[i];
218         }
219         return null;
220     }
221 
222     private TOperation getAbstractOperation(String name, TPortType portType)
223     {
224         TOperation[] xOperations = portType.getOperationArray();
225         
226         for ( int j = 0; j < xOperations.length; j++ )
227         {
228             if ( xOperations[j].getName().equals(name) )
229                 return xOperations[j];
230         }
231         return null;
232     }
233 
234     private TPortType getPortType(TDefinitions defs, QName portType)
235     {
236         TPortType[] portTypes = defs.getPortTypeArray();
237         for ( int i = 0; i < portTypes.length; i++ )
238         {
239             if ( portTypes[i].getName().equals(portType.getLocalPart()) )
240                 return portTypes[i];
241         }
242         
243         return null;
244     }
245 
246     private TBinding getBinding(TDefinitions defs, QName binding)
247     {
248         TBinding[] bindings = defs.getBindingArray();
249         for ( int i = 0; i < bindings.length; i++ )
250         {
251             if ( bindings[i].getName().equals(binding.getLocalPart()) )
252                 return bindings[i];
253         }
254         
255         return null;
256     }
257 
258     public class Service
259     {
260         private String name;
261         private String url;
262         private List methods;
263         private String encoding = "UTF-8";
264         private XmlObject xmlObject;
265         private QName binding;
266         private QName portType;
267         private boolean isRest;
268         private String soapVersion;
269         
270         public Set getImports()
271         {
272             Set imports = new HashSet();
273             
274             if ( methods != null )
275             {
276                 for ( Iterator itr = methods.iterator(); itr.hasNext(); )
277                 {
278                     ServiceMethod m = (ServiceMethod) itr.next();
279                     
280                     if ( m.getRequestParameters() != null )
281                     {
282                         for ( Iterator pitr = m.getRequestParameters().iterator(); pitr.hasNext(); )
283                         {
284                             Parameter p = (Parameter) pitr.next();
285                             imports.add( p.getType() );
286                         }
287                     }
288                     
289                     if ( m.getResponseParameters() != null )
290                     {
291                         for ( Iterator pitr = m.getResponseParameters().iterator(); pitr.hasNext(); )
292                         {
293                             Parameter p = (Parameter) pitr.next();
294                             imports.add( p.getType() );
295                         }
296                     }
297                     
298                     if ( m.getRequestHeaders() != null )
299                     {
300                         for ( Iterator pitr = m.getRequestHeaders().iterator(); pitr.hasNext(); )
301                         {
302                             Parameter p = (Parameter) pitr.next();
303                             imports.add( p.getType() );
304                         }
305                     }
306                 }
307             }
308             return imports;
309         }
310 
311         public String getSoapVersion()
312         {
313             return soapVersion;
314         }
315         public void setSoapVersion(String soapVersion)
316         {
317             this.soapVersion = soapVersion;
318         }
319         public boolean isRest()
320         {
321             return isRest;
322         }
323         public void setRest(boolean isRest)
324         {
325             this.isRest = isRest;
326         }
327         public QName getPortType()
328         {
329             return portType;
330         }
331         public void setPortType(QName portType)
332         {
333             this.portType = portType;
334         }
335         public QName getBinding()
336         {
337             return binding;
338         }
339         public void setBinding(QName binding)
340         {
341             this.binding = binding;
342         }
343         public XmlObject getXmlObject()
344         {
345             return xmlObject;
346         }
347         public void setXmlObject(XmlObject xmlObject)
348         {
349             this.xmlObject = xmlObject;
350         }
351         public void addMethod( ServiceMethod m )
352         {
353             if ( methods == null )
354                 methods = new ArrayList();
355             
356             methods.add(m);
357         }
358         
359         public String getEncoding()
360         {
361             return encoding;
362         }
363         public void setEncoding(String encoding)
364         {
365             this.encoding = encoding;
366         }
367         public List getMethods()
368         {
369             return methods;
370         }
371         public void setMethods(List methods)
372         {
373             this.methods = methods;
374         }
375         public String getName()
376         {
377             return name;
378         }
379         public void setName(String name)
380         {
381             this.name = name;
382         }
383         public String getUrl()
384         {
385             return url;
386         }
387         public void setUrl(String url)
388         {
389             this.url = url;
390         }
391     }
392     
393     public class ServiceMethod
394     {
395         private String soapAction;
396         private String name;
397         private List requestParameters;
398         private List responseParameters;
399         private List requestHeaders;
400         private List responseHeaders;
401         private XmlObject xmlObject;
402 
403         public void addRequestParameter( Parameter parameter )
404         {
405             if ( requestParameters == null )
406                 requestParameters = new ArrayList();
407             
408             requestParameters.add(parameter);
409         }
410         public void addResponseParameter( Parameter parameter )
411         {
412             if ( responseParameters == null )
413                 responseParameters = new ArrayList();
414             
415             responseParameters.add(parameter);
416         }
417         
418         public void addRequestHeader( Parameter parameter )
419         {
420             if ( requestHeaders == null )
421                 requestHeaders = new ArrayList();
422             
423             requestHeaders.add(parameter);
424         }
425         
426         public void addResponseHeader( Parameter parameter )
427         {
428             if ( responseHeaders == null )
429                 responseHeaders = new ArrayList();
430             
431             responseHeaders.add(parameter);
432         }
433         
434         public List getRequestParameters()
435         {
436             return requestParameters;
437         }
438         public void setRequestParameters(List requestParameters)
439         {
440             this.requestParameters = requestParameters;
441         }
442         public List getResponseParameters()
443         {
444             return responseParameters;
445         }
446         public void setResponseParameters(List responseParameters)
447         {
448             this.responseParameters = responseParameters;
449         }
450         public List getRequestHeaders()
451         {
452             return requestHeaders;
453         }
454         public void setRequestHeaders(List requestHeaders)
455         {
456             this.requestHeaders = requestHeaders;
457         }
458         public List getResponseHeaders()
459         {
460             return responseHeaders;
461         }
462         public void setResponseHeaders(List responseHeaders)
463         {
464             this.responseHeaders = responseHeaders;
465         }
466         public String getSoapAction()
467         {
468             return soapAction;
469         }
470         public XmlObject getXmlObject()
471         {
472             return xmlObject;
473         }
474         public void setXmlObject(XmlObject xmlObject)
475         {
476             this.xmlObject = xmlObject;
477         }
478         public String getName()
479         {
480             return name;
481         }
482         public void setName(String name)
483         {
484             this.name = name;
485         }
486         public void setSoapAction(String soapAction)
487         {
488             this.soapAction = soapAction;
489         }
490     }
491     
492     public class Parameter
493     {
494         private SchemaType type;
495         private String name;
496         
497         public String getName()
498         {
499             return name;
500         }
501         public void setName(String name)
502         {
503             this.name = name;
504         }
505         public SchemaType getType()
506         {
507             return type;
508         }
509         public void setType(SchemaType type)
510         {
511             this.type = type;
512         }
513     }
514 }