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

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 408
b0610cd08440
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

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

mercurial