View Javadoc

    1   package org.codehaus.xfire.wsdl11.builder;
    2
    3   import java.util.ArrayList;
    4   import java.util.HashMap;
    5   import java.util.Iterator;
    6   import java.util.List;
    7   import java.util.Map;
    8
    9   import javax.wsdl.Binding;
    10  import javax.wsdl.BindingInput;
    11  import javax.wsdl.BindingOperation;
    12  import javax.wsdl.Definition;
    13  import javax.wsdl.Input;
    14  import javax.wsdl.Message;
    15  import javax.wsdl.Output;
    16  import javax.wsdl.Part;
    17  import javax.wsdl.Port;
    18  import javax.wsdl.PortType;
    19  import javax.wsdl.WSDLException;
    20  import javax.wsdl.extensions.soap.SOAPHeader;
    21  import javax.xml.namespace.QName;
    22
    23  import org.codehaus.xfire.service.MessageHeaderInfo;
    24  import org.codehaus.xfire.service.MessageInfo;
    25  import org.codehaus.xfire.service.MessagePartInfo;
    26  import org.codehaus.xfire.service.OperationInfo;
    27  import org.codehaus.xfire.service.Service;
    28  import org.codehaus.xfire.soap.SoapConstants;
    29  import org.codehaus.xfire.transport.Transport;
    30  import org.codehaus.xfire.transport.TransportManager;
    31  import org.codehaus.xfire.wsdl.SchemaType;
    32  import org.codehaus.xfire.wsdl.WSDLWriter;
    33  import org.codehaus.xfire.wsdl11.WSDL11ParameterBinding;
    34  import org.codehaus.xfire.wsdl11.WSDL11Transport;
    35  import org.codehaus.yom.Attribute;
    36  import org.codehaus.yom.Element;
    37
    38  import com.ibm.wsdl.extensions.soap.SOAPHeaderImpl;
    39
    40  /***
    41   * WSDL
    42   *
    43   * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
    44   */
    45  public class WSDLBuilder
    46      extends org.codehaus.xfire.wsdl11.builder.AbstractWSDL
    47      implements WSDLWriter
    48  {
    49      private PortType portType;
    50
    51      private Binding binding;
    52
    53      private TransportManager transportManager;
    54
    55      private Map wsdlOps = new HashMap();
    56
    57      private WSDL11ParameterBinding paramBinding;
    58
    59      private List declaredParameters = new ArrayList();
    60
    61      public WSDLBuilder(Service service,
    62                         TransportManager transportManager,
    63                         WSDL11ParameterBinding paramBinding) throws WSDLException
    64      {
    65          super(service);
    66
    67          this.transportManager = transportManager;
    68          this.paramBinding = paramBinding;
    69
    70          PortType portType = createAbstractInterface();
    71
    72          createConcreteInterface(portType);
    73
    74          writeDocument();
    75      }
    76
    77      public PortType createAbstractInterface()
    78          throws WSDLException
    79      {
    80          Service service = getService();
    81          Definition def = getDefinition();
    82
    83          QName portName = new QName(getInfo().getTargetNamespace(), getInfo().getPortType());
    84
    85          portType = def.createPortType();
    86          portType.setQName(portName);
    87          portType.setUndefined(false);
    88          def.addPortType(portType);
    89
    90          // Create Abstract operations
    91          for (Iterator itr = service.getServiceInfo().getOperations().iterator(); itr.hasNext();)
    92          {
    93              OperationInfo op = (OperationInfo) itr.next();
    94
    95              // Create input message
    96              Message req = createInputMessage(op);
    97              def.addMessage(req);
    98
    99              // Create output message if we have an out MEP
    100             Message res = null;
    101             if (op.getMEP().equals(SoapConstants.MEP_ROBUST_IN_OUT))
    102             {
    103                 res = createOutputMessage(op);
    104                 def.addMessage(res);
    105             }
    106
    107             javax.wsdl.Operation wsdlOp = createOperation(op, req, res);
    108             wsdlOp.setUndefined(false);
    109             portType.addOperation(wsdlOp);
    110
    111             wsdlOps.put(op.getName(), wsdlOp);
    112         }
    113
    114         return portType;
    115     }
    116
    117     public void createConcreteInterface(PortType portType)
    118     {
    119         Service service = getService();
    120         Definition def = getDefinition();
    121
    122         QName name = new QName(getInfo().getTargetNamespace(), getInfo().getServiceName());
    123
    124         // Create a concrete instance for each transport.
    125         javax.wsdl.Service wsdlService = def.createService();
    126         wsdlService.setQName(name);
    127
    128         for (Iterator itr = transportManager.getTransports(service.getName()).iterator(); itr.hasNext();)
    129         {
    130             Object transportObj = (Transport) itr.next();
    131
    132             if (!(transportObj instanceof WSDL11Transport))
    133             {
    134                 continue;
    135             }
    136
    137             WSDL11Transport transport = (WSDL11Transport) transportObj;
    138
    139             Binding transportBinding = transport.createBinding(this, portType, paramBinding);
    140
    141             for (Iterator oitr = service.getServiceInfo().getOperations().iterator(); oitr.hasNext();)
    142             {
    143                 // todo: move out of the first loop, we'll be creating req/res
    144                 // multiple times otherwise
    145                 OperationInfo op = (OperationInfo) oitr.next();
    146
    147                 javax.wsdl.Operation wsdlOp = (javax.wsdl.Operation) wsdlOps.get(op.getName());
    148
    149                 BindingOperation bop = transport.createBindingOperation(this, portType, wsdlOp, paramBinding);
    150                 transportBinding.addBindingOperation(bop);
    151
    152                 createHeaders(op, bop);
    153             }
    154
    155             Port transportPort = transport.createPort(this, transportBinding);
    156
    157             def.addBinding(transportBinding);
    158             wsdlService.addPort(transportPort);
    159         }
    160
    161         def.addService(wsdlService);
    162
    163     }
    164
    165     private void createHeaders(OperationInfo op, BindingOperation bop)
    166     {
    167         List inputHeaders = op.getInputMessage().getMessageHeaders();
    168         if (inputHeaders.size() == 0)
    169         {
    170             return;
    171         }
    172
    173         BindingInput bindingInput = bop.getBindingInput();
    174
    175         Message reqHeaders = createHeaderMessages(op.getInputMessage());
    176         getDefinition().addMessage(reqHeaders);
    177
    178         for (Iterator headerItr = reqHeaders.getParts().values().iterator(); headerItr.hasNext();)
    179         {
    180             Part headerInfo = (Part) headerItr.next();
    181
    182             SOAPHeader soapHeader = new SOAPHeaderImpl();
    183             soapHeader.setMessage(reqHeaders.getQName());
    184             soapHeader.setPart(headerInfo.getName());
    185             soapHeader.setUse(paramBinding.getUse());
    186
    187             bindingInput.addExtensibilityElement(soapHeader);
    188         }
    189     }
    190
    191     private Message createOutputMessage(OperationInfo op)
    192     {
    193         // response message
    194         Message res = getDefinition().createMessage();
    195         res.setQName(new QName(getInfo().getTargetNamespace(), op.getName() + "Response"));
    196
    197         res.setUndefined(false);
    198
    199         paramBinding.createOutputParts(this, res, op);
    200
    201         return res;
    202     }
    203
    204     private Message createInputMessage(OperationInfo op)
    205     {
    206         Message req = getDefinition().createMessage();
    207         req.setQName(new QName(getInfo().getTargetNamespace(), op.getName() + "Request"));
    208         req.setUndefined(false);
    209
    210         paramBinding.createInputParts(this, req, op);
    211
    212         return req;
    213     }
    214
    215     private Message createHeaderMessages(MessageInfo msgInfo)
    216     {
    217         Message msg = getDefinition().createMessage();
    218
    219         msg.setQName(new QName(getInfo().getTargetNamespace(), msgInfo.getName().getLocalPart() + "Headers"));
    220         msg.setUndefined(false);
    221
    222         for (Iterator itr = msgInfo.getMessageHeaders().iterator(); itr.hasNext();)
    223         {
    224             MessageHeaderInfo header = (MessageHeaderInfo) itr.next();
    225
    226             Part part = createPart(header);
    227
    228             msg.addPart(part);
    229         }
    230
    231         return msg;
    232     }
    233
    234     public Part createPart(MessageHeaderInfo header)
    235     {
    236         return createPart(header.getName(), header.getTypeClass(), header.getSchemaType());
    237     }
    238
    239     public Part createPart(MessagePartInfo part)
    240     {
    241         return createPart(part.getName(), part.getTypeClass(), part.getSchemaType());
    242     }
    243
    244     public Part createPart(QName pName, Class clazz, SchemaType type)
    245     {
    246         addDependency(type);
    247
    248         QName schemaTypeName = type.getSchemaType();
    249
    250         Part part = getDefinition().createPart();
    251         part.setName(pName.getLocalPart());
    252
    253         if (!type.isAbstract())
    254         {
    255             String prefix = getNamespacePrefix(schemaTypeName.getNamespaceURI());
    256             addNamespace(prefix, schemaTypeName.getNamespaceURI());
    257
    258             part.setElementName(schemaTypeName);
    259
    260             return part;
    261         }
    262
    263         if (!declaredParameters.contains(pName))
    264         {
    265             Element schemaEl = createSchemaType(getInfo().getTargetNamespace());
    266
    267             Element element = new Element(AbstractWSDL.elementQ, SoapConstants.XSD);
    268             schemaEl.appendChild(element);
    269
    270             String prefix = getNamespacePrefix(schemaTypeName.getNamespaceURI());
    271             addNamespace(prefix, schemaTypeName.getNamespaceURI());
    272
    273             if (type.isAbstract())
    274             {
    275                 element.addAttribute(new Attribute("name", pName.getLocalPart()));
    276                 element.addAttribute(new Attribute("type",
    277                                                    prefix + ":" + schemaTypeName.getLocalPart()));
    278             }
    279
    280             declaredParameters.add(pName);
    281         }
    282
    283         part.setElementName(pName);
    284
    285         return part;
    286     }
    287
    288     public javax.wsdl.Operation createOperation(OperationInfo op, Message req, Message res)
    289     {
    290         Definition def = getDefinition();
    291         javax.wsdl.Operation wsdlOp = def.createOperation();
    292
    293         Input input = def.createInput();
    294         input.setMessage(req);
    295         input.setName(req.getQName().getLocalPart());
    296         wsdlOp.setInput(input);
    297
    298         if (res != null)
    299         {
    300             Output output = def.createOutput();
    301             output.setMessage(res);
    302             output.setName(res.getQName().getLocalPart());
    303             wsdlOp.setOutput(output);
    304         }
    305
    306         wsdlOp.setName(op.getName());
    307
    308         return wsdlOp;
    309     }
    310 }