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