View Javadoc

    1   package org.codehaus.xfire.service.binding;
    2
    3   import java.util.ArrayList;
    4   import java.util.Collection;
    5   import java.util.Iterator;
    6   import java.util.List;
    7
    8   import javax.wsdl.Message;
    9   import javax.wsdl.Part;
    10  import javax.xml.namespace.QName;
    11
    12  import org.codehaus.xfire.MessageContext;
    13  import org.codehaus.xfire.exchange.InMessage;
    14  import org.codehaus.xfire.fault.XFireFault;
    15  import org.codehaus.xfire.service.MessageInfo;
    16  import org.codehaus.xfire.service.MessagePartInfo;
    17  import org.codehaus.xfire.service.OperationInfo;
    18  import org.codehaus.xfire.service.Service;
    19  import org.codehaus.xfire.soap.SoapConstants;
    20  import org.codehaus.xfire.util.DepthXMLStreamReader;
    21  import org.codehaus.xfire.util.STAXUtils;
    22  import org.codehaus.xfire.wsdl.SchemaType;
    23  import org.codehaus.xfire.wsdl11.WSDL11ParameterBinding;
    24  import org.codehaus.xfire.wsdl11.builder.AbstractWSDL;
    25  import org.codehaus.xfire.wsdl11.builder.WSDLBuilder;
    26  import org.codehaus.yom.Attribute;
    27  import org.codehaus.yom.Element;
    28
    29  public class RPCEncodedBinding
    30      extends WrappedBinding
    31      implements WSDL11ParameterBinding
    32  {
    33      public RPCEncodedBinding()
    34      {
    35          setStyle(SoapConstants.STYLE_RPC);
    36          setUse(SoapConstants.USE_ENCODED);
    37      }
    38
    39      public void readMessage(InMessage inMessage, MessageContext context)
    40          throws XFireFault
    41      {
    42          Service endpoint = context.getService();
    43
    44          List parameters = new ArrayList();
    45          DepthXMLStreamReader dr = new DepthXMLStreamReader(context.getInMessage().getXMLStreamReader());
    46
    47          if ( !STAXUtils.toNextElement(dr) )
    48              throw new XFireFault("There must be a method name element.", XFireFault.SENDER);
    49
    50          String opName = dr.getLocalName();
    51          OperationInfo operation = endpoint.getServiceInfo().getOperation( opName );
    52          if (operation == null)
    53          {
    54              // Determine the operation name which is in the form of:
    55              // xxxxRequest where xxxx is the operation.
    56              int index = opName.indexOf("Request");
    57              if (index > 0)
    58              {
    59                  operation = endpoint.getServiceInfo().getOperation( opName.substring(0, index) );
    60              }
    61          }
    62
    63          // Move from operation element to whitespace or start element
    64          nextEvent(dr);
    65
    66          setOperation(operation, context);
    67
    68          if (operation == null)
    69          {
    70              throw new XFireFault("Invalid operation.", XFireFault.SENDER);
    71          }
    72
    73          while(STAXUtils.toNextElement(dr))
    74          {
    75              MessagePartInfo p = operation.getInputMessage().getMessagePart(dr.getName());
    76
    77              if (p == null)
    78              {
    79                  throw new XFireFault("Parameter " + dr.getName() + " does not exist!",
    80                                       XFireFault.SENDER);
    81              }
    82
    83              parameters.add( getBindingProvider().readParameter(p, dr, context) );
    84          }
    85
    86          context.getInMessage().setBody(parameters);
    87      }
    88
    89      public void createInputParts(WSDLBuilder builder,
    90                                   Message req,
    91                                   OperationInfo op)
    92      {
    93          writeParametersSchema(builder, req, op.getInputMessage());
    94      }
    95
    96      public void createOutputParts(WSDLBuilder builder,
    97                                    Message req,
    98                                    OperationInfo op)
    99      {
    100         writeParametersSchema(builder, req, op.getOutputMessage());
    101     }
    102
    103     protected void writeParametersSchema(WSDLBuilder builder,
    104                                          Message message,
    105                                          MessageInfo xmsg)
    106     {
    107         Collection params = xmsg.getMessageParts();
    108
    109         for (Iterator itr = params.iterator(); itr.hasNext();)
    110         {
    111             MessagePartInfo param = (MessagePartInfo) itr.next();
    112             Class clazz = param.getTypeClass();
    113             QName pName = param.getName();
    114
    115             SchemaType type = param.getSchemaType();
    116             builder.addDependency(type);
    117             QName schemaType = type.getSchemaType();
    118
    119             Part part = builder.getDefinition().createPart();
    120             part.setName(pName.getLocalPart());
    121
    122             if (type.isComplex())
    123             {
    124                 part.setElementName(pName);
    125
    126                 Element schemaEl = builder.createSchemaType(builder.getInfo().getTargetNamespace());
    127                 Element element = new Element(AbstractWSDL.elementQ, SoapConstants.XSD);
    128                 schemaEl.appendChild(element);
    129
    130                 element.addAttribute(new Attribute("name", pName.getLocalPart()));
    131
    132                 String prefix = builder.getNamespacePrefix(schemaType.getNamespaceURI());
    133                 builder.addNamespace(prefix, schemaType.getNamespaceURI());
    134
    135                 element.addAttribute(new Attribute("type",
    136                                                    prefix + ":" + schemaType.getLocalPart()));
    137             }
    138             else
    139             {
    140                 part.setElementName(type.getSchemaType());
    141             }
    142
    143             message.addPart(part);
    144         }
    145     }
    146
    147     public Object clone()
    148     {
    149         RPCEncodedBinding binding = new RPCEncodedBinding();
    150         binding.setBindingProvider(getBindingProvider());
    151
    152         return binding;
    153     }
    154 }