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 }