blob: 2b666bc7b8b1993d5a76a529b48bd06d6b56794d [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.axis2.rmi.wsdl;
import org.apache.axis2.rmi.exception.SchemaGenerationException;
import org.apache.axis2.rmi.metadata.Operation;
import org.apache.axis2.rmi.metadata.Parameter;
import org.apache.axis2.rmi.metadata.Service;
import org.apache.axis2.rmi.metadata.xml.XmlSchema;
import org.apache.axis2.rmi.util.Util;
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.Message;
import javax.wsdl.OperationType;
import javax.wsdl.Output;
import javax.wsdl.Part;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Types;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.ExtensionRegistry;
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.factory.WSDLFactory;
import javax.xml.namespace.QName;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* this class is used to create the wsdl11 object sturcture from the
* service object structure.
*/
public class WSDL11DefinitionBuilder {
/**
* service to generate the
*/
private Service service;
/**
* wsdl definition object to populate
*/
private Definition wsdlDefinition;
/**
* port type for this wsdl
*/
private PortType portType;
private Binding httpSoapBinding;
//TODO: generate code for this binding.
private Binding httpSoap12Binding;
public WSDL11DefinitionBuilder(Service service) {
this.service = service;
}
/**
* generates the wsdl for this service
*
* @throws SchemaGenerationException
*/
public Definition generateWSDL() throws SchemaGenerationException {
try {
this.wsdlDefinition = WSDLFactory.newInstance().newDefinition();
//TODO: keep the namespace prefix map if needed
this.wsdlDefinition.addNamespace(Util.getNextNamespacePrefix(), this.service.getNamespace());
this.wsdlDefinition.addNamespace(Util.getNextNamespacePrefix(), "http://schemas.xmlsoap.org/wsdl/soap/");
this.wsdlDefinition.setTargetNamespace(this.service.getNamespace());
// first generate the schemas
generateTypes();
generatePortType();
generateBindings();
generateService();
generateOperationsAndMessages();
return this.wsdlDefinition;
} catch (WSDLException e) {
throw new SchemaGenerationException("Error in creating a new wsdl definition", e);
}
}
/**
* generates the schemas for the wsdl
*
* @throws SchemaGenerationException
*/
private void generateTypes() throws SchemaGenerationException {
Types types = this.wsdlDefinition.createTypes();
this.wsdlDefinition.setTypes(types);
XmlSchema xmlSchema;
for (Iterator iter = this.service.getSchemaMap().values().iterator(); iter.hasNext();) {
xmlSchema = (XmlSchema) iter.next();
xmlSchema.generateWSDLSchema();
types.addExtensibilityElement(xmlSchema.getWsdlSchema());
}
}
/**
* generates the port type for the wsdl
*/
private void generatePortType() {
this.portType = this.wsdlDefinition.createPortType();
this.portType.setUndefined(false);
this.portType.setQName(new QName(this.service.getNamespace(), this.service.getName() + "PortType"));
this.wsdlDefinition.addPortType(portType);
}
private void generateBindings() throws SchemaGenerationException {
this.httpSoapBinding = this.wsdlDefinition.createBinding();
this.httpSoapBinding.setUndefined(false);
this.httpSoapBinding.setQName(new QName(this.service.getNamespace(),
this.service.getName() + "HttpSoapBinding"));
this.httpSoapBinding.setPortType(this.portType);
// add soap transport parts
ExtensionRegistry extensionRegistry = null;
try {
extensionRegistry = WSDLFactory.newInstance().newPopulatedExtensionRegistry();
SOAPBinding soapBinding = (SOAPBinding) extensionRegistry.createExtension(
Binding.class, new QName("http://schemas.xmlsoap.org/wsdl/soap/", "binding"));
soapBinding.setTransportURI("http://schemas.xmlsoap.org/soap/http");
soapBinding.setStyle("document");
this.httpSoapBinding.addExtensibilityElement(soapBinding);
} catch (WSDLException e) {
throw new SchemaGenerationException("Can not crete a wsdl factory");
}
this.wsdlDefinition.addBinding(this.httpSoapBinding);
this.wsdlDefinition.getBindings().put(this.httpSoapBinding.getQName(),
this.httpSoapBinding);
}
private void generateService()
throws SchemaGenerationException {
// now add the binding portType and messages corresponding to every operation
javax.wsdl.Service service = this.wsdlDefinition.createService();
service.setQName(new QName(this.service.getNamespace(), this.service.getName()));
Port port = this.wsdlDefinition.createPort();
port.setName(this.service.getName() + "HttpSoapPort");
port.setBinding(this.httpSoapBinding);
ExtensionRegistry extensionRegistry = null;
try {
extensionRegistry = WSDLFactory.newInstance().newPopulatedExtensionRegistry();
SOAPAddress soapAddress = (SOAPAddress) extensionRegistry.createExtension(
Port.class, new QName("http://schemas.xmlsoap.org/wsdl/soap/", "address"));
soapAddress.setLocationURI("http://localhost:8080/axis2/services/" + this.service.getName());
port.addExtensibilityElement(soapAddress);
} catch (WSDLException e) {
throw new SchemaGenerationException("Can not crete a wsdl factory");
}
service.addPort(port);
this.wsdlDefinition.addService(service);
}
private void generateOperationsAndMessages()
throws SchemaGenerationException {
org.apache.axis2.rmi.metadata.Operation operation;
Message inputMessage;
Message outputMessage;
javax.wsdl.Operation wsdlOperation;
BindingOperation bindingOperation;
//generate messages for exceptions
Map exceptionMessagesMap = new HashMap();
Class exceptionClass;
Parameter parameter;
Message faultMessage;
String messageName;
Part part;
for (Iterator iter = this.service.getExceptionClassToParameterMap().keySet().iterator(); iter.hasNext();) {
exceptionClass = (Class) iter.next();
parameter = (Parameter) this.service.getExceptionClassToParameterMap().get(exceptionClass);
messageName = exceptionClass.getName();
messageName = messageName.substring(messageName.lastIndexOf(".") + 1);
faultMessage = this.wsdlDefinition.createMessage();
faultMessage.setUndefined(false);
faultMessage.setQName(new QName(this.service.getNamespace(), messageName));
part = this.wsdlDefinition.createPart();
part.setName("fault");
// add this element namespace to the definition
if (this.wsdlDefinition.getPrefix(parameter.getElement().getNamespace()) == null) {
this.wsdlDefinition.addNamespace(Util.getNextNamespacePrefix(), parameter.getElement().getNamespace());
}
part.setElementName(parameter.getElement().getType().getQname());
faultMessage.addPart(part);
exceptionMessagesMap.put(exceptionClass, faultMessage);
this.wsdlDefinition.addMessage(faultMessage);
}
for (Iterator iter = this.service.getOperations().iterator(); iter.hasNext();) {
operation = (org.apache.axis2.rmi.metadata.Operation) iter.next();
// add input and out put messages
inputMessage = getWSDLInputMessage(this.wsdlDefinition, operation);
outputMessage = getWSDLOutputMessage(this.wsdlDefinition, operation);
this.wsdlDefinition.addMessage(inputMessage);
this.wsdlDefinition.addMessage(outputMessage);
wsdlOperation = getWSDLOperation(this.wsdlDefinition,
inputMessage,
outputMessage,
exceptionMessagesMap,
operation);
this.portType.addOperation(wsdlOperation);
bindingOperation = getWSDLBindingOperation(this.wsdlDefinition,
wsdlOperation,
operation);
this.httpSoapBinding.addBindingOperation(bindingOperation);
}
}
/**
* creates the corresponding wsdl message for input
*
* @param definition
* @return input message
*/
public Message getWSDLInputMessage(Definition definition,
Operation operation) {
Message inputMessage = definition.createMessage();
inputMessage.setUndefined(false);
inputMessage.setQName(new QName(operation.getNamespace(), operation.getName() + "RequestMessage"));
Part part = definition.createPart();
part.setName("input");
part.setElementName(new QName(operation.getInputElement().getNamespace(), operation.getInputElement().getName()));
inputMessage.addPart(part);
return inputMessage;
}
/**
* creates the corresponding wsdl message for output
*
* @param definition
* @return output message
*/
public Message getWSDLOutputMessage(Definition definition,
Operation operation) {
Message outputMessage = definition.createMessage();
outputMessage.setUndefined(false);
outputMessage.setQName(new QName(operation.getNamespace(), operation.getName() + "ResponseMessage"));
Part part = definition.createPart();
part.setName("output");
part.setElementName(new QName(operation.getOutPutElement().getNamespace(), operation.getOutPutElement().getName()));
outputMessage.addPart(part);
return outputMessage;
}
/**
* generates the wsdl operation for the rmi operation
*
* @param definition
* @param inputMessage
* @param outputMessage
* @param faultMessageMap
* @param operation
* @return wsdl operation
*/
public javax.wsdl.Operation getWSDLOperation(Definition definition,
Message inputMessage,
Message outputMessage,
Map faultMessageMap,
Operation operation) {
javax.wsdl.Operation wsdlOperation = definition.createOperation();
wsdlOperation.setUndefined(false);
wsdlOperation.setName(operation.getName());
Input input = definition.createInput();
input.setMessage(inputMessage);
input.setName("input");
Output output = definition.createOutput();
output.setMessage(outputMessage);
output.setName("output");
wsdlOperation.setInput(input);
wsdlOperation.setOutput(output);
wsdlOperation.setStyle(OperationType.REQUEST_RESPONSE);
// add fault messages
Class[] exceptionClasses = operation.getJavaMethod().getExceptionTypes();
Message faultMessage;
Fault fault;
String faultName;
for (int i = 0; i < exceptionClasses.length; i++) {
faultName = exceptionClasses[i].getName();
faultName = faultName.substring(faultName.lastIndexOf(".") + 1);
faultMessage = (Message) faultMessageMap.get(exceptionClasses[i]);
fault = definition.createFault();
fault.setMessage(faultMessage);
fault.setName("fault" + faultName);
wsdlOperation.addFault(fault);
}
return wsdlOperation;
}
/**
* generates the soap11 binding operation for the soap 11 binding.
*
* @param definition
* @param wsdlOperation
* @param operation
* @return
* @throws SchemaGenerationException
*/
public BindingOperation getWSDLBindingOperation(Definition definition,
javax.wsdl.Operation wsdlOperation,
Operation operation)
throws SchemaGenerationException {
BindingOperation bindingOperation = definition.createBindingOperation();
bindingOperation.setName(operation.getName());
bindingOperation.setOperation(wsdlOperation);
BindingInput bindingInput = definition.createBindingInput();
bindingOperation.setBindingInput(bindingInput);
BindingOutput bindingOutput = definition.createBindingOutput();
bindingOperation.setBindingOutput(bindingOutput);
ExtensionRegistry extensionRegistry = null;
try {
extensionRegistry = WSDLFactory.newInstance().newPopulatedExtensionRegistry();
SOAPOperation soapOperation = (SOAPOperation) extensionRegistry.createExtension(
BindingOperation.class, new QName("http://schemas.xmlsoap.org/wsdl/soap/", "operation"));
soapOperation.setSoapActionURI("urn:" + operation.getName());
soapOperation.setStyle("document");
bindingOperation.addExtensibilityElement(soapOperation);
SOAPBody inputSoapBody = (SOAPBody) extensionRegistry.createExtension(
BindingInput.class, new QName("http://schemas.xmlsoap.org/wsdl/soap/", "body"));
inputSoapBody.setUse("literal");
bindingInput.addExtensibilityElement(inputSoapBody);
SOAPBody outputSoapBody = (SOAPBody) extensionRegistry.createExtension(
BindingOutput.class, new QName("http://schemas.xmlsoap.org/wsdl/soap/", "body"));
outputSoapBody.setUse("literal");
bindingOutput.addExtensibilityElement(outputSoapBody);
// adding fault messages
Class[] exceptionClasses = operation.getJavaMethod().getExceptionTypes();
BindingFault bindingFault;
String faultName;
for (int i = 0; i < exceptionClasses.length; i++) {
faultName = exceptionClasses[i].getName();
faultName = faultName.substring(faultName.lastIndexOf(".") + 1);
bindingFault = definition.createBindingFault();
bindingFault.setName("fault" + faultName);
bindingOperation.addBindingFault(bindingFault);
SOAPFault soapFault = (SOAPFault) extensionRegistry.createExtension(
BindingFault.class, new QName("http://schemas.xmlsoap.org/wsdl/soap/", "fault"));
soapFault.setUse("literal");
soapFault.setName("fault" + faultName);
bindingFault.addExtensibilityElement(soapFault);
}
} catch (WSDLException e) {
throw new SchemaGenerationException("Can not crete a wsdl factory");
}
return bindingOperation;
}
}