0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common Development
0008: * and Distribution License("CDDL") (collectively, the "License"). You
0009: * may not use this file except in compliance with the License. You can obtain
0010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
0011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
0012: * language governing permissions and limitations under the License.
0013: *
0014: * When distributing the software, include this License Header Notice in each
0015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
0016: * Sun designates this particular file as subject to the "Classpath" exception
0017: * as provided by Sun in the GPL Version 2 section of the License file that
0018: * accompanied this code. If applicable, add the following below the License
0019: * Header, with the fields enclosed by brackets [] replaced by your own
0020: * identifying information: "Portions Copyrighted [year]
0021: * [name of copyright owner]"
0022: *
0023: * Contributor(s):
0024: *
0025: * If you wish your version of this file to be governed by only the CDDL or
0026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
0027: * elects to include this software in this distribution under the [CDDL or GPL
0028: * Version 2] license." If you don't indicate a single choice of license, a
0029: * recipient has the option to distribute your version of this file under
0030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
0031: * its licensees as provided above. However, if you add GPL Version 2 code
0032: * and therefore, elected the GPL Version 2 license, then the option applies
0033: * only if the new code is made subject to such option by the copyright
0034: * holder.
0035: */
0036: package com.sun.xml.ws.wsdl.writer;
0037:
0038: import com.sun.xml.bind.api.JAXBRIContext;
0039: import static com.sun.xml.bind.v2.schemagen.Util.*;
0040: import com.sun.xml.txw2.TXW;
0041: import com.sun.xml.txw2.TypedXmlWriter;
0042: import com.sun.xml.txw2.output.ResultFactory;
0043: import com.sun.xml.txw2.output.XmlSerializer;
0044: import com.sun.xml.ws.api.SOAPVersion;
0045: import com.sun.xml.ws.api.WSBinding;
0046: import com.sun.xml.ws.api.model.JavaMethod;
0047: import com.sun.xml.ws.api.model.MEP;
0048: import com.sun.xml.ws.api.model.ParameterBinding;
0049: import com.sun.xml.ws.api.model.SEIModel;
0050: import com.sun.xml.ws.api.model.soap.SOAPBinding;
0051: import com.sun.xml.ws.api.server.Container;
0052: import com.sun.xml.ws.api.wsdl.writer.WSDLGeneratorExtension;
0053: import com.sun.xml.ws.api.wsdl.writer.WSDLGenExtnContext;
0054: import com.sun.xml.ws.encoding.soap.streaming.SOAP12NamespaceConstants;
0055: import com.sun.xml.ws.encoding.soap.streaming.SOAPNamespaceConstants;
0056: import com.sun.xml.ws.model.AbstractSEIModelImpl;
0057: import com.sun.xml.ws.model.CheckedExceptionImpl;
0058: import com.sun.xml.ws.model.JavaMethodImpl;
0059: import com.sun.xml.ws.model.ParameterImpl;
0060: import com.sun.xml.ws.model.WrapperParameter;
0061: import com.sun.xml.ws.wsdl.parser.SOAPConstants;
0062: import com.sun.xml.ws.wsdl.parser.WSDLConstants;
0063: import com.sun.xml.ws.wsdl.writer.document.Binding;
0064: import com.sun.xml.ws.wsdl.writer.document.BindingOperationType;
0065: import com.sun.xml.ws.wsdl.writer.document.Definitions;
0066: import com.sun.xml.ws.wsdl.writer.document.Fault;
0067: import com.sun.xml.ws.wsdl.writer.document.FaultType;
0068: import com.sun.xml.ws.wsdl.writer.document.Import;
0069: import com.sun.xml.ws.wsdl.writer.document.Message;
0070: import com.sun.xml.ws.wsdl.writer.document.Operation;
0071: import com.sun.xml.ws.wsdl.writer.document.ParamType;
0072: import com.sun.xml.ws.wsdl.writer.document.Port;
0073: import com.sun.xml.ws.wsdl.writer.document.PortType;
0074: import com.sun.xml.ws.wsdl.writer.document.Service;
0075: import com.sun.xml.ws.wsdl.writer.document.Types;
0076: import com.sun.xml.ws.wsdl.writer.document.soap.Body;
0077: import com.sun.xml.ws.wsdl.writer.document.soap.BodyType;
0078: import com.sun.xml.ws.wsdl.writer.document.soap.Header;
0079: import com.sun.xml.ws.wsdl.writer.document.soap.SOAPAddress;
0080: import com.sun.xml.ws.wsdl.writer.document.soap.SOAPFault;
0081: import com.sun.xml.ws.util.RuntimeVersion;
0082:
0083: import javax.jws.soap.SOAPBinding.Style;
0084: import javax.jws.soap.SOAPBinding.Use;
0085: import javax.xml.bind.SchemaOutputResolver;
0086: import javax.xml.namespace.QName;
0087: import javax.xml.transform.Result;
0088: import javax.xml.ws.Holder;
0089: import javax.xml.ws.WebServiceException;
0090: import java.io.IOException;
0091: import java.net.URI;
0092: import java.net.URISyntaxException;
0093: import java.util.ArrayList;
0094: import java.util.HashSet;
0095: import java.util.Iterator;
0096: import java.util.List;
0097: import java.util.Set;
0098:
0099: /**
0100: * Class used to generate WSDLs from a {@link SEIModel}.
0101: *
0102: * @author WS Development Team
0103: */
0104: public class WSDLGenerator {
0105: private JAXWSOutputSchemaResolver resolver;
0106: private WSDLResolver wsdlResolver = null;
0107: private AbstractSEIModelImpl model;
0108: private Definitions serviceDefinitions;
0109: private Definitions portDefinitions;
0110: private Types types;
0111: /**
0112: * Constant String for ".wsdl"
0113: */
0114: private static final String DOT_WSDL = ".wsdl";
0115: /**
0116: * Constant String appended to response message names
0117: */
0118: private static final String RESPONSE = "Response";
0119: /**
0120: * constant String used for part name for wrapped request messages
0121: */
0122: private static final String PARAMETERS = "parameters";
0123: /**
0124: * the part name for unwrappable response messages
0125: */
0126: private static final String RESULT = "parameters";
0127: /**
0128: * the part name for response messages that are not unwrappable
0129: */
0130: private static final String UNWRAPPABLE_RESULT = "result";
0131: /**
0132: * The WSDL namespace
0133: */
0134: private static final String WSDL_NAMESPACE = WSDLConstants.NS_WSDL;
0135:
0136: /**
0137: * the XSD namespace
0138: */
0139: private static final String XSD_NAMESPACE = SOAPNamespaceConstants.XSD;
0140: /**
0141: * the namespace prefix to use for the XSD namespace
0142: */
0143: private static final String XSD_PREFIX = "xsd";
0144: /**
0145: * The SOAP 1.1 namespace
0146: */
0147: private static final String SOAP11_NAMESPACE = SOAPConstants.NS_WSDL_SOAP;
0148: /**
0149: * The SOAP 1.2 namespace
0150: */
0151: private static final String SOAP12_NAMESPACE = SOAPConstants.NS_WSDL_SOAP12;
0152: /**
0153: * The namespace prefix to use for the SOAP 1.1 namespace
0154: */
0155: private static final String SOAP_PREFIX = "soap";
0156: /**
0157: * The namespace prefix to use for the SOAP 1.2 namespace
0158: */
0159: private static final String SOAP12_PREFIX = "soap12";
0160: /**
0161: * The namespace prefix to use for the targetNamespace
0162: */
0163: private static final String TNS_PREFIX = "tns";
0164: /**
0165: * The URI for the SOAP 1.1 HTTP Transport. Used to create soapBindings
0166: */
0167: private static final String SOAP_HTTP_TRANSPORT = SOAPNamespaceConstants.TRANSPORT_HTTP;
0168: /**
0169: * The URI for the SOAP 1.2 HTTP Transport. Used to create soapBindings
0170: */
0171: private static final String SOAP12_HTTP_TRANSPORT = SOAP12NamespaceConstants.TRANSPORT_HTTP;
0172: /**
0173: * Constant String "document" used to specify <code>document</code> style
0174: * soapBindings
0175: */
0176: private static final String DOCUMENT = "document";
0177: /**
0178: * Constant String "rpc" used to specify <code>rpc</code> style
0179: * soapBindings
0180: */
0181: private static final String RPC = "rpc";
0182: /**
0183: * Constant String "literal" used to create <code>literal</code> use binddings
0184: */
0185: private static final String LITERAL = "literal";
0186: /**
0187: * Constant String to flag the URL to replace at runtime for the endpoint
0188: */
0189: private static final String REPLACE_WITH_ACTUAL_URL = "REPLACE_WITH_ACTUAL_URL";
0190: private Set<QName> processedExceptions = new HashSet<QName>();
0191: private WSBinding binding;
0192: private String wsdlLocation;
0193: private String portWSDLID;
0194: private String schemaPrefix;
0195: private WSDLGeneratorExtension extension;
0196: List<WSDLGeneratorExtension> extensionHandlers;
0197:
0198: private String endpointAddress = REPLACE_WITH_ACTUAL_URL;
0199: private Container container;
0200: private final Class implType;
0201:
0202: /**
0203: * Creates the WSDLGenerator
0204: * @param model The {@link AbstractSEIModelImpl} used to generate the WSDL
0205: * @param wsdlResolver The {@link WSDLResolver} to use resovle names while generating the WSDL
0206: * @param binding specifies which {@link javax.xml.ws.BindingType} to generate
0207: * @param extensions an array {@link WSDLGeneratorExtension} that will
0208: * be invoked to generate WSDL extensions
0209: */
0210: public WSDLGenerator(AbstractSEIModelImpl model,
0211: WSDLResolver wsdlResolver, WSBinding binding,
0212: Container container, Class implType,
0213: WSDLGeneratorExtension... extensions) {
0214: this .model = model;
0215: resolver = new JAXWSOutputSchemaResolver();
0216: this .wsdlResolver = wsdlResolver;
0217: this .binding = binding;
0218: this .container = container;
0219: this .implType = implType;
0220: extensionHandlers = new ArrayList<WSDLGeneratorExtension>();
0221:
0222: // register handlers for default extensions
0223: register(new W3CAddressingWSDLGeneratorExtension());
0224:
0225: for (WSDLGeneratorExtension w : extensions)
0226: register(w);
0227:
0228: this .extension = new WSDLGeneratorExtensionFacade(
0229: extensionHandlers
0230: .toArray(new WSDLGeneratorExtension[0]));
0231: }
0232:
0233: /**
0234: * Sets the endpoint address string to be written.
0235: * Defaults to {@link #REPLACE_WITH_ACTUAL_URL}.
0236: */
0237: public void setEndpointAddress(String address) {
0238: this .endpointAddress = address;
0239: }
0240:
0241: /**
0242: * Performes the actual WSDL generation
0243: */
0244: public void doGeneration() {
0245: XmlSerializer serviceWriter;
0246: XmlSerializer portWriter = null;
0247: String fileName = JAXBRIContext.mangleNameToClassName(model
0248: .getServiceQName().getLocalPart());
0249: Result result = wsdlResolver.getWSDL(fileName + DOT_WSDL);
0250: wsdlLocation = result.getSystemId();
0251: serviceWriter = new CommentFilter(ResultFactory
0252: .createSerializer(result));
0253: if (model.getServiceQName().getNamespaceURI().equals(
0254: model.getTargetNamespace())) {
0255: portWriter = serviceWriter;
0256: schemaPrefix = fileName + "_";
0257: } else {
0258: String wsdlName = JAXBRIContext.mangleNameToClassName(model
0259: .getPortTypeName().getLocalPart());
0260: if (wsdlName.equals(fileName))
0261: wsdlName += "PortType";
0262: Holder<String> absWSDLName = new Holder<String>();
0263: absWSDLName.value = wsdlName + DOT_WSDL;
0264: result = wsdlResolver.getAbstractWSDL(absWSDLName);
0265:
0266: if (result != null) {
0267: portWSDLID = result.getSystemId();
0268: if (portWSDLID.equals(wsdlLocation)) {
0269: portWriter = serviceWriter;
0270: } else {
0271: portWriter = new CommentFilter(ResultFactory
0272: .createSerializer(result));
0273: }
0274: } else {
0275: portWSDLID = absWSDLName.value;
0276: }
0277: schemaPrefix = new java.io.File(portWSDLID).getName();
0278: int idx = schemaPrefix.lastIndexOf('.');
0279: if (idx > 0)
0280: schemaPrefix = schemaPrefix.substring(0, idx);
0281: schemaPrefix = JAXBRIContext
0282: .mangleNameToClassName(schemaPrefix)
0283: + "_";
0284: }
0285: generateDocument(serviceWriter, portWriter);
0286: }
0287:
0288: /**
0289: * Writing directly to XmlSerializer is a problem, since it doesn't suppress
0290: * xml declaration. Creating filter so that comment is written before TXW writes
0291: * anything in the WSDL.
0292: */
0293: private static class CommentFilter implements XmlSerializer {
0294: final XmlSerializer serializer;
0295: private static final String VERSION_COMMENT = " Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is "
0296: + RuntimeVersion.VERSION + ". ";
0297:
0298: CommentFilter(XmlSerializer serializer) {
0299: this .serializer = serializer;
0300: }
0301:
0302: public void startDocument() {
0303: serializer.startDocument();
0304: comment(new StringBuilder(VERSION_COMMENT));
0305: text(new StringBuilder("\n"));
0306: }
0307:
0308: public void beginStartTag(String uri, String localName,
0309: String prefix) {
0310: serializer.beginStartTag(uri, localName, prefix);
0311: }
0312:
0313: public void writeAttribute(String uri, String localName,
0314: String prefix, StringBuilder value) {
0315: serializer.writeAttribute(uri, localName, prefix, value);
0316: }
0317:
0318: public void writeXmlns(String prefix, String uri) {
0319: serializer.writeXmlns(prefix, uri);
0320: }
0321:
0322: public void endStartTag(String uri, String localName,
0323: String prefix) {
0324: serializer.endStartTag(uri, localName, prefix);
0325: }
0326:
0327: public void endTag() {
0328: serializer.endTag();
0329: }
0330:
0331: public void text(StringBuilder text) {
0332: serializer.text(text);
0333: }
0334:
0335: public void cdata(StringBuilder text) {
0336: serializer.cdata(text);
0337: }
0338:
0339: public void comment(StringBuilder comment) {
0340: serializer.comment(comment);
0341: }
0342:
0343: public void endDocument() {
0344: serializer.endDocument();
0345: }
0346:
0347: public void flush() {
0348: serializer.flush();
0349: }
0350:
0351: }
0352:
0353: private void generateDocument(XmlSerializer serviceStream,
0354: XmlSerializer portStream) {
0355: serviceDefinitions = TXW.create(Definitions.class,
0356: serviceStream);
0357: serviceDefinitions._namespace(WSDL_NAMESPACE, "");//WSDL_PREFIX);
0358: serviceDefinitions._namespace(XSD_NAMESPACE, XSD_PREFIX);
0359: serviceDefinitions.targetNamespace(model.getServiceQName()
0360: .getNamespaceURI());
0361: serviceDefinitions._namespace(model.getServiceQName()
0362: .getNamespaceURI(), TNS_PREFIX);
0363: if (binding.getSOAPVersion() == SOAPVersion.SOAP_12)
0364: serviceDefinitions._namespace(SOAP12_NAMESPACE,
0365: SOAP12_PREFIX);
0366: else
0367: serviceDefinitions
0368: ._namespace(SOAP11_NAMESPACE, SOAP_PREFIX);
0369: serviceDefinitions.name(model.getServiceQName().getLocalPart());
0370: WSDLGenExtnContext serviceCtx = new WSDLGenExtnContext(
0371: serviceDefinitions, model, binding, container, implType);
0372: extension.start(serviceCtx);
0373: if (serviceStream != portStream && portStream != null) {
0374: // generate an abstract and concrete wsdl
0375: portDefinitions = TXW.create(Definitions.class, portStream);
0376: portDefinitions._namespace(WSDL_NAMESPACE, "");//WSDL_PREFIX);
0377: portDefinitions._namespace(XSD_NAMESPACE, XSD_PREFIX);
0378: if (model.getTargetNamespace() != null) {
0379: portDefinitions.targetNamespace(model
0380: .getTargetNamespace());
0381: portDefinitions._namespace(model.getTargetNamespace(),
0382: TNS_PREFIX);
0383: }
0384:
0385: String schemaLoc = relativize(portWSDLID, wsdlLocation);
0386: Import _import = serviceDefinitions._import().namespace(
0387: model.getTargetNamespace());
0388: _import.location(schemaLoc);
0389: } else if (portStream != null) {
0390: // abstract and concrete are the same
0391: portDefinitions = serviceDefinitions;
0392: } else {
0393: // import a provided abstract wsdl
0394: String schemaLoc = relativize(portWSDLID, wsdlLocation);
0395: Import _import = serviceDefinitions._import().namespace(
0396: model.getTargetNamespace());
0397: _import.location(schemaLoc);
0398: }
0399: extension.addDefinitionsExtension(serviceDefinitions);
0400:
0401: if (portDefinitions != null) {
0402: generateTypes();
0403: generateMessages();
0404: generatePortType();
0405: }
0406: generateBinding();
0407: generateService();
0408: //Give a chance to WSDLGeneratorExtensions to write stuff before closing </wsdl:defintions>
0409: extension.end(serviceCtx);
0410: serviceDefinitions.commit();
0411: if (portDefinitions != null
0412: && portDefinitions != serviceDefinitions)
0413: portDefinitions.commit();
0414: }
0415:
0416: /**
0417: * Generates the types section of the WSDL
0418: */
0419: protected void generateTypes() {
0420: types = portDefinitions.types();
0421: if (model.getJAXBContext() != null) {
0422: try {
0423: model.getJAXBContext().generateSchema(resolver);
0424: } catch (IOException e) {
0425: // TODO locallize and wrap this
0426: e.printStackTrace();
0427: throw new WebServiceException(e.getMessage());
0428: }
0429: }
0430: }
0431:
0432: /**
0433: * Generates the WSDL messages
0434: */
0435: protected void generateMessages() {
0436: for (JavaMethodImpl method : model.getJavaMethods()) {
0437: generateSOAPMessages(method, method.getBinding());
0438: }
0439: }
0440:
0441: /**
0442: * Generates messages for a SOAPBinding
0443: * @param method The {@link JavaMethod} to generate messages for
0444: * @param binding The {@link com.sun.xml.ws.api.model.soap.SOAPBinding} to add the generated messages to
0445: */
0446: protected void generateSOAPMessages(JavaMethodImpl method,
0447: com.sun.xml.ws.api.model.soap.SOAPBinding binding) {
0448: boolean isDoclit = binding.isDocLit();
0449: // Message message = portDefinitions.message().name(method.getOperation().getName().getLocalPart());
0450: Message message = portDefinitions.message().name(
0451: method.getRequestMessageName());
0452: extension.addInputMessageExtension(message, method);
0453: com.sun.xml.ws.wsdl.writer.document.Part part;
0454: JAXBRIContext jaxbContext = model.getJAXBContext();
0455: boolean unwrappable = true;
0456: for (ParameterImpl param : method.getRequestParameters()) {
0457: if (isDoclit) {
0458: if (isHeaderParameter(param))
0459: unwrappable = false;
0460: if (param.isWrapperStyle()) {
0461: part = message.part().name(PARAMETERS);
0462: part.element(param.getName());
0463: } else {
0464: part = message.part().name(param.getPartName());
0465: part.element(param.getName());
0466: }
0467: } else {
0468: if (param.isWrapperStyle()) {
0469: for (ParameterImpl childParam : ((WrapperParameter) param)
0470: .getWrapperChildren()) {
0471: part = message.part().name(
0472: childParam.getPartName());
0473: part.type(jaxbContext.getTypeName(childParam
0474: .getBridge().getTypeReference()));
0475: }
0476: } else {
0477: part = message.part().name(param.getPartName());
0478: part.element(param.getName());
0479: }
0480: }
0481: }
0482: if (method.getMEP() != MEP.ONE_WAY) {
0483: // message = portDefinitions.message().name(method.getOperation().getName().getLocalPart()+RESPONSE);
0484: message = portDefinitions.message().name(
0485: method.getResponseMessageName());
0486: extension.addOutputMessageExtension(message, method);
0487: if (unwrappable) {
0488: for (ParameterImpl param : method
0489: .getResponseParameters()) {
0490: if (isHeaderParameter(param))
0491: unwrappable = false;
0492: }
0493: }
0494:
0495: for (ParameterImpl param : method.getResponseParameters()) {
0496: if (isDoclit) {
0497: if (param.isWrapperStyle()) {
0498: // if its not really wrapper style dont use the same name as input message
0499: if (unwrappable)
0500: part = message.part().name(RESULT);
0501: else
0502: part = message.part().name(
0503: UNWRAPPABLE_RESULT);
0504: part.element(param.getName());
0505: } else {
0506: part = message.part().name(param.getPartName());
0507: part.element(param.getName());
0508: }
0509: } else {
0510: if (param.isWrapperStyle()) {
0511: for (ParameterImpl childParam : ((WrapperParameter) param)
0512: .getWrapperChildren()) {
0513: part = message.part().name(
0514: childParam.getPartName());
0515: part.type(jaxbContext
0516: .getTypeName(childParam.getBridge()
0517: .getTypeReference()));
0518: }
0519: } else {
0520: part = message.part().name(param.getPartName());
0521: part.element(param.getName());
0522: }
0523: }
0524: }
0525: }
0526: for (CheckedExceptionImpl exception : method
0527: .getCheckedExceptions()) {
0528: QName tagName = exception.getDetailType().tagName;
0529: String messageName = exception.getMessageName();
0530: QName messageQName = new QName(model.getTargetNamespace(),
0531: messageName);
0532: if (processedExceptions.contains(messageQName))
0533: continue;
0534: message = portDefinitions.message().name(messageName);
0535:
0536: extension.addFaultMessageExtension(message, method,
0537: exception);
0538: part = message.part().name("fault");//tagName.getLocalPart());
0539: part.element(tagName);
0540: processedExceptions.add(messageQName);
0541: }
0542: }
0543:
0544: /**
0545: * Generates the WSDL portType
0546: */
0547: protected void generatePortType() {
0548:
0549: PortType portType = portDefinitions.portType().name(
0550: model.getPortTypeName().getLocalPart());
0551: extension.addPortTypeExtension(portType);
0552: for (JavaMethodImpl method : model.getJavaMethods()) {
0553: Operation operation = portType.operation().name(
0554: method.getOperationName());
0555: generateParameterOrder(operation, method);
0556: extension.addOperationExtension(operation, method);
0557: switch (method.getMEP()) {
0558: case REQUEST_RESPONSE:
0559: // input message
0560: generateInputMessage(operation, method);
0561: // output message
0562: generateOutputMessage(operation, method);
0563: break;
0564: case ONE_WAY:
0565: generateInputMessage(operation, method);
0566: break;
0567: }
0568: // faults
0569: for (CheckedExceptionImpl exception : method
0570: .getCheckedExceptions()) {
0571: QName messageName = new QName(model
0572: .getTargetNamespace(), exception
0573: .getMessageName());
0574: FaultType paramType = operation.fault().message(
0575: messageName).name(exception.getMessageName());
0576: extension.addOperationFaultExtension(paramType, method,
0577: exception);
0578: }
0579: }
0580: }
0581:
0582: /**
0583: * Determines if the <CODE>method</CODE> is wrapper style
0584: * @param method The {@link JavaMethod} to check if it is wrapper style
0585: * @return true if the method is wrapper style, otherwise, false.
0586: */
0587: protected boolean isWrapperStyle(JavaMethodImpl method) {
0588: if (method.getRequestParameters().size() > 0) {
0589: ParameterImpl param = method.getRequestParameters()
0590: .iterator().next();
0591: return param.isWrapperStyle();
0592: }
0593: return false;
0594: }
0595:
0596: /**
0597: * Determines if a {@link JavaMethod} is rpc/literal
0598: * @param method The method to check
0599: * @return true if method is rpc/literal, otherwise, false
0600: */
0601: protected boolean isRpcLit(JavaMethodImpl method) {
0602: return method.getBinding().getStyle() == Style.RPC;
0603: }
0604:
0605: /**
0606: * Generates the parameterOrder for a PortType operation
0607: * @param operation The operation to generate the parameterOrder for
0608: * @param method The {@link JavaMethod} to generate the parameterOrder from
0609: */
0610: protected void generateParameterOrder(Operation operation,
0611: JavaMethodImpl method) {
0612: if (method.getMEP() == MEP.ONE_WAY)
0613: return;
0614: if (isRpcLit(method))
0615: generateRpcParameterOrder(operation, method);
0616: else
0617: generateDocumentParameterOrder(operation, method);
0618: }
0619:
0620: /**
0621: * Generates the parameterOrder for a PortType operation
0622: * @param operation the operation to generate the parameterOrder for
0623: * @param method the {@link JavaMethod} to generate the parameterOrder from
0624: */
0625: protected void generateRpcParameterOrder(Operation operation,
0626: JavaMethodImpl method) {
0627: String partName;
0628: StringBuffer paramOrder = new StringBuffer();
0629: Set<String> partNames = new HashSet<String>();
0630: List<ParameterImpl> sortedParams = sortMethodParameters(method);
0631: int i = 0;
0632: for (ParameterImpl parameter : sortedParams) {
0633: if (parameter.getIndex() >= 0) {
0634: partName = parameter.getPartName();
0635: if (!partNames.contains(partName)) {
0636: if (i++ > 0)
0637: paramOrder.append(' ');
0638: paramOrder.append(partName);
0639: partNames.add(partName);
0640: }
0641: }
0642: }
0643: operation.parameterOrder(paramOrder.toString());
0644: }
0645:
0646: /**
0647: * Generates the parameterOrder for a PortType operation
0648: * @param operation the operation to generate the parameterOrder for
0649: * @param method the {@link JavaMethod} to generate the parameterOrder from
0650: */
0651: protected void generateDocumentParameterOrder(Operation operation,
0652: JavaMethodImpl method) {
0653: String partName;
0654: StringBuffer paramOrder = new StringBuffer();
0655: Set<String> partNames = new HashSet<String>();
0656: List<ParameterImpl> sortedParams = sortMethodParameters(method);
0657: boolean isWrapperStyle = isWrapperStyle(method);
0658: int i = 0;
0659: for (ParameterImpl parameter : sortedParams) {
0660: // System.out.println("param: "+parameter.getIndex()+" name: "+parameter.getName().getLocalPart());
0661: if (parameter.getIndex() < 0)
0662: continue;
0663: if (isWrapperStyle && isBodyParameter(parameter)) {
0664: // System.out.println("isWrapper and is body");
0665: if (method.getRequestParameters().contains(parameter))
0666: partName = PARAMETERS;
0667: else {
0668: // really make sure this is a wrapper style wsdl we are creating
0669: partName = RESPONSE;
0670: }
0671: } else {
0672: partName = parameter.getPartName();
0673: }
0674: if (!partNames.contains(partName)) {
0675: if (i++ > 0)
0676: paramOrder.append(' ');
0677: paramOrder.append(partName);
0678: partNames.add(partName);
0679: }
0680: }
0681: if (i > 1) {
0682: operation.parameterOrder(paramOrder.toString());
0683: }
0684: }
0685:
0686: /**
0687: * Sorts the parameters for the method by their position
0688: * @param method the {@link JavaMethod} used to sort the parameters
0689: * @return the sorted {@link List} of parameters
0690: */
0691: protected List<ParameterImpl> sortMethodParameters(
0692: JavaMethodImpl method) {
0693: Set<ParameterImpl> paramSet = new HashSet<ParameterImpl>();
0694: List<ParameterImpl> sortedParams = new ArrayList<ParameterImpl>();
0695: if (isRpcLit(method)) {
0696: for (ParameterImpl param : method.getRequestParameters()) {
0697: if (param instanceof WrapperParameter) {
0698: paramSet.addAll(((WrapperParameter) param)
0699: .getWrapperChildren());
0700: } else {
0701: paramSet.add(param);
0702: }
0703: }
0704: for (ParameterImpl param : method.getResponseParameters()) {
0705: if (param instanceof WrapperParameter) {
0706: paramSet.addAll(((WrapperParameter) param)
0707: .getWrapperChildren());
0708: } else {
0709: paramSet.add(param);
0710: }
0711: }
0712: } else {
0713: paramSet.addAll(method.getRequestParameters());
0714: paramSet.addAll(method.getResponseParameters());
0715: }
0716: Iterator<ParameterImpl> params = paramSet.iterator();
0717: if (paramSet.size() == 0)
0718: return sortedParams;
0719: ParameterImpl param = params.next();
0720: sortedParams.add(param);
0721: ParameterImpl sortedParam;
0722: int pos;
0723: for (int i = 1; i < paramSet.size(); i++) {
0724: param = params.next();
0725: for (pos = 0; pos < i; pos++) {
0726: sortedParam = sortedParams.get(pos);
0727: if (param.getIndex() == sortedParam.getIndex()
0728: && param instanceof WrapperParameter)
0729: break;
0730: if (param.getIndex() < sortedParam.getIndex()) {
0731: break;
0732: }
0733: }
0734: sortedParams.add(pos, param);
0735: }
0736: return sortedParams;
0737: }
0738:
0739: /**
0740: * Determines if a parameter is associated with the message Body
0741: * @param parameter the parameter to check
0742: * @return true if the parameter is a <code>body</code> parameter
0743: */
0744: protected boolean isBodyParameter(ParameterImpl parameter) {
0745: ParameterBinding paramBinding = parameter.getBinding();
0746: return paramBinding.isBody();
0747: }
0748:
0749: protected boolean isHeaderParameter(ParameterImpl parameter) {
0750: ParameterBinding paramBinding = parameter.getBinding();
0751: return paramBinding.isHeader();
0752: }
0753:
0754: protected boolean isAttachmentParameter(ParameterImpl parameter) {
0755: ParameterBinding paramBinding = parameter.getBinding();
0756: return paramBinding.isAttachment();
0757: }
0758:
0759: /**
0760: * Generates the Binding section of the WSDL
0761: */
0762: protected void generateBinding() {
0763: Binding binding = serviceDefinitions.binding().name(
0764: model.getBoundPortTypeName().getLocalPart());
0765: extension.addBindingExtension(binding);
0766: binding.type(model.getPortTypeName());
0767: boolean first = true;
0768: for (JavaMethodImpl method : model.getJavaMethods()) {
0769: if (first) {
0770: SOAPBinding sBinding = method.getBinding();
0771: SOAPVersion soapVersion = sBinding.getSOAPVersion();
0772: if (soapVersion == SOAPVersion.SOAP_12) {
0773: com.sun.xml.ws.wsdl.writer.document.soap12.SOAPBinding soapBinding = binding
0774: .soap12Binding();
0775: soapBinding.transport(SOAP12_HTTP_TRANSPORT);
0776: if (sBinding.getStyle().equals(Style.DOCUMENT))
0777: soapBinding.style(DOCUMENT);
0778: else
0779: soapBinding.style(RPC);
0780: } else {
0781: com.sun.xml.ws.wsdl.writer.document.soap.SOAPBinding soapBinding = binding
0782: .soapBinding();
0783: soapBinding.transport(SOAP_HTTP_TRANSPORT);
0784: if (sBinding.getStyle().equals(Style.DOCUMENT))
0785: soapBinding.style(DOCUMENT);
0786: else
0787: soapBinding.style(RPC);
0788: }
0789: first = false;
0790: }
0791: if (this .binding.getBindingId().getSOAPVersion() == SOAPVersion.SOAP_12)
0792: generateSOAP12BindingOperation(method, binding);
0793: else
0794: generateBindingOperation(method, binding);
0795: }
0796: }
0797:
0798: protected void generateBindingOperation(JavaMethodImpl method,
0799: Binding binding) {
0800: BindingOperationType operation = binding.operation().name(
0801: method.getOperationName());
0802: extension.addBindingOperationExtension(operation, method);
0803: String targetNamespace = model.getTargetNamespace();
0804: QName requestMessage = new QName(targetNamespace, method
0805: .getOperationName());
0806: List<ParameterImpl> bodyParams = new ArrayList<ParameterImpl>();
0807: List<ParameterImpl> headerParams = new ArrayList<ParameterImpl>();
0808: splitParameters(bodyParams, headerParams, method
0809: .getRequestParameters());
0810: SOAPBinding soapBinding = method.getBinding();
0811: operation.soapOperation().soapAction(
0812: soapBinding.getSOAPAction());
0813:
0814: // input
0815: TypedXmlWriter input = operation.input();
0816: extension.addBindingOperationInputExtension(input, method);
0817: BodyType body = input._element(Body.class);
0818: boolean isRpc = soapBinding.getStyle().equals(Style.RPC);
0819: if (soapBinding.getUse() == Use.LITERAL) {
0820: body.use(LITERAL);
0821: if (headerParams.size() > 0) {
0822: if (bodyParams.size() > 0) {
0823: ParameterImpl param = bodyParams.iterator().next();
0824: if (isRpc) {
0825: StringBuffer parts = new StringBuffer();
0826: int i = 0;
0827: for (ParameterImpl parameter : ((WrapperParameter) param)
0828: .getWrapperChildren()) {
0829: if (i++ > 0)
0830: parts.append(' ');
0831: parts.append(parameter.getPartName());
0832: }
0833: body.parts(parts.toString());
0834: } else if (param.isWrapperStyle()) {
0835: body.parts(PARAMETERS);
0836: } else {
0837: body.parts(param.getPartName());
0838: }
0839: } else {
0840: body.parts("");
0841: }
0842: generateSOAPHeaders(input, headerParams, requestMessage);
0843: }
0844: if (isRpc) {
0845: body.namespace(method.getRequestParameters().iterator()
0846: .next().getName().getNamespaceURI());
0847: }
0848: } else {
0849: // TODO localize this
0850: throw new WebServiceException(
0851: "encoded use is not supported");
0852: }
0853:
0854: if (method.getMEP() != MEP.ONE_WAY) {
0855: boolean unwrappable = headerParams.size() == 0;
0856: // output
0857: bodyParams.clear();
0858: headerParams.clear();
0859: splitParameters(bodyParams, headerParams, method
0860: .getResponseParameters());
0861: unwrappable = unwrappable ? headerParams.size() == 0
0862: : unwrappable;
0863: TypedXmlWriter output = operation.output();
0864: extension
0865: .addBindingOperationOutputExtension(output, method);
0866: body = output._element(Body.class);
0867: body.use(LITERAL);
0868: if (headerParams.size() > 0) {
0869: String parts = "";
0870: if (bodyParams.size() > 0) {
0871: ParameterImpl param = bodyParams.iterator()
0872: .hasNext() ? bodyParams.iterator().next()
0873: : null;
0874: if (param != null) {
0875: if (isRpc) {
0876: int i = 0;
0877: for (ParameterImpl parameter : ((WrapperParameter) param)
0878: .getWrapperChildren()) {
0879: if (i++ > 0)
0880: parts += " ";
0881: parts += parameter.getPartName();
0882: }
0883: } else {
0884: if (param.isWrapperStyle()) {
0885: // if its not really wrapper style dont use the same name as input message
0886: if (unwrappable)
0887: parts = RESULT;
0888: else
0889: parts = UNWRAPPABLE_RESULT;
0890: } else {
0891: parts = param.getPartName();
0892: }
0893: }
0894: }
0895: }
0896: body.parts(parts);
0897: QName responseMessage = new QName(targetNamespace,
0898: method.getResponseMessageName());
0899: generateSOAPHeaders(output, headerParams,
0900: responseMessage);
0901: }
0902: if (isRpc) {
0903: body.namespace(method.getRequestParameters().iterator()
0904: .next().getName().getNamespaceURI());
0905: }
0906: }
0907: for (CheckedExceptionImpl exception : method
0908: .getCheckedExceptions()) {
0909: Fault fault = operation.fault().name(
0910: exception.getMessageName());
0911: extension.addBindingOperationFaultExtension(fault, method,
0912: exception);
0913: SOAPFault soapFault = fault._element(SOAPFault.class).name(
0914: exception.getMessageName());
0915: soapFault.use(LITERAL);
0916: }
0917: }
0918:
0919: protected void generateSOAP12BindingOperation(
0920: JavaMethodImpl method, Binding binding) {
0921: BindingOperationType operation = binding.operation().name(
0922: method.getOperationName());
0923: String targetNamespace = model.getTargetNamespace();
0924: QName requestMessage = new QName(targetNamespace, method
0925: .getOperationName());
0926:
0927: ArrayList<ParameterImpl> bodyParams = new ArrayList<ParameterImpl>();
0928: ArrayList<ParameterImpl> headerParams = new ArrayList<ParameterImpl>();
0929: splitParameters(bodyParams, headerParams, method
0930: .getRequestParameters());
0931: SOAPBinding soapBinding = method.getBinding();
0932: operation.soap12Operation().soapAction(
0933: soapBinding.getSOAPAction());
0934:
0935: // input
0936: TypedXmlWriter input = operation.input();
0937:
0938: com.sun.xml.ws.wsdl.writer.document.soap12.BodyType body = input
0939: ._element(com.sun.xml.ws.wsdl.writer.document.soap12.Body.class);
0940: boolean isRpc = soapBinding.getStyle().equals(Style.RPC);
0941: if (soapBinding.getUse().equals(Use.LITERAL)) {
0942: body.use(LITERAL);
0943: if (headerParams.size() > 0) {
0944: if (bodyParams.size() > 0) {
0945: ParameterImpl param = bodyParams.iterator().next();
0946: if (isRpc) {
0947: StringBuffer parts = new StringBuffer();
0948: int i = 0;
0949: for (ParameterImpl parameter : ((WrapperParameter) param)
0950: .getWrapperChildren()) {
0951: if (i++ > 0)
0952: parts.append(' ');
0953: parts.append(parameter.getPartName());
0954: }
0955: body.parts(parts.toString());
0956: } else if (param.isWrapperStyle()) {
0957: body.parts(PARAMETERS);
0958: } else {
0959: body.parts(param.getPartName());
0960: }
0961: } else {
0962: body.parts("");
0963: }
0964: generateSOAP12Headers(input, headerParams,
0965: requestMessage);
0966: }
0967: if (isRpc) {
0968: body.namespace(method.getRequestParameters().iterator()
0969: .next().getName().getNamespaceURI());
0970: }
0971: } else {
0972: // TODO localize this
0973: throw new WebServiceException(
0974: "encoded use is not supported");
0975: }
0976:
0977: if (method.getMEP() != MEP.ONE_WAY) {
0978: // output
0979: boolean unwrappable = headerParams.size() == 0;
0980: bodyParams.clear();
0981: headerParams.clear();
0982: splitParameters(bodyParams, headerParams, method
0983: .getResponseParameters());
0984: unwrappable = unwrappable ? headerParams.size() == 0
0985: : unwrappable;
0986: TypedXmlWriter output = operation.output();
0987: body = output
0988: ._element(com.sun.xml.ws.wsdl.writer.document.soap12.Body.class);
0989: body.use(LITERAL);
0990: if (headerParams.size() > 0) {
0991: if (bodyParams.size() > 0) {
0992: ParameterImpl param = bodyParams.iterator().next();
0993: if (isRpc) {
0994: String parts = "";
0995: int i = 0;
0996: for (ParameterImpl parameter : ((WrapperParameter) param)
0997: .getWrapperChildren()) {
0998: if (i++ > 0)
0999: parts += " ";
1000: parts += parameter.getPartName();
1001: }
1002: body.parts(parts);
1003: } else if (param.isWrapperStyle()) {
1004: // if its not really wrapper style dont use the same name as input message
1005: if (unwrappable)
1006: body.parts(RESULT);
1007: else
1008: body.parts(UNWRAPPABLE_RESULT);
1009: } else {
1010: body.parts(param.getPartName());
1011: }
1012: } else {
1013: body.parts("");
1014: }
1015: QName responseMessage = new QName(targetNamespace,
1016: method.getResponseMessageName());
1017: generateSOAP12Headers(output, headerParams,
1018: responseMessage);
1019: }
1020: if (isRpc) {
1021: body.namespace(method.getRequestParameters().iterator()
1022: .next().getName().getNamespaceURI());
1023: }
1024: }
1025: for (CheckedExceptionImpl exception : method
1026: .getCheckedExceptions()) {
1027: Fault fault = operation.fault().name(
1028: exception.getMessageName());
1029: com.sun.xml.ws.wsdl.writer.document.soap12.SOAPFault soapFault = fault
1030: ._element(
1031: com.sun.xml.ws.wsdl.writer.document.soap12.SOAPFault.class)
1032: .name(exception.getMessageName());
1033: soapFault.use(LITERAL);
1034: }
1035: }
1036:
1037: /**
1038: *
1039: * @param bodyParams
1040: * @param headerParams
1041: * @param params
1042: */
1043: protected void splitParameters(List<ParameterImpl> bodyParams,
1044: List<ParameterImpl> headerParams, List<ParameterImpl> params) {
1045: for (ParameterImpl parameter : params) {
1046: if (isBodyParameter(parameter)) {
1047: bodyParams.add(parameter);
1048: } else {
1049: headerParams.add(parameter);
1050: }
1051: }
1052: }
1053:
1054: /**
1055: *
1056: * @param writer
1057: * @param parameters
1058: * @param message
1059: */
1060: protected void generateSOAPHeaders(TypedXmlWriter writer,
1061: List<ParameterImpl> parameters, QName message) {
1062:
1063: for (ParameterImpl headerParam : parameters) {
1064: Header header = writer._element(Header.class);
1065: header.message(message);
1066: header.part(headerParam.getPartName());
1067: header.use(LITERAL);
1068: }
1069: }
1070:
1071: /**
1072: *
1073: * @param writer
1074: * @param parameters
1075: * @param message
1076: */
1077: protected void generateSOAP12Headers(TypedXmlWriter writer,
1078: List<ParameterImpl> parameters, QName message) {
1079:
1080: for (ParameterImpl headerParam : parameters) {
1081: com.sun.xml.ws.wsdl.writer.document.soap12.Header header = writer
1082: ._element(com.sun.xml.ws.wsdl.writer.document.soap12.Header.class);
1083: header.message(message);
1084:
1085: header.part(headerParam.getPartName());
1086: header.use(LITERAL);
1087: }
1088: }
1089:
1090: /**
1091: * Generates the Service section of the WSDL
1092: */
1093: protected void generateService() {
1094: QName portQName = model.getPortName();
1095: QName serviceQName = model.getServiceQName();
1096: Service service = serviceDefinitions.service().name(
1097: serviceQName.getLocalPart());
1098: extension.addServiceExtension(service);
1099: Port port = service.port().name(portQName.getLocalPart());
1100: port.binding(model.getBoundPortTypeName());
1101: extension.addPortExtension(port);
1102: if (model.getJavaMethods().size() == 0)
1103: return;
1104:
1105: if (this .binding.getBindingId().getSOAPVersion() == SOAPVersion.SOAP_12) {
1106: com.sun.xml.ws.wsdl.writer.document.soap12.SOAPAddress address = port
1107: ._element(com.sun.xml.ws.wsdl.writer.document.soap12.SOAPAddress.class);
1108: address.location(endpointAddress);
1109: } else {
1110: SOAPAddress address = port._element(SOAPAddress.class);
1111: address.location(endpointAddress);
1112: }
1113: }
1114:
1115: /**
1116: *
1117: * @param operation
1118: * @param method
1119: */
1120: protected void generateInputMessage(Operation operation,
1121: JavaMethodImpl method) {
1122: ParamType paramType = operation.input();
1123: extension.addOperationInputExtension(paramType, method);
1124: // paramType.message(method.getOperation().getName());
1125: paramType.message(new QName(model.getTargetNamespace(), method
1126: .getRequestMessageName()));
1127: }
1128:
1129: /**
1130: *
1131: * @param operation
1132: * @param method
1133: */
1134: protected void generateOutputMessage(Operation operation,
1135: JavaMethodImpl method) {
1136: ParamType paramType = operation.output();
1137: extension.addOperationOutputExtension(paramType, method);
1138: // paramType.message(new QName(model.getTargetNamespace(), method.getOperation().getLocalName()+RESPONSE));
1139: paramType.message(new QName(model.getTargetNamespace(), method
1140: .getResponseMessageName()));
1141: }
1142:
1143: /**
1144: * Creates the {@link Result} object used by JAXB to generate a schema for the
1145: * namesapceUri namespace.
1146: * @param namespaceUri The namespace for the schema being generated
1147: * @param suggestedFileName the JAXB suggested file name for the schema file
1148: * @return the {@link Result} for JAXB to generate the schema into
1149: * @throws java.io.IOException thrown if on IO error occurs
1150: */
1151: public Result createOutputFile(String namespaceUri,
1152: String suggestedFileName) throws IOException {
1153: Result result;
1154: if (namespaceUri.equals("")) {
1155: return null;
1156: }
1157: com.sun.xml.ws.wsdl.writer.document.xsd.Import _import = types
1158: .schema()._import().namespace(namespaceUri);
1159:
1160: Holder<String> fileNameHolder = new Holder<String>();
1161: fileNameHolder.value = schemaPrefix + suggestedFileName;
1162: result = wsdlResolver.getSchemaOutput(namespaceUri,
1163: fileNameHolder);
1164: // System.out.println("schema file: "+fileNameHolder.value);
1165: // System.out.println("result: "+result);
1166: String schemaLoc;
1167: if (result == null)
1168: schemaLoc = fileNameHolder.value;
1169: else
1170: schemaLoc = relativize(result.getSystemId(), wsdlLocation);
1171: // System.out.println("schemaLoca: "+schemaLoc);
1172: _import.schemaLocation(schemaLoc);
1173: return result;
1174: }
1175:
1176: /**
1177: * Relativizes a URI by using another URI (base URI.)
1178: *
1179: * <p>
1180: * For example, {@code relative("http://www.sun.com/abc/def","http://www.sun.com/pqr/stu") => "../abc/def"}
1181: *
1182: * <p>
1183: * This method only works on hierarchical URI's, not opaque URI's (refer to the
1184: * <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/URI.html">java.net.URI</a>
1185: * javadoc for complete definitions of these terms.
1186: *
1187: * <p>
1188: * This method will not normalize the relative URI.
1189: * @param uri the URI to relativize
1190: *
1191: *
1192: * @param baseUri the base URI to use for the relativization
1193: * @return the relative URI or the original URI if a relative one could not be computed
1194: */
1195: protected static String relativize(String uri, String baseUri) {
1196: try {
1197: assert uri != null;
1198:
1199: if (baseUri == null)
1200: return uri;
1201:
1202: URI theUri = new URI(escapeURI(uri));
1203: URI theBaseUri = new URI(escapeURI(baseUri));
1204:
1205: if (theUri.isOpaque() || theBaseUri.isOpaque())
1206: return uri;
1207:
1208: if (!equalsIgnoreCase(theUri.getScheme(), theBaseUri
1209: .getScheme())
1210: || !equal(theUri.getAuthority(), theBaseUri
1211: .getAuthority()))
1212: return uri;
1213:
1214: String uriPath = theUri.getPath();
1215: String basePath = theBaseUri.getPath();
1216:
1217: // normalize base path
1218: if (!basePath.endsWith("/")) {
1219: basePath = normalizeUriPath(basePath);
1220: }
1221:
1222: if (uriPath.equals(basePath))
1223: return ".";
1224:
1225: String relPath = calculateRelativePath(uriPath, basePath);
1226:
1227: if (relPath == null)
1228: return uri; // recursion found no commonality in the two uris at all
1229: StringBuffer relUri = new StringBuffer();
1230: relUri.append(relPath);
1231: if (theUri.getQuery() != null)
1232: relUri.append('?').append(theUri.getQuery());
1233: if (theUri.getFragment() != null)
1234: relUri.append('#').append(theUri.getFragment());
1235:
1236: return relUri.toString();
1237: } catch (URISyntaxException e) {
1238: throw new InternalError(
1239: "Error escaping one of these uris:\n\t" + uri
1240: + "\n\t" + baseUri);
1241: }
1242: }
1243:
1244: private static String calculateRelativePath(String uri, String base) {
1245: if (base == null) {
1246: return null;
1247: }
1248: if (uri.startsWith(base)) {
1249: return uri.substring(base.length());
1250: } else {
1251: return "../"
1252: + calculateRelativePath(uri, getParentUriPath(base));
1253: }
1254: }
1255:
1256: /**
1257: * Implements the SchemaOutputResolver used by JAXB to
1258: */
1259: protected class JAXWSOutputSchemaResolver extends
1260: SchemaOutputResolver {
1261:
1262: /**
1263: * Creates the {@link Result} object used by JAXB to generate a schema for the
1264: * namesapceUri namespace.
1265: * @param namespaceUri The namespace for the schema being generated
1266: * @param suggestedFileName the JAXB suggested file name for the schema file
1267: * @return the {@link Result} for JAXB to generate the schema into
1268: * @throws java.io.IOException thrown if on IO error occurs
1269: */
1270: public Result createOutput(String namespaceUri,
1271: String suggestedFileName) throws IOException {
1272: return createOutputFile(namespaceUri, suggestedFileName);
1273: }
1274: }
1275:
1276: private void register(WSDLGeneratorExtension h) {
1277: extensionHandlers.add(h);
1278: }
1279: }
|