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         TParam output = abstractOp.getOutput();
143         message = getMessage( output.getMessage().getLocalPart(), defs );
144         
145         xParts = message.getPartArray();
146         for ( int i = 0; i < xParts.length; i++ )
147         {
148             Parameter p = new Parameter();
149             p.setName(xParts[i].getName());
150             p.setType( loader.findDocumentType(xParts[i].getElement()) );
151             
152             m.addResponseParameter(p);
153         }
154         
155         // todo get soap action
156         return m;
157     }
158 
159     private TMessage getMessage(String name, TDefinitions defs)
160     {
161         TMessage[] xMessages = defs.getMessageArray();
162         for ( int i = 0; i < xMessages.length; i ++ )
163         {
164             if ( xMessages[i].getName().equals(name) )
165                 return xMessages[i];
166         }
167         return null;
168     }
169 
170     private TOperation getAbstractOperation(String name, TPortType portType)
171     {
172         TOperation[] xOperations = portType.getOperationArray();
173         
174         for ( int j = 0; j < xOperations.length; j++ )
175         {
176             if ( xOperations[j].getName().equals(name) )
177                 return xOperations[j];
178         }
179         return null;
180     }
181 
182     private TPortType getPortType(TDefinitions defs, QName portType)
183     {
184         TPortType[] portTypes = defs.getPortTypeArray();
185         for ( int i = 0; i < portTypes.length; i++ )
186         {
187             if ( portTypes[i].getName().equals(portType.getLocalPart()) )
188                 return portTypes[i];
189         }
190         
191         return null;
192     }
193 
194     private TBinding getBinding(TDefinitions defs, QName binding)
195     {
196         TBinding[] bindings = defs.getBindingArray();
197         for ( int i = 0; i < bindings.length; i++ )
198         {
199             if ( bindings[i].getName().equals(binding.getLocalPart()) )
200                 return bindings[i];
201         }
202         
203         return null;
204     }
205 
206     public class Service
207     {
208         private String name;
209         private String url;
210         private List methods;
211         private String encoding = "UTF-8";
212         private XmlObject xmlObject;
213         private QName binding;
214         private QName portType;
215         private boolean isRest;
216         private String soapVersion;
217         
218         public Set getImports()
219         {
220             Set imports = new HashSet();
221             
222             if ( methods != null )
223             {
224                 for ( Iterator itr = methods.iterator(); itr.hasNext(); )
225                 {
226                     ServiceMethod m = (ServiceMethod) itr.next();
227                     
228                     if ( m.getRequestParameters() != null )
229                     {
230                         for ( Iterator pitr = m.getRequestParameters().iterator(); pitr.hasNext(); )
231                         {
232                             Parameter p = (Parameter) pitr.next();
233                             imports.add( p.getType() );
234                         }
235                     }
236                     
237                     if ( m.getResponseParameters() != null )
238                     {
239                         for ( Iterator pitr = m.getResponseParameters().iterator(); pitr.hasNext(); )
240                         {
241                             Parameter p = (Parameter) pitr.next();
242                             imports.add( p.getType() );
243                         }
244                     }
245                 }
246             }
247             return imports;
248         }
249 
250         public String getSoapVersion()
251         {
252             return soapVersion;
253         }
254         public void setSoapVersion(String soapVersion)
255         {
256             this.soapVersion = soapVersion;
257         }
258         public boolean isRest()
259         {
260             return isRest;
261         }
262         public void setRest(boolean isRest)
263         {
264             this.isRest = isRest;
265         }
266         public QName getPortType()
267         {
268             return portType;
269         }
270         public void setPortType(QName portType)
271         {
272             this.portType = portType;
273         }
274         public QName getBinding()
275         {
276             return binding;
277         }
278         public void setBinding(QName binding)
279         {
280             this.binding = binding;
281         }
282         public XmlObject getXmlObject()
283         {
284             return xmlObject;
285         }
286         public void setXmlObject(XmlObject xmlObject)
287         {
288             this.xmlObject = xmlObject;
289         }
290         public void addMethod( ServiceMethod m )
291         {
292             if ( methods == null )
293                 methods = new ArrayList();
294             
295             methods.add(m);
296         }
297         
298         public String getEncoding()
299         {
300             return encoding;
301         }
302         public void setEncoding(String encoding)
303         {
304             this.encoding = encoding;
305         }
306         public List getMethods()
307         {
308             return methods;
309         }
310         public void setMethods(List methods)
311         {
312             this.methods = methods;
313         }
314         public String getName()
315         {
316             return name;
317         }
318         public void setName(String name)
319         {
320             this.name = name;
321         }
322         public String getUrl()
323         {
324             return url;
325         }
326         public void setUrl(String url)
327         {
328             this.url = url;
329         }
330     }
331     
332     public class ServiceMethod
333     {
334         private String soapAction;
335         private String name;
336         private List requestParameters;
337         private List responseParameters;
338         private XmlObject xmlObject;
339 
340         public void addRequestParameter( Parameter parameter )
341         {
342             if ( requestParameters == null )
343                 requestParameters = new ArrayList();
344             
345             requestParameters.add(parameter);
346         }
347         public void addResponseParameter( Parameter parameter )
348         {
349             if ( responseParameters == null )
350                 responseParameters = new ArrayList();
351             
352             responseParameters.add(parameter);
353         }
354         public List getRequestParameters()
355         {
356             return requestParameters;
357         }
358         public void setRequestParameters(List requestParameters)
359         {
360             this.requestParameters = requestParameters;
361         }
362         public List getResponseParameters()
363         {
364             return responseParameters;
365         }
366         public void setResponseParameters(List responseParameters)
367         {
368             this.responseParameters = responseParameters;
369         }
370         public String getSoapAction()
371         {
372             return soapAction;
373         }
374         public XmlObject getXmlObject()
375         {
376             return xmlObject;
377         }
378         public void setXmlObject(XmlObject xmlObject)
379         {
380             this.xmlObject = xmlObject;
381         }
382         public String getName()
383         {
384             return name;
385         }
386         public void setName(String name)
387         {
388             this.name = name;
389         }
390         public void setSoapAction(String soapAction)
391         {
392             this.soapAction = soapAction;
393         }
394     }
395     
396     public class Parameter
397     {
398         private SchemaType type;
399         private String name;
400         
401         public String getName()
402         {
403             return name;
404         }
405         public void setName(String name)
406         {
407             this.name = name;
408         }
409         public SchemaType getType()
410         {
411             return type;
412         }
413         public void setType(SchemaType type)
414         {
415             this.type = type;
416         }
417     }
418 }