0001: /*
0002: * Portions Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
0003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004: *
0005: * This code is free software; you can redistribute it and/or modify it
0006: * under the terms of the GNU General Public License version 2 only, as
0007: * published by the Free Software Foundation. Sun designates this
0008: * particular file as subject to the "Classpath" exception as provided
0009: * by Sun in the LICENSE file that accompanied this code.
0010: *
0011: * This code is distributed in the hope that it will be useful, but WITHOUT
0012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014: * version 2 for more details (a copy is included in the LICENSE file that
0015: * accompanied this code).
0016: *
0017: * You should have received a copy of the GNU General Public License version
0018: * 2 along with this work; if not, write to the Free Software Foundation,
0019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020: *
0021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022: * CA 95054 USA or visit www.sun.com if you need additional information or
0023: * have any questions.
0024: */
0025: package com.sun.xml.internal.ws.wsdl.writer;
0026:
0027: import com.sun.xml.internal.ws.pept.presentation.MessageStruct;
0028: import com.sun.xml.internal.bind.api.JAXBRIContext;
0029: import static com.sun.xml.internal.bind.v2.schemagen.Util.*;
0030: import com.sun.xml.internal.txw2.TXW;
0031: import com.sun.xml.internal.txw2.TypedXmlWriter;
0032: import com.sun.xml.internal.txw2.output.ResultFactory;
0033: import com.sun.xml.internal.txw2.output.XmlSerializer;
0034: import com.sun.xml.internal.ws.encoding.soap.SOAPVersion;
0035: import com.sun.xml.internal.ws.encoding.soap.streaming.SOAPNamespaceConstants;
0036: import com.sun.xml.internal.ws.encoding.soap.streaming.SOAP12NamespaceConstants;
0037: import com.sun.xml.internal.ws.model.CheckedException;
0038: import com.sun.xml.internal.ws.model.JavaMethod;
0039: import com.sun.xml.internal.ws.model.Parameter;
0040: import com.sun.xml.internal.ws.model.ParameterBinding;
0041: import com.sun.xml.internal.ws.model.RuntimeModel;
0042: import com.sun.xml.internal.ws.model.WrapperParameter;
0043: import com.sun.xml.internal.ws.model.soap.SOAPBinding;
0044: import com.sun.xml.internal.ws.model.soap.Style;
0045: import com.sun.xml.internal.ws.model.soap.Use;
0046: import com.sun.xml.internal.ws.wsdl.parser.SOAPConstants;
0047: import com.sun.xml.internal.ws.wsdl.parser.WSDLConstants;
0048: import com.sun.xml.internal.ws.wsdl.writer.document.Binding;
0049: import com.sun.xml.internal.ws.wsdl.writer.document.BindingOperationType;
0050: import com.sun.xml.internal.ws.wsdl.writer.document.Definitions;
0051: import com.sun.xml.internal.ws.wsdl.writer.document.Fault;
0052: import com.sun.xml.internal.ws.wsdl.writer.document.FaultType;
0053: import com.sun.xml.internal.ws.wsdl.writer.document.Import;
0054: import com.sun.xml.internal.ws.wsdl.writer.document.Message;
0055: import com.sun.xml.internal.ws.wsdl.writer.document.Operation;
0056: import com.sun.xml.internal.ws.wsdl.writer.document.ParamType;
0057: import com.sun.xml.internal.ws.wsdl.writer.document.Port;
0058: import com.sun.xml.internal.ws.wsdl.writer.document.PortType;
0059: import com.sun.xml.internal.ws.wsdl.writer.document.Service;
0060: import com.sun.xml.internal.ws.wsdl.writer.document.Types;
0061: import com.sun.xml.internal.ws.wsdl.writer.document.soap.Body;
0062: import com.sun.xml.internal.ws.wsdl.writer.document.soap.BodyType;
0063: import com.sun.xml.internal.ws.wsdl.writer.document.soap.Header;
0064: import com.sun.xml.internal.ws.wsdl.writer.document.soap.SOAPAddress;
0065: import com.sun.xml.internal.ws.wsdl.writer.document.soap.SOAPFault;
0066:
0067: import javax.xml.bind.SchemaOutputResolver;
0068: import javax.xml.namespace.QName;
0069: import javax.xml.transform.Result;
0070: import javax.xml.ws.Holder;
0071: import javax.xml.ws.WebServiceException;
0072: import java.io.IOException;
0073: import java.net.URI;
0074: import java.net.URISyntaxException;
0075: import java.util.ArrayList;
0076: import java.util.HashSet;
0077: import java.util.Iterator;
0078: import java.util.List;
0079: import java.util.Set;
0080:
0081: /**
0082: * Class used to generate WSDLs from a <code>RunTimeModel</code>
0083: *
0084: * @author WS Development Team
0085: */
0086: public class WSDLGenerator {
0087: private JAXWSOutputSchemaResolver resolver;
0088: private WSDLOutputResolver wsdlResolver = null;
0089: private RuntimeModel model;
0090: private Definitions serviceDefinitions;
0091: private Definitions portDefinitions;
0092: private Types types;
0093: public static final String DOT_WSDL = ".wsdl";
0094: public static final String RESPONSE = "Response";
0095: public static final String PARAMETERS = "parameters";
0096: public static final String RESULT = "parameters";
0097: public static final String UNWRAPPABLE_RESULT = "result";
0098: public static final String WSDL_NAMESPACE = WSDLConstants.NS_WSDL;
0099: public static final String WSDL_PREFIX = "wsdl";
0100: public static final String XSD_NAMESPACE = SOAPNamespaceConstants.XSD;
0101: public static final String XSD_PREFIX = "xsd";
0102: public static final String SOAP11_NAMESPACE = SOAPConstants.NS_WSDL_SOAP;
0103: public static final String SOAP12_NAMESPACE = SOAPConstants.NS_WSDL_SOAP12;
0104: public static final String SOAP_PREFIX = "soap";
0105: public static final String SOAP12_PREFIX = "soap12";
0106: public static final String TNS_PREFIX = "tns";
0107: public static final String BINDING = "Binding";
0108: public static final String SOAP_HTTP_TRANSPORT = SOAPNamespaceConstants.TRANSPORT_HTTP;
0109: public static final String SOAP12_HTTP_TRANSPORT = SOAP12NamespaceConstants.TRANSPORT_HTTP;
0110: public static final String DOCUMENT = "document";
0111: public static final String RPC = "rpc";
0112: public static final String LITERAL = "literal";
0113: public static final String REPLACE_WITH_ACTUAL_URL = "REPLACE_WITH_ACTUAL_URL";
0114: private Set<QName> processedExceptions = new HashSet<QName>();
0115: private String bindingId;
0116: private String wsdlLocation;
0117: private String portWSDLID;
0118: private String schemaPrefix;
0119:
0120: public WSDLGenerator(RuntimeModel model,
0121: WSDLOutputResolver wsdlResolver, String bindingId) {
0122: this .model = model;
0123: resolver = new JAXWSOutputSchemaResolver();
0124: this .wsdlResolver = wsdlResolver;
0125: this .bindingId = bindingId;
0126: }
0127:
0128: public void doGeneration() {
0129: XmlSerializer serviceWriter;
0130: XmlSerializer portWriter = null;
0131: String fileName = JAXBRIContext.mangleNameToClassName(model
0132: .getServiceQName().getLocalPart());
0133: // System.out.println("concrete name: "+ fileName);
0134: Result result = wsdlResolver.getWSDLOutput(fileName + DOT_WSDL);
0135: if (result == null)
0136: return;
0137: wsdlLocation = result.getSystemId();
0138: serviceWriter = ResultFactory.createSerializer(result);
0139: if (model.getServiceQName().getNamespaceURI().equals(
0140: model.getTargetNamespace())) {
0141: portWriter = serviceWriter;
0142: schemaPrefix = fileName + "_";
0143: } else {
0144: String wsdlName = JAXBRIContext.mangleNameToClassName(model
0145: .getPortTypeName().getLocalPart());
0146: if (wsdlName.equals(fileName))
0147: wsdlName += "PortType";
0148: // System.out.println("abstract name: "+ wsdlName);
0149: Holder<String> absWSDLName = new Holder<String>();
0150: absWSDLName.value = wsdlName + DOT_WSDL;
0151: // System.out.println("absWSDLName.value: "+ absWSDLName.value);
0152: result = wsdlResolver.getAbstractWSDLOutput(absWSDLName);
0153: // System.out.println("absWSDLName.value: "+ absWSDLName.value);
0154: // schemaPrefix = model.getJAXBContext().mangleNameToClassName(portWSDLID)+"_";
0155:
0156: if (result != null) {
0157: portWSDLID = result.getSystemId();
0158: if (portWSDLID.equals(wsdlLocation)) {
0159: portWriter = serviceWriter;
0160: } else {
0161: portWriter = ResultFactory.createSerializer(result);
0162: }
0163: } else {
0164: portWSDLID = absWSDLName.value;
0165: }
0166: schemaPrefix = new java.io.File(portWSDLID).getName();
0167: int idx = schemaPrefix.lastIndexOf('.');
0168: if (idx > 0)
0169: schemaPrefix = schemaPrefix.substring(0, idx);
0170: schemaPrefix = JAXBRIContext
0171: .mangleNameToClassName(schemaPrefix)
0172: + "_";
0173: // System.out.println("portWSDLID: "+ portWSDLID);
0174: // schemaPrefix = model.getJAXBContext().mangleNameToClassName(portWSDLID)+"_";
0175: // System.out.println("schemaPrefix: "+ schemaPrefix);
0176: }
0177: generateDocument(serviceWriter, portWriter);
0178: }
0179:
0180: private void generateDocument(XmlSerializer serviceStream,
0181: XmlSerializer portStream) {
0182: serviceDefinitions = TXW.create(Definitions.class,
0183: serviceStream);
0184: serviceDefinitions._namespace(WSDL_NAMESPACE, "");//WSDL_PREFIX);
0185: serviceDefinitions._namespace(XSD_NAMESPACE, XSD_PREFIX);
0186: serviceDefinitions.targetNamespace(model.getServiceQName()
0187: .getNamespaceURI());
0188: serviceDefinitions._namespace(model.getServiceQName()
0189: .getNamespaceURI(), TNS_PREFIX);
0190: if (bindingId
0191: .equals(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING))
0192: serviceDefinitions._namespace(SOAP12_NAMESPACE,
0193: SOAP12_PREFIX);
0194: else
0195: serviceDefinitions
0196: ._namespace(SOAP11_NAMESPACE, SOAP_PREFIX);
0197: serviceDefinitions.name(model.getServiceQName().getLocalPart());
0198: if (serviceStream != portStream && portStream != null) {
0199: // generate an abstract and concrete wsdl
0200: portDefinitions = TXW.create(Definitions.class, portStream);
0201: portDefinitions._namespace(WSDL_NAMESPACE, "");//WSDL_PREFIX);
0202: portDefinitions._namespace(XSD_NAMESPACE, XSD_PREFIX);
0203: if (model.getTargetNamespace() != null) {
0204: portDefinitions.targetNamespace(model
0205: .getTargetNamespace());
0206: portDefinitions._namespace(model.getTargetNamespace(),
0207: TNS_PREFIX);
0208: }
0209:
0210: String schemaLoc = relativize(portWSDLID, wsdlLocation);
0211: Import _import = serviceDefinitions._import().namespace(
0212: model.getTargetNamespace());
0213: _import.location(schemaLoc);
0214: } else if (portStream != null) {
0215: // abstract and concrete are the same
0216: portDefinitions = serviceDefinitions;
0217: } else {
0218: // import a provided abstract wsdl
0219: String schemaLoc = relativize(portWSDLID, wsdlLocation);
0220: Import _import = serviceDefinitions._import().namespace(
0221: model.getTargetNamespace());
0222: _import.location(schemaLoc);
0223: }
0224:
0225: if (portDefinitions != null) {
0226: generateTypes();
0227: generateMessages();
0228: generatePortType();
0229: }
0230: generateBinding();
0231: generateService();
0232: serviceDefinitions.commit();
0233: if (portDefinitions != null
0234: && portDefinitions != serviceDefinitions)
0235: portDefinitions.commit();
0236: }
0237:
0238: protected void generateTypes() {
0239: types = portDefinitions.types();
0240: if (model.getJAXBContext() != null) {
0241: try {
0242: model.getJAXBContext().generateSchema(resolver);
0243: } catch (IOException e) {
0244: // TODO locallize and wrap this
0245: e.printStackTrace();
0246: throw new WebServiceException(e.getMessage());
0247: }
0248: }
0249: }
0250:
0251: protected void generateMessages() {
0252: for (JavaMethod method : model.getJavaMethods()) {
0253: if (method.getBinding() instanceof SOAPBinding)
0254: generateSOAPMessages(method, (SOAPBinding) method
0255: .getBinding());
0256: }
0257: }
0258:
0259: protected void generateSOAPMessages(JavaMethod method,
0260: SOAPBinding binding) {
0261: boolean isDoclit = binding.isDocLit();
0262: Message message = portDefinitions.message().name(
0263: method.getOperationName());
0264: com.sun.xml.internal.ws.wsdl.writer.document.Part part;
0265: JAXBRIContext jaxbContext = model.getJAXBContext();
0266: boolean unwrappable = true;
0267: for (Parameter param : method.getRequestParameters()) {
0268: if (isDoclit) {
0269: if (isHeaderParameter(param))
0270: unwrappable = false;
0271: if (param.isWrapperStyle()) {
0272: part = message.part().name(PARAMETERS);
0273: part.element(param.getName());
0274: } else {
0275: part = message.part().name(param.getPartName());
0276: part.element(param.getName());
0277: }
0278: } else {
0279: if (param.isWrapperStyle()) {
0280: for (Parameter childParam : ((WrapperParameter) param)
0281: .getWrapperChildren()) {
0282: part = message.part().name(
0283: childParam.getPartName());
0284: part.type(jaxbContext.getTypeName(childParam
0285: .getTypeReference()));
0286: }
0287: } else {
0288: part = message.part().name(param.getPartName());
0289: part.element(param.getName());
0290: }
0291: }
0292: }
0293: if (method.getMEP() != MessageStruct.ONE_WAY_MEP) {
0294: message = portDefinitions.message().name(
0295: method.getOperationName() + RESPONSE);
0296: if (unwrappable) {
0297: for (Parameter param : method.getResponseParameters()) {
0298: if (isHeaderParameter(param))
0299: unwrappable = false;
0300: }
0301: }
0302:
0303: for (Parameter param : method.getResponseParameters()) {
0304: if (isDoclit) {
0305: if (param.isWrapperStyle()) {
0306: // if its not really wrapper style dont use the same name as input message
0307: if (unwrappable)
0308: part = message.part().name(RESULT);
0309: else
0310: part = message.part().name(
0311: UNWRAPPABLE_RESULT);
0312: part.element(param.getName());
0313: } else {
0314: part = message.part().name(param.getPartName());
0315: part.element(param.getName());
0316: }
0317: } else {
0318: if (param.isWrapperStyle()) {
0319: for (Parameter childParam : ((WrapperParameter) param)
0320: .getWrapperChildren()) {
0321: part = message.part().name(
0322: childParam.getPartName());
0323: part.type(jaxbContext
0324: .getTypeName(childParam
0325: .getTypeReference()));
0326: }
0327: } else {
0328: part = message.part().name(param.getPartName());
0329: part.element(param.getName());
0330: }
0331: }
0332: }
0333: }
0334: for (CheckedException exception : method.getCheckedExceptions()) {
0335: QName tagName = exception.getDetailType().tagName;
0336: // if (processedExceptions.contains(tagName))
0337: // continue;
0338: // message = portDefinitions.message().name(tagName.getLocalPart());
0339: String messageName = exception.getMessageName();
0340: QName messageQName = new QName(model.getTargetNamespace(),
0341: messageName);
0342: if (processedExceptions.contains(messageQName))
0343: continue;
0344: message = portDefinitions.message().name(messageName);
0345:
0346: part = message.part().name("fault");//tagName.getLocalPart());
0347: part.element(tagName);
0348: // processedExceptions.add(tagName);
0349: processedExceptions.add(messageQName);
0350: }
0351: }
0352:
0353: protected void generatePortType() {
0354:
0355: PortType portType = portDefinitions.portType().name(
0356: model.getPortTypeName().getLocalPart());
0357: for (JavaMethod method : model.getJavaMethods()) {
0358: Operation operation = portType.operation().name(
0359: method.getOperationName());
0360: generateParameterOrder(operation, method);
0361: switch (method.getMEP()) {
0362: case MessageStruct.REQUEST_RESPONSE_MEP:
0363: // input message
0364: generateInputMessage(operation, method);
0365: // output message
0366: generateOutputMessage(operation, method);
0367: break;
0368: case MessageStruct.ONE_WAY_MEP:
0369: generateInputMessage(operation, method);
0370: break;
0371: }
0372: // faults
0373: for (CheckedException exception : method
0374: .getCheckedExceptions()) {
0375: QName tagName = exception.getDetailType().tagName;
0376: // QName messageName = new QName(model.getTargetNamespace(), tagName.getLocalPart());
0377: // FaultType paramType = operation.fault().name(tagName.getLocalPart()).message(messageName);
0378: QName messageName = new QName(model
0379: .getTargetNamespace(), exception
0380: .getMessageName());
0381: FaultType paramType = operation.fault().name(
0382: exception.getMessageName())
0383: .message(messageName);
0384: }
0385: }
0386: }
0387:
0388: protected boolean isWrapperStyle(JavaMethod method) {
0389: if (method.getRequestParameters().size() > 0) {
0390: Parameter param = method.getRequestParameters().iterator()
0391: .next();
0392: return param.isWrapperStyle();
0393: }
0394: return false;
0395: }
0396:
0397: protected boolean isRpcLit(JavaMethod method) {
0398: if (method.getBinding() instanceof SOAPBinding) {
0399: if (((SOAPBinding) method.getBinding()).getStyle().equals(
0400: Style.RPC))
0401: return true;
0402: }
0403: return false;
0404: }
0405:
0406: protected void generateParameterOrder(Operation operation,
0407: JavaMethod method) {
0408: if (method.getMEP() == MessageStruct.ONE_WAY_MEP)
0409: return;
0410: if (isRpcLit(method))
0411: generateRpcParameterOrder(operation, method);
0412: else
0413: generateDocumentParameterOrder(operation, method);
0414: }
0415:
0416: protected void generateRpcParameterOrder(Operation operation,
0417: JavaMethod method) {
0418: String partName;
0419: StringBuffer paramOrder = new StringBuffer();
0420: Set<String> partNames = new HashSet<String>();
0421: List<Parameter> sortedParams = sortMethodParameters(method);
0422: int i = 0;
0423: for (Parameter parameter : sortedParams) {
0424: if (parameter.getIndex() >= 0) {
0425: partName = parameter.getPartName();
0426: if (!partNames.contains(partName)) {
0427: if (i++ > 0)
0428: paramOrder.append(' ');
0429: paramOrder.append(partName);
0430: partNames.add(partName);
0431: }
0432: }
0433: }
0434: operation.parameterOrder(paramOrder.toString());
0435: }
0436:
0437: protected void generateDocumentParameterOrder(Operation operation,
0438: JavaMethod method) {
0439: String partName;
0440: StringBuffer paramOrder = new StringBuffer();
0441: Set<String> partNames = new HashSet<String>();
0442: List<Parameter> sortedParams = sortMethodParameters(method);
0443: boolean isWrapperStyle = isWrapperStyle(method);
0444: int i = 0;
0445: for (Parameter parameter : sortedParams) {
0446: // System.out.println("param: "+parameter.getIndex()+" name: "+parameter.getName().getLocalPart());
0447: if (parameter.getIndex() < 0)
0448: continue;
0449: if (isWrapperStyle && isBodyParameter(parameter)) {
0450: // System.out.println("isWrapper and is body");
0451: if (method.getRequestParameters().contains(parameter))
0452: partName = PARAMETERS;
0453: else {
0454: // really make sure this is a wrapper style wsdl we are creating
0455: partName = RESPONSE;
0456: }
0457: } else {
0458: partName = parameter.getPartName();
0459: }
0460: if (!partNames.contains(partName)) {
0461: if (i++ > 0)
0462: paramOrder.append(' ');
0463: paramOrder.append(partName);
0464: partNames.add(partName);
0465: }
0466: }
0467: if (i > 1) {
0468: operation.parameterOrder(paramOrder.toString());
0469: }
0470: }
0471:
0472: protected List<Parameter> sortMethodParameters(JavaMethod method) {
0473: Set<Parameter> paramSet = new HashSet<Parameter>();
0474: List<Parameter> sortedParams = new ArrayList<Parameter>();
0475: if (isRpcLit(method)) {
0476: for (Parameter param : method.getRequestParameters()) {
0477: if (param instanceof WrapperParameter) {
0478: paramSet.addAll(((WrapperParameter) param)
0479: .getWrapperChildren());
0480: } else {
0481: paramSet.add(param);
0482: }
0483: }
0484: for (Parameter param : method.getResponseParameters()) {
0485: if (param instanceof WrapperParameter) {
0486: paramSet.addAll(((WrapperParameter) param)
0487: .getWrapperChildren());
0488: } else {
0489: paramSet.add(param);
0490: }
0491: }
0492: } else {
0493: paramSet.addAll(method.getRequestParameters());
0494: paramSet.addAll(method.getResponseParameters());
0495: }
0496: Iterator<Parameter> params = paramSet.iterator();
0497: if (paramSet.size() == 0)
0498: return sortedParams;
0499: Parameter param = params.next();
0500: sortedParams.add(param);
0501: Parameter sortedParam;
0502: int pos;
0503: for (int i = 1; i < paramSet.size(); i++) {
0504: param = params.next();
0505: for (pos = 0; pos < i; pos++) {
0506: sortedParam = sortedParams.get(pos);
0507: if (param.getIndex() == sortedParam.getIndex()
0508: && param instanceof WrapperParameter)
0509: break;
0510: if (param.getIndex() < sortedParam.getIndex()) {
0511: break;
0512: }
0513: }
0514: sortedParams.add(pos, param);
0515: }
0516: return sortedParams;
0517: }
0518:
0519: protected boolean isBodyParameter(Parameter parameter) {
0520: ParameterBinding paramBinding = parameter.getBinding();
0521: return paramBinding.isBody();
0522: }
0523:
0524: protected boolean isHeaderParameter(Parameter parameter) {
0525: ParameterBinding paramBinding = parameter.getBinding();
0526: return paramBinding.isHeader();
0527: }
0528:
0529: protected boolean isAttachmentParameter(Parameter parameter) {
0530: ParameterBinding paramBinding = parameter.getBinding();
0531: return paramBinding.isAttachment();
0532: }
0533:
0534: protected void generateBinding() {
0535: Binding binding = serviceDefinitions.binding().name(
0536: model.getPortName().getLocalPart() + BINDING);
0537: binding.type(model.getPortTypeName());
0538: boolean first = true;
0539: for (JavaMethod method : model.getJavaMethods()) {
0540: if (first) {
0541: if (method.getBinding() instanceof SOAPBinding) {
0542: SOAPBinding sBinding = (SOAPBinding) method
0543: .getBinding();
0544: SOAPVersion soapVersion = sBinding.getSOAPVersion();
0545:
0546: if (soapVersion
0547: .equals(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)) {
0548: com.sun.xml.internal.ws.wsdl.writer.document.soap12.SOAPBinding soapBinding = binding
0549: .soap12Binding();
0550: soapBinding.transport(SOAP12_HTTP_TRANSPORT);
0551: if (sBinding.getStyle().equals(Style.DOCUMENT))
0552: soapBinding.style(DOCUMENT);
0553: else
0554: soapBinding.style(RPC);
0555: } else {
0556: com.sun.xml.internal.ws.wsdl.writer.document.soap.SOAPBinding soapBinding = binding
0557: .soapBinding();
0558: soapBinding.transport(SOAP_HTTP_TRANSPORT);
0559: if (sBinding.getStyle().equals(Style.DOCUMENT))
0560: soapBinding.style(DOCUMENT);
0561: else
0562: soapBinding.style(RPC);
0563: }
0564: }
0565: first = false;
0566: }
0567: if (bindingId
0568: .equals(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING))
0569: generateSOAP12BindingOperation(method, binding);
0570: else
0571: generateBindingOperation(method, binding);
0572: }
0573: }
0574:
0575: protected void generateBindingOperation(JavaMethod method,
0576: Binding binding) {
0577: BindingOperationType operation = binding.operation().name(
0578: method.getOperationName());
0579: String targetNamespace = model.getTargetNamespace();
0580: QName requestMessage = new QName(targetNamespace, method
0581: .getOperationName());
0582: QName responseMessage = new QName(targetNamespace, method
0583: .getOperationName()
0584: + RESPONSE);
0585: if (method.getBinding() instanceof SOAPBinding) {
0586: List<Parameter> bodyParams = new ArrayList<Parameter>();
0587: List<Parameter> headerParams = new ArrayList<Parameter>();
0588: splitParameters(bodyParams, headerParams, method
0589: .getRequestParameters());
0590: SOAPBinding soapBinding = (SOAPBinding) method.getBinding();
0591: operation.soapOperation().soapAction(
0592: soapBinding.getSOAPAction());
0593:
0594: // input
0595: TypedXmlWriter input = operation.input();
0596: BodyType body = input._element(Body.class);
0597: boolean isRpc = soapBinding.getStyle().equals(Style.RPC);
0598: if (soapBinding.getUse().equals(Use.LITERAL)) {
0599: body.use(LITERAL);
0600: if (headerParams.size() > 0) {
0601: if (bodyParams.size() > 0) {
0602: Parameter param = bodyParams.iterator().next();
0603: if (isRpc) {
0604: StringBuffer parts = new StringBuffer();
0605: int i = 0;
0606: for (Parameter parameter : ((WrapperParameter) param)
0607: .getWrapperChildren()) {
0608: if (i++ > 0)
0609: parts.append(' ');
0610: parts.append(parameter.getPartName());
0611: }
0612: body.parts(parts.toString());
0613: } else if (param.isWrapperStyle()) {
0614: body.parts(PARAMETERS);
0615: } else {
0616: body.parts(param.getPartName());
0617: }
0618: } else {
0619: body.parts("");
0620: }
0621: generateSOAPHeaders(input, headerParams,
0622: requestMessage);
0623: }
0624: if (isRpc) {
0625: body.namespace(method.getRequestParameters()
0626: .iterator().next().getName()
0627: .getNamespaceURI());
0628: }
0629: } else {
0630: // TODO localize this
0631: throw new WebServiceException(
0632: "encoded use is not supported");
0633: }
0634:
0635: if (method.getMEP() != MessageStruct.ONE_WAY_MEP) {
0636: boolean unwrappable = headerParams.size() == 0;
0637: // output
0638: bodyParams.clear();
0639: headerParams.clear();
0640: splitParameters(bodyParams, headerParams, method
0641: .getResponseParameters());
0642: unwrappable = unwrappable ? headerParams.size() == 0
0643: : unwrappable;
0644: TypedXmlWriter output = operation.output();
0645: body = output._element(Body.class);
0646: body.use(LITERAL);
0647: if (headerParams.size() > 0) {
0648: String parts = "";
0649: if (bodyParams.size() > 0) {
0650: Parameter param = bodyParams.iterator().next();
0651: if (isRpc) {
0652: int i = 0;
0653: for (Parameter parameter : ((WrapperParameter) param)
0654: .getWrapperChildren()) {
0655: if (i++ > 0)
0656: parts += " ";
0657: parts += parameter.getPartName();
0658: }
0659: } else {
0660: if (param != null) {
0661: if (param.isWrapperStyle()) {
0662: // if its not really wrapper style dont use the same name as input message
0663: if (unwrappable)
0664: parts = RESULT;
0665: else
0666: parts = UNWRAPPABLE_RESULT;
0667: } else {
0668: parts = param.getPartName();
0669: }
0670: }
0671: }
0672: }
0673: body.parts(parts);
0674: generateSOAPHeaders(output, headerParams,
0675: responseMessage);
0676: }
0677: if (isRpc) {
0678: body.namespace(method.getRequestParameters()
0679: .iterator().next().getName()
0680: .getNamespaceURI());
0681: }
0682: }
0683: for (CheckedException exception : method
0684: .getCheckedExceptions()) {
0685: // QName tagName = exception.getDetailType().tagName;
0686: // Fault fault = operation.fault().name(tagName.getLocalPart());
0687: // SOAPFault soapFault = fault._element(SOAPFault.class).name(tagName.getLocalPart());
0688: Fault fault = operation.fault().name(
0689: exception.getMessageName());
0690: SOAPFault soapFault = fault._element(SOAPFault.class)
0691: .name(exception.getMessageName());
0692: soapFault.use(LITERAL);
0693: }
0694: }
0695: }
0696:
0697: protected void generateSOAP12BindingOperation(JavaMethod method,
0698: Binding binding) {
0699: BindingOperationType operation = binding.operation().name(
0700: method.getOperationName());
0701: String targetNamespace = model.getTargetNamespace();
0702: QName requestMessage = new QName(targetNamespace, method
0703: .getOperationName());
0704: QName responseMessage = new QName(targetNamespace, method
0705: .getOperationName()
0706: + RESPONSE);
0707: if (method.getBinding() instanceof SOAPBinding) {
0708: List<Parameter> bodyParams = new ArrayList<Parameter>();
0709: List<Parameter> headerParams = new ArrayList<Parameter>();
0710: splitParameters(bodyParams, headerParams, method
0711: .getRequestParameters());
0712: SOAPBinding soapBinding = (SOAPBinding) method.getBinding();
0713: operation.soap12Operation().soapAction(
0714: soapBinding.getSOAPAction());
0715:
0716: // input
0717: TypedXmlWriter input = operation.input();
0718:
0719: com.sun.xml.internal.ws.wsdl.writer.document.soap12.BodyType body = input
0720: ._element(com.sun.xml.internal.ws.wsdl.writer.document.soap12.Body.class);
0721: boolean isRpc = soapBinding.getStyle().equals(Style.RPC);
0722: if (soapBinding.getUse().equals(Use.LITERAL)) {
0723: body.use(LITERAL);
0724: if (headerParams.size() > 0) {
0725: if (bodyParams.size() > 0) {
0726: Parameter param = bodyParams.iterator().next();
0727: if (isRpc) {
0728: StringBuffer parts = new StringBuffer();
0729: int i = 0;
0730: for (Parameter parameter : ((WrapperParameter) param)
0731: .getWrapperChildren()) {
0732: if (i++ > 0)
0733: parts.append(' ');
0734: parts.append(parameter.getPartName());
0735: }
0736: body.parts(parts.toString());
0737: } else if (param.isWrapperStyle()) {
0738: body.parts(PARAMETERS);
0739: } else {
0740: body.parts(param.getPartName());
0741: }
0742: } else {
0743: body.parts("");
0744: }
0745: generateSOAP12Headers(input, headerParams,
0746: requestMessage);
0747: }
0748: if (isRpc) {
0749: body.namespace(method.getRequestParameters()
0750: .iterator().next().getName()
0751: .getNamespaceURI());
0752: }
0753: } else {
0754: // TODO localize this
0755: throw new WebServiceException(
0756: "encoded use is not supported");
0757: }
0758:
0759: if (method.getMEP() != MessageStruct.ONE_WAY_MEP) {
0760: // output
0761: boolean unwrappable = headerParams.size() == 0;
0762: bodyParams.clear();
0763: headerParams.clear();
0764: splitParameters(bodyParams, headerParams, method
0765: .getResponseParameters());
0766: unwrappable = unwrappable ? headerParams.size() == 0
0767: : unwrappable;
0768: TypedXmlWriter output = operation.output();
0769: body = output
0770: ._element(com.sun.xml.internal.ws.wsdl.writer.document.soap12.Body.class);
0771: body.use(LITERAL);
0772: if (headerParams.size() > 0) {
0773: if (bodyParams.size() > 0) {
0774: Parameter param = bodyParams.iterator().next();
0775: if (isRpc) {
0776: String parts = "";
0777: int i = 0;
0778: for (Parameter parameter : ((WrapperParameter) param)
0779: .getWrapperChildren()) {
0780: if (i++ > 0)
0781: parts += " ";
0782: parts += parameter.getPartName();
0783: }
0784: body.parts(parts);
0785: } else if (param.isWrapperStyle()) {
0786: // if its not really wrapper style dont use the same name as input message
0787: if (unwrappable)
0788: body.parts(RESULT);
0789: else
0790: body.parts(UNWRAPPABLE_RESULT);
0791: } else {
0792: body.parts(param.getPartName());
0793: }
0794: } else {
0795: body.parts("");
0796: }
0797: generateSOAP12Headers(output, headerParams,
0798: responseMessage);
0799: }
0800: if (isRpc) {
0801: body.namespace(method.getRequestParameters()
0802: .iterator().next().getName()
0803: .getNamespaceURI());
0804: }
0805: }
0806: for (CheckedException exception : method
0807: .getCheckedExceptions()) {
0808: // QName tagName = exception.getDetailType().tagName;
0809: // Fault fault = operation.fault().name(tagName.getLocalPart());
0810: // 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(tagName.getLocalPart());
0811: Fault fault = operation.fault().name(
0812: exception.getMessageName());
0813: com.sun.xml.internal.ws.wsdl.writer.document.soap12.SOAPFault soapFault = fault
0814: ._element(
0815: com.sun.xml.internal.ws.wsdl.writer.document.soap12.SOAPFault.class)
0816: .name(exception.getMessageName());
0817: soapFault.use(LITERAL);
0818: }
0819: }
0820: }
0821:
0822: protected void splitParameters(List<Parameter> bodyParams,
0823: List<Parameter> headerParams, List<Parameter> params) {
0824: for (Parameter parameter : params) {
0825: if (isBodyParameter(parameter)) {
0826: bodyParams.add(parameter);
0827: } else {
0828: headerParams.add(parameter);
0829: }
0830: }
0831: }
0832:
0833: protected void generateSOAPHeaders(TypedXmlWriter writer,
0834: List<Parameter> parameters, QName message) {
0835:
0836: for (Parameter headerParam : parameters) {
0837: Header header = writer._element(Header.class);
0838: header.message(message);
0839: header.part(headerParam.getPartName());
0840: header.use(LITERAL);
0841: }
0842: }
0843:
0844: protected void generateSOAP12Headers(TypedXmlWriter writer,
0845: List<Parameter> parameters, QName message) {
0846:
0847: for (Parameter headerParam : parameters) {
0848: com.sun.xml.internal.ws.wsdl.writer.document.soap12.Header header = writer
0849: ._element(com.sun.xml.internal.ws.wsdl.writer.document.soap12.Header.class);
0850: header.message(message);
0851:
0852: header.part(headerParam.getPartName());
0853: header.use(LITERAL);
0854: }
0855: }
0856:
0857: protected void generateService() {
0858: QName portQName = model.getPortName();
0859: QName serviceQName = model.getServiceQName();
0860: Service service = serviceDefinitions.service().name(
0861: serviceQName.getLocalPart());
0862: Port port = service.port().name(portQName.getLocalPart());
0863: port.binding(new QName(serviceQName.getNamespaceURI(),
0864: portQName.getLocalPart() + BINDING));
0865: if (model.getJavaMethods().size() == 0)
0866: return;
0867: if (model.getJavaMethods().iterator().next().getBinding() instanceof SOAPBinding) {
0868: if (bindingId
0869: .equals(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)) {
0870: com.sun.xml.internal.ws.wsdl.writer.document.soap12.SOAPAddress address = port
0871: ._element(com.sun.xml.internal.ws.wsdl.writer.document.soap12.SOAPAddress.class);
0872: address.location(REPLACE_WITH_ACTUAL_URL);
0873: } else {
0874: SOAPAddress address = port._element(SOAPAddress.class);
0875: address.location(REPLACE_WITH_ACTUAL_URL);
0876: }
0877: }
0878: }
0879:
0880: protected void generateInputMessage(Operation operation,
0881: JavaMethod method) {
0882: ParamType paramType = operation.input();
0883: paramType.message(new QName(model.getTargetNamespace(), method
0884: .getOperationName()));
0885: }
0886:
0887: protected void generateOutputMessage(Operation operation,
0888: JavaMethod method) {
0889: ParamType paramType = operation.output();
0890: paramType.message(new QName(model.getTargetNamespace(), method
0891: .getOperationName()
0892: + RESPONSE));
0893: }
0894:
0895: public Result createOutputFile(String namespaceUri,
0896: String suggestedFileName) throws IOException {
0897: Result result;
0898: if (namespaceUri.equals("")) {
0899: return null;
0900: }
0901: com.sun.xml.internal.ws.wsdl.writer.document.xsd.Import _import = types
0902: .schema()._import().namespace(namespaceUri);
0903:
0904: Holder<String> fileNameHolder = new Holder<String>();
0905: fileNameHolder.value = schemaPrefix + suggestedFileName;
0906: result = wsdlResolver.getSchemaOutput(namespaceUri,
0907: fileNameHolder);
0908: // System.out.println("schema file: "+fileNameHolder.value);
0909: // System.out.println("result: "+result);
0910: String schemaLoc;
0911: if (result == null)
0912: schemaLoc = fileNameHolder.value;
0913: else
0914: schemaLoc = relativize(result.getSystemId(), wsdlLocation);
0915: // System.out.println("schemaLoca: "+schemaLoc);
0916: _import.schemaLocation(schemaLoc);
0917: return result;
0918: }
0919:
0920: /**
0921: * Relativizes a URI by using another URI (base URI.)
0922: *
0923: * <p>
0924: * For example, {@code relative("http://www.sun.com/abc/def","http://www.sun.com/pqr/stu") => "../abc/def"}
0925: *
0926: * <p>
0927: * This method only works on hierarchical URI's, not opaque URI's (refer to the
0928: * <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/URI.html">java.net.URI</a>
0929: * javadoc for complete definitions of these terms.
0930: *
0931: * <p>
0932: * This method will not normalize the relative URI.
0933: *
0934: * @return the relative URI or the original URI if a relative one could not be computed
0935: */
0936: protected static String relativize(String uri, String baseUri) {
0937: try {
0938: assert uri != null;
0939:
0940: if (baseUri == null)
0941: return uri;
0942:
0943: URI theUri = new URI(escapeURI(uri));
0944: URI theBaseUri = new URI(escapeURI(baseUri));
0945:
0946: if (theUri.isOpaque() || theBaseUri.isOpaque())
0947: return uri;
0948:
0949: if (!equalsIgnoreCase(theUri.getScheme(), theBaseUri
0950: .getScheme())
0951: || !equal(theUri.getAuthority(), theBaseUri
0952: .getAuthority()))
0953: return uri;
0954:
0955: String uriPath = theUri.getPath();
0956: String basePath = theBaseUri.getPath();
0957:
0958: // normalize base path
0959: if (!basePath.endsWith("/")) {
0960: basePath = normalizeUriPath(basePath);
0961: }
0962:
0963: if (uriPath.equals(basePath))
0964: return ".";
0965:
0966: String relPath = calculateRelativePath(uriPath, basePath);
0967:
0968: if (relPath == null)
0969: return uri; // recursion found no commonality in the two uris at all
0970: StringBuffer relUri = new StringBuffer();
0971: relUri.append(relPath);
0972: if (theUri.getQuery() != null)
0973: relUri.append('?').append(theUri.getQuery());
0974: if (theUri.getFragment() != null)
0975: relUri.append('#').append(theUri.getFragment());
0976:
0977: return relUri.toString();
0978: } catch (URISyntaxException e) {
0979: throw new InternalError(
0980: "Error escaping one of these uris:\n\t" + uri
0981: + "\n\t" + baseUri);
0982: }
0983: }
0984:
0985: private static String calculateRelativePath(String uri, String base) {
0986: if (base == null) {
0987: return null;
0988: }
0989: if (uri.startsWith(base)) {
0990: return uri.substring(base.length());
0991: } else {
0992: return "../"
0993: + calculateRelativePath(uri, getParentUriPath(base));
0994: }
0995: }
0996:
0997: protected class JAXWSOutputSchemaResolver extends
0998: SchemaOutputResolver {
0999: public Result createOutput(String namespaceUri,
1000: String suggestedFileName) throws IOException {
1001: return createOutputFile(namespaceUri, suggestedFileName);
1002: }
1003: }
1004: }
|