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