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