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 import javax.xml.stream.XMLStreamWriter;
12
13 import org.codehaus.xfire.MessageContext;
14 import org.codehaus.xfire.exchange.InMessage;
15 import org.codehaus.xfire.exchange.OutMessage;
16 import org.codehaus.xfire.fault.XFireFault;
17 import org.codehaus.xfire.service.MessageInfo;
18 import org.codehaus.xfire.service.MessagePartInfo;
19 import org.codehaus.xfire.service.OperationInfo;
20 import org.codehaus.xfire.service.Service;
21 import org.codehaus.xfire.soap.SoapConstants;
22 import org.codehaus.xfire.util.DepthXMLStreamReader;
23 import org.codehaus.xfire.util.STAXUtils;
24 import org.codehaus.xfire.wsdl11.WSDL11ParameterBinding;
25 import org.codehaus.xfire.wsdl11.builder.WSDLBuilder;
26
27 public class DocumentBinding
28 extends AbstractBinding
29 implements WSDL11ParameterBinding, Cloneable
30 {
31 public DocumentBinding()
32 {
33 setStyle(SoapConstants.STYLE_DOCUMENT);
34 setUse(SoapConstants.USE_LITERAL);
35 }
36
37 public void readMessage(InMessage inMessage, MessageContext context)
38 throws XFireFault
39 {
40 Service endpoint = context.getService();
41
42 List parameters = new ArrayList();
43 DepthXMLStreamReader dr = new DepthXMLStreamReader(context.getInMessage().getXMLStreamReader());
44
45 while (STAXUtils.toNextElement(dr))
46 {
47 MessagePartInfo p = findMessagePart(endpoint, dr.getName());
48
49 if (p == null)
50 {
51 throw new XFireFault("Parameter " + dr.getName() + " does not exist!",
52 XFireFault.SENDER);
53 }
54
55 parameters.add( getBindingProvider().readParameter(p, dr, context) );
56 }
57
58 if (!isClientModeOn())
59 {
60 setOperation(findOperation(endpoint, parameters), context);
61 }
62
63 context.getInMessage().setBody(parameters);
64 }
65
66 public void writeMessage(OutMessage message, XMLStreamWriter writer, MessageContext context)
67 throws XFireFault
68 {
69 OperationInfo op = context.getExchange().getOperation();
70 Object[] values = (Object[]) message.getBody();
71 int i = 0;
72
73 MessageInfo msgInfo = null;
74 if (isClientModeOn())
75 {
76 msgInfo = op.getInputMessage();
77 }
78 else
79 {
80 msgInfo = op.getOutputMessage();
81 }
82
83 for(Iterator itr = msgInfo.getMessageParts().iterator(); itr.hasNext();)
84 {
85 MessagePartInfo outParam = (MessagePartInfo) itr.next();
86
87 getBindingProvider().writeParameter(outParam, writer, context, values[i]);
88 i++;
89 }
90 }
91
92 protected OperationInfo findOperation(Service endpoint, List parameters)
93 {
94 for ( Iterator itr = endpoint.getServiceInfo().getOperations().iterator(); itr.hasNext(); )
95 {
96 OperationInfo o = (OperationInfo) itr.next();
97 List messageParts = o.getInputMessage().getMessageParts();
98 if ( messageParts.size() == parameters.size() )
99 {
100 if (checkParameters(messageParts, parameters))
101 return o;
102 }
103 }
104
105 return null;
106 }
107
108 private boolean checkParameters(List messageParts, List parameters)
109 {
110 Iterator messagePartIterator = messageParts.iterator();
111 for (Iterator parameterIterator = parameters.iterator(); parameterIterator.hasNext();)
112 {
113 Object param = parameterIterator.next();
114 MessagePartInfo mpi = (MessagePartInfo) messagePartIterator.next();
115 if (!mpi.getTypeClass().isAssignableFrom(param.getClass()))
116 return false;
117 }
118 return true;
119 }
120
121 protected MessagePartInfo findMessagePart(Service endpoint, QName name)
122 {
123
124 for ( Iterator itr = endpoint.getServiceInfo().getOperations().iterator(); itr.hasNext(); )
125 {
126 OperationInfo op = (OperationInfo) itr.next();
127 MessageInfo msgInfo = null;
128 if (isClientModeOn())
129 {
130 msgInfo = op.getOutputMessage();
131 }
132 else
133 {
134 msgInfo = op.getInputMessage();
135 }
136
137 MessagePartInfo p = msgInfo.getMessagePart(name);
138
139 if ( p != null )
140 return p;
141 }
142 return null;
143 }
144
145
146 public void createInputParts(WSDLBuilder builder,
147 Message req,
148 OperationInfo op)
149 {
150 writeParameters(builder, req, op.getInputMessage().getMessageParts());
151 }
152
153 public void createOutputParts(WSDLBuilder builder,
154 Message req,
155 OperationInfo op)
156 {
157 writeParameters(builder, req, op.getOutputMessage().getMessageParts());
158 }
159
160 private void writeParameters(WSDLBuilder builder,
161 Message message,
162 Collection params)
163 {
164 for (Iterator itr = params.iterator(); itr.hasNext();)
165 {
166 MessagePartInfo param = (MessagePartInfo) itr.next();
167
168 Part part = builder.createPart(param);
169
170 message.addPart(part);
171 }
172 }
173
174 public Object clone()
175 {
176 DocumentBinding binding = new DocumentBinding();
177 binding.setBindingProvider(getBindingProvider());
178
179 return binding;
180 }
181 }