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
55
56 int index = opName.indexOf("Request");
57 if (index > 0)
58 {
59 operation = endpoint.getServiceInfo().getOperation( opName.substring(0, index) );
60 }
61 }
62
63
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 }