1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/jaxws_classes/com/sun/xml/internal/ws/wsdl/writer/WSDLGenerator.java Wed Apr 27 01:27:09 2016 +0800 1.3 @@ -0,0 +1,1282 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package com.sun.xml.internal.ws.wsdl.writer; 1.30 + 1.31 + 1.32 +import static com.sun.xml.internal.bind.v2.schemagen.Util.*; 1.33 + 1.34 +import com.oracle.webservices.internal.api.databinding.WSDLResolver; 1.35 + 1.36 +import com.sun.xml.internal.txw2.TXW; 1.37 +import com.sun.xml.internal.txw2.TypedXmlWriter; 1.38 +import com.sun.xml.internal.txw2.output.ResultFactory; 1.39 +import com.sun.xml.internal.txw2.output.XmlSerializer; 1.40 +import com.sun.xml.internal.txw2.output.TXWResult; 1.41 +import com.sun.xml.internal.ws.api.SOAPVersion; 1.42 +import com.sun.xml.internal.ws.api.WSBinding; 1.43 +import com.sun.xml.internal.ws.api.model.JavaMethod; 1.44 +import com.sun.xml.internal.ws.api.model.MEP; 1.45 +import com.sun.xml.internal.ws.api.model.ParameterBinding; 1.46 +import com.sun.xml.internal.ws.api.model.SEIModel; 1.47 +import com.sun.xml.internal.ws.api.model.soap.SOAPBinding; 1.48 +import com.sun.xml.internal.ws.api.server.Container; 1.49 +import com.sun.xml.internal.ws.api.wsdl.writer.WSDLGeneratorExtension; 1.50 +import com.sun.xml.internal.ws.api.wsdl.writer.WSDLGenExtnContext; 1.51 +import com.sun.xml.internal.ws.model.AbstractSEIModelImpl; 1.52 +import com.sun.xml.internal.ws.model.CheckedExceptionImpl; 1.53 +import com.sun.xml.internal.ws.model.JavaMethodImpl; 1.54 +import com.sun.xml.internal.ws.model.ParameterImpl; 1.55 +import com.sun.xml.internal.ws.model.WrapperParameter; 1.56 +import com.sun.xml.internal.ws.util.xml.XmlUtil; 1.57 +import com.sun.xml.internal.ws.wsdl.parser.SOAPConstants; 1.58 +import com.sun.xml.internal.ws.wsdl.parser.WSDLConstants; 1.59 +import com.sun.xml.internal.ws.wsdl.writer.document.Binding; 1.60 +import com.sun.xml.internal.ws.wsdl.writer.document.BindingOperationType; 1.61 +import com.sun.xml.internal.ws.wsdl.writer.document.Definitions; 1.62 +import com.sun.xml.internal.ws.wsdl.writer.document.Fault; 1.63 +import com.sun.xml.internal.ws.wsdl.writer.document.FaultType; 1.64 +import com.sun.xml.internal.ws.wsdl.writer.document.Import; 1.65 +import com.sun.xml.internal.ws.wsdl.writer.document.Message; 1.66 +import com.sun.xml.internal.ws.wsdl.writer.document.Operation; 1.67 +import com.sun.xml.internal.ws.wsdl.writer.document.ParamType; 1.68 +import com.sun.xml.internal.ws.wsdl.writer.document.Port; 1.69 +import com.sun.xml.internal.ws.wsdl.writer.document.PortType; 1.70 +import com.sun.xml.internal.ws.wsdl.writer.document.Service; 1.71 +import com.sun.xml.internal.ws.wsdl.writer.document.Types; 1.72 +import com.sun.xml.internal.ws.wsdl.writer.document.soap.Body; 1.73 +import com.sun.xml.internal.ws.wsdl.writer.document.soap.BodyType; 1.74 +import com.sun.xml.internal.ws.wsdl.writer.document.soap.Header; 1.75 +import com.sun.xml.internal.ws.wsdl.writer.document.soap.SOAPAddress; 1.76 +import com.sun.xml.internal.ws.wsdl.writer.document.soap.SOAPFault; 1.77 +import com.sun.xml.internal.ws.wsdl.writer.document.xsd.Schema; 1.78 +import com.sun.xml.internal.ws.spi.db.BindingContext; 1.79 +import com.sun.xml.internal.ws.spi.db.BindingHelper; 1.80 +import com.sun.xml.internal.ws.spi.db.TypeInfo; 1.81 +import com.sun.xml.internal.ws.spi.db.WrapperComposite; 1.82 +import com.sun.xml.internal.ws.util.RuntimeVersion; 1.83 +import com.sun.xml.internal.ws.policy.jaxws.PolicyWSDLGeneratorExtension; 1.84 +import com.sun.xml.internal.ws.encoding.soap.streaming.SOAPNamespaceConstants; 1.85 +import com.sun.xml.internal.bind.v2.schemagen.xmlschema.Element; 1.86 +import com.sun.xml.internal.bind.v2.schemagen.xmlschema.ComplexType; 1.87 +import com.sun.xml.internal.bind.v2.schemagen.xmlschema.ExplicitGroup; 1.88 +import com.sun.xml.internal.bind.v2.schemagen.xmlschema.LocalElement; 1.89 + 1.90 +import javax.jws.soap.SOAPBinding.Style; 1.91 +import javax.jws.soap.SOAPBinding.Use; 1.92 +import javax.xml.bind.SchemaOutputResolver; 1.93 +import javax.xml.namespace.QName; 1.94 +import javax.xml.transform.Result; 1.95 +import javax.xml.transform.Transformer; 1.96 +import javax.xml.transform.TransformerConfigurationException; 1.97 +import javax.xml.transform.TransformerException; 1.98 +import javax.xml.transform.TransformerFactory; 1.99 +import javax.xml.transform.dom.DOMResult; 1.100 +import javax.xml.transform.dom.DOMSource; 1.101 +import javax.xml.transform.sax.SAXResult; 1.102 +import javax.xml.ws.Holder; 1.103 +import javax.xml.ws.WebServiceException; 1.104 + 1.105 +import org.w3c.dom.Document; 1.106 + 1.107 +import java.io.IOException; 1.108 +import java.net.URI; 1.109 +import java.net.URISyntaxException; 1.110 +import java.util.ArrayList; 1.111 +import java.util.HashMap; 1.112 +import java.util.HashSet; 1.113 +import java.util.Iterator; 1.114 +import java.util.List; 1.115 +import java.util.Set; 1.116 + 1.117 + 1.118 +/** 1.119 + * Class used to generate WSDLs from a {@link SEIModel}. 1.120 + * 1.121 + * @author WS Development Team 1.122 + */ 1.123 +public class WSDLGenerator { 1.124 + private JAXWSOutputSchemaResolver resolver; 1.125 + private WSDLResolver wsdlResolver = null; 1.126 + private AbstractSEIModelImpl model; 1.127 + private Definitions serviceDefinitions; 1.128 + private Definitions portDefinitions; 1.129 + private Types types; 1.130 + /** 1.131 + * Constant String for ".wsdl" 1.132 + */ 1.133 + private static final String DOT_WSDL = ".wsdl"; 1.134 + /** 1.135 + * Constant String appended to response message names 1.136 + */ 1.137 + private static final String RESPONSE = "Response"; 1.138 + /** 1.139 + * constant String used for part name for wrapped request messages 1.140 + */ 1.141 + private static final String PARAMETERS = "parameters"; 1.142 + /** 1.143 + * the part name for unwrappable response messages 1.144 + */ 1.145 + private static final String RESULT = "parameters"; 1.146 + /** 1.147 + * the part name for response messages that are not unwrappable 1.148 + */ 1.149 + private static final String UNWRAPPABLE_RESULT = "result"; 1.150 + /** 1.151 + * The WSDL namespace 1.152 + */ 1.153 + private static final String WSDL_NAMESPACE = WSDLConstants.NS_WSDL; 1.154 + 1.155 + /** 1.156 + * the XSD namespace 1.157 + */ 1.158 + private static final String XSD_NAMESPACE = SOAPNamespaceConstants.XSD; 1.159 + /** 1.160 + * the namespace prefix to use for the XSD namespace 1.161 + */ 1.162 + private static final String XSD_PREFIX = "xsd"; 1.163 + /** 1.164 + * The SOAP 1.1 namespace 1.165 + */ 1.166 + private static final String SOAP11_NAMESPACE = SOAPConstants.NS_WSDL_SOAP; 1.167 + /** 1.168 + * The SOAP 1.2 namespace 1.169 + */ 1.170 + private static final String SOAP12_NAMESPACE = SOAPConstants.NS_WSDL_SOAP12; 1.171 + /** 1.172 + * The namespace prefix to use for the SOAP 1.1 namespace 1.173 + */ 1.174 + private static final String SOAP_PREFIX = "soap"; 1.175 + /** 1.176 + * The namespace prefix to use for the SOAP 1.2 namespace 1.177 + */ 1.178 + private static final String SOAP12_PREFIX = "soap12"; 1.179 + /** 1.180 + * The namespace prefix to use for the targetNamespace 1.181 + */ 1.182 + private static final String TNS_PREFIX = "tns"; 1.183 + 1.184 + /** 1.185 + * Constant String "document" used to specify <code>document</code> style 1.186 + * soapBindings 1.187 + */ 1.188 + private static final String DOCUMENT = "document"; 1.189 + /** 1.190 + * Constant String "rpc" used to specify <code>rpc</code> style 1.191 + * soapBindings 1.192 + */ 1.193 + private static final String RPC = "rpc"; 1.194 + /** 1.195 + * Constant String "literal" used to create <code>literal</code> use binddings 1.196 + */ 1.197 + private static final String LITERAL = "literal"; 1.198 + /** 1.199 + * Constant String to flag the URL to replace at runtime for the endpoint 1.200 + */ 1.201 + private static final String REPLACE_WITH_ACTUAL_URL = "REPLACE_WITH_ACTUAL_URL"; 1.202 + private Set<QName> processedExceptions = new HashSet<QName>(); 1.203 + private WSBinding binding; 1.204 + private String wsdlLocation; 1.205 + private String portWSDLID; 1.206 + private String schemaPrefix; 1.207 + private WSDLGeneratorExtension extension; 1.208 + List<WSDLGeneratorExtension> extensionHandlers; 1.209 + 1.210 + private String endpointAddress = REPLACE_WITH_ACTUAL_URL; 1.211 + private Container container; 1.212 + private final Class implType; 1.213 + 1.214 + private boolean inlineSchemas; // TODO 1.215 + private final boolean disableXmlSecurity; 1.216 + 1.217 + /** 1.218 + * Creates the WSDLGenerator 1.219 + * @param model The {@link AbstractSEIModelImpl} used to generate the WSDL 1.220 + * @param wsdlResolver The {@link WSDLResolver} to use resovle names while generating the WSDL 1.221 + * @param binding specifies which {@link javax.xml.ws.BindingType} to generate 1.222 + * @param extensions an array {@link WSDLGeneratorExtension} that will 1.223 + * be invoked to generate WSDL extensions 1.224 + */ 1.225 + public WSDLGenerator(AbstractSEIModelImpl model, WSDLResolver wsdlResolver, WSBinding binding, Container container, 1.226 + Class implType, boolean inlineSchemas, WSDLGeneratorExtension... extensions) { 1.227 + this(model, wsdlResolver, binding, container, implType, inlineSchemas, false, extensions); 1.228 + } 1.229 + 1.230 + /** 1.231 + * Creates the WSDLGenerator 1.232 + * @param model The {@link AbstractSEIModelImpl} used to generate the WSDL 1.233 + * @param wsdlResolver The {@link WSDLResolver} to use resovle names while generating the WSDL 1.234 + * @param binding specifies which {@link javax.xml.ws.BindingType} to generate 1.235 + * @param disableXmlSecurity specifies whether to disable the secure xml processing feature 1.236 + * @param extensions an array {@link WSDLGeneratorExtension} that will 1.237 + * be invoked to generate WSDL extensions 1.238 + */ 1.239 + public WSDLGenerator(AbstractSEIModelImpl model, WSDLResolver wsdlResolver, WSBinding binding, Container container, 1.240 + Class implType, boolean inlineSchemas, boolean disableXmlSecurity, 1.241 + WSDLGeneratorExtension... extensions) { 1.242 + 1.243 + this.model = model; 1.244 + resolver = new JAXWSOutputSchemaResolver(); 1.245 + this.wsdlResolver = wsdlResolver; 1.246 + this.binding = binding; 1.247 + this.container = container; 1.248 + this.implType = implType; 1.249 + extensionHandlers = new ArrayList<WSDLGeneratorExtension>(); 1.250 + this.inlineSchemas = inlineSchemas; 1.251 + this.disableXmlSecurity = disableXmlSecurity; 1.252 + 1.253 + // register handlers for default extensions 1.254 + register(new W3CAddressingWSDLGeneratorExtension()); 1.255 + register(new W3CAddressingMetadataWSDLGeneratorExtension()); 1.256 + register(new PolicyWSDLGeneratorExtension()); 1.257 + 1.258 + if (container != null) { // on server 1.259 + WSDLGeneratorExtension[] wsdlGeneratorExtensions = container.getSPI(WSDLGeneratorExtension[].class); 1.260 + if (wsdlGeneratorExtensions != null) { 1.261 + for (WSDLGeneratorExtension wsdlGeneratorExtension : wsdlGeneratorExtensions) { 1.262 + register(wsdlGeneratorExtension); 1.263 + } 1.264 + } 1.265 + } 1.266 + 1.267 + for (WSDLGeneratorExtension w : extensions) 1.268 + register(w); 1.269 + 1.270 + this.extension = new WSDLGeneratorExtensionFacade(extensionHandlers.toArray(new WSDLGeneratorExtension[0])); 1.271 + } 1.272 + 1.273 + /** 1.274 + * Sets the endpoint address string to be written. 1.275 + * Defaults to {@link #REPLACE_WITH_ACTUAL_URL}. 1.276 + * 1.277 + * @param address wsdl:port/soap:address/[@location] value 1.278 + */ 1.279 + public void setEndpointAddress(String address) { 1.280 + this.endpointAddress = address; 1.281 + } 1.282 + 1.283 + protected String mangleName(String name) { 1.284 + return BindingHelper.mangleNameToClassName(name); 1.285 + } 1.286 + 1.287 + /** 1.288 + * Performes the actual WSDL generation 1.289 + */ 1.290 + public void doGeneration() { 1.291 + XmlSerializer serviceWriter; 1.292 + XmlSerializer portWriter = null; 1.293 + String fileName = mangleName(model.getServiceQName().getLocalPart()); 1.294 + Result result = wsdlResolver.getWSDL(fileName + DOT_WSDL); 1.295 + wsdlLocation = result.getSystemId(); 1.296 + serviceWriter = new CommentFilter(ResultFactory.createSerializer(result)); 1.297 + if (model.getServiceQName().getNamespaceURI().equals(model.getTargetNamespace())) { 1.298 + portWriter = serviceWriter; 1.299 + schemaPrefix = fileName + "_"; 1.300 + } else { 1.301 + String wsdlName = mangleName(model.getPortTypeName().getLocalPart()); 1.302 + if (wsdlName.equals(fileName)) 1.303 + wsdlName += "PortType"; 1.304 + Holder<String> absWSDLName = new Holder<String>(); 1.305 + absWSDLName.value = wsdlName + DOT_WSDL; 1.306 + result = wsdlResolver.getAbstractWSDL(absWSDLName); 1.307 + 1.308 + if (result != null) { 1.309 + portWSDLID = result.getSystemId(); 1.310 + if (portWSDLID.equals(wsdlLocation)) { 1.311 + portWriter = serviceWriter; 1.312 + } else { 1.313 + portWriter = new CommentFilter(ResultFactory.createSerializer(result)); 1.314 + } 1.315 + } else { 1.316 + portWSDLID = absWSDLName.value; 1.317 + } 1.318 + schemaPrefix = new java.io.File(portWSDLID).getName(); 1.319 + int idx = schemaPrefix.lastIndexOf('.'); 1.320 + if (idx > 0) 1.321 + schemaPrefix = schemaPrefix.substring(0, idx); 1.322 + schemaPrefix = mangleName(schemaPrefix) + "_"; 1.323 + } 1.324 + generateDocument(serviceWriter, portWriter); 1.325 + } 1.326 + 1.327 + /** 1.328 + * Writing directly to XmlSerializer is a problem, since it doesn't suppress 1.329 + * xml declaration. Creating filter so that comment is written before TXW writes 1.330 + * anything in the WSDL. 1.331 + */ 1.332 + private static class CommentFilter implements XmlSerializer { 1.333 + final XmlSerializer serializer; 1.334 + private static final String VERSION_COMMENT = 1.335 + " Generated by JAX-WS RI (http://jax-ws.java.net). RI's version is " + RuntimeVersion.VERSION + ". "; 1.336 + 1.337 + CommentFilter(XmlSerializer serializer) { 1.338 + this.serializer = serializer; 1.339 + } 1.340 + 1.341 + @Override 1.342 + public void startDocument() { 1.343 + serializer.startDocument(); 1.344 + comment(new StringBuilder(VERSION_COMMENT)); 1.345 + text(new StringBuilder("\n")); 1.346 + } 1.347 + 1.348 + @Override 1.349 + public void beginStartTag(String uri, String localName, String prefix) { 1.350 + serializer.beginStartTag(uri, localName, prefix); 1.351 + } 1.352 + 1.353 + @Override 1.354 + public void writeAttribute(String uri, String localName, String prefix, StringBuilder value) { 1.355 + serializer.writeAttribute(uri, localName, prefix, value); 1.356 + } 1.357 + 1.358 + @Override 1.359 + public void writeXmlns(String prefix, String uri) { 1.360 + serializer.writeXmlns(prefix, uri); 1.361 + } 1.362 + 1.363 + @Override 1.364 + public void endStartTag(String uri, String localName, String prefix) { 1.365 + serializer.endStartTag(uri, localName, prefix); 1.366 + } 1.367 + 1.368 + @Override 1.369 + public void endTag() { 1.370 + serializer.endTag(); 1.371 + } 1.372 + 1.373 + @Override 1.374 + public void text(StringBuilder text) { 1.375 + serializer.text(text); 1.376 + } 1.377 + 1.378 + @Override 1.379 + public void cdata(StringBuilder text) { 1.380 + serializer.cdata(text); 1.381 + } 1.382 + 1.383 + @Override 1.384 + public void comment(StringBuilder comment) { 1.385 + serializer.comment(comment); 1.386 + } 1.387 + 1.388 + @Override 1.389 + public void endDocument() { 1.390 + serializer.endDocument(); 1.391 + } 1.392 + 1.393 + @Override 1.394 + public void flush() { 1.395 + serializer.flush(); 1.396 + } 1.397 + 1.398 + } 1.399 + 1.400 + private void generateDocument(XmlSerializer serviceStream, XmlSerializer portStream) { 1.401 + serviceDefinitions = TXW.create(Definitions.class, serviceStream); 1.402 + serviceDefinitions._namespace(WSDL_NAMESPACE, "");//WSDL_PREFIX); 1.403 + serviceDefinitions._namespace(XSD_NAMESPACE, XSD_PREFIX); 1.404 + serviceDefinitions.targetNamespace(model.getServiceQName().getNamespaceURI()); 1.405 + serviceDefinitions._namespace(model.getServiceQName().getNamespaceURI(), TNS_PREFIX); 1.406 + if (binding.getSOAPVersion() == SOAPVersion.SOAP_12) 1.407 + serviceDefinitions._namespace(SOAP12_NAMESPACE, SOAP12_PREFIX); 1.408 + else 1.409 + serviceDefinitions._namespace(SOAP11_NAMESPACE, SOAP_PREFIX); 1.410 + serviceDefinitions.name(model.getServiceQName().getLocalPart()); 1.411 + WSDLGenExtnContext serviceCtx = new WSDLGenExtnContext(serviceDefinitions, model, binding, container, implType); 1.412 + extension.start(serviceCtx); 1.413 + if (serviceStream != portStream && portStream != null) { 1.414 + // generate an abstract and concrete wsdl 1.415 + portDefinitions = TXW.create(Definitions.class, portStream); 1.416 + portDefinitions._namespace(WSDL_NAMESPACE, "");//WSDL_PREFIX); 1.417 + portDefinitions._namespace(XSD_NAMESPACE, XSD_PREFIX); 1.418 + if (model.getTargetNamespace() != null) { 1.419 + portDefinitions.targetNamespace(model.getTargetNamespace()); 1.420 + portDefinitions._namespace(model.getTargetNamespace(), TNS_PREFIX); 1.421 + } 1.422 + 1.423 + String schemaLoc = relativize(portWSDLID, wsdlLocation); 1.424 + Import _import = serviceDefinitions._import().namespace(model.getTargetNamespace()); 1.425 + _import.location(schemaLoc); 1.426 + } else if (portStream != null) { 1.427 + // abstract and concrete are the same 1.428 + portDefinitions = serviceDefinitions; 1.429 + } else { 1.430 + // import a provided abstract wsdl 1.431 + String schemaLoc = relativize(portWSDLID, wsdlLocation); 1.432 + Import _import = serviceDefinitions._import().namespace(model.getTargetNamespace()); 1.433 + _import.location(schemaLoc); 1.434 + } 1.435 + extension.addDefinitionsExtension(serviceDefinitions); 1.436 + 1.437 + if (portDefinitions != null) { 1.438 + generateTypes(); 1.439 + generateMessages(); 1.440 + generatePortType(); 1.441 + } 1.442 + generateBinding(); 1.443 + generateService(); 1.444 + //Give a chance to WSDLGeneratorExtensions to write stuff before closing </wsdl:defintions> 1.445 + extension.end(serviceCtx); 1.446 + serviceDefinitions.commit(); 1.447 + if (portDefinitions != null && portDefinitions != serviceDefinitions) 1.448 + portDefinitions.commit(); 1.449 + } 1.450 + 1.451 + 1.452 + /** 1.453 + * Generates the types section of the WSDL 1.454 + */ 1.455 + protected void generateTypes() { 1.456 + types = portDefinitions.types(); 1.457 + if (model.getBindingContext() != null) { 1.458 + if (inlineSchemas && model.getBindingContext().getClass().getName().indexOf("glassfish") == -1) { 1.459 + resolver.nonGlassfishSchemas = new ArrayList<DOMResult>(); 1.460 + } 1.461 + try { 1.462 + model.getBindingContext().generateSchema(resolver); 1.463 + } catch (IOException e) { 1.464 + // TODO locallize and wrap this 1.465 + throw new WebServiceException(e.getMessage()); 1.466 + } 1.467 + } 1.468 + if (resolver.nonGlassfishSchemas != null) { 1.469 + TransformerFactory tf = XmlUtil.newTransformerFactory(!disableXmlSecurity); 1.470 + try { 1.471 + Transformer t = tf.newTransformer(); 1.472 + for (DOMResult xsd : resolver.nonGlassfishSchemas) { 1.473 + Document doc = (Document) xsd.getNode(); 1.474 + SAXResult sax = new SAXResult(new TXWContentHandler(types)); 1.475 + t.transform(new DOMSource(doc.getDocumentElement()), sax); 1.476 + } 1.477 + } catch (TransformerConfigurationException e) { 1.478 + throw new WebServiceException(e.getMessage(), e); 1.479 + } catch (TransformerException e) { 1.480 + throw new WebServiceException(e.getMessage(), e); 1.481 + } 1.482 + } 1.483 + generateWrappers(); 1.484 + } 1.485 + 1.486 + void generateWrappers() { 1.487 + List<WrapperParameter> wrappers = new ArrayList<WrapperParameter>(); 1.488 + for (JavaMethodImpl method : model.getJavaMethods()) { 1.489 + if(method.getBinding().isRpcLit()) continue; 1.490 + for (ParameterImpl p : method.getRequestParameters()) { 1.491 + if (p instanceof WrapperParameter) { 1.492 + if (WrapperComposite.class.equals((((WrapperParameter)p).getTypeInfo().type))) { 1.493 + wrappers.add((WrapperParameter)p); 1.494 + } 1.495 + } 1.496 + } 1.497 + for (ParameterImpl p : method.getResponseParameters()) { 1.498 + if (p instanceof WrapperParameter) { 1.499 + if (WrapperComposite.class.equals((((WrapperParameter)p).getTypeInfo().type))) { 1.500 + wrappers.add((WrapperParameter)p); 1.501 + } 1.502 + } 1.503 + } 1.504 + } 1.505 + if (wrappers.isEmpty()) return; 1.506 + HashMap<String, Schema> xsds = new HashMap<String, Schema>(); 1.507 + for(WrapperParameter wp : wrappers) { 1.508 + String tns = wp.getName().getNamespaceURI(); 1.509 + Schema xsd = xsds.get(tns); 1.510 + if (xsd == null) { 1.511 + xsd = types.schema(); 1.512 + xsd.targetNamespace(tns); 1.513 + xsds.put(tns, xsd); 1.514 + } 1.515 + Element e = xsd._element(Element.class); 1.516 + e._attribute("name", wp.getName().getLocalPart()); 1.517 + e.type(wp.getName()); 1.518 + ComplexType ct = xsd._element(ComplexType.class); 1.519 + ct._attribute("name", wp.getName().getLocalPart()); 1.520 + ExplicitGroup sq = ct.sequence(); 1.521 + for (ParameterImpl p : wp.getWrapperChildren() ) { 1.522 + if (p.getBinding().isBody()) { 1.523 + LocalElement le = sq.element(); 1.524 + le._attribute("name", p.getName().getLocalPart()); 1.525 + TypeInfo typeInfo = p.getItemType(); 1.526 + boolean repeatedElement = false; 1.527 + if (typeInfo == null) { 1.528 + typeInfo = p.getTypeInfo(); 1.529 + } else { 1.530 + repeatedElement = true; 1.531 + } 1.532 + QName type = model.getBindingContext().getTypeName(typeInfo); 1.533 + le.type(type); 1.534 + if (repeatedElement) { 1.535 + le.minOccurs(0); 1.536 + le.maxOccurs("unbounded"); 1.537 + } 1.538 + } 1.539 + } 1.540 + } 1.541 + } 1.542 + 1.543 + /** 1.544 + * Generates the WSDL messages 1.545 + */ 1.546 + protected void generateMessages() { 1.547 + for (JavaMethodImpl method : model.getJavaMethods()) { 1.548 + generateSOAPMessages(method, method.getBinding()); 1.549 + } 1.550 + } 1.551 + 1.552 + /** 1.553 + * Generates messages for a SOAPBinding 1.554 + * @param method The {@link JavaMethod} to generate messages for 1.555 + * @param binding The {@link com.sun.xml.internal.ws.api.model.soap.SOAPBinding} to add the generated messages to 1.556 + */ 1.557 + protected void generateSOAPMessages(JavaMethodImpl method, com.sun.xml.internal.ws.api.model.soap.SOAPBinding binding) { 1.558 + boolean isDoclit = binding.isDocLit(); 1.559 +// Message message = portDefinitions.message().name(method.getOperation().getName().getLocalPart()); 1.560 + Message message = portDefinitions.message().name(method.getRequestMessageName()); 1.561 + extension.addInputMessageExtension(message, method); 1.562 + com.sun.xml.internal.ws.wsdl.writer.document.Part part; 1.563 + BindingContext jaxbContext = model.getBindingContext(); 1.564 + boolean unwrappable = true; 1.565 + for (ParameterImpl param : method.getRequestParameters()) { 1.566 + if (isDoclit) { 1.567 + if (isHeaderParameter(param)) 1.568 + unwrappable = false; 1.569 + 1.570 + part = message.part().name(param.getPartName()); 1.571 + part.element(param.getName()); 1.572 + } else { 1.573 + if (param.isWrapperStyle()) { 1.574 + for (ParameterImpl childParam : ((WrapperParameter) param).getWrapperChildren()) { 1.575 + part = message.part().name(childParam.getPartName()); 1.576 + part.type(jaxbContext.getTypeName(childParam.getXMLBridge().getTypeInfo())); 1.577 + } 1.578 + } else { 1.579 + part = message.part().name(param.getPartName()); 1.580 + part.element(param.getName()); 1.581 + } 1.582 + } 1.583 + } 1.584 + if (method.getMEP() != MEP.ONE_WAY) { 1.585 + message = portDefinitions.message().name(method.getResponseMessageName()); 1.586 + extension.addOutputMessageExtension(message, method); 1.587 + 1.588 + for (ParameterImpl param : method.getResponseParameters()) { 1.589 + if (isDoclit) { 1.590 + part = message.part().name(param.getPartName()); 1.591 + part.element(param.getName()); 1.592 + 1.593 + } else { 1.594 + if (param.isWrapperStyle()) { 1.595 + for (ParameterImpl childParam : ((WrapperParameter) param).getWrapperChildren()) { 1.596 + part = message.part().name(childParam.getPartName()); 1.597 + part.type(jaxbContext.getTypeName(childParam.getXMLBridge().getTypeInfo())); 1.598 + } 1.599 + } else { 1.600 + part = message.part().name(param.getPartName()); 1.601 + part.element(param.getName()); 1.602 + } 1.603 + } 1.604 + } 1.605 + } 1.606 + for (CheckedExceptionImpl exception : method.getCheckedExceptions()) { 1.607 + QName tagName = exception.getDetailType().tagName; 1.608 + String messageName = exception.getMessageName(); 1.609 + QName messageQName = new QName(model.getTargetNamespace(), messageName); 1.610 + if (processedExceptions.contains(messageQName)) 1.611 + continue; 1.612 + message = portDefinitions.message().name(messageName); 1.613 + 1.614 + extension.addFaultMessageExtension(message, method, exception); 1.615 + part = message.part().name("fault");//tagName.getLocalPart()); 1.616 + part.element(tagName); 1.617 + processedExceptions.add(messageQName); 1.618 + } 1.619 + } 1.620 + 1.621 + /** 1.622 + * Generates the WSDL portType 1.623 + */ 1.624 + protected void generatePortType() { 1.625 + 1.626 + PortType portType = portDefinitions.portType().name(model.getPortTypeName().getLocalPart()); 1.627 + extension.addPortTypeExtension(portType); 1.628 + for (JavaMethodImpl method : model.getJavaMethods()) { 1.629 + Operation operation = portType.operation().name(method.getOperationName()); 1.630 + generateParameterOrder(operation, method); 1.631 + extension.addOperationExtension(operation, method); 1.632 + switch (method.getMEP()) { 1.633 + case REQUEST_RESPONSE: 1.634 + // input message 1.635 + generateInputMessage(operation, method); 1.636 + // output message 1.637 + generateOutputMessage(operation, method); 1.638 + break; 1.639 + case ONE_WAY: 1.640 + generateInputMessage(operation, method); 1.641 + break; 1.642 + default: 1.643 + break; 1.644 + } 1.645 + // faults 1.646 + for (CheckedExceptionImpl exception : method.getCheckedExceptions()) { 1.647 + QName messageName = new QName(model.getTargetNamespace(), exception.getMessageName()); 1.648 + FaultType paramType = operation.fault().message(messageName).name(exception.getMessageName()); 1.649 + extension.addOperationFaultExtension(paramType, method, exception); 1.650 + } 1.651 + } 1.652 + } 1.653 + 1.654 + /** 1.655 + * Determines if the <CODE>method</CODE> is wrapper style 1.656 + * @param method The {@link JavaMethod} to check if it is wrapper style 1.657 + * @return true if the method is wrapper style, otherwise, false. 1.658 + */ 1.659 + protected boolean isWrapperStyle(JavaMethodImpl method) { 1.660 + if (method.getRequestParameters().size() > 0) { 1.661 + ParameterImpl param = method.getRequestParameters().iterator().next(); 1.662 + return param.isWrapperStyle(); 1.663 + } 1.664 + return false; 1.665 + } 1.666 + 1.667 + /** 1.668 + * Determines if a {@link JavaMethod} is rpc/literal 1.669 + * @param method The method to check 1.670 + * @return true if method is rpc/literal, otherwise, false 1.671 + */ 1.672 + protected boolean isRpcLit(JavaMethodImpl method) { 1.673 + return method.getBinding().getStyle() == Style.RPC; 1.674 + } 1.675 + 1.676 + /** 1.677 + * Generates the parameterOrder for a PortType operation 1.678 + * @param operation The operation to generate the parameterOrder for 1.679 + * @param method The {@link JavaMethod} to generate the parameterOrder from 1.680 + */ 1.681 + protected void generateParameterOrder(Operation operation, JavaMethodImpl method) { 1.682 + if (method.getMEP() == MEP.ONE_WAY) 1.683 + return; 1.684 + if (isRpcLit(method)) 1.685 + generateRpcParameterOrder(operation, method); 1.686 + else 1.687 + generateDocumentParameterOrder(operation, method); 1.688 + } 1.689 + 1.690 + /** 1.691 + * Generates the parameterOrder for a PortType operation 1.692 + * @param operation the operation to generate the parameterOrder for 1.693 + * @param method the {@link JavaMethod} to generate the parameterOrder from 1.694 + */ 1.695 + protected void generateRpcParameterOrder(Operation operation, JavaMethodImpl method) { 1.696 + String partName; 1.697 + StringBuilder paramOrder = new StringBuilder(); 1.698 + Set<String> partNames = new HashSet<String>(); 1.699 + List<ParameterImpl> sortedParams = sortMethodParameters(method); 1.700 + int i = 0; 1.701 + for (ParameterImpl parameter : sortedParams) { 1.702 + if (parameter.getIndex() >= 0) { 1.703 + partName = parameter.getPartName(); 1.704 + if (!partNames.contains(partName)) { 1.705 + if (i++ > 0) 1.706 + paramOrder.append(' '); 1.707 + paramOrder.append(partName); 1.708 + partNames.add(partName); 1.709 + } 1.710 + } 1.711 + } 1.712 + if (i > 1) { 1.713 + operation.parameterOrder(paramOrder.toString()); 1.714 + } 1.715 + } 1.716 + 1.717 + 1.718 + /** 1.719 + * Generates the parameterOrder for a PortType operation 1.720 + * @param operation the operation to generate the parameterOrder for 1.721 + * @param method the {@link JavaMethod} to generate the parameterOrder from 1.722 + */ 1.723 + protected void generateDocumentParameterOrder(Operation operation, JavaMethodImpl method) { 1.724 + String partName; 1.725 + StringBuilder paramOrder = new StringBuilder(); 1.726 + Set<String> partNames = new HashSet<String>(); 1.727 + List<ParameterImpl> sortedParams = sortMethodParameters(method); 1.728 +// boolean isWrapperStyle = isWrapperStyle(method); 1.729 + int i = 0; 1.730 + for (ParameterImpl parameter : sortedParams) { 1.731 +// System.out.println("param: "+parameter.getIndex()+" name: "+parameter.getName().getLocalPart()); 1.732 + if (parameter.getIndex() < 0) 1.733 + continue; 1.734 + 1.735 + // This should be safe change. if it affects compatibility, 1.736 + // remove the following single statement and uncomment the code in block below. 1.737 + partName = parameter.getPartName(); 1.738 + /* 1.739 + if (isWrapperStyle && isBodyParameter(parameter)) { 1.740 + System.out.println("isWrapper and is body"); 1.741 + if (method.getRequestParameters().contains(parameter)) 1.742 + partName = PARAMETERS; 1.743 + else { 1.744 + //Rama: don't understand this logic "Response" below, 1.745 + 1.746 + // really make sure this is a wrapper style wsdl we are creating 1.747 + partName = RESPONSE; 1.748 + } 1.749 + } else { 1.750 + partName = parameter.getPartName(); 1.751 + }*/ 1.752 + 1.753 + if (!partNames.contains(partName)) { 1.754 + if (i++ > 0) 1.755 + paramOrder.append(' '); 1.756 + paramOrder.append(partName); 1.757 + partNames.add(partName); 1.758 + } 1.759 + } 1.760 + if (i > 1) { 1.761 + operation.parameterOrder(paramOrder.toString()); 1.762 + } 1.763 + } 1.764 + 1.765 + /** 1.766 + * Sorts the parameters for the method by their position 1.767 + * @param method the {@link JavaMethod} used to sort the parameters 1.768 + * @return the sorted {@link List} of parameters 1.769 + */ 1.770 + protected List<ParameterImpl> sortMethodParameters(JavaMethodImpl method) { 1.771 + Set<ParameterImpl> paramSet = new HashSet<ParameterImpl>(); 1.772 + List<ParameterImpl> sortedParams = new ArrayList<ParameterImpl>(); 1.773 + if (isRpcLit(method)) { 1.774 + for (ParameterImpl param : method.getRequestParameters()) { 1.775 + if (param instanceof WrapperParameter) { 1.776 + paramSet.addAll(((WrapperParameter) param).getWrapperChildren()); 1.777 + } else { 1.778 + paramSet.add(param); 1.779 + } 1.780 + } 1.781 + for (ParameterImpl param : method.getResponseParameters()) { 1.782 + if (param instanceof WrapperParameter) { 1.783 + paramSet.addAll(((WrapperParameter) param).getWrapperChildren()); 1.784 + } else { 1.785 + paramSet.add(param); 1.786 + } 1.787 + } 1.788 + } else { 1.789 + paramSet.addAll(method.getRequestParameters()); 1.790 + paramSet.addAll(method.getResponseParameters()); 1.791 + } 1.792 + Iterator<ParameterImpl> params = paramSet.iterator(); 1.793 + if (paramSet.isEmpty()) 1.794 + return sortedParams; 1.795 + ParameterImpl param = params.next(); 1.796 + sortedParams.add(param); 1.797 + ParameterImpl sortedParam; 1.798 + int pos; 1.799 + for (int i = 1; i < paramSet.size(); i++) { 1.800 + param = params.next(); 1.801 + for (pos = 0; pos < i; pos++) { 1.802 + sortedParam = sortedParams.get(pos); 1.803 + if (param.getIndex() == sortedParam.getIndex() && 1.804 + param instanceof WrapperParameter) 1.805 + break; 1.806 + if (param.getIndex() < sortedParam.getIndex()) { 1.807 + break; 1.808 + } 1.809 + } 1.810 + sortedParams.add(pos, param); 1.811 + } 1.812 + return sortedParams; 1.813 + } 1.814 + 1.815 + /** 1.816 + * Determines if a parameter is associated with the message Body 1.817 + * @param parameter the parameter to check 1.818 + * @return true if the parameter is a <code>body</code> parameter 1.819 + */ 1.820 + protected boolean isBodyParameter(ParameterImpl parameter) { 1.821 + ParameterBinding paramBinding = parameter.getBinding(); 1.822 + return paramBinding.isBody(); 1.823 + } 1.824 + 1.825 + protected boolean isHeaderParameter(ParameterImpl parameter) { 1.826 + ParameterBinding paramBinding = parameter.getBinding(); 1.827 + return paramBinding.isHeader(); 1.828 + } 1.829 + 1.830 + protected boolean isAttachmentParameter(ParameterImpl parameter) { 1.831 + ParameterBinding paramBinding = parameter.getBinding(); 1.832 + return paramBinding.isAttachment(); 1.833 + } 1.834 + 1.835 + 1.836 + /** 1.837 + * Generates the Binding section of the WSDL 1.838 + */ 1.839 + protected void generateBinding() { 1.840 + Binding newBinding = serviceDefinitions.binding().name(model.getBoundPortTypeName().getLocalPart()); 1.841 + extension.addBindingExtension(newBinding); 1.842 + newBinding.type(model.getPortTypeName()); 1.843 + boolean first = true; 1.844 + for (JavaMethodImpl method : model.getJavaMethods()) { 1.845 + if (first) { 1.846 + SOAPBinding sBinding = method.getBinding(); 1.847 + SOAPVersion soapVersion = sBinding.getSOAPVersion(); 1.848 + if (soapVersion == SOAPVersion.SOAP_12) { 1.849 + com.sun.xml.internal.ws.wsdl.writer.document.soap12.SOAPBinding soapBinding = newBinding.soap12Binding(); 1.850 + soapBinding.transport(this.binding.getBindingId().getTransport()); 1.851 + if (sBinding.getStyle().equals(Style.DOCUMENT)) 1.852 + soapBinding.style(DOCUMENT); 1.853 + else 1.854 + soapBinding.style(RPC); 1.855 + } else { 1.856 + com.sun.xml.internal.ws.wsdl.writer.document.soap.SOAPBinding soapBinding = newBinding.soapBinding(); 1.857 + soapBinding.transport(this.binding.getBindingId().getTransport()); 1.858 + if (sBinding.getStyle().equals(Style.DOCUMENT)) 1.859 + soapBinding.style(DOCUMENT); 1.860 + else 1.861 + soapBinding.style(RPC); 1.862 + } 1.863 + first = false; 1.864 + } 1.865 + if (this.binding.getBindingId().getSOAPVersion() == SOAPVersion.SOAP_12) 1.866 + generateSOAP12BindingOperation(method, newBinding); 1.867 + else 1.868 + generateBindingOperation(method, newBinding); 1.869 + } 1.870 + } 1.871 + 1.872 + protected void generateBindingOperation(JavaMethodImpl method, Binding binding) { 1.873 + BindingOperationType operation = binding.operation().name(method.getOperationName()); 1.874 + extension.addBindingOperationExtension(operation, method); 1.875 + String targetNamespace = model.getTargetNamespace(); 1.876 + QName requestMessage = new QName(targetNamespace, method.getOperationName()); 1.877 + List<ParameterImpl> bodyParams = new ArrayList<ParameterImpl>(); 1.878 + List<ParameterImpl> headerParams = new ArrayList<ParameterImpl>(); 1.879 + splitParameters(bodyParams, headerParams, method.getRequestParameters()); 1.880 + SOAPBinding soapBinding = method.getBinding(); 1.881 + operation.soapOperation().soapAction(soapBinding.getSOAPAction()); 1.882 + 1.883 + // input 1.884 + TypedXmlWriter input = operation.input(); 1.885 + extension.addBindingOperationInputExtension(input, method); 1.886 + BodyType body = input._element(Body.class); 1.887 + boolean isRpc = soapBinding.getStyle().equals(Style.RPC); 1.888 + if (soapBinding.getUse() == Use.LITERAL) { 1.889 + body.use(LITERAL); 1.890 + if (headerParams.size() > 0) { 1.891 + if (bodyParams.size() > 0) { 1.892 + ParameterImpl param = bodyParams.iterator().next(); 1.893 + if (isRpc) { 1.894 + StringBuilder parts = new StringBuilder(); 1.895 + int i = 0; 1.896 + for (ParameterImpl parameter : ((WrapperParameter) param).getWrapperChildren()) { 1.897 + if (i++ > 0) 1.898 + parts.append(' '); 1.899 + parts.append(parameter.getPartName()); 1.900 + } 1.901 + body.parts(parts.toString()); 1.902 + } else { 1.903 + body.parts(param.getPartName()); 1.904 + } 1.905 + } else { 1.906 + body.parts(""); 1.907 + } 1.908 + generateSOAPHeaders(input, headerParams, requestMessage); 1.909 + } 1.910 + if (isRpc) { 1.911 + body.namespace(method.getRequestParameters().iterator().next().getName().getNamespaceURI()); 1.912 + } 1.913 + } else { 1.914 + // TODO localize this 1.915 + throw new WebServiceException("encoded use is not supported"); 1.916 + } 1.917 + 1.918 + if (method.getMEP() != MEP.ONE_WAY) { 1.919 + // output 1.920 + bodyParams.clear(); 1.921 + headerParams.clear(); 1.922 + splitParameters(bodyParams, headerParams, method.getResponseParameters()); 1.923 + TypedXmlWriter output = operation.output(); 1.924 + extension.addBindingOperationOutputExtension(output, method); 1.925 + body = output._element(Body.class); 1.926 + body.use(LITERAL); 1.927 + if (headerParams.size() > 0) { 1.928 + StringBuilder parts = new StringBuilder(); 1.929 + if (bodyParams.size() > 0) { 1.930 + ParameterImpl param = bodyParams.iterator().hasNext() ? bodyParams.iterator().next() : null; 1.931 + if (param != null) { 1.932 + if (isRpc) { 1.933 + int i = 0; 1.934 + for (ParameterImpl parameter : ((WrapperParameter) param).getWrapperChildren()) { 1.935 + if (i++ > 0) { 1.936 + parts.append(" "); 1.937 + } 1.938 + parts.append(parameter.getPartName()); 1.939 + } 1.940 + } else { 1.941 + parts = new StringBuilder(param.getPartName()); 1.942 + } 1.943 + } 1.944 + } 1.945 + body.parts(parts.toString()); 1.946 + QName responseMessage = new QName(targetNamespace, method.getResponseMessageName()); 1.947 + generateSOAPHeaders(output, headerParams, responseMessage); 1.948 + } 1.949 + if (isRpc) { 1.950 + body.namespace(method.getRequestParameters().iterator().next().getName().getNamespaceURI()); 1.951 + } 1.952 + } 1.953 + for (CheckedExceptionImpl exception : method.getCheckedExceptions()) { 1.954 + Fault fault = operation.fault().name(exception.getMessageName()); 1.955 + extension.addBindingOperationFaultExtension(fault, method, exception); 1.956 + SOAPFault soapFault = fault._element(SOAPFault.class).name(exception.getMessageName()); 1.957 + soapFault.use(LITERAL); 1.958 + } 1.959 + } 1.960 + 1.961 + protected void generateSOAP12BindingOperation(JavaMethodImpl method, Binding binding) { 1.962 + BindingOperationType operation = binding.operation().name(method.getOperationName()); 1.963 + extension.addBindingOperationExtension(operation, method); 1.964 + String targetNamespace = model.getTargetNamespace(); 1.965 + QName requestMessage = new QName(targetNamespace, method.getOperationName()); 1.966 + ArrayList<ParameterImpl> bodyParams = new ArrayList<ParameterImpl>(); 1.967 + ArrayList<ParameterImpl> headerParams = new ArrayList<ParameterImpl>(); 1.968 + splitParameters(bodyParams, headerParams, method.getRequestParameters()); 1.969 + SOAPBinding soapBinding = method.getBinding(); 1.970 + 1.971 + String soapAction = soapBinding.getSOAPAction(); 1.972 + if (soapAction != null) { 1.973 + operation.soap12Operation().soapAction(soapAction); 1.974 + } 1.975 + 1.976 + // input 1.977 + TypedXmlWriter input = operation.input(); 1.978 + extension.addBindingOperationInputExtension(input, method); 1.979 + com.sun.xml.internal.ws.wsdl.writer.document.soap12.BodyType body = input._element(com.sun.xml.internal.ws.wsdl.writer.document.soap12.Body.class); 1.980 + boolean isRpc = soapBinding.getStyle().equals(Style.RPC); 1.981 + if (soapBinding.getUse().equals(Use.LITERAL)) { 1.982 + body.use(LITERAL); 1.983 + if (headerParams.size() > 0) { 1.984 + if (bodyParams.size() > 0) { 1.985 + ParameterImpl param = bodyParams.iterator().next(); 1.986 + if (isRpc) { 1.987 + StringBuilder parts = new StringBuilder(); 1.988 + int i = 0; 1.989 + for (ParameterImpl parameter : ((WrapperParameter) param).getWrapperChildren()) { 1.990 + if (i++ > 0) 1.991 + parts.append(' '); 1.992 + parts.append(parameter.getPartName()); 1.993 + } 1.994 + body.parts(parts.toString()); 1.995 + } else { 1.996 + body.parts(param.getPartName()); 1.997 + } 1.998 + } else { 1.999 + body.parts(""); 1.1000 + } 1.1001 + generateSOAP12Headers(input, headerParams, requestMessage); 1.1002 + } 1.1003 + if (isRpc) { 1.1004 + body.namespace(method.getRequestParameters().iterator().next().getName().getNamespaceURI()); 1.1005 + } 1.1006 + } else { 1.1007 + // TODO localize this 1.1008 + throw new WebServiceException("encoded use is not supported"); 1.1009 + } 1.1010 + 1.1011 + if (method.getMEP() != MEP.ONE_WAY) { 1.1012 + // output 1.1013 + bodyParams.clear(); 1.1014 + headerParams.clear(); 1.1015 + splitParameters(bodyParams, headerParams, method.getResponseParameters()); 1.1016 + TypedXmlWriter output = operation.output(); 1.1017 + extension.addBindingOperationOutputExtension(output, method); 1.1018 + body = output._element(com.sun.xml.internal.ws.wsdl.writer.document.soap12.Body.class); 1.1019 + body.use(LITERAL); 1.1020 + if (headerParams.size() > 0) { 1.1021 + if (bodyParams.size() > 0) { 1.1022 + ParameterImpl param = bodyParams.iterator().next(); 1.1023 + if (isRpc) { 1.1024 + StringBuilder parts = new StringBuilder(); 1.1025 + int i = 0; 1.1026 + for (ParameterImpl parameter : ((WrapperParameter) param).getWrapperChildren()) { 1.1027 + if (i++ > 0) { 1.1028 + parts.append(" "); 1.1029 + } 1.1030 + parts.append(parameter.getPartName()); 1.1031 + } 1.1032 + body.parts(parts.toString()); 1.1033 + } else { 1.1034 + body.parts(param.getPartName()); 1.1035 + } 1.1036 + } else { 1.1037 + body.parts(""); 1.1038 + } 1.1039 + QName responseMessage = new QName(targetNamespace, method.getResponseMessageName()); 1.1040 + generateSOAP12Headers(output, headerParams, responseMessage); 1.1041 + } 1.1042 + if (isRpc) { 1.1043 + body.namespace(method.getRequestParameters().iterator().next().getName().getNamespaceURI()); 1.1044 + } 1.1045 + } 1.1046 + for (CheckedExceptionImpl exception : method.getCheckedExceptions()) { 1.1047 + Fault fault = operation.fault().name(exception.getMessageName()); 1.1048 + extension.addBindingOperationFaultExtension(fault, method, exception); 1.1049 + 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()); 1.1050 + soapFault.use(LITERAL); 1.1051 + } 1.1052 + } 1.1053 + 1.1054 + protected void splitParameters(List<ParameterImpl> bodyParams, List<ParameterImpl> headerParams, List<ParameterImpl> params) { 1.1055 + for (ParameterImpl parameter : params) { 1.1056 + if (isBodyParameter(parameter)) { 1.1057 + bodyParams.add(parameter); 1.1058 + } else { 1.1059 + headerParams.add(parameter); 1.1060 + } 1.1061 + } 1.1062 + } 1.1063 + 1.1064 + protected void generateSOAPHeaders(TypedXmlWriter writer, List<ParameterImpl> parameters, QName message) { 1.1065 + 1.1066 + for (ParameterImpl headerParam : parameters) { 1.1067 + Header header = writer._element(Header.class); 1.1068 + header.message(message); 1.1069 + header.part(headerParam.getPartName()); 1.1070 + header.use(LITERAL); 1.1071 + } 1.1072 + } 1.1073 + 1.1074 + protected void generateSOAP12Headers(TypedXmlWriter writer, List<ParameterImpl> parameters, QName message) { 1.1075 + 1.1076 + for (ParameterImpl headerParam : parameters) { 1.1077 + com.sun.xml.internal.ws.wsdl.writer.document.soap12.Header header = writer._element(com.sun.xml.internal.ws.wsdl.writer.document.soap12.Header.class); 1.1078 + header.message(message); 1.1079 + 1.1080 + 1.1081 + header.part(headerParam.getPartName()); 1.1082 + header.use(LITERAL); 1.1083 + } 1.1084 + } 1.1085 + 1.1086 + /** 1.1087 + * Generates the Service section of the WSDL 1.1088 + */ 1.1089 + protected void generateService() { 1.1090 + QName portQName = model.getPortName(); 1.1091 + QName serviceQName = model.getServiceQName(); 1.1092 + Service service = serviceDefinitions.service().name(serviceQName.getLocalPart()); 1.1093 + extension.addServiceExtension(service); 1.1094 + Port port = service.port().name(portQName.getLocalPart()); 1.1095 + port.binding(model.getBoundPortTypeName()); 1.1096 + extension.addPortExtension(port); 1.1097 + if (model.getJavaMethods().isEmpty()) 1.1098 + return; 1.1099 + 1.1100 + if (this.binding.getBindingId().getSOAPVersion() == SOAPVersion.SOAP_12) { 1.1101 + com.sun.xml.internal.ws.wsdl.writer.document.soap12.SOAPAddress address = port._element(com.sun.xml.internal.ws.wsdl.writer.document.soap12.SOAPAddress.class); 1.1102 + address.location(endpointAddress); 1.1103 + } else { 1.1104 + SOAPAddress address = port._element(SOAPAddress.class); 1.1105 + address.location(endpointAddress); 1.1106 + } 1.1107 + } 1.1108 + 1.1109 + protected void generateInputMessage(Operation operation, JavaMethodImpl method) { 1.1110 + ParamType paramType = operation.input(); 1.1111 + extension.addOperationInputExtension(paramType, method); 1.1112 +// paramType.message(method.getOperation().getName()); 1.1113 + paramType.message(new QName(model.getTargetNamespace(), method.getRequestMessageName())); 1.1114 + } 1.1115 + 1.1116 + protected void generateOutputMessage(Operation operation, JavaMethodImpl method) { 1.1117 + ParamType paramType = operation.output(); 1.1118 + extension.addOperationOutputExtension(paramType, method); 1.1119 +// paramType.message(new QName(model.getTargetNamespace(), method.getOperation().getLocalName()+RESPONSE)); 1.1120 + paramType.message(new QName(model.getTargetNamespace(), method.getResponseMessageName())); 1.1121 + } 1.1122 + 1.1123 + /** 1.1124 + * Creates the {@link Result} object used by JAXB to generate a schema for the 1.1125 + * namesapceUri namespace. 1.1126 + * @param namespaceUri The namespace for the schema being generated 1.1127 + * @param suggestedFileName the JAXB suggested file name for the schema file 1.1128 + * @return the {@link Result} for JAXB to generate the schema into 1.1129 + * @throws java.io.IOException thrown if on IO error occurs 1.1130 + */ 1.1131 + public Result createOutputFile(String namespaceUri, String suggestedFileName) throws IOException { 1.1132 + Result result; 1.1133 + if (namespaceUri == null) { 1.1134 + return null; 1.1135 + } 1.1136 + 1.1137 + Holder<String> fileNameHolder = new Holder<String>(); 1.1138 + fileNameHolder.value = schemaPrefix + suggestedFileName; 1.1139 + result = wsdlResolver.getSchemaOutput(namespaceUri, fileNameHolder); 1.1140 +// System.out.println("schema file: "+fileNameHolder.value); 1.1141 +// System.out.println("result: "+result); 1.1142 + String schemaLoc; 1.1143 + if (result == null) 1.1144 + schemaLoc = fileNameHolder.value; 1.1145 + else 1.1146 + schemaLoc = relativize(result.getSystemId(), wsdlLocation); 1.1147 + boolean isEmptyNs = namespaceUri.trim().equals(""); 1.1148 + if (!isEmptyNs) { 1.1149 + com.sun.xml.internal.ws.wsdl.writer.document.xsd.Import _import = types.schema()._import(); 1.1150 + _import.namespace(namespaceUri); 1.1151 + _import.schemaLocation(schemaLoc); 1.1152 + } 1.1153 + return result; 1.1154 + } 1.1155 + 1.1156 + private Result createInlineSchema(String namespaceUri, String suggestedFileName) throws IOException { 1.1157 + Result result; 1.1158 + if (namespaceUri.equals("")) { 1.1159 + return null; 1.1160 + } 1.1161 + 1.1162 +// Holder<String> fileNameHolder = new Holder<String>(); 1.1163 +// fileNameHolder.value = schemaPrefix+suggestedFileName; 1.1164 +// result = wsdlResolver.getSchemaOutput(namespaceUri, fileNameHolder); 1.1165 +// if (result == null) { 1.1166 +// // JAXB doesn't have to generate it, a schema is already available 1.1167 +// com.sun.xml.internal.ws.wsdl.writer.document.xsd.Import _import = types.schema()._import().namespace(namespaceUri); 1.1168 +// _import.schemaLocation(fileNameHolder.value); 1.1169 +// } else { 1.1170 + // Let JAXB write the schema directly into wsdl's TypedXmlWriter 1.1171 + result = new TXWResult(types); 1.1172 + result.setSystemId(""); 1.1173 +// } 1.1174 + return result; 1.1175 + } 1.1176 + 1.1177 + /** 1.1178 + * Relativizes a URI by using another URI (base URI.) 1.1179 + * 1.1180 + * <p> 1.1181 + * For example, {@code relative("http://www.sun.com/abc/def","http://www.sun.com/pqr/stu") => "../abc/def"} 1.1182 + * 1.1183 + * <p> 1.1184 + * This method only works on hierarchical URI's, not opaque URI's (refer to the 1.1185 + * <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/URI.html">java.net.URI</a> 1.1186 + * javadoc for complete definitions of these terms. 1.1187 + * 1.1188 + * <p> 1.1189 + * This method will not normalize the relative URI. 1.1190 + * @param uri the URI to relativize 1.1191 + * 1.1192 + * 1.1193 + * @param baseUri the base URI to use for the relativization 1.1194 + * @return the relative URI or the original URI if a relative one could not be computed 1.1195 + */ 1.1196 + protected static String relativize(String uri, String baseUri) { 1.1197 + try { 1.1198 + assert uri != null; 1.1199 + 1.1200 + if (baseUri == null) return uri; 1.1201 + 1.1202 + URI theUri = new URI(escapeURI(uri)); 1.1203 + URI theBaseUri = new URI(escapeURI(baseUri)); 1.1204 + 1.1205 + if (theUri.isOpaque() || theBaseUri.isOpaque()) 1.1206 + return uri; 1.1207 + 1.1208 + if (!equalsIgnoreCase(theUri.getScheme(), theBaseUri.getScheme()) || 1.1209 + !equal(theUri.getAuthority(), theBaseUri.getAuthority())) 1.1210 + return uri; 1.1211 + 1.1212 + String uriPath = theUri.getPath(); 1.1213 + String basePath = theBaseUri.getPath(); 1.1214 + 1.1215 + // normalize base path 1.1216 + if (!basePath.endsWith("/")) { 1.1217 + basePath = normalizeUriPath(basePath); 1.1218 + } 1.1219 + 1.1220 + if (uriPath.equals(basePath)) 1.1221 + return "."; 1.1222 + 1.1223 + String relPath = calculateRelativePath(uriPath, basePath); 1.1224 + 1.1225 + if (relPath == null) 1.1226 + return uri; // recursion found no commonality in the two uris at all 1.1227 + StringBuilder relUri = new StringBuilder(); 1.1228 + relUri.append(relPath); 1.1229 + if (theUri.getQuery() != null) 1.1230 + relUri.append('?').append(theUri.getQuery()); 1.1231 + if (theUri.getFragment() != null) 1.1232 + relUri.append('#').append(theUri.getFragment()); 1.1233 + 1.1234 + return relUri.toString(); 1.1235 + } catch (URISyntaxException e) { 1.1236 + throw new InternalError("Error escaping one of these uris:\n\t" + uri + "\n\t" + baseUri); 1.1237 + } 1.1238 + } 1.1239 + 1.1240 + private static String calculateRelativePath(String uri, String base) { 1.1241 + if (base == null) { 1.1242 + return null; 1.1243 + } 1.1244 + if (uri.startsWith(base)) { 1.1245 + return uri.substring(base.length()); 1.1246 + } else { 1.1247 + return "../" + calculateRelativePath(uri, getParentUriPath(base)); 1.1248 + } 1.1249 + } 1.1250 + 1.1251 + 1.1252 + /** 1.1253 + * Implements the SchemaOutputResolver used by JAXB to 1.1254 + */ 1.1255 + protected class JAXWSOutputSchemaResolver extends SchemaOutputResolver { 1.1256 + ArrayList<DOMResult> nonGlassfishSchemas = null; 1.1257 + 1.1258 + /** 1.1259 + * Creates the {@link Result} object used by JAXB to generate a schema for the 1.1260 + * namesapceUri namespace. 1.1261 + * @param namespaceUri The namespace for the schema being generated 1.1262 + * @param suggestedFileName the JAXB suggested file name for the schema file 1.1263 + * @return the {@link Result} for JAXB to generate the schema into 1.1264 + * @throws java.io.IOException thrown if on IO error occurs 1.1265 + */ 1.1266 + @Override 1.1267 + public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException { 1.1268 + return inlineSchemas 1.1269 + ? ((nonGlassfishSchemas != null) ? nonGlassfishSchemaResult(namespaceUri, suggestedFileName) : createInlineSchema(namespaceUri, suggestedFileName)) 1.1270 +// ? createInlineSchema(namespaceUri, suggestedFileName) 1.1271 + : createOutputFile(namespaceUri, suggestedFileName); 1.1272 + } 1.1273 + 1.1274 + private Result nonGlassfishSchemaResult(String namespaceUri, String suggestedFileName) throws IOException { 1.1275 + DOMResult result = new DOMResult(); 1.1276 + result.setSystemId(""); 1.1277 + nonGlassfishSchemas.add(result); 1.1278 + return result; 1.1279 + } 1.1280 + } 1.1281 + 1.1282 + private void register(WSDLGeneratorExtension h) { 1.1283 + extensionHandlers.add(h); 1.1284 + } 1.1285 +}