|
1 /* |
|
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 * or visit www.oracle.com if you need additional information or have any |
|
23 * questions. |
|
24 */ |
|
25 |
|
26 package com.sun.xml.internal.ws.wsdl.writer; |
|
27 |
|
28 |
|
29 import static com.sun.xml.internal.bind.v2.schemagen.Util.*; |
|
30 |
|
31 import com.sun.xml.internal.txw2.TXW; |
|
32 import com.sun.xml.internal.txw2.TypedXmlWriter; |
|
33 import com.sun.xml.internal.txw2.output.ResultFactory; |
|
34 import com.sun.xml.internal.txw2.output.XmlSerializer; |
|
35 import com.sun.xml.internal.txw2.output.TXWResult; |
|
36 import com.sun.xml.internal.ws.api.SOAPVersion; |
|
37 import com.sun.xml.internal.ws.api.WSBinding; |
|
38 import com.sun.xml.internal.ws.api.model.JavaMethod; |
|
39 import com.sun.xml.internal.ws.api.model.MEP; |
|
40 import com.sun.xml.internal.ws.api.model.ParameterBinding; |
|
41 import com.sun.xml.internal.ws.api.model.SEIModel; |
|
42 import com.sun.xml.internal.ws.api.model.soap.SOAPBinding; |
|
43 import com.sun.xml.internal.ws.api.server.Container; |
|
44 import com.sun.xml.internal.ws.api.wsdl.writer.WSDLGeneratorExtension; |
|
45 import com.sun.xml.internal.ws.api.wsdl.writer.WSDLGenExtnContext; |
|
46 import com.sun.xml.internal.ws.model.AbstractSEIModelImpl; |
|
47 import com.sun.xml.internal.ws.model.CheckedExceptionImpl; |
|
48 import com.sun.xml.internal.ws.model.JavaMethodImpl; |
|
49 import com.sun.xml.internal.ws.model.ParameterImpl; |
|
50 import com.sun.xml.internal.ws.model.WrapperParameter; |
|
51 import com.sun.xml.internal.ws.wsdl.parser.SOAPConstants; |
|
52 import com.sun.xml.internal.ws.wsdl.parser.WSDLConstants; |
|
53 import com.sun.xml.internal.ws.wsdl.writer.document.Binding; |
|
54 import com.sun.xml.internal.ws.wsdl.writer.document.BindingOperationType; |
|
55 import com.sun.xml.internal.ws.wsdl.writer.document.Definitions; |
|
56 import com.sun.xml.internal.ws.wsdl.writer.document.Fault; |
|
57 import com.sun.xml.internal.ws.wsdl.writer.document.FaultType; |
|
58 import com.sun.xml.internal.ws.wsdl.writer.document.Import; |
|
59 import com.sun.xml.internal.ws.wsdl.writer.document.Message; |
|
60 import com.sun.xml.internal.ws.wsdl.writer.document.Operation; |
|
61 import com.sun.xml.internal.ws.wsdl.writer.document.ParamType; |
|
62 import com.sun.xml.internal.ws.wsdl.writer.document.Port; |
|
63 import com.sun.xml.internal.ws.wsdl.writer.document.PortType; |
|
64 import com.sun.xml.internal.ws.wsdl.writer.document.Service; |
|
65 import com.sun.xml.internal.ws.wsdl.writer.document.Types; |
|
66 import com.sun.xml.internal.ws.wsdl.writer.document.soap.Body; |
|
67 import com.sun.xml.internal.ws.wsdl.writer.document.soap.BodyType; |
|
68 import com.sun.xml.internal.ws.wsdl.writer.document.soap.Header; |
|
69 import com.sun.xml.internal.ws.wsdl.writer.document.soap.SOAPAddress; |
|
70 import com.sun.xml.internal.ws.wsdl.writer.document.soap.SOAPFault; |
|
71 import com.sun.xml.internal.ws.spi.db.BindingContext; |
|
72 import com.sun.xml.internal.ws.spi.db.BindingHelper; |
|
73 import com.sun.xml.internal.ws.util.RuntimeVersion; |
|
74 import com.sun.xml.internal.ws.policy.jaxws.PolicyWSDLGeneratorExtension; |
|
75 import com.sun.xml.internal.ws.encoding.soap.streaming.SOAPNamespaceConstants; |
|
76 |
|
77 import javax.jws.soap.SOAPBinding.Style; |
|
78 import javax.jws.soap.SOAPBinding.Use; |
|
79 import javax.xml.bind.SchemaOutputResolver; |
|
80 import javax.xml.namespace.QName; |
|
81 import javax.xml.transform.Result; |
|
82 import javax.xml.transform.Transformer; |
|
83 import javax.xml.transform.TransformerConfigurationException; |
|
84 import javax.xml.transform.TransformerException; |
|
85 import javax.xml.transform.TransformerFactory; |
|
86 import javax.xml.transform.dom.DOMResult; |
|
87 import javax.xml.transform.dom.DOMSource; |
|
88 import javax.xml.transform.sax.SAXResult; |
|
89 import javax.xml.ws.Holder; |
|
90 import javax.xml.ws.WebServiceException; |
|
91 |
|
92 import org.w3c.dom.Document; |
|
93 |
|
94 import java.io.IOException; |
|
95 import java.net.URI; |
|
96 import java.net.URISyntaxException; |
|
97 import java.util.ArrayList; |
|
98 import java.util.HashSet; |
|
99 import java.util.Iterator; |
|
100 import java.util.List; |
|
101 import java.util.Set; |
|
102 |
|
103 |
|
104 /** |
|
105 * Class used to generate WSDLs from a {@link SEIModel}. |
|
106 * |
|
107 * @author WS Development Team |
|
108 */ |
|
109 public class WSDLGenerator { |
|
110 private JAXWSOutputSchemaResolver resolver; |
|
111 private WSDLResolver wsdlResolver = null; |
|
112 private AbstractSEIModelImpl model; |
|
113 private Definitions serviceDefinitions; |
|
114 private Definitions portDefinitions; |
|
115 private Types types; |
|
116 /** |
|
117 * Constant String for ".wsdl" |
|
118 */ |
|
119 private static final String DOT_WSDL = ".wsdl"; |
|
120 /** |
|
121 * Constant String appended to response message names |
|
122 */ |
|
123 private static final String RESPONSE = "Response"; |
|
124 /** |
|
125 * constant String used for part name for wrapped request messages |
|
126 */ |
|
127 private static final String PARAMETERS = "parameters"; |
|
128 /** |
|
129 * the part name for unwrappable response messages |
|
130 */ |
|
131 private static final String RESULT = "parameters"; |
|
132 /** |
|
133 * the part name for response messages that are not unwrappable |
|
134 */ |
|
135 private static final String UNWRAPPABLE_RESULT = "result"; |
|
136 /** |
|
137 * The WSDL namespace |
|
138 */ |
|
139 private static final String WSDL_NAMESPACE = WSDLConstants.NS_WSDL; |
|
140 |
|
141 /** |
|
142 * the XSD namespace |
|
143 */ |
|
144 private static final String XSD_NAMESPACE = SOAPNamespaceConstants.XSD; |
|
145 /** |
|
146 * the namespace prefix to use for the XSD namespace |
|
147 */ |
|
148 private static final String XSD_PREFIX = "xsd"; |
|
149 /** |
|
150 * The SOAP 1.1 namespace |
|
151 */ |
|
152 private static final String SOAP11_NAMESPACE = SOAPConstants.NS_WSDL_SOAP; |
|
153 /** |
|
154 * The SOAP 1.2 namespace |
|
155 */ |
|
156 private static final String SOAP12_NAMESPACE = SOAPConstants.NS_WSDL_SOAP12; |
|
157 /** |
|
158 * The namespace prefix to use for the SOAP 1.1 namespace |
|
159 */ |
|
160 private static final String SOAP_PREFIX = "soap"; |
|
161 /** |
|
162 * The namespace prefix to use for the SOAP 1.2 namespace |
|
163 */ |
|
164 private static final String SOAP12_PREFIX = "soap12"; |
|
165 /** |
|
166 * The namespace prefix to use for the targetNamespace |
|
167 */ |
|
168 private static final String TNS_PREFIX = "tns"; |
|
169 |
|
170 /** |
|
171 * Constant String "document" used to specify <code>document</code> style |
|
172 * soapBindings |
|
173 */ |
|
174 private static final String DOCUMENT = "document"; |
|
175 /** |
|
176 * Constant String "rpc" used to specify <code>rpc</code> style |
|
177 * soapBindings |
|
178 */ |
|
179 private static final String RPC = "rpc"; |
|
180 /** |
|
181 * Constant String "literal" used to create <code>literal</code> use binddings |
|
182 */ |
|
183 private static final String LITERAL = "literal"; |
|
184 /** |
|
185 * Constant String to flag the URL to replace at runtime for the endpoint |
|
186 */ |
|
187 private static final String REPLACE_WITH_ACTUAL_URL = "REPLACE_WITH_ACTUAL_URL"; |
|
188 private Set<QName> processedExceptions = new HashSet<QName>(); |
|
189 private WSBinding binding; |
|
190 private String wsdlLocation; |
|
191 private String portWSDLID; |
|
192 private String schemaPrefix; |
|
193 private WSDLGeneratorExtension extension; |
|
194 List<WSDLGeneratorExtension> extensionHandlers; |
|
195 |
|
196 private String endpointAddress = REPLACE_WITH_ACTUAL_URL; |
|
197 private Container container; |
|
198 private final Class implType; |
|
199 |
|
200 private boolean inlineSchemas; // TODO |
|
201 |
|
202 /** |
|
203 * Creates the WSDLGenerator |
|
204 * @param model The {@link AbstractSEIModelImpl} used to generate the WSDL |
|
205 * @param wsdlResolver The {@link WSDLResolver} to use resovle names while generating the WSDL |
|
206 * @param binding specifies which {@link javax.xml.ws.BindingType} to generate |
|
207 * @param extensions an array {@link WSDLGeneratorExtension} that will |
|
208 * be invoked to generate WSDL extensions |
|
209 */ |
|
210 public WSDLGenerator(AbstractSEIModelImpl model, WSDLResolver wsdlResolver, WSBinding binding, Container container, |
|
211 Class implType, boolean inlineSchemas, WSDLGeneratorExtension... extensions) { |
|
212 this.model = model; |
|
213 resolver = new JAXWSOutputSchemaResolver(); |
|
214 this.wsdlResolver = wsdlResolver; |
|
215 this.binding = binding; |
|
216 this.container = container; |
|
217 this.implType = implType; |
|
218 extensionHandlers = new ArrayList<WSDLGeneratorExtension>(); |
|
219 this.inlineSchemas = inlineSchemas; |
|
220 |
|
221 // register handlers for default extensions |
|
222 register(new W3CAddressingWSDLGeneratorExtension()); |
|
223 register(new W3CAddressingMetadataWSDLGeneratorExtension()); |
|
224 register(new PolicyWSDLGeneratorExtension()); |
|
225 |
|
226 if (container != null) { // on server |
|
227 WSDLGeneratorExtension[] wsdlGeneratorExtensions = container.getSPI(WSDLGeneratorExtension[].class); |
|
228 if (wsdlGeneratorExtensions != null) { |
|
229 for (WSDLGeneratorExtension wsdlGeneratorExtension : wsdlGeneratorExtensions) { |
|
230 register(wsdlGeneratorExtension); |
|
231 } |
|
232 } |
|
233 } |
|
234 |
|
235 for (WSDLGeneratorExtension w : extensions) |
|
236 register(w); |
|
237 |
|
238 this.extension = new WSDLGeneratorExtensionFacade(extensionHandlers.toArray(new WSDLGeneratorExtension[0])); |
|
239 } |
|
240 |
|
241 /** |
|
242 * Sets the endpoint address string to be written. |
|
243 * Defaults to {@link #REPLACE_WITH_ACTUAL_URL}. |
|
244 * |
|
245 * @param address wsdl:port/soap:address/[@location] value |
|
246 */ |
|
247 public void setEndpointAddress(String address) { |
|
248 this.endpointAddress = address; |
|
249 } |
|
250 |
|
251 protected String mangleName(String name) { |
|
252 return BindingHelper.mangleNameToClassName(name); |
|
253 } |
|
254 |
|
255 /** |
|
256 * Performes the actual WSDL generation |
|
257 */ |
|
258 public void doGeneration() { |
|
259 XmlSerializer serviceWriter; |
|
260 XmlSerializer portWriter = null; |
|
261 String fileName = mangleName(model.getServiceQName().getLocalPart()); |
|
262 Result result = wsdlResolver.getWSDL(fileName + DOT_WSDL); |
|
263 wsdlLocation = result.getSystemId(); |
|
264 serviceWriter = new CommentFilter(ResultFactory.createSerializer(result)); |
|
265 if (model.getServiceQName().getNamespaceURI().equals(model.getTargetNamespace())) { |
|
266 portWriter = serviceWriter; |
|
267 schemaPrefix = fileName + "_"; |
|
268 } else { |
|
269 String wsdlName = mangleName(model.getPortTypeName().getLocalPart()); |
|
270 if (wsdlName.equals(fileName)) |
|
271 wsdlName += "PortType"; |
|
272 Holder<String> absWSDLName = new Holder<String>(); |
|
273 absWSDLName.value = wsdlName + DOT_WSDL; |
|
274 result = wsdlResolver.getAbstractWSDL(absWSDLName); |
|
275 |
|
276 if (result != null) { |
|
277 portWSDLID = result.getSystemId(); |
|
278 if (portWSDLID.equals(wsdlLocation)) { |
|
279 portWriter = serviceWriter; |
|
280 } else { |
|
281 portWriter = new CommentFilter(ResultFactory.createSerializer(result)); |
|
282 } |
|
283 } else { |
|
284 portWSDLID = absWSDLName.value; |
|
285 } |
|
286 schemaPrefix = new java.io.File(portWSDLID).getName(); |
|
287 int idx = schemaPrefix.lastIndexOf('.'); |
|
288 if (idx > 0) |
|
289 schemaPrefix = schemaPrefix.substring(0, idx); |
|
290 schemaPrefix = mangleName(schemaPrefix) + "_"; |
|
291 } |
|
292 generateDocument(serviceWriter, portWriter); |
|
293 } |
|
294 |
|
295 /** |
|
296 * Writing directly to XmlSerializer is a problem, since it doesn't suppress |
|
297 * xml declaration. Creating filter so that comment is written before TXW writes |
|
298 * anything in the WSDL. |
|
299 */ |
|
300 private static class CommentFilter implements XmlSerializer { |
|
301 final XmlSerializer serializer; |
|
302 private static final String VERSION_COMMENT = |
|
303 " Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is " + RuntimeVersion.VERSION + ". "; |
|
304 |
|
305 CommentFilter(XmlSerializer serializer) { |
|
306 this.serializer = serializer; |
|
307 } |
|
308 |
|
309 public void startDocument() { |
|
310 serializer.startDocument(); |
|
311 comment(new StringBuilder(VERSION_COMMENT)); |
|
312 text(new StringBuilder("\n")); |
|
313 } |
|
314 |
|
315 public void beginStartTag(String uri, String localName, String prefix) { |
|
316 serializer.beginStartTag(uri, localName, prefix); |
|
317 } |
|
318 |
|
319 public void writeAttribute(String uri, String localName, String prefix, StringBuilder value) { |
|
320 serializer.writeAttribute(uri, localName, prefix, value); |
|
321 } |
|
322 |
|
323 public void writeXmlns(String prefix, String uri) { |
|
324 serializer.writeXmlns(prefix, uri); |
|
325 } |
|
326 |
|
327 public void endStartTag(String uri, String localName, String prefix) { |
|
328 serializer.endStartTag(uri, localName, prefix); |
|
329 } |
|
330 |
|
331 public void endTag() { |
|
332 serializer.endTag(); |
|
333 } |
|
334 |
|
335 public void text(StringBuilder text) { |
|
336 serializer.text(text); |
|
337 } |
|
338 |
|
339 public void cdata(StringBuilder text) { |
|
340 serializer.cdata(text); |
|
341 } |
|
342 |
|
343 public void comment(StringBuilder comment) { |
|
344 serializer.comment(comment); |
|
345 } |
|
346 |
|
347 public void endDocument() { |
|
348 serializer.endDocument(); |
|
349 } |
|
350 |
|
351 public void flush() { |
|
352 serializer.flush(); |
|
353 } |
|
354 |
|
355 } |
|
356 |
|
357 private void generateDocument(XmlSerializer serviceStream, XmlSerializer portStream) { |
|
358 serviceDefinitions = TXW.create(Definitions.class, serviceStream); |
|
359 serviceDefinitions._namespace(WSDL_NAMESPACE, "");//WSDL_PREFIX); |
|
360 serviceDefinitions._namespace(XSD_NAMESPACE, XSD_PREFIX); |
|
361 serviceDefinitions.targetNamespace(model.getServiceQName().getNamespaceURI()); |
|
362 serviceDefinitions._namespace(model.getServiceQName().getNamespaceURI(), TNS_PREFIX); |
|
363 if (binding.getSOAPVersion() == SOAPVersion.SOAP_12) |
|
364 serviceDefinitions._namespace(SOAP12_NAMESPACE, SOAP12_PREFIX); |
|
365 else |
|
366 serviceDefinitions._namespace(SOAP11_NAMESPACE, SOAP_PREFIX); |
|
367 serviceDefinitions.name(model.getServiceQName().getLocalPart()); |
|
368 WSDLGenExtnContext serviceCtx = new WSDLGenExtnContext(serviceDefinitions, model, binding, container, implType); |
|
369 extension.start(serviceCtx); |
|
370 if (serviceStream != portStream && portStream != null) { |
|
371 // generate an abstract and concrete wsdl |
|
372 portDefinitions = TXW.create(Definitions.class, portStream); |
|
373 portDefinitions._namespace(WSDL_NAMESPACE, "");//WSDL_PREFIX); |
|
374 portDefinitions._namespace(XSD_NAMESPACE, XSD_PREFIX); |
|
375 if (model.getTargetNamespace() != null) { |
|
376 portDefinitions.targetNamespace(model.getTargetNamespace()); |
|
377 portDefinitions._namespace(model.getTargetNamespace(), TNS_PREFIX); |
|
378 } |
|
379 |
|
380 String schemaLoc = relativize(portWSDLID, wsdlLocation); |
|
381 Import _import = serviceDefinitions._import().namespace(model.getTargetNamespace()); |
|
382 _import.location(schemaLoc); |
|
383 } else if (portStream != null) { |
|
384 // abstract and concrete are the same |
|
385 portDefinitions = serviceDefinitions; |
|
386 } else { |
|
387 // import a provided abstract wsdl |
|
388 String schemaLoc = relativize(portWSDLID, wsdlLocation); |
|
389 Import _import = serviceDefinitions._import().namespace(model.getTargetNamespace()); |
|
390 _import.location(schemaLoc); |
|
391 } |
|
392 extension.addDefinitionsExtension(serviceDefinitions); |
|
393 |
|
394 if (portDefinitions != null) { |
|
395 generateTypes(); |
|
396 generateMessages(); |
|
397 generatePortType(); |
|
398 } |
|
399 generateBinding(); |
|
400 generateService(); |
|
401 //Give a chance to WSDLGeneratorExtensions to write stuff before closing </wsdl:defintions> |
|
402 extension.end(serviceCtx); |
|
403 serviceDefinitions.commit(); |
|
404 if (portDefinitions != null && portDefinitions != serviceDefinitions) |
|
405 portDefinitions.commit(); |
|
406 } |
|
407 |
|
408 |
|
409 /** |
|
410 * Generates the types section of the WSDL |
|
411 */ |
|
412 protected void generateTypes() { |
|
413 types = portDefinitions.types(); |
|
414 if (model.getBindingContext() != null) { |
|
415 if (inlineSchemas && model.getBindingContext().getClass().getName().indexOf("glassfish") == -1) { |
|
416 resolver.nonGlassfishSchemas = new ArrayList<DOMResult>(); |
|
417 } |
|
418 try { |
|
419 model.getBindingContext().generateSchema(resolver); |
|
420 } catch (IOException e) { |
|
421 // TODO locallize and wrap this |
|
422 e.printStackTrace(); |
|
423 throw new WebServiceException(e.getMessage()); |
|
424 } |
|
425 } |
|
426 if (resolver.nonGlassfishSchemas != null) { |
|
427 TransformerFactory tf = TransformerFactory.newInstance(); |
|
428 try { |
|
429 Transformer t = tf.newTransformer(); |
|
430 for (DOMResult xsd : resolver.nonGlassfishSchemas) { |
|
431 Document doc = (Document) xsd.getNode(); |
|
432 SAXResult sax = new SAXResult(new TXWContentHandler(types)); |
|
433 t.transform(new DOMSource(doc.getDocumentElement()), sax); |
|
434 } |
|
435 } catch (TransformerConfigurationException e) { |
|
436 e.printStackTrace(); |
|
437 throw new WebServiceException(e.getMessage(), e); |
|
438 } catch (TransformerException e) { |
|
439 e.printStackTrace(); |
|
440 throw new WebServiceException(e.getMessage(), e); |
|
441 } |
|
442 } |
|
443 } |
|
444 |
|
445 /** |
|
446 * Generates the WSDL messages |
|
447 */ |
|
448 protected void generateMessages() { |
|
449 for (JavaMethodImpl method : model.getJavaMethods()) { |
|
450 generateSOAPMessages(method, method.getBinding()); |
|
451 } |
|
452 } |
|
453 |
|
454 /** |
|
455 * Generates messages for a SOAPBinding |
|
456 * @param method The {@link JavaMethod} to generate messages for |
|
457 * @param binding The {@link com.sun.xml.internal.ws.api.model.soap.SOAPBinding} to add the generated messages to |
|
458 */ |
|
459 protected void generateSOAPMessages(JavaMethodImpl method, com.sun.xml.internal.ws.api.model.soap.SOAPBinding binding) { |
|
460 boolean isDoclit = binding.isDocLit(); |
|
461 // Message message = portDefinitions.message().name(method.getOperation().getName().getLocalPart()); |
|
462 Message message = portDefinitions.message().name(method.getRequestMessageName()); |
|
463 extension.addInputMessageExtension(message, method); |
|
464 com.sun.xml.internal.ws.wsdl.writer.document.Part part; |
|
465 BindingContext jaxbContext = model.getBindingContext(); |
|
466 boolean unwrappable = true; |
|
467 for (ParameterImpl param : method.getRequestParameters()) { |
|
468 if (isDoclit) { |
|
469 if (isHeaderParameter(param)) |
|
470 unwrappable = false; |
|
471 |
|
472 part = message.part().name(param.getPartName()); |
|
473 part.element(param.getName()); |
|
474 } else { |
|
475 if (param.isWrapperStyle()) { |
|
476 for (ParameterImpl childParam : ((WrapperParameter) param).getWrapperChildren()) { |
|
477 part = message.part().name(childParam.getPartName()); |
|
478 part.type(jaxbContext.getTypeName(childParam.getXMLBridge().getTypeInfo())); |
|
479 } |
|
480 } else { |
|
481 part = message.part().name(param.getPartName()); |
|
482 part.element(param.getName()); |
|
483 } |
|
484 } |
|
485 } |
|
486 if (method.getMEP() != MEP.ONE_WAY) { |
|
487 // message = portDefinitions.message().name(method.getOperation().getName().getLocalPart()+RESPONSE); |
|
488 message = portDefinitions.message().name(method.getResponseMessageName()); |
|
489 extension.addOutputMessageExtension(message, method); |
|
490 if (unwrappable) { |
|
491 for (ParameterImpl param : method.getResponseParameters()) { |
|
492 if (isHeaderParameter(param)) |
|
493 unwrappable = false; |
|
494 } |
|
495 } |
|
496 |
|
497 for (ParameterImpl param : method.getResponseParameters()) { |
|
498 if (isDoclit) { |
|
499 part = message.part().name(param.getPartName()); |
|
500 part.element(param.getName()); |
|
501 |
|
502 } else { |
|
503 if (param.isWrapperStyle()) { |
|
504 for (ParameterImpl childParam : ((WrapperParameter) param).getWrapperChildren()) { |
|
505 part = message.part().name(childParam.getPartName()); |
|
506 part.type(jaxbContext.getTypeName(childParam.getXMLBridge().getTypeInfo())); |
|
507 } |
|
508 } else { |
|
509 part = message.part().name(param.getPartName()); |
|
510 part.element(param.getName()); |
|
511 } |
|
512 } |
|
513 } |
|
514 } |
|
515 for (CheckedExceptionImpl exception : method.getCheckedExceptions()) { |
|
516 QName tagName = exception.getDetailType().tagName; |
|
517 String messageName = exception.getMessageName(); |
|
518 QName messageQName = new QName(model.getTargetNamespace(), messageName); |
|
519 if (processedExceptions.contains(messageQName)) |
|
520 continue; |
|
521 message = portDefinitions.message().name(messageName); |
|
522 |
|
523 extension.addFaultMessageExtension(message, method, exception); |
|
524 part = message.part().name("fault");//tagName.getLocalPart()); |
|
525 part.element(tagName); |
|
526 processedExceptions.add(messageQName); |
|
527 } |
|
528 } |
|
529 |
|
530 /** |
|
531 * Generates the WSDL portType |
|
532 */ |
|
533 protected void generatePortType() { |
|
534 |
|
535 PortType portType = portDefinitions.portType().name(model.getPortTypeName().getLocalPart()); |
|
536 extension.addPortTypeExtension(portType); |
|
537 for (JavaMethodImpl method : model.getJavaMethods()) { |
|
538 Operation operation = portType.operation().name(method.getOperationName()); |
|
539 generateParameterOrder(operation, method); |
|
540 extension.addOperationExtension(operation, method); |
|
541 switch (method.getMEP()) { |
|
542 case REQUEST_RESPONSE: |
|
543 // input message |
|
544 generateInputMessage(operation, method); |
|
545 // output message |
|
546 generateOutputMessage(operation, method); |
|
547 break; |
|
548 case ONE_WAY: |
|
549 generateInputMessage(operation, method); |
|
550 break; |
|
551 } |
|
552 // faults |
|
553 for (CheckedExceptionImpl exception : method.getCheckedExceptions()) { |
|
554 QName messageName = new QName(model.getTargetNamespace(), exception.getMessageName()); |
|
555 FaultType paramType = operation.fault().message(messageName).name(exception.getMessageName()); |
|
556 extension.addOperationFaultExtension(paramType, method, exception); |
|
557 } |
|
558 } |
|
559 } |
|
560 |
|
561 /** |
|
562 * Determines if the <CODE>method</CODE> is wrapper style |
|
563 * @param method The {@link JavaMethod} to check if it is wrapper style |
|
564 * @return true if the method is wrapper style, otherwise, false. |
|
565 */ |
|
566 protected boolean isWrapperStyle(JavaMethodImpl method) { |
|
567 if (method.getRequestParameters().size() > 0) { |
|
568 ParameterImpl param = method.getRequestParameters().iterator().next(); |
|
569 return param.isWrapperStyle(); |
|
570 } |
|
571 return false; |
|
572 } |
|
573 |
|
574 /** |
|
575 * Determines if a {@link JavaMethod} is rpc/literal |
|
576 * @param method The method to check |
|
577 * @return true if method is rpc/literal, otherwise, false |
|
578 */ |
|
579 protected boolean isRpcLit(JavaMethodImpl method) { |
|
580 return method.getBinding().getStyle() == Style.RPC; |
|
581 } |
|
582 |
|
583 /** |
|
584 * Generates the parameterOrder for a PortType operation |
|
585 * @param operation The operation to generate the parameterOrder for |
|
586 * @param method The {@link JavaMethod} to generate the parameterOrder from |
|
587 */ |
|
588 protected void generateParameterOrder(Operation operation, JavaMethodImpl method) { |
|
589 if (method.getMEP() == MEP.ONE_WAY) |
|
590 return; |
|
591 if (isRpcLit(method)) |
|
592 generateRpcParameterOrder(operation, method); |
|
593 else |
|
594 generateDocumentParameterOrder(operation, method); |
|
595 } |
|
596 |
|
597 /** |
|
598 * Generates the parameterOrder for a PortType operation |
|
599 * @param operation the operation to generate the parameterOrder for |
|
600 * @param method the {@link JavaMethod} to generate the parameterOrder from |
|
601 */ |
|
602 protected void generateRpcParameterOrder(Operation operation, JavaMethodImpl method) { |
|
603 String partName; |
|
604 StringBuffer paramOrder = new StringBuffer(); |
|
605 Set<String> partNames = new HashSet<String>(); |
|
606 List<ParameterImpl> sortedParams = sortMethodParameters(method); |
|
607 int i = 0; |
|
608 for (ParameterImpl parameter : sortedParams) { |
|
609 if (parameter.getIndex() >= 0) { |
|
610 partName = parameter.getPartName(); |
|
611 if (!partNames.contains(partName)) { |
|
612 if (i++ > 0) |
|
613 paramOrder.append(' '); |
|
614 paramOrder.append(partName); |
|
615 partNames.add(partName); |
|
616 } |
|
617 } |
|
618 } |
|
619 if (i > 1) { |
|
620 operation.parameterOrder(paramOrder.toString()); |
|
621 } |
|
622 } |
|
623 |
|
624 |
|
625 /** |
|
626 * Generates the parameterOrder for a PortType operation |
|
627 * @param operation the operation to generate the parameterOrder for |
|
628 * @param method the {@link JavaMethod} to generate the parameterOrder from |
|
629 */ |
|
630 protected void generateDocumentParameterOrder(Operation operation, JavaMethodImpl method) { |
|
631 String partName; |
|
632 StringBuffer paramOrder = new StringBuffer(); |
|
633 Set<String> partNames = new HashSet<String>(); |
|
634 List<ParameterImpl> sortedParams = sortMethodParameters(method); |
|
635 boolean isWrapperStyle = isWrapperStyle(method); |
|
636 int i = 0; |
|
637 for (ParameterImpl parameter : sortedParams) { |
|
638 // System.out.println("param: "+parameter.getIndex()+" name: "+parameter.getName().getLocalPart()); |
|
639 if (parameter.getIndex() < 0) |
|
640 continue; |
|
641 |
|
642 // This should be safe change. if it affects compatibility, |
|
643 // remove the following single statement and uncomment the code in block below. |
|
644 partName = parameter.getPartName(); |
|
645 /* |
|
646 if (isWrapperStyle && isBodyParameter(parameter)) { |
|
647 System.out.println("isWrapper and is body"); |
|
648 if (method.getRequestParameters().contains(parameter)) |
|
649 partName = PARAMETERS; |
|
650 else { |
|
651 //Rama: don't understand this logic "Response" below, |
|
652 |
|
653 // really make sure this is a wrapper style wsdl we are creating |
|
654 partName = RESPONSE; |
|
655 } |
|
656 } else { |
|
657 partName = parameter.getPartName(); |
|
658 }*/ |
|
659 |
|
660 if (!partNames.contains(partName)) { |
|
661 if (i++ > 0) |
|
662 paramOrder.append(' '); |
|
663 paramOrder.append(partName); |
|
664 partNames.add(partName); |
|
665 } |
|
666 } |
|
667 if (i > 1) { |
|
668 operation.parameterOrder(paramOrder.toString()); |
|
669 } |
|
670 } |
|
671 |
|
672 /** |
|
673 * Sorts the parameters for the method by their position |
|
674 * @param method the {@link JavaMethod} used to sort the parameters |
|
675 * @return the sorted {@link List} of parameters |
|
676 */ |
|
677 protected List<ParameterImpl> sortMethodParameters(JavaMethodImpl method) { |
|
678 Set<ParameterImpl> paramSet = new HashSet<ParameterImpl>(); |
|
679 List<ParameterImpl> sortedParams = new ArrayList<ParameterImpl>(); |
|
680 if (isRpcLit(method)) { |
|
681 for (ParameterImpl param : method.getRequestParameters()) { |
|
682 if (param instanceof WrapperParameter) { |
|
683 paramSet.addAll(((WrapperParameter) param).getWrapperChildren()); |
|
684 } else { |
|
685 paramSet.add(param); |
|
686 } |
|
687 } |
|
688 for (ParameterImpl param : method.getResponseParameters()) { |
|
689 if (param instanceof WrapperParameter) { |
|
690 paramSet.addAll(((WrapperParameter) param).getWrapperChildren()); |
|
691 } else { |
|
692 paramSet.add(param); |
|
693 } |
|
694 } |
|
695 } else { |
|
696 paramSet.addAll(method.getRequestParameters()); |
|
697 paramSet.addAll(method.getResponseParameters()); |
|
698 } |
|
699 Iterator<ParameterImpl> params = paramSet.iterator(); |
|
700 if (paramSet.size() == 0) |
|
701 return sortedParams; |
|
702 ParameterImpl param = params.next(); |
|
703 sortedParams.add(param); |
|
704 ParameterImpl sortedParam; |
|
705 int pos; |
|
706 for (int i = 1; i < paramSet.size(); i++) { |
|
707 param = params.next(); |
|
708 for (pos = 0; pos < i; pos++) { |
|
709 sortedParam = sortedParams.get(pos); |
|
710 if (param.getIndex() == sortedParam.getIndex() && |
|
711 param instanceof WrapperParameter) |
|
712 break; |
|
713 if (param.getIndex() < sortedParam.getIndex()) { |
|
714 break; |
|
715 } |
|
716 } |
|
717 sortedParams.add(pos, param); |
|
718 } |
|
719 return sortedParams; |
|
720 } |
|
721 |
|
722 /** |
|
723 * Determines if a parameter is associated with the message Body |
|
724 * @param parameter the parameter to check |
|
725 * @return true if the parameter is a <code>body</code> parameter |
|
726 */ |
|
727 protected boolean isBodyParameter(ParameterImpl parameter) { |
|
728 ParameterBinding paramBinding = parameter.getBinding(); |
|
729 return paramBinding.isBody(); |
|
730 } |
|
731 |
|
732 protected boolean isHeaderParameter(ParameterImpl parameter) { |
|
733 ParameterBinding paramBinding = parameter.getBinding(); |
|
734 return paramBinding.isHeader(); |
|
735 } |
|
736 |
|
737 protected boolean isAttachmentParameter(ParameterImpl parameter) { |
|
738 ParameterBinding paramBinding = parameter.getBinding(); |
|
739 return paramBinding.isAttachment(); |
|
740 } |
|
741 |
|
742 |
|
743 /** |
|
744 * Generates the Binding section of the WSDL |
|
745 */ |
|
746 protected void generateBinding() { |
|
747 Binding binding = serviceDefinitions.binding().name(model.getBoundPortTypeName().getLocalPart()); |
|
748 extension.addBindingExtension(binding); |
|
749 binding.type(model.getPortTypeName()); |
|
750 boolean first = true; |
|
751 for (JavaMethodImpl method : model.getJavaMethods()) { |
|
752 if (first) { |
|
753 SOAPBinding sBinding = method.getBinding(); |
|
754 SOAPVersion soapVersion = sBinding.getSOAPVersion(); |
|
755 if (soapVersion == SOAPVersion.SOAP_12) { |
|
756 com.sun.xml.internal.ws.wsdl.writer.document.soap12.SOAPBinding soapBinding = binding.soap12Binding(); |
|
757 soapBinding.transport(this.binding.getBindingId().getTransport()); |
|
758 if (sBinding.getStyle().equals(Style.DOCUMENT)) |
|
759 soapBinding.style(DOCUMENT); |
|
760 else |
|
761 soapBinding.style(RPC); |
|
762 } else { |
|
763 com.sun.xml.internal.ws.wsdl.writer.document.soap.SOAPBinding soapBinding = binding.soapBinding(); |
|
764 soapBinding.transport(this.binding.getBindingId().getTransport()); |
|
765 if (sBinding.getStyle().equals(Style.DOCUMENT)) |
|
766 soapBinding.style(DOCUMENT); |
|
767 else |
|
768 soapBinding.style(RPC); |
|
769 } |
|
770 first = false; |
|
771 } |
|
772 if (this.binding.getBindingId().getSOAPVersion() == SOAPVersion.SOAP_12) |
|
773 generateSOAP12BindingOperation(method, binding); |
|
774 else |
|
775 generateBindingOperation(method, binding); |
|
776 } |
|
777 } |
|
778 |
|
779 protected void generateBindingOperation(JavaMethodImpl method, Binding binding) { |
|
780 BindingOperationType operation = binding.operation().name(method.getOperationName()); |
|
781 extension.addBindingOperationExtension(operation, method); |
|
782 String targetNamespace = model.getTargetNamespace(); |
|
783 QName requestMessage = new QName(targetNamespace, method.getOperationName()); |
|
784 List<ParameterImpl> bodyParams = new ArrayList<ParameterImpl>(); |
|
785 List<ParameterImpl> headerParams = new ArrayList<ParameterImpl>(); |
|
786 splitParameters(bodyParams, headerParams, method.getRequestParameters()); |
|
787 SOAPBinding soapBinding = method.getBinding(); |
|
788 operation.soapOperation().soapAction(soapBinding.getSOAPAction()); |
|
789 |
|
790 // input |
|
791 TypedXmlWriter input = operation.input(); |
|
792 extension.addBindingOperationInputExtension(input, method); |
|
793 BodyType body = input._element(Body.class); |
|
794 boolean isRpc = soapBinding.getStyle().equals(Style.RPC); |
|
795 if (soapBinding.getUse() == Use.LITERAL) { |
|
796 body.use(LITERAL); |
|
797 if (headerParams.size() > 0) { |
|
798 if (bodyParams.size() > 0) { |
|
799 ParameterImpl param = bodyParams.iterator().next(); |
|
800 if (isRpc) { |
|
801 StringBuffer parts = new StringBuffer(); |
|
802 int i = 0; |
|
803 for (ParameterImpl parameter : ((WrapperParameter) param).getWrapperChildren()) { |
|
804 if (i++ > 0) |
|
805 parts.append(' '); |
|
806 parts.append(parameter.getPartName()); |
|
807 } |
|
808 body.parts(parts.toString()); |
|
809 } else { |
|
810 body.parts(param.getPartName()); |
|
811 } |
|
812 } else { |
|
813 body.parts(""); |
|
814 } |
|
815 generateSOAPHeaders(input, headerParams, requestMessage); |
|
816 } |
|
817 if (isRpc) { |
|
818 body.namespace(method.getRequestParameters().iterator().next().getName().getNamespaceURI()); |
|
819 } |
|
820 } else { |
|
821 // TODO localize this |
|
822 throw new WebServiceException("encoded use is not supported"); |
|
823 } |
|
824 |
|
825 if (method.getMEP() != MEP.ONE_WAY) { |
|
826 boolean unwrappable = headerParams.size() == 0; |
|
827 // output |
|
828 bodyParams.clear(); |
|
829 headerParams.clear(); |
|
830 splitParameters(bodyParams, headerParams, method.getResponseParameters()); |
|
831 unwrappable = unwrappable ? headerParams.size() == 0 : unwrappable; |
|
832 TypedXmlWriter output = operation.output(); |
|
833 extension.addBindingOperationOutputExtension(output, method); |
|
834 body = output._element(Body.class); |
|
835 body.use(LITERAL); |
|
836 if (headerParams.size() > 0) { |
|
837 String parts = ""; |
|
838 if (bodyParams.size() > 0) { |
|
839 ParameterImpl param = bodyParams.iterator().hasNext() ? bodyParams.iterator().next() : null; |
|
840 if (param != null) { |
|
841 if (isRpc) { |
|
842 int i = 0; |
|
843 for (ParameterImpl parameter : ((WrapperParameter) param).getWrapperChildren()) { |
|
844 if (i++ > 0) |
|
845 parts += " "; |
|
846 parts += parameter.getPartName(); |
|
847 } |
|
848 } else { |
|
849 parts = param.getPartName(); |
|
850 } |
|
851 } |
|
852 } |
|
853 body.parts(parts); |
|
854 QName responseMessage = new QName(targetNamespace, method.getResponseMessageName()); |
|
855 generateSOAPHeaders(output, headerParams, responseMessage); |
|
856 } |
|
857 if (isRpc) { |
|
858 body.namespace(method.getRequestParameters().iterator().next().getName().getNamespaceURI()); |
|
859 } |
|
860 } |
|
861 for (CheckedExceptionImpl exception : method.getCheckedExceptions()) { |
|
862 Fault fault = operation.fault().name(exception.getMessageName()); |
|
863 extension.addBindingOperationFaultExtension(fault, method, exception); |
|
864 SOAPFault soapFault = fault._element(SOAPFault.class).name(exception.getMessageName()); |
|
865 soapFault.use(LITERAL); |
|
866 } |
|
867 } |
|
868 |
|
869 protected void generateSOAP12BindingOperation(JavaMethodImpl method, Binding binding) { |
|
870 BindingOperationType operation = binding.operation().name(method.getOperationName()); |
|
871 extension.addBindingOperationExtension(operation, method); |
|
872 String targetNamespace = model.getTargetNamespace(); |
|
873 QName requestMessage = new QName(targetNamespace, method.getOperationName()); |
|
874 ArrayList<ParameterImpl> bodyParams = new ArrayList<ParameterImpl>(); |
|
875 ArrayList<ParameterImpl> headerParams = new ArrayList<ParameterImpl>(); |
|
876 splitParameters(bodyParams, headerParams, method.getRequestParameters()); |
|
877 SOAPBinding soapBinding = method.getBinding(); |
|
878 |
|
879 String soapAction = soapBinding.getSOAPAction(); |
|
880 if (soapAction != null) { |
|
881 operation.soap12Operation().soapAction(soapAction); |
|
882 } |
|
883 |
|
884 // input |
|
885 TypedXmlWriter input = operation.input(); |
|
886 extension.addBindingOperationInputExtension(input, method); |
|
887 com.sun.xml.internal.ws.wsdl.writer.document.soap12.BodyType body = input._element(com.sun.xml.internal.ws.wsdl.writer.document.soap12.Body.class); |
|
888 boolean isRpc = soapBinding.getStyle().equals(Style.RPC); |
|
889 if (soapBinding.getUse().equals(Use.LITERAL)) { |
|
890 body.use(LITERAL); |
|
891 if (headerParams.size() > 0) { |
|
892 if (bodyParams.size() > 0) { |
|
893 ParameterImpl param = bodyParams.iterator().next(); |
|
894 if (isRpc) { |
|
895 StringBuffer parts = new StringBuffer(); |
|
896 int i = 0; |
|
897 for (ParameterImpl parameter : ((WrapperParameter) param).getWrapperChildren()) { |
|
898 if (i++ > 0) |
|
899 parts.append(' '); |
|
900 parts.append(parameter.getPartName()); |
|
901 } |
|
902 body.parts(parts.toString()); |
|
903 } else { |
|
904 body.parts(param.getPartName()); |
|
905 } |
|
906 } else { |
|
907 body.parts(""); |
|
908 } |
|
909 generateSOAP12Headers(input, headerParams, requestMessage); |
|
910 } |
|
911 if (isRpc) { |
|
912 body.namespace(method.getRequestParameters().iterator().next().getName().getNamespaceURI()); |
|
913 } |
|
914 } else { |
|
915 // TODO localize this |
|
916 throw new WebServiceException("encoded use is not supported"); |
|
917 } |
|
918 |
|
919 if (method.getMEP() != MEP.ONE_WAY) { |
|
920 // output |
|
921 boolean unwrappable = headerParams.size() == 0; |
|
922 bodyParams.clear(); |
|
923 headerParams.clear(); |
|
924 splitParameters(bodyParams, headerParams, method.getResponseParameters()); |
|
925 unwrappable = unwrappable ? headerParams.size() == 0 : unwrappable; |
|
926 TypedXmlWriter output = operation.output(); |
|
927 extension.addBindingOperationOutputExtension(output, method); |
|
928 body = output._element(com.sun.xml.internal.ws.wsdl.writer.document.soap12.Body.class); |
|
929 body.use(LITERAL); |
|
930 if (headerParams.size() > 0) { |
|
931 if (bodyParams.size() > 0) { |
|
932 ParameterImpl param = bodyParams.iterator().next(); |
|
933 if (isRpc) { |
|
934 String parts = ""; |
|
935 int i = 0; |
|
936 for (ParameterImpl parameter : ((WrapperParameter) param).getWrapperChildren()) { |
|
937 if (i++ > 0) |
|
938 parts += " "; |
|
939 parts += parameter.getPartName(); |
|
940 } |
|
941 body.parts(parts); |
|
942 } else { |
|
943 body.parts(param.getPartName()); |
|
944 } |
|
945 } else { |
|
946 body.parts(""); |
|
947 } |
|
948 QName responseMessage = new QName(targetNamespace, method.getResponseMessageName()); |
|
949 generateSOAP12Headers(output, headerParams, responseMessage); |
|
950 } |
|
951 if (isRpc) { |
|
952 body.namespace(method.getRequestParameters().iterator().next().getName().getNamespaceURI()); |
|
953 } |
|
954 } |
|
955 for (CheckedExceptionImpl exception : method.getCheckedExceptions()) { |
|
956 Fault fault = operation.fault().name(exception.getMessageName()); |
|
957 extension.addBindingOperationFaultExtension(fault, method, exception); |
|
958 com.sun.xml.internal.ws.wsdl.writer.document.soap12.SOAPFault soapFault = fault._element(com.sun.xml.internal.ws.wsdl.writer.document.soap12.SOAPFault.class).name(exception.getMessageName()); |
|
959 soapFault.use(LITERAL); |
|
960 } |
|
961 } |
|
962 |
|
963 protected void splitParameters(List<ParameterImpl> bodyParams, List<ParameterImpl> headerParams, List<ParameterImpl> params) { |
|
964 for (ParameterImpl parameter : params) { |
|
965 if (isBodyParameter(parameter)) { |
|
966 bodyParams.add(parameter); |
|
967 } else { |
|
968 headerParams.add(parameter); |
|
969 } |
|
970 } |
|
971 } |
|
972 |
|
973 protected void generateSOAPHeaders(TypedXmlWriter writer, List<ParameterImpl> parameters, QName message) { |
|
974 |
|
975 for (ParameterImpl headerParam : parameters) { |
|
976 Header header = writer._element(Header.class); |
|
977 header.message(message); |
|
978 header.part(headerParam.getPartName()); |
|
979 header.use(LITERAL); |
|
980 } |
|
981 } |
|
982 |
|
983 protected void generateSOAP12Headers(TypedXmlWriter writer, List<ParameterImpl> parameters, QName message) { |
|
984 |
|
985 for (ParameterImpl headerParam : parameters) { |
|
986 com.sun.xml.internal.ws.wsdl.writer.document.soap12.Header header = writer._element(com.sun.xml.internal.ws.wsdl.writer.document.soap12.Header.class); |
|
987 header.message(message); |
|
988 |
|
989 |
|
990 header.part(headerParam.getPartName()); |
|
991 header.use(LITERAL); |
|
992 } |
|
993 } |
|
994 |
|
995 /** |
|
996 * Generates the Service section of the WSDL |
|
997 */ |
|
998 protected void generateService() { |
|
999 QName portQName = model.getPortName(); |
|
1000 QName serviceQName = model.getServiceQName(); |
|
1001 Service service = serviceDefinitions.service().name(serviceQName.getLocalPart()); |
|
1002 extension.addServiceExtension(service); |
|
1003 Port port = service.port().name(portQName.getLocalPart()); |
|
1004 port.binding(model.getBoundPortTypeName()); |
|
1005 extension.addPortExtension(port); |
|
1006 if (model.getJavaMethods().size() == 0) |
|
1007 return; |
|
1008 |
|
1009 if (this.binding.getBindingId().getSOAPVersion() == SOAPVersion.SOAP_12) { |
|
1010 com.sun.xml.internal.ws.wsdl.writer.document.soap12.SOAPAddress address = port._element(com.sun.xml.internal.ws.wsdl.writer.document.soap12.SOAPAddress.class); |
|
1011 address.location(endpointAddress); |
|
1012 } else { |
|
1013 SOAPAddress address = port._element(SOAPAddress.class); |
|
1014 address.location(endpointAddress); |
|
1015 } |
|
1016 } |
|
1017 |
|
1018 protected void generateInputMessage(Operation operation, JavaMethodImpl method) { |
|
1019 ParamType paramType = operation.input(); |
|
1020 extension.addOperationInputExtension(paramType, method); |
|
1021 // paramType.message(method.getOperation().getName()); |
|
1022 paramType.message(new QName(model.getTargetNamespace(), method.getRequestMessageName())); |
|
1023 } |
|
1024 |
|
1025 protected void generateOutputMessage(Operation operation, JavaMethodImpl method) { |
|
1026 ParamType paramType = operation.output(); |
|
1027 extension.addOperationOutputExtension(paramType, method); |
|
1028 // paramType.message(new QName(model.getTargetNamespace(), method.getOperation().getLocalName()+RESPONSE)); |
|
1029 paramType.message(new QName(model.getTargetNamespace(), method.getResponseMessageName())); |
|
1030 } |
|
1031 |
|
1032 /** |
|
1033 * Creates the {@link Result} object used by JAXB to generate a schema for the |
|
1034 * namesapceUri namespace. |
|
1035 * @param namespaceUri The namespace for the schema being generated |
|
1036 * @param suggestedFileName the JAXB suggested file name for the schema file |
|
1037 * @return the {@link Result} for JAXB to generate the schema into |
|
1038 * @throws java.io.IOException thrown if on IO error occurs |
|
1039 */ |
|
1040 public Result createOutputFile(String namespaceUri, String suggestedFileName) throws IOException { |
|
1041 Result result; |
|
1042 if (namespaceUri == null) { |
|
1043 return null; |
|
1044 } |
|
1045 |
|
1046 Holder<String> fileNameHolder = new Holder<String>(); |
|
1047 fileNameHolder.value = schemaPrefix + suggestedFileName; |
|
1048 result = wsdlResolver.getSchemaOutput(namespaceUri, fileNameHolder); |
|
1049 // System.out.println("schema file: "+fileNameHolder.value); |
|
1050 // System.out.println("result: "+result); |
|
1051 String schemaLoc; |
|
1052 if (result == null) |
|
1053 schemaLoc = fileNameHolder.value; |
|
1054 else |
|
1055 schemaLoc = relativize(result.getSystemId(), wsdlLocation); |
|
1056 boolean isEmptyNs = namespaceUri.trim().equals(""); |
|
1057 if (!isEmptyNs) { |
|
1058 com.sun.xml.internal.ws.wsdl.writer.document.xsd.Import _import = types.schema()._import(); |
|
1059 _import.namespace(namespaceUri); |
|
1060 _import.schemaLocation(schemaLoc); |
|
1061 } |
|
1062 return result; |
|
1063 } |
|
1064 |
|
1065 private Result createInlineSchema(String namespaceUri, String suggestedFileName) throws IOException { |
|
1066 Result result; |
|
1067 if (namespaceUri.equals("")) { |
|
1068 return null; |
|
1069 } |
|
1070 |
|
1071 // Holder<String> fileNameHolder = new Holder<String>(); |
|
1072 // fileNameHolder.value = schemaPrefix+suggestedFileName; |
|
1073 // result = wsdlResolver.getSchemaOutput(namespaceUri, fileNameHolder); |
|
1074 // if (result == null) { |
|
1075 // // JAXB doesn't have to generate it, a schema is already available |
|
1076 // com.sun.xml.internal.ws.wsdl.writer.document.xsd.Import _import = types.schema()._import().namespace(namespaceUri); |
|
1077 // _import.schemaLocation(fileNameHolder.value); |
|
1078 // } else { |
|
1079 // Let JAXB write the schema directly into wsdl's TypedXmlWriter |
|
1080 result = new TXWResult(types); |
|
1081 result.setSystemId(""); |
|
1082 // } |
|
1083 return result; |
|
1084 } |
|
1085 |
|
1086 /** |
|
1087 * Relativizes a URI by using another URI (base URI.) |
|
1088 * |
|
1089 * <p> |
|
1090 * For example, {@code relative("http://www.sun.com/abc/def","http://www.sun.com/pqr/stu") => "../abc/def"} |
|
1091 * |
|
1092 * <p> |
|
1093 * This method only works on hierarchical URI's, not opaque URI's (refer to the |
|
1094 * <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/URI.html">java.net.URI</a> |
|
1095 * javadoc for complete definitions of these terms. |
|
1096 * |
|
1097 * <p> |
|
1098 * This method will not normalize the relative URI. |
|
1099 * @param uri the URI to relativize |
|
1100 * |
|
1101 * |
|
1102 * @param baseUri the base URI to use for the relativization |
|
1103 * @return the relative URI or the original URI if a relative one could not be computed |
|
1104 */ |
|
1105 protected static String relativize(String uri, String baseUri) { |
|
1106 try { |
|
1107 assert uri != null; |
|
1108 |
|
1109 if (baseUri == null) return uri; |
|
1110 |
|
1111 URI theUri = new URI(escapeURI(uri)); |
|
1112 URI theBaseUri = new URI(escapeURI(baseUri)); |
|
1113 |
|
1114 if (theUri.isOpaque() || theBaseUri.isOpaque()) |
|
1115 return uri; |
|
1116 |
|
1117 if (!equalsIgnoreCase(theUri.getScheme(), theBaseUri.getScheme()) || |
|
1118 !equal(theUri.getAuthority(), theBaseUri.getAuthority())) |
|
1119 return uri; |
|
1120 |
|
1121 String uriPath = theUri.getPath(); |
|
1122 String basePath = theBaseUri.getPath(); |
|
1123 |
|
1124 // normalize base path |
|
1125 if (!basePath.endsWith("/")) { |
|
1126 basePath = normalizeUriPath(basePath); |
|
1127 } |
|
1128 |
|
1129 if (uriPath.equals(basePath)) |
|
1130 return "."; |
|
1131 |
|
1132 String relPath = calculateRelativePath(uriPath, basePath); |
|
1133 |
|
1134 if (relPath == null) |
|
1135 return uri; // recursion found no commonality in the two uris at all |
|
1136 StringBuffer relUri = new StringBuffer(); |
|
1137 relUri.append(relPath); |
|
1138 if (theUri.getQuery() != null) |
|
1139 relUri.append('?').append(theUri.getQuery()); |
|
1140 if (theUri.getFragment() != null) |
|
1141 relUri.append('#').append(theUri.getFragment()); |
|
1142 |
|
1143 return relUri.toString(); |
|
1144 } catch (URISyntaxException e) { |
|
1145 throw new InternalError("Error escaping one of these uris:\n\t" + uri + "\n\t" + baseUri); |
|
1146 } |
|
1147 } |
|
1148 |
|
1149 private static String calculateRelativePath(String uri, String base) { |
|
1150 if (base == null) { |
|
1151 return null; |
|
1152 } |
|
1153 if (uri.startsWith(base)) { |
|
1154 return uri.substring(base.length()); |
|
1155 } else { |
|
1156 return "../" + calculateRelativePath(uri, getParentUriPath(base)); |
|
1157 } |
|
1158 } |
|
1159 |
|
1160 |
|
1161 /** |
|
1162 * Implements the SchemaOutputResolver used by JAXB to |
|
1163 */ |
|
1164 protected class JAXWSOutputSchemaResolver extends SchemaOutputResolver { |
|
1165 ArrayList<DOMResult> nonGlassfishSchemas = null; |
|
1166 |
|
1167 /** |
|
1168 * Creates the {@link Result} object used by JAXB to generate a schema for the |
|
1169 * namesapceUri namespace. |
|
1170 * @param namespaceUri The namespace for the schema being generated |
|
1171 * @param suggestedFileName the JAXB suggested file name for the schema file |
|
1172 * @return the {@link Result} for JAXB to generate the schema into |
|
1173 * @throws java.io.IOException thrown if on IO error occurs |
|
1174 */ |
|
1175 public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException { |
|
1176 return inlineSchemas |
|
1177 ? ((nonGlassfishSchemas != null) ? nonGlassfishSchemaResult(namespaceUri, suggestedFileName) : createInlineSchema(namespaceUri, suggestedFileName)) |
|
1178 // ? createInlineSchema(namespaceUri, suggestedFileName) |
|
1179 : createOutputFile(namespaceUri, suggestedFileName); |
|
1180 } |
|
1181 |
|
1182 private Result nonGlassfishSchemaResult(String namespaceUri, String suggestedFileName) throws IOException { |
|
1183 DOMResult result = new DOMResult(); |
|
1184 result.setSystemId(""); |
|
1185 nonGlassfishSchemas.add(result); |
|
1186 return result; |
|
1187 } |
|
1188 } |
|
1189 |
|
1190 private void register(WSDLGeneratorExtension h) { |
|
1191 extensionHandlers.add(h); |
|
1192 } |
|
1193 } |