src/share/jaxws_classes/com/sun/xml/internal/ws/wsdl/writer/WSDLGenerator.java

Fri, 04 Oct 2013 16:21:34 +0100

author
mkos
date
Fri, 04 Oct 2013 16:21:34 +0100
changeset 408
b0610cd08440
parent 397
b99d7e355d4b
child 637
9c07ef4934dd
permissions
-rw-r--r--

8025054: Update JAX-WS RI integration to 2.2.9-b130926.1035
Reviewed-by: chegar

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
mkos@408 212 private final boolean disableXmlSecurity;
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
mkos@408 232 * @param disableXmlSecurity 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,
mkos@408 237 Class implType, boolean inlineSchemas, boolean disableXmlSecurity,
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;
mkos@408 248 this.disableXmlSecurity = disableXmlSecurity;
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 =
mkos@397 332 " Generated by JAX-WS RI (http://jax-ws.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) {
mkos@408 466 TransformerFactory tf = XmlUtil.newTransformerFactory(!disableXmlSecurity);
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 }

mercurial