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 }