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
91 for (Iterator itr = service.getServiceInfo().getOperations().iterator(); itr.hasNext();)
92 {
93 OperationInfo op = (OperationInfo) itr.next();
94
95
96 Message req = createInputMessage(op);
97 def.addMessage(req);
98
99
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
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
144
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
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 }