blob: 5308b3c0e733dd1c6a8d8f577daa4cc8b1b35953 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.binding.ws.wsdlgen;
import java.util.Iterator;
import javax.wsdl.Binding;
import javax.wsdl.BindingFault;
import javax.wsdl.BindingInput;
import javax.wsdl.BindingOperation;
import javax.wsdl.BindingOutput;
import javax.wsdl.Definition;
import javax.wsdl.Fault;
import javax.wsdl.Input;
import javax.wsdl.Operation;
import javax.wsdl.Output;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.wsdl.Types;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.wsdl.extensions.soap.SOAPBinding;
import javax.wsdl.extensions.soap.SOAPBody;
import javax.wsdl.extensions.soap.SOAPFault;
import javax.wsdl.extensions.soap.SOAPOperation;
import javax.wsdl.extensions.soap12.SOAP12Address;
import javax.wsdl.extensions.soap12.SOAP12Binding;
import javax.wsdl.extensions.soap12.SOAP12Body;
import javax.wsdl.extensions.soap12.SOAP12Fault;
import javax.wsdl.extensions.soap12.SOAP12Operation;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;
import javax.xml.namespace.QName;
import org.apache.tuscany.sca.binding.ws.WebServiceBinding;
import org.w3c.dom.Element;
/**
*
* @version $Rev$ $Date$
*/
public class WSDLDefinitionGenerator {
private static final String SOAP_NS = "http://schemas.xmlsoap.org/wsdl/soap/";
public static final QName SOAP_ADDRESS = new QName(SOAP_NS, "address");
private static final QName SOAP_BINDING = new QName(SOAP_NS, "binding");
private static final QName SOAP_BODY = new QName(SOAP_NS, "body");
private static final QName SOAP_FAULT = new QName(SOAP_NS, "fault");
private static final QName SOAP_OPERATION = new QName(SOAP_NS, "operation");
private static final String SOAP12_NS = "http://schemas.xmlsoap.org/wsdl/soap12/";
public static final QName SOAP12_ADDRESS = new QName(SOAP12_NS, "address");
private static final QName SOAP12_BINDING = new QName(SOAP12_NS, "binding");
private static final QName SOAP12_BODY = new QName(SOAP12_NS, "body");
private static final QName SOAP12_FAULT = new QName(SOAP12_NS, "fault");
private static final QName SOAP12_OPERATION = new QName(SOAP12_NS, "operation");
private static final String BINDING_SUFFIX = "Binding";
private static final String SERVICE_SUFFIX = "Service";
private static final String PORT_SUFFIX = "Port";
private boolean requiresSOAP12;
private QName soapAddress;
private QName soapBinding;
private QName soapBody;
private QName soapFault;
private QName soapOperation;
private String wsBindingName;
public WSDLDefinitionGenerator(WebServiceBinding wsBinding) {
this(BindingWSDLGenerator.requiresSOAP12(wsBinding));
wsBindingName = wsBinding.getName();
}
public WSDLDefinitionGenerator(boolean isSOAP12) {
super();
this.requiresSOAP12 = isSOAP12;
soapAddress = requiresSOAP12 ? SOAP12_ADDRESS : SOAP_ADDRESS;
soapBinding = requiresSOAP12 ? SOAP12_BINDING : SOAP_BINDING;
soapBody = requiresSOAP12 ? SOAP12_BODY : SOAP_BODY;
soapFault = requiresSOAP12 ? SOAP12_FAULT : SOAP_FAULT;
soapOperation = requiresSOAP12 ? SOAP12_OPERATION : SOAP_OPERATION;
}
public Definition cloneDefinition(WSDLFactory factory, Definition definition) throws WSDLException {
Element root = definition.getDocumentationElement();
root = (Element)root.cloneNode(true);
WSDLReader reader = factory.newWSDLReader();
return reader.readWSDL(definition.getDocumentBaseURI(), root);
}
public Types createTypes(Definition definition) {
Types types = definition.createTypes();
definition.setTypes(types);
return types;
}
public Binding createBinding(Definition definition, PortType portType) {
try {
Binding binding = definition.createBinding();
binding.setPortType(portType);
configureBinding(definition, binding, portType);
ExtensibilityElement bindingExtension =
definition.getExtensionRegistry().createExtension(Binding.class, soapBinding);
if (requiresSOAP12) {
((SOAP12Binding)bindingExtension).setStyle("document");
((SOAP12Binding)bindingExtension).setTransportURI("http://schemas.xmlsoap.org/soap/http");
} else {
((SOAPBinding)bindingExtension).setStyle("document");
((SOAPBinding)bindingExtension).setTransportURI("http://schemas.xmlsoap.org/soap/http");
}
binding.addExtensibilityElement(bindingExtension);
return binding;
} catch (WSDLException e) {
throw new WSDLGenerationException(e);
}
}
protected void configureBinding(Definition definition, Binding binding, PortType portType) throws WSDLException {
if ( wsBindingName != null ) {
QName name = new QName(definition.getTargetNamespace(), wsBindingName + getSOAPVersionString() + BINDING_SUFFIX);
if ( definition.getBinding(name) == null ) {
binding.setQName(name);
return;
}
}
QName portTypeName = portType.getQName();
if (portTypeName != null) {
// Choose <porttype>Binding if available. If this name is in use, insert
// separating underscores until there is no clash.
for (String suffix = BINDING_SUFFIX; ; suffix = "_" + suffix) {
QName name = new QName(definition.getTargetNamespace(), portTypeName.getLocalPart() + suffix);
if (definition.getBinding(name) == null) {
binding.setQName(name);
break;
}
}
}
}
@SuppressWarnings("unchecked")
public void createBindingOperations(Definition definition, Binding binding, PortType portType) {
try {
for (Iterator oi = portType.getOperations().iterator(); oi.hasNext();) {
Operation operation = (Operation)oi.next();
BindingOperation bindingOperation =
createBindingOperation(definition, operation, "urn:" + operation.getName());
binding.addBindingOperation(bindingOperation);
}
} catch (WSDLException e) {
throw new WSDLGenerationException(e);
}
}
@SuppressWarnings("unchecked")
public BindingOperation createBindingOperation(Definition definition, Operation operation, String action)
throws WSDLException {
BindingOperation bindingOperation = definition.createBindingOperation();
bindingOperation.setOperation(operation);
configureBindingOperation(bindingOperation, operation);
ExtensibilityElement operationExtension =
definition.getExtensionRegistry().createExtension(BindingOperation.class, soapOperation);
if (requiresSOAP12) {
((SOAP12Operation)operationExtension).setSoapActionURI(action);
} else {
((SOAPOperation)operationExtension).setSoapActionURI(action);
}
bindingOperation.addExtensibilityElement(operationExtension);
if (operation.getInput() != null) {
BindingInput bindingInput = definition.createBindingInput();
configureBindingInput(bindingInput, operation.getInput());
ExtensibilityElement inputExtension =
definition.getExtensionRegistry().createExtension(BindingInput.class, soapBody);
if (requiresSOAP12) {
((SOAP12Body)inputExtension).setUse("literal");
} else {
((SOAPBody)inputExtension).setUse("literal");
}
bindingInput.addExtensibilityElement(inputExtension);
bindingOperation.setBindingInput(bindingInput);
}
if (operation.getOutput() != null) {
BindingOutput bindingOutput = definition.createBindingOutput();
configureBindingOutput(bindingOutput, operation.getOutput());
ExtensibilityElement outputExtension =
definition.getExtensionRegistry().createExtension(BindingOutput.class, soapBody);
if (requiresSOAP12) {
((SOAP12Body)outputExtension).setUse("literal");
} else {
((SOAPBody)outputExtension).setUse("literal");
}
bindingOutput.addExtensibilityElement(outputExtension);
bindingOperation.setBindingOutput(bindingOutput);
}
for (Iterator fi = operation.getFaults().values().iterator(); fi.hasNext();) {
Fault fault = (Fault)fi.next();
BindingFault bindingFault = definition.createBindingFault();
ExtensibilityElement faultExtension =
definition.getExtensionRegistry().createExtension(BindingFault.class, soapFault);
configureBindingFault(bindingFault, faultExtension, fault);
bindingFault.addExtensibilityElement(faultExtension);
bindingOperation.addBindingFault(bindingFault);
}
return bindingOperation;
}
protected void configureBindingOperation(BindingOperation bindingOperation, Operation operation)
throws WSDLException {
bindingOperation.setName(operation.getName());
}
protected void configureBindingInput(BindingInput bindingInput, Input input) throws WSDLException {
bindingInput.setName(input.getName());
}
protected void configureBindingOutput(BindingOutput bindingOutput, Output output) throws WSDLException {
bindingOutput.setName(output.getName());
}
protected void configureBindingFault(BindingFault bindingFault,
ExtensibilityElement faultExtension,
Fault fault)
throws WSDLException {
String faultName = fault.getName();
bindingFault.setName(faultName);
if (requiresSOAP12) {
((SOAP12Fault)faultExtension).setName(faultName);
((SOAP12Fault)faultExtension).setUse("literal");
} else {
((SOAPFault)faultExtension).setName(faultName);
((SOAPFault)faultExtension).setUse("literal");
}
}
public Service createService(Definition definition, PortType portType, String serviceName) {
try {
Service service = definition.createService();
configureService(definition, service, portType, serviceName);
definition.addService(service);
return service;
} catch (WSDLException e) {
throw new WSDLGenerationException(e);
}
}
public Service createService(Definition definition, Binding binding, String serviceName) {
try {
Service service = definition.createService();
configureService(definition, service, binding.getPortType(), serviceName);
definition.addService(service);
return service;
} catch (WSDLException e) {
throw new WSDLGenerationException(e);
}
}
protected void configureService(Definition definition, Service service, PortType portType, String serviceName) throws WSDLException {
if ( serviceName != null ) {
QName name = new QName(definition.getTargetNamespace(), serviceName);
if ( definition.getService(name) == null ) {
service.setQName(name);
return;
}
}
QName portTypeName = portType.getQName();
if (portTypeName != null) {
// Choose <porttype>Service if available. If this name is in use, insert
// separating underscores until there is no clash.
for (String suffix = SERVICE_SUFFIX; ; suffix = "_" + suffix) {
QName name = new QName(definition.getTargetNamespace(), portTypeName.getLocalPart() + suffix);
if (definition.getService(name) == null) {
service.setQName(name);
break;
}
}
}
}
public Port createPort(Definition definition, Binding binding, Service service, String uri) {
try {
Port port = definition.createPort();
port.setBinding(binding);
configurePort(port, binding);
if (uri != null) {
ExtensibilityElement portExtension =
definition.getExtensionRegistry().createExtension(Port.class, soapAddress);
if (requiresSOAP12) {
((SOAP12Address)portExtension).setLocationURI(uri);
} else {
((SOAPAddress)portExtension).setLocationURI(uri);
}
port.addExtensibilityElement(portExtension);
}
service.addPort(port);
return port;
} catch (WSDLException e) {
throw new WSDLGenerationException(e);
}
}
protected void configurePort(Port port, Binding binding) throws WSDLException {
if ( wsBindingName != null ) {
port.setName(wsBindingName + getSOAPVersionString() + PORT_SUFFIX);
} else if (binding.getPortType() != null && binding.getPortType().getQName() != null) {
port.setName(binding.getPortType().getQName().getLocalPart() + PORT_SUFFIX);
}
}
private String getSOAPVersionString() {
if ( requiresSOAP12 ) {
return "SOAP12";
} else {
return "SOAP11";
}
}
}