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

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

mercurial