org.apache.axis2.description.WSDL11ToAxisServiceBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of axis2-kernel Show documentation
Show all versions of axis2-kernel Show documentation
Core Parts of Axis2. This includes Axis2 engine, Client API, Addressing support, etc.,
/*
* 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.description;
import com.ibm.wsdl.util.xml.DOM2Writer;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAP11Constants;
import org.apache.axiom.soap.SOAP12Constants;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.AddressingConstants;
import org.apache.axis2.addressing.AddressingHelper;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.addressing.EndpointReferenceHelper;
import org.apache.axis2.addressing.wsdl.WSDL11ActionHelper;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.axis2.util.LoggingControl;
import org.apache.axis2.util.PolicyUtil;
import org.apache.axis2.util.XMLUtils;
import org.apache.axis2.wsdl.SOAPHeaderMessage;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.axis2.wsdl.WSDLUtil;
import org.apache.axis2.wsdl.util.WSDLDefinitionWrapper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.neethi.Constants;
import org.apache.neethi.Policy;
import org.apache.neethi.PolicyReference;
import org.apache.ws.commons.schema.utils.NamespaceMap;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
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.Import;
import javax.wsdl.Input;
import javax.wsdl.Message;
import javax.wsdl.Operation;
import javax.wsdl.OperationType;
import javax.wsdl.Output;
import javax.wsdl.Part;
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.UnknownExtensibilityElement;
import javax.wsdl.extensions.http.HTTPAddress;
import javax.wsdl.extensions.http.HTTPBinding;
import javax.wsdl.extensions.http.HTTPOperation;
import javax.wsdl.extensions.http.HTTPUrlEncoded;
import javax.wsdl.extensions.mime.MIMEContent;
import javax.wsdl.extensions.mime.MIMEMimeXml;
import javax.wsdl.extensions.mime.MIMEMultipartRelated;
import javax.wsdl.extensions.mime.MIMEPart;
import javax.wsdl.extensions.schema.Schema;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.wsdl.extensions.soap.SOAPBinding;
import javax.wsdl.extensions.soap.SOAPBody;
import javax.wsdl.extensions.soap.SOAPHeader;
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.SOAP12Header;
import javax.wsdl.extensions.soap12.SOAP12Operation;
import javax.wsdl.xml.WSDLLocator;
import javax.wsdl.xml.WSDLReader;
import javax.xml.namespace.QName;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
public class WSDL11ToAxisServiceBuilder extends WSDLToAxisServiceBuilder {
public static final int COMPONENT_PORT_TYPE = 1;
public static final int COMPONENT_MESSAGE = 2;
public static final int COMPONENT_BINDING = 3;
/**
* Parameter used on {@link AxisMessage} objects to track the value of the name
* attribute of the wsdl:fault. Note that this is more like a workaround. The problem
* is that {@link AxisMessage} stores the faults as a simple list. A better fix would be to
* replace that by a map with the fault name as key, similar to what WSDL4J does (see
* {@link Operation#getFaults()}).
*/
private static final String FAULT_NAME = "faultName";
protected static final Log log = LogFactory
.getLog(WSDL11ToAxisServiceBuilder.class);
private static final boolean isTraceEnabled = log.isTraceEnabled();
protected String portName;
private static final String BINDING = "Binding";
private static final String SERVICE = "Service";
private static final String PORT = "Port";
private static final String PORT_TYPE = "PortType";
private static final String PORT_TYPE_OPERATION = "PortType.Operation";
private static final String PORT_TYPE_OPERATION_INPUT = "PortType.Operation.Input";
private static final String PORT_TYPE_OPERATION_OUTPUT = "PortType.Operation.Output";
private static final String PORT_TYPE_OPERATION_FAULT = "PortType.Operation.Fault";
private static final String BINDING_OPERATION = "Binding.Operation";
private static final String BINDING_OPERATION_INPUT = "Binding.Operation.Input";
private static final String BINDING_OPERATION_OUTPUT = "Binding.Operation.Output";
protected Definition wsdl4jDefinition = null;
protected String wsdlBaseDocumentURI = null;
private WSDLLocator customWSDLResolver;
public static final String RPC_STYLE = "rpc";
public static final String DOCUMENT_STYLE = "document";
public static final String ENCODED_USE = "encoded";
/**
* List of BindingOperationEntry objects.
* Each object in the list may require a wrapped schema element for
* the input/output or both.
*/
private List wrappableBOEs = new ArrayList();
// used to keep the binding type of the selected binding
private String bindingType;
public static final String WRAPPED_OUTPUTNAME_SUFFIX = "Response";
public static final String XML_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/";
public static final String NAMESPACE_DECLARATION_PREFIX = "xmlns:";
private static int prefixCounter = 0;
public static final String NAMESPACE_URI = "namespace";
public static final String TRAGET_NAMESPACE = "targetNamespace";
public static final String BINDING_TYPE_SOAP = "soap";
public static final String BINDING_TYPE_HTTP = "http";
/**
* keep track of whether setup code related to the entire wsdl is complete.
* Note that WSDL11ToAllAxisServices will call setup multiple times, so this
* field is used to make subsequent calls no-ops.
*/
private boolean setupComplete = false;
private Map schemaMap = null;
private static final String JAVAX_WSDL_VERBOSE_MODE_KEY = "javax.wsdl.verbose";
// As bindings are processed add it to this array so that we dont process the same binding twice
private Map processedBindings;
private boolean isAllPorts;
/**
* constructor taking in the service name and the port name
*
* @param in - InputStream for the WSDL
* @param serviceName - The service Name
* @param portName - The port name
*/
public WSDL11ToAxisServiceBuilder(InputStream in, QName serviceName,
String portName) {
super(in, serviceName);
this.portName = portName;
}
/**
* @param def - The WSDL4J Definition object
* @param serviceName - The service Name
* @param portName - The port name
*/
public WSDL11ToAxisServiceBuilder(Definition def, QName serviceName,
String portName) {
super(null, serviceName);
this.wsdl4jDefinition = def;
this.portName = portName;
this.isAllPorts = false;
}
/**
* @param def - The WSDL4J Definition object
* @param serviceName - The service Name
* @param portName - The port name
* @param isAllPorts - boolean representing whether to generate code for all ports or not
*/
public WSDL11ToAxisServiceBuilder(Definition def,
QName serviceName,
String portName,
boolean isAllPorts) {
this(def, serviceName, portName);
this.isAllPorts = isAllPorts;
}
/**
* @param in
* @param service
*/
public WSDL11ToAxisServiceBuilder(InputStream in, AxisService service) {
super(in, service);
}
/**
* @param in
*/
public WSDL11ToAxisServiceBuilder(InputStream in) {
this(in, null, null);
}
/**
* sets a custom WSDL locator
*
* @param customResolver
*/
public void setCustomWSDLResolver(WSDLLocator customResolver) {
this.customWSDLResolver = customResolver;
setDocumentBaseUri(this.customWSDLResolver.getBaseURI());
}
/**
* Sets the URI to the base document associated with the WSDL definition.
* This identifies the origin of the Definition and allows the
* Definition to be reloaded. Note that this is the URI of the base
* document, not the imports.
*
* @param baseUri
*/
public void setDocumentBaseUri(String baseUri) {
if (wsdl4jDefinition != null) {
wsdl4jDefinition.setDocumentBaseURI(baseUri);
}
wsdlBaseDocumentURI = baseUri;
}
/**
* Gets the URI to the base document associated with the WSDL definition.
* This identifies the origin of the Definition and allows the
* Definition to be reloaded. Note that this is the URI of the base
* document, not the imports.
*
*/
public String getDocumentBaseUri() {
return wsdlBaseDocumentURI;
}
/**
* Populates a given service.
*
* @throws AxisFault
*/
public AxisService populateService() throws AxisFault {
try {
setup();
// NOTE: set the axisService with the Parameter for the WSDL
// Definition after the rest of the work
if (wsdl4jDefinition == null) {
return null;
}
// setting target name space
axisService.setTargetNamespace(wsdl4jDefinition.getTargetNamespace());
axisService.setNamespaceMap(new NamespaceMap(wsdl4jDefinition.getNamespaces()));
Map importsMap = wsdl4jDefinition.getImports();
if (importsMap != null) {
List imports = new ArrayList(importsMap.keySet());
axisService.setImportedNamespaces(imports);
}
//TODO : find the service also in imported wsdls
Service wsdl4jService = findService(wsdl4jDefinition);
Binding binding = findBinding(wsdl4jDefinition, wsdl4jService);
Definition bindingWSDL = getParentDefinition(wsdl4jDefinition,
binding.getQName(), COMPONENT_BINDING, new HashSet());
//do not search for wsdl where port type is defined, this search is depth-first
//and might lead to a wsdl where the port is only referenced but undefined
//instead look up the port type in the wsdl and only if not found fall back to binding's port type
PortType portType = wsdl4jDefinition.getPortType(binding.getPortType().getQName());
if (portType == null) {
//TODO in case of recursive imports, binding's port type will contain operations with null input message
//requires fix for http://sourceforge.net/p/wsdl4j/bugs/39
portType = binding.getPortType();
}
if (portType == null) {
throw new AxisFault("There is no port type associated with the binding");
}
// create new Schema extensions element for wrapping
// (if its present)
Element[] schemaElements = generateWrapperSchema(schemaMap, binding, portType);
processTypes(wsdl4jDefinition, axisService);
// add the newly created schemas
if (schemaElements != null && schemaElements.length > 0) {
for (int i = 0; i < schemaElements.length; i++) {
Element schemaElement = schemaElements[i];
if (schemaElement != null) {
axisService.addSchema(getXMLSchema(schemaElement, null));
}
}
}
// copy the documentation element content to the description
Element documentationElement = wsdl4jDefinition.getDocumentationElement();
addDocumentation(axisService, documentationElement);
axisService.setName(wsdl4jService.getQName().getLocalPart());
populateEndpoints(binding, bindingWSDL,wsdl4jService, portType);
processPoliciesInDefintion(wsdl4jDefinition);
axisService.getPolicyInclude().setPolicyRegistry(registry);
// Setting wsdl4jdefintion to the axisService parameter include list,
// so if someone needs to use the definition directly,
// he can do that by getting the parameter
Parameter wsdlDefinitionParameter = new Parameter();
wsdlDefinitionParameter.setName(WSDLConstants.WSDL_4_J_DEFINITION);
if (!(wsdl4jDefinition instanceof WSDLDefinitionWrapper)) {
AxisConfiguration ac = axisService.getAxisConfiguration();
if (ac == null) {
ac = this.axisConfig;
}
WSDLDefinitionWrapper wrapper = new WSDLDefinitionWrapper(wsdl4jDefinition, ac);
wsdlDefinitionParameter.setValue(wrapper);
} else {
wsdlDefinitionParameter.setValue(wsdl4jDefinition);
}
axisService.addParameter(wsdlDefinitionParameter);
axisService.setWsdlFound(true);
axisService.setCustomWsdl(true);
return axisService;
} catch (WSDLException e) {
if(log.isDebugEnabled()){
log.debug(e.getMessage(), e);
}
throw AxisFault.makeFault(e);
} catch (Exception e) {
if(log.isDebugEnabled()){
log.debug(e.getMessage(), e);
}
throw AxisFault.makeFault(e);
}
}
private void processTypes(Definition wsdlDefinition, AxisService axisService)
throws AxisFault {
processTypes(wsdlDefinition, axisService, new HashSet());
}
private void processTypes(Definition wsdlDefinition,
AxisService axisService,
Set visitedWSDLs)
throws AxisFault {
visitedWSDLs.add(wsdlDefinition.getDocumentBaseURI());
// process all the types in all the wsdls
Types types = wsdlDefinition.getTypes();
if (types != null) {
copyExtensibleElements(types.getExtensibilityElements(),
wsdlDefinition,
axisService,
TYPES);
}
// process the types in other wsdls
Iterator iter = wsdlDefinition.getImports().values().iterator();
Vector values = null;
Import wsdlImport = null;
for (; iter.hasNext();) {
values = (Vector) iter.next();
for (Iterator valuesIter = values.iterator(); valuesIter.hasNext();) {
wsdlImport = (Import) valuesIter.next();
// process the types recuresiveilt
Definition innerDefinition = wsdlImport.getDefinition();
if(!visitedWSDLs.contains(innerDefinition.getDocumentBaseURI())){
processTypes(innerDefinition, axisService, visitedWSDLs);
}
}
}
}
private void addDocumentation(AxisDescription axisDescription, Element documentationElement) {
if ((documentationElement != null) && (documentationElement.getFirstChild() != null)) {
Node firstChild = documentationElement.getFirstChild();
String documentation = DOM2Writer.nodeToString(firstChild);
if (!"".equals(documentation)) {
axisDescription.setDocumentation(documentation);
}
}
}
/**
* @param binding
* @param wsdl4jService must have atlease one port
* @throws AxisFault
*/
private void populateEndpoints(Binding binding,
Definition bindingWSDL,
Service wsdl4jService,
PortType portType) throws AxisFault {
Map wsdl4jPorts = wsdl4jService.getPorts();
QName bindingName = binding.getQName();
Port port;
AxisEndpoint axisEndpoint = null;
processedBindings = new HashMap();
// process the port type for this binding
// although we support multiports they must be belongs to same port type and should have the
// same soap style
populatePortType(portType);
Binding currentBinding;
Definition currentBindingWSDL = null;
for (Iterator iterator = wsdl4jPorts.values().iterator(); iterator.hasNext();) {
port = (Port) iterator.next();
// if the user has picked a port then we have to process only that port
if ((this.portName == null) || (this.portName.equals(port.getName()))) {
// we process the port only if it has the same port type as the selected binding
currentBindingWSDL = getParentDefinition(wsdl4jDefinition,
port.getBinding().getQName(), COMPONENT_BINDING, new HashSet());
currentBinding = currentBindingWSDL.getBinding(port.getBinding().getQName());
if (currentBinding.getPortType().getQName().equals(binding.getPortType().getQName())) {
axisEndpoint = new AxisEndpoint();
axisEndpoint.setName(port.getName());
if (axisService.getEndpointName() == null &&
bindingName.equals(port.getBinding().getQName())) {
populateEndpoint(axisEndpoint, port, currentBinding,
bindingWSDL, portType, true);
axisService.setEndpointName(axisEndpoint.getName());
axisService.setBindingName(axisEndpoint.getBinding().getName().getLocalPart());
} else {
populateEndpoint(axisEndpoint, port, currentBinding,
bindingWSDL, portType, false);
}
axisEndpoint.setParent(axisService);
axisService.addEndpoint(port.getName(), axisEndpoint);
}
}
}
}
/**
* setting message qname is a binding dependent process for an example message element depends on the
* soap style (rpc or document) and parts elememet of the soap body
* On the otherhand we keep only one set of axis operations belongs to a selected port type in axis service
* So setting qname refetences done only with the selected binding processing
*
* @param axisEndpoint
* @param wsdl4jPort
* @param isSetMessageQNames
* @throws AxisFault
*/
private void populateEndpoint(AxisEndpoint axisEndpoint,
Port wsdl4jPort,
Binding wsdl4jBinding,
Definition bindingWSDL,
PortType portType,
boolean isSetMessageQNames)
throws AxisFault {
copyExtensibleElements(wsdl4jPort.getExtensibilityElements(), wsdl4jDefinition,
axisEndpoint, BINDING);
processEmbeddedEPR(wsdl4jPort.getExtensibilityElements(), axisEndpoint);
addDocumentation(axisEndpoint, wsdl4jPort.getDocumentationElement());
if (processedBindings.containsKey(wsdl4jBinding.getQName())) {
axisEndpoint.setBinding(
(AxisBinding) processedBindings.get(wsdl4jBinding.getQName()));
} else {
AxisBinding axisBinding = new AxisBinding();
axisBinding.setName(wsdl4jBinding.getQName());
axisBinding.setParent(axisEndpoint);
axisEndpoint.setBinding(axisBinding);
axisBinding.setParent(axisEndpoint);
populateBinding(axisBinding,
wsdl4jBinding,
bindingWSDL,
portType,
isSetMessageQNames);
processedBindings.put(wsdl4jBinding.getQName(), axisBinding);
}
}
private void processEmbeddedEPR(List extensibilityElements, AxisEndpoint axisEndpoint) {
Iterator eelts = extensibilityElements.iterator();
while(eelts.hasNext()){
ExtensibilityElement ee = (ExtensibilityElement)eelts.next();
if(AddressingConstants.Final.WSA_ENDPOINT_REFERENCE.equals(ee.getElementType())){
try {
Element elt = ((UnknownExtensibilityElement)ee).getElement();
OMElement eprOMElement = XMLUtils.toOM(elt);
EndpointReference epr = EndpointReferenceHelper.fromOM(eprOMElement);
Map referenceParameters = epr.getAllReferenceParameters();
if(referenceParameters != null){
axisEndpoint.addParameter(AddressingConstants.REFERENCE_PARAMETER_PARAMETER, new ArrayList(referenceParameters.values()));
}
for (OMElement extensibleElement : epr.getExtensibleElements()) {
if (AddressingConstants.QNAME_IDENTITY.equals(extensibleElement.getQName())) {
axisEndpoint.addParameter(AddressingConstants.ADDRESSING_IDENTITY_PARAMETER, extensibleElement.cloneOMElement());
break;
}
}
} catch (Exception e) {
if(log.isDebugEnabled()){
log.debug("Exception encountered processing embedded wsa:EndpointReference", e);
}
}
}
}
}
private void populatePortType(PortType wsdl4jPortType) throws AxisFault {
copyExtensionAttributes(wsdl4jPortType.getExtensionAttributes(),
axisService, PORT_TYPE);
List wsdl4jOperations = wsdl4jPortType.getOperations();
// Added to use in ?wsdl2 as the interface name
axisService.addParameter(new Parameter(WSDL2Constants.INTERFACE_LOCAL_NAME,
wsdl4jPortType.getQName().getLocalPart()));
if (wsdl4jOperations.size() < 1) {
throw new AxisFault("No operation found in the portType element");
}
AxisOperation axisOperation;
List operationNames = new ArrayList();
QName opName;
Operation wsdl4jOperation;
for (Iterator iterator = wsdl4jOperations.iterator(); iterator.hasNext();) {
wsdl4jOperation = (Operation) iterator.next();
axisOperation = populateOperations(wsdl4jOperation, wsdl4jPortType);
addDocumentation(axisOperation, wsdl4jOperation.getDocumentationElement());
if (wsdl4jOperation.getInput() != null) {
addMessageDocumentation(axisOperation, wsdl4jOperation.getInput().getDocumentationElement(), WSDLConstants.MESSAGE_LABEL_IN_VALUE);
}
if (wsdl4jOperation.getOutput() != null) {
addMessageDocumentation(axisOperation, wsdl4jOperation.getOutput().getDocumentationElement(), WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
}
axisOperation.setParent(axisService);
axisService.addChild(axisOperation);
operationNames.add(axisOperation.getName());
}
// this is used only in codegen to preserve operation order
if (isCodegen) {
axisService.setOperationsNameList(operationNames);
}
}
/**
* This method is used for adding documentation for the message types of the service operations
* eg: input message
* output message
* fault messages
*
* @param axisOperation
* @param documentationElement
* @param messageLabel
*/
private void addMessageDocumentation(AxisOperation axisOperation, Element documentationElement, String messageLabel) {
if ((documentationElement != null) && (documentationElement.getFirstChild() != null)) {
Node firstChild = documentationElement.getFirstChild();
String documentation = DOM2Writer.nodeToString(firstChild);
if (!"".equals(documentation)) {
(axisOperation.getMessage(messageLabel)).setDocumentation(documentation);
}
}
}
private void populateBinding(AxisBinding axisBinding,
Binding wsdl4jBinding,
Definition bindingWSDL,
PortType portType,
boolean isSetMessageQNames)
throws AxisFault {
copyExtensibleElements(wsdl4jBinding.getExtensibilityElements(), bindingWSDL,
axisBinding, BINDING);
List wsdl4jBidingOperations = wsdl4jBinding.getBindingOperations();
if (wsdl4jBidingOperations.size() < 1) {
throw new AxisFault("No operation found for the binding");
}
addDocumentation(axisBinding, wsdl4jBinding.getDocumentationElement());
AxisOperation axisOperation;
Operation wsdl4jOperation;
AxisBindingOperation axisBindingOperation;
BindingOperation wsdl4jBindingOperation;
Map httpLocationMap = createHttpLocationTable();
String httpLocation = null;
for (Iterator iterator = wsdl4jBidingOperations.iterator(); iterator.hasNext();) {
axisBindingOperation = new AxisBindingOperation();
wsdl4jBindingOperation = (BindingOperation) iterator.next();
wsdl4jOperation = findOperation(portType, wsdl4jBindingOperation);
axisBindingOperation.setName(new QName(bindingWSDL.getTargetNamespace(), wsdl4jBindingOperation.getName()));
addDocumentation(axisBindingOperation, wsdl4jBindingOperation.getDocumentationElement());
axisOperation = axisService.getOperation(new QName(portType.getQName().getNamespaceURI(), wsdl4jOperation.getName()));
axisBindingOperation.setAxisOperation(axisOperation);
// process ExtensibilityElements of the wsdl4jBinding
copyExtensibleElements(wsdl4jBindingOperation.getExtensibilityElements(),
wsdl4jDefinition, axisBindingOperation, BINDING_OPERATION);
httpLocation =
(String) axisBindingOperation.getProperty(WSDL2Constants.ATTR_WHTTP_LOCATION);
String httpMethod =
(String) axisBindingOperation.getProperty(WSDL2Constants.ATTR_WHTTP_METHOD);
if (httpMethod == null || "".equals(httpMethod)) {
httpMethod = HTTPConstants.HEADER_POST;
}
if (httpLocation != null) {
httpLocationMap.put(WSDLUtil.getConstantFromHTTPLocation(httpLocation, httpMethod),
axisBindingOperation.getAxisOperation());
}
BindingInput wsdl4jBindingInput = wsdl4jBindingOperation.getBindingInput();
if (isServerSide) {
if (wsdl4jBindingInput != null &&
WSDLUtil.isInputPresentForMEP(axisOperation.getMessageExchangePattern())) {
AxisBindingMessage axisBindingInMessage = new AxisBindingMessage();
axisBindingInMessage.setParent(axisBindingOperation);
addDocumentation(axisBindingInMessage, wsdl4jBindingInput.getDocumentationElement());
copyExtensibleElements(wsdl4jBindingInput.getExtensibilityElements(),
wsdl4jDefinition,
axisBindingInMessage, BINDING_OPERATION_INPUT);
AxisMessage axisInMessage =
axisOperation.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
//This is a hack to get AXIS2-2771 working , I had to copy soap headers
// from binding message to AxisMessage
List soapHeaders = (List) axisBindingInMessage.getProperty(
WSDL2Constants.ATTR_WSOAP_HEADER);
if (soapHeaders != null) {
for (int i = 0; i < soapHeaders.size(); i++) {
SOAPHeaderMessage headerMessage = (SOAPHeaderMessage) soapHeaders.get(i);
axisInMessage.addSoapHeader(headerMessage);
}
}
if (isSetMessageQNames) {
BindingOperationEntry boe = find(wrappableBOEs, wsdl4jBindingOperation);
boolean isWrapped = (boe == null) ? false : boe.isWrappedInput();
addQNameReference(axisInMessage, wsdl4jOperation,
wsdl4jBindingInput,
isWrapped);
}
axisBindingInMessage.setAxisMessage(axisInMessage);
axisBindingInMessage.setName(axisInMessage.getName());
axisBindingInMessage.setDirection(axisInMessage.getDirection());
axisBindingOperation
.addChild(WSDLConstants.MESSAGE_LABEL_IN_VALUE, axisBindingInMessage);
}
} else {
if (wsdl4jBindingInput != null &&
WSDLUtil.isOutputPresentForMEP(axisOperation.getMessageExchangePattern())) {
AxisBindingMessage axisBindingOutMessage = new AxisBindingMessage();
axisBindingOutMessage.setParent(axisBindingOperation);
addDocumentation(axisBindingOutMessage, wsdl4jBindingInput.getDocumentationElement());
copyExtensibleElements(wsdl4jBindingInput.getExtensibilityElements(),
wsdl4jDefinition,
axisBindingOutMessage, BINDING_OPERATION_OUTPUT);
AxisMessage axisOutMessage =
axisOperation.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
//This is a hack to get AXIS2-2771 working , I had to copy soap headers
// from binding message to AxisMessage
List soapHeaders = (List) axisBindingOutMessage.getProperty(
WSDL2Constants.ATTR_WSOAP_HEADER);
if (soapHeaders != null) {
for (int i = 0; i < soapHeaders.size(); i++) {
SOAPHeaderMessage headerMessage = (SOAPHeaderMessage) soapHeaders.get(i);
axisOutMessage.addSoapHeader(headerMessage);
}
}
if (isSetMessageQNames) {
BindingOperationEntry boe = find(wrappableBOEs, wsdl4jBindingOperation);
boolean isWrapped = (boe == null) ? false : boe.isWrappedInput();
addQNameReference(axisOutMessage, wsdl4jOperation,
wsdl4jBindingInput,
isWrapped);
}
axisBindingOutMessage.setAxisMessage(axisOutMessage);
axisBindingOutMessage.setName(axisOutMessage.getName());
axisBindingOutMessage.setDirection(axisOutMessage.getDirection());
axisBindingOperation
.addChild(WSDLConstants.MESSAGE_LABEL_OUT_VALUE, axisBindingOutMessage);
}
}
BindingOutput wsdl4jBindingOutput = wsdl4jBindingOperation.getBindingOutput();
if (isServerSide) {
if (wsdl4jBindingOutput != null &&
WSDLUtil.isOutputPresentForMEP(axisOperation.getMessageExchangePattern())) {
AxisBindingMessage axisBindingOutMessage = new AxisBindingMessage();
axisBindingOutMessage.setParent(axisBindingOperation);
addDocumentation(axisBindingOutMessage, wsdl4jBindingOutput.getDocumentationElement());
AxisMessage axisOutMessage =
axisOperation.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
copyExtensibleElements(wsdl4jBindingOutput.getExtensibilityElements(),
wsdl4jDefinition,
axisBindingOutMessage, BINDING_OPERATION_OUTPUT);
//This is a hack to get AXIS2-2771 working , I had to copy soap headers
// from binding message to AxisMessage
List soapHeaders =
(List) axisBindingOutMessage.getProperty(WSDL2Constants.ATTR_WSOAP_HEADER);
if (soapHeaders != null) {
for (int i = 0; i < soapHeaders.size(); i++) {
SOAPHeaderMessage headerMessage = (SOAPHeaderMessage) soapHeaders.get(i);
axisOutMessage.addSoapHeader(headerMessage);
}
}
if (isSetMessageQNames) {
BindingOperationEntry boe = find(wrappableBOEs, wsdl4jBindingOperation);
boolean isWrapped = (boe == null) ? false : boe.isWrappedOutput();
axisOutMessage.setWrapped(isWrapped);
addQNameReference(axisOutMessage, wsdl4jOperation,
wsdl4jBindingOutput,
isWrapped);
}
axisBindingOutMessage.setAxisMessage(axisOutMessage);
axisBindingOutMessage.setName(axisOutMessage.getName());
axisBindingOutMessage.setDirection(axisOutMessage.getDirection());
axisBindingOperation
.addChild(WSDLConstants.MESSAGE_LABEL_OUT_VALUE, axisBindingOutMessage);
}
} else {
if (wsdl4jBindingOutput != null &&
WSDLUtil.isInputPresentForMEP(axisOperation.getMessageExchangePattern())) {
AxisBindingMessage axisBindingInMessage = new AxisBindingMessage();
axisBindingInMessage.setParent(axisBindingOperation);
addDocumentation(axisBindingInMessage, wsdl4jBindingOutput.getDocumentationElement());
AxisMessage axisInMessage =
axisOperation.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
copyExtensibleElements(wsdl4jBindingOutput.getExtensibilityElements(),
wsdl4jDefinition,
axisBindingInMessage, BINDING_OPERATION_INPUT);
//This is a hack to get AXIS2-2771 working , I had to copy soap headers
// from binding message to AxisMessage
List soapHeaders =
(List) axisBindingInMessage.getProperty(WSDL2Constants.ATTR_WSOAP_HEADER);
if (soapHeaders != null) {
for (int i = 0; i < soapHeaders.size(); i++) {
SOAPHeaderMessage headerMessage = (SOAPHeaderMessage) soapHeaders.get(i);
axisInMessage.addSoapHeader(headerMessage);
}
}
if (isSetMessageQNames) {
BindingOperationEntry boe = find(wrappableBOEs, wsdl4jBindingOperation);
boolean isWrapped = (boe == null) ? false : boe.isWrappedOutput();
axisInMessage.setWrapped(isWrapped);
addQNameReference(axisInMessage, wsdl4jOperation,
wsdl4jBindingOutput,
isWrapped);
}
axisBindingInMessage.setAxisMessage(axisInMessage);
axisBindingInMessage.setName(axisInMessage.getName());
axisBindingInMessage.setDirection(axisInMessage.getDirection());
axisBindingOperation
.addChild(WSDLConstants.MESSAGE_LABEL_IN_VALUE, axisBindingInMessage);
}
}
Map bindingFaultsMap = wsdl4jBindingOperation.getBindingFaults();
/* process the binding faults */
for (Iterator bindingFaults = bindingFaultsMap.values().iterator();
bindingFaults.hasNext();) {
BindingFault bindingFault = (BindingFault) bindingFaults.next();
if (bindingFault.getName() == null) {
throw new AxisFault("Binding name is null for the binding fault in " +
" binding operation ==> " + wsdl4jBindingOperation.getName());
} else {
Fault wsdl4jFault = wsdl4jOperation.getFault(bindingFault.getName());
if (wsdl4jFault == null){
throw new AxisFault("Can not find the corresponding fault element in " +
"wsdl operation " + wsdl4jOperation.getName() + " for the fault" +
" name " + bindingFault.getName());
} else {
Message wsdl4jFaultMessge = wsdl4jFault.getMessage();
AxisMessage faultMessage = findFaultMessage(
wsdl4jFault.getName(),
axisOperation.getFaultMessages());
AxisBindingMessage axisBindingFaultMessage = new AxisBindingMessage();
addDocumentation(axisBindingFaultMessage, wsdl4jFaultMessge.getDocumentationElement());
axisBindingFaultMessage.setFault(true);
axisBindingFaultMessage.setAxisMessage(faultMessage);
axisBindingFaultMessage.setName(faultMessage.getName());
axisBindingFaultMessage.setParent(axisBindingOperation);
axisBindingOperation.addFault(axisBindingFaultMessage);
if (isSetMessageQNames) {
addQNameReference(faultMessage, wsdl4jFault.getMessage());
}
}
}
}
axisBindingOperation.setParent(axisBinding);
axisBinding.addChild(axisBindingOperation.getName(), axisBindingOperation);
}
axisBinding.setProperty(WSDL2Constants.HTTP_LOCATION_TABLE, httpLocationMap);
}
/**
* contains all code which gathers non-service specific information from the
* wsdl. After all the setup completes successfully, the setupComplete
* field is set so that any subsequent calls to setup() will result in a
* no-op. Note that subclass WSDL11ToAllAxisServicesBuilder will call
* populateService for each port in the WSDL. Separating the non-service
* specific information here allows WSDL11ToAllAxisServicesBuilder to only
* do this work 1 time per WSDL, instead of for each port on each service.
*
* @throws WSDLException if readInTheWSDLFile fails
*/
protected void setup() throws WSDLException {
if (setupComplete) { // already setup, just do nothing and return
return;
}
if (wsdl4jDefinition == null) {
wsdl4jDefinition = readInTheWSDLFile(in);
}
if (wsdl4jDefinition == null) {
return; // can't continue without wsdl
}
// setup the schemaMap
this.schemaMap = new HashMap();
populateSchemaMap(wsdl4jDefinition, new HashSet());
setPolicyRegistryFromService(axisService);
setupComplete = true; // if any part of setup fails, don't mark
// setupComplete
}
/**
* Populate a map of targetNamespace vs DOM schema element This is used to
* grab the correct schema element when adding a new element
*
* @param definition
*/
private void populateSchemaMap(Definition definition, Set visitedWSDLs) {
visitedWSDLs.add(definition.getDocumentBaseURI());
// first process the types in the given wsdl
Types types = definition.getTypes();
Object extensibilityElement;
if (types != null) {
for (Iterator iterator = types.getExtensibilityElements().iterator(); iterator.hasNext();)
{
extensibilityElement = iterator.next();
if (extensibilityElement instanceof Schema) {
Element schemaElement = ((Schema) extensibilityElement).getElement();
schemaMap.put(schemaElement.getAttribute(XSD_TARGETNAMESPACE), schemaElement);
}
}
}
// popualte the imports as well
Iterator iter = definition.getImports().values().iterator();
Vector values = null;
Import wsdlImport = null;
for (; iter.hasNext();) {
values = (Vector) iter.next();
for (Iterator valuesIter = values.iterator(); valuesIter.hasNext();) {
wsdlImport = (Import) valuesIter.next();
Definition innerDefinition = wsdlImport.getDefinition();
if(!visitedWSDLs.contains(innerDefinition.getDocumentBaseURI())) {
populateSchemaMap(innerDefinition, visitedWSDLs);
}
}
}
}
/**
* return the service to process
* if user has specified we check whether it exists
* else pick a random service and throws an exception if not found any thing
*
* @param definition
* @return service to process
* @throws AxisFault
*/
private Service findService(Definition definition) throws AxisFault {
Map services = definition.getServices();
Service service = null;
if (serviceName != null) {
// i.e if a user has specified a pirticular port
service = (Service) services.get(serviceName);
if (service == null) {
throw new AxisFault("Service " + serviceName
+ " was not found in the WSDL");
}
} else {
if (services.size() > 0) {
for (Iterator iter = services.values().iterator(); iter.hasNext();) {
service = (Service) iter.next();
if (service.getPorts().size() > 0) {
//i.e we have found a service with ports
break;
}
}
if ((service == null) || (service.getPorts().size() == 0)) {
throw new AxisFault("there is no service with ports to pick");
}
} else {
throw new AxisFault("No services found in the WSDL at " +
definition.getDocumentBaseURI()
+ " with targetnamespace "
+ definition.getTargetNamespace());
}
}
return service;
}
/**
* Look for the relevant binding!
* if user has spcifed a port get it
* otherwise find first soap port or pick random one if there is no soap port
*
* @param dif
* @param service service can not be null
* @throws AxisFault
*/
private Binding findBinding(Definition dif, Service service) throws AxisFault {
Binding binding = null;
Port port = null;
copyExtensibleElements(service.getExtensibilityElements(), dif, axisService, SERVICE);
if (portName != null) {
// i.e if user has specified a service
port = service.getPort(portName);
if (port == null) {
throw new AxisFault("No port found for the given name :" + portName);
}
} else {
Map ports = service.getPorts();
if (ports != null && ports.size() > 0) {
// pick the port with the SOAP address as the default port
port = findPort(ports);
if (port == null) {
// a SOAP port was not found - log a warning
// and use the first port in the list
log.info("A SOAP port was not found - "
+ "picking a random port!");
port = (Port) ports.values().toArray()[0];
}
if (port != null) {
// i.e we have find a correct port
// this is only use full in codegen time.
if (this.isCodegen && !this.isAllPorts) {
// if user has not set all option
// we have to generate code only for that option.
this.portName = port.getName();
}
}
}
}
axisService.setName(service.getQName().getLocalPart());
if (port != null) {
copyExtensibleElements(port.getExtensibilityElements(), dif,
axisService, PORT);
Definition parentDefinition = getParentDefinition(dif,
port.getBinding().getQName(), COMPONENT_BINDING, new HashSet());
binding = parentDefinition.getBinding(port.getBinding().getQName());
if (binding == null) {
binding = port.getBinding();
}
}
return binding;
}
/**
* Finds a SOAP port given the port map
*/
private Port findPort(Map ports) {
Port port;
Port returnPort = null;
for (Iterator portsIterator = ports.values().iterator(); portsIterator.hasNext();) {
port = (Port) portsIterator.next();
List extensibilityElements = port.getExtensibilityElements();
for (int i = 0; i < extensibilityElements.size(); i++) {
Object extElement = extensibilityElements.get(i);
if (extElement instanceof SOAP12Address) {
// SOAP 1.2 address found - keep this and loop until http address is found
returnPort = port;
String location = ((SOAP12Address)extElement).getLocationURI().trim();
if ((location != null) && location.startsWith("http:")){
// i.e we have found an http port so return from here
break;
}
}
}
}
if (returnPort != null){
return returnPort;
}
for (Iterator portsIterator = ports.values().iterator(); portsIterator
.hasNext();) {
port = (Port) portsIterator.next();
List extensibilityElements = port.getExtensibilityElements();
for (int i = 0; i < extensibilityElements.size(); i++) {
Object extElement = extensibilityElements.get(i);
if (extElement instanceof SOAPAddress) {
// SOAP 1.1 address found - keep this and loop until http address is found
returnPort = port;
String location = ((SOAPAddress)extElement).getLocationURI().trim();
if ((location != null) && location.startsWith("http:")){
// i.e we have found an http port so return from here
break;
}
}
}
}
if (returnPort != null){
return returnPort;
}
for (Iterator portsIterator = ports.values().iterator(); portsIterator
.hasNext();) {
port = (Port) portsIterator.next();
List extensibilityElements = port.getExtensibilityElements();
for (int i = 0; i < extensibilityElements.size(); i++) {
Object extElement = extensibilityElements.get(i);
if (extElement instanceof HTTPAddress) {
// HTTP address found - keep this and loop until http address is found
returnPort = port;
String location = ((HTTPAddress)extElement).getLocationURI().trim();
if ((location != null) && location.startsWith("http:")){
// i.e we have found an http port so return from here
break;
}
}
}
}
return returnPort;
}
private Operation findOperation(PortType portType,
BindingOperation wsdl4jBindingOperation) {
Operation op = wsdl4jBindingOperation.getOperation();
String input = null;
if (op != null && op.getInput() != null) {
input = op.getInput().getName();
if (":none".equals(input)) {
input = null;
}
}
String output = null;
if (op != null && op.getOutput() != null) {
output = op.getOutput().getName();
if (":none".equals(output)) {
output = null;
}
}
Operation op2 = portType.getOperation(op.getName(), input, output);
return ((op2 == null) ? op : op2);
}
/**
* Find the fault message relevant to a given name from the fault message
* list
*
* @param name
* @param faultMessages
*/
private AxisMessage findFaultMessage(String name, ArrayList faultMessages) {
AxisMessage tempMessage;
for (int i = 0; i < faultMessages.size(); i++) {
tempMessage = (AxisMessage) faultMessages.get(i);
if (name.equals(tempMessage.getParameterValue(FAULT_NAME))) {
return tempMessage;
}
}
return null;
}
/**
* Add the QName for the binding input
*
* @param inMessage
* @param wsdl4jOperation
* @param bindingInput
* @param isWrapped - basically whether the operation is soap/rpc or not
*/
private void addQNameReference(AxisMessage inMessage,
Operation wsdl4jOperation, BindingInput bindingInput,
boolean isWrapped) {
List extensibilityElements = bindingInput.getExtensibilityElements();
Message wsdl4jMessage = wsdl4jOperation.getInput().getMessage();
addQNameReference(inMessage,
wsdl4jOperation,
isWrapped,
extensibilityElements,
wsdl4jMessage,
wsdl4jOperation.getName());
}
/**
* Add the QName for the binding output
*
* @param outMessage
* @param wsdl4jOperation
* @param isWrapped
*/
private void addQNameReference(AxisMessage outMessage,
Operation wsdl4jOperation, BindingOutput bindingOutput,
boolean isWrapped) {
if (bindingOutput != null) {
List extensibilityElements = bindingOutput.getExtensibilityElements();
if (wsdl4jOperation.getOutput() == null) {
return;
}
Message wsdl4jMessage = wsdl4jOperation.getOutput().getMessage();
addQNameReference(outMessage,
wsdl4jOperation,
isWrapped,
extensibilityElements,
wsdl4jMessage,
wsdl4jOperation.getName() + WRAPPED_OUTPUTNAME_SUFFIX);
}
}
private void addQNameReference(AxisMessage message,
Operation wsdl4jOperation,
boolean isWrapped,
List extensibilityElements,
Message wsdl4jMessage,
String rpcOperationName) {
if (isWrapped) {
// we have already validated and process the qname references
// so set it here
// The schema for this should be already made ! Find the
// QName from
// the list and add it - the name for this is just the
message.setElementQName((QName) resolvedRpcWrappedElementMap
.get(rpcOperationName));
message.getAxisOperation().getAxisService().addMessageElementQNameToOperationMapping(
(QName) resolvedRpcWrappedElementMap.get(rpcOperationName),
message.getAxisOperation());
} else {
// now we are sure this is an document literal type element
List bindingPartsList = getPartsListFromSoapBody(extensibilityElements);
if (bindingPartsList == null) {
// i.e user has not given any part list so we go to message and pick the firest part if
// available
if ((wsdl4jMessage.getParts() != null) && (wsdl4jMessage.getParts().size() > 0)) {
if (wsdl4jMessage.getParts().size() == 1) {
Part part = (Part) wsdl4jMessage.getParts().values().iterator().next();
QName elementName = part.getElementName();
if (elementName != null) {
message.setElementQName(elementName);
message.setMessagePartName(part.getName());
AxisOperation operation = message.getAxisOperation();
AxisService service = operation.getAxisService();
service.addMessageElementQNameToOperationMapping(elementName,
operation);
} else {
throw new WSDLProcessingException(
"No element type is defined for message " +
wsdl4jMessage.getQName().getLocalPart() + " (see WS-I BP 1.0, R2204)");
}
} else {
// user has specified more than one parts with out specifing a part in
// soap body
throw new WSDLProcessingException("More than one part for message " +
wsdl4jMessage.getQName().getLocalPart());
}
} else {
// This is allowed in the spec in this case element qname is null and nothing is send
// in the soap body. This is true for Doc/Lit/Bare operations that do not have any paramaters.
// In this case, add a mapping of the operation to a null key so the empty body can be routed on
// (for example in SOAPMessageBodyBasedDispatcher).
message.setElementQName(null);
AxisOperation operation = message.getAxisOperation();
AxisService service = operation.getAxisService();
service.addMessageElementQNameToOperationMapping(null, operation);
}
} else {
if (bindingPartsList.size() == 0) {
// we donot have to set the element qname
message.setElementQName(null);
} else if (bindingPartsList.size() == 1) {
Part part = wsdl4jMessage.getPart((String) bindingPartsList.get(0));
if (part != null) {
QName elementName = part.getElementName();
if (elementName != null) {
message.setElementQName(elementName);
message.setMessagePartName(part.getName());
AxisOperation operation = message.getAxisOperation();
AxisService service = operation.getAxisService();
service.addMessageElementQNameToOperationMapping(elementName,
operation);
} else {
throw new WSDLProcessingException(
"No element type is defined for message " +
wsdl4jMessage.getQName().getLocalPart() + " (see WS-I BP 1.0, R2204)");
}
} else {
throw new WSDLProcessingException("Missing part named "
+ bindingPartsList.get(0) + " ");
}
} else {
// i.e more than one part specified in this case we have
// to send an exception
throw new WSDLProcessingException(
"More than one element part is not allwed in document literal " +
" type binding operation " + wsdl4jOperation.getName());
}
}
}
}
/**
* Add the QName for the binding output
*/
private void addQNameReference(AxisMessage faultMessage,
Message wsdl4jMessage) throws AxisFault {
// for a fault this is trivial - All faults are related directly to a
// message by the name and are supposed to have a single part. So it is
// a matter of copying the right QName from the message part
// get the part
Map parts = wsdl4jMessage.getParts();
if (parts == null || parts.size() == 0) {
String message = "There are no parts"
+ " for fault message : "
+ wsdl4jMessage.getQName();
log.error(message);
throw new WSDLProcessingException(message);
}
Part wsdl4jMessagePart = (Part) parts.values()
.toArray()[0];
if (wsdl4jMessagePart == null) {
throw new WSDLProcessingException();
}
QName name = wsdl4jMessagePart.getElementName();
if (name == null) {
String message = "Part '"
+ wsdl4jMessagePart.getName()
+ "' of fault message '"
+ wsdl4jMessage.getQName()
+ "' must be defined with 'element=QName' and not 'type=QName'";
log.error(message);
throw new AxisFault(message);
}
faultMessage.setMessagePartName(wsdl4jMessagePart.getName());
faultMessage.setElementQName(name);
}
/**
* A util method that returns the SOAP style included in the binding
* operation
*
* @param bindingOp
*/
private String getSOAPStyle(BindingOperation bindingOp) {
List extensibilityElements = bindingOp.getExtensibilityElements();
for (int i = 0; i < extensibilityElements.size(); i++) {
Object extElement = extensibilityElements.get(i);
if (extElement instanceof SOAPOperation) {
return ((SOAPOperation) extElement).getStyle();
} else if (extElement instanceof SOAP12Operation) {
return ((SOAP12Operation) extElement).getStyle();
}
}
return null;
}
/**
* Copy the component from the operation
*
* @param wsdl4jOperation
* @param dif
* @throws AxisFault
*/
private AxisOperation populateOperations(Operation wsdl4jOperation,
PortType wsdl4jPortType)
throws AxisFault {
QName opName = new QName(wsdl4jPortType.getQName().getNamespaceURI(), wsdl4jOperation.getName());
// Copy Name Attribute
AxisOperation axisOperation = axisService.getOperation(opName);
if (axisOperation == null) {
String MEP = getMEP(wsdl4jOperation);
axisOperation = AxisOperationFactory.getOperationDescription(MEP);
axisOperation.setName(opName);
// setting the PolicyInclude property of the AxisOperation
PolicyInclude policyInclude = new PolicyInclude(axisOperation);
axisOperation.setPolicyInclude(policyInclude);
}
copyExtensionAttributes(wsdl4jOperation.getExtensionAttributes(),
axisOperation, PORT_TYPE_OPERATION);
Input wsdl4jInputMessage = wsdl4jOperation.getInput();
if (isServerSide) {
if (null != wsdl4jInputMessage) {
AxisMessage inMessage = axisOperation
.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
Message message = wsdl4jInputMessage.getMessage();
if (null != message) {
inMessage.setName(message.getQName().getLocalPart());
copyExtensionAttributes(wsdl4jInputMessage.getExtensionAttributes(),
inMessage, PORT_TYPE_OPERATION_INPUT);
}
// Check if the action is already set as we don't want to
// override it
// with the Default Action Pattern
ArrayList inputActions = axisOperation.getWSAMappingList();
String action = null;
if (inputActions == null || inputActions.size() == 0) {
action = WSDL11ActionHelper
.getActionFromInputElement(wsdl4jDefinition, wsdl4jPortType,
wsdl4jOperation, wsdl4jInputMessage);
}
if (action != null) {
if (inputActions == null) {
inputActions = new ArrayList();
axisOperation.setWsamappingList(inputActions);
}
inputActions.add(action);
axisService.mapActionToOperation(action, axisOperation);
}
}
// Create an output message and add
Output wsdl4jOutputMessage = wsdl4jOperation.getOutput();
if (null != wsdl4jOutputMessage) {
AxisMessage outMessage = axisOperation
.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
Message message = wsdl4jOutputMessage.getMessage();
if (null != message) {
outMessage.setName(message.getQName().getLocalPart());
copyExtensionAttributes(wsdl4jOutputMessage.getExtensionAttributes(),
outMessage, PORT_TYPE_OPERATION_OUTPUT);
// wsdl:portType -> wsdl:operation -> wsdl:output
}
// Check if the action is already set as we don't want to
// override it
// with the Default Action Pattern
String action = axisOperation.getOutputAction();
if (action == null) {
action = WSDL11ActionHelper.getActionFromOutputElement(wsdl4jDefinition,
wsdl4jPortType,
wsdl4jOperation,
wsdl4jOutputMessage);
}
if (action != null) {
axisOperation.setOutputAction(action);
}
}
} else {
// for the client side we have to do something that is a bit
// weird. The in message is actually taken from the output
// and the output is taken from the in
if (null != wsdl4jInputMessage) {
AxisMessage inMessage = axisOperation
.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
Message message = wsdl4jInputMessage.getMessage();
if (null != message) {
inMessage.setName(message.getQName().getLocalPart());
copyExtensionAttributes(wsdl4jInputMessage.getExtensionAttributes(),
inMessage, PORT_TYPE_OPERATION_OUTPUT);
}
// Check if the action is already set as we don't want to
// override it
// with the Default Action Pattern
String action = axisOperation.getOutputAction();
if (action == null) {
action = WSDL11ActionHelper
.getActionFromInputElement(wsdl4jDefinition, wsdl4jPortType,
wsdl4jOperation, wsdl4jInputMessage);
}
if (action != null) {
axisOperation.setOutputAction(action);
}
}
// Create an output message and add
Output wsdl4jOutputMessage = wsdl4jOperation.getOutput();
if (null != wsdl4jOutputMessage) {
AxisMessage outMessage = axisOperation
.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
Message message = wsdl4jOutputMessage.getMessage();
if (null != message) {
outMessage.setName(message.getQName().getLocalPart());
copyExtensionAttributes(wsdl4jOutputMessage.getExtensionAttributes(),
outMessage, PORT_TYPE_OPERATION_INPUT);
// wsdl:portType -> wsdl:operation -> wsdl:output
}
// Check if the action is already set as we don't want to
// override it
// with the Default Action Pattern
ArrayList inputActions = axisOperation.getWSAMappingList();
String action = null;
if (inputActions == null || inputActions.size() == 0) {
action = WSDL11ActionHelper.getActionFromOutputElement(wsdl4jDefinition,
wsdl4jPortType,
wsdl4jOperation,
wsdl4jOutputMessage);
}
if (action != null) {
if (inputActions == null) {
inputActions = new ArrayList();
axisOperation.setWsamappingList(inputActions);
}
inputActions.add(action);
}
}
}
Map faults = wsdl4jOperation.getFaults();
Iterator faultKeyIterator = faults.keySet().iterator();
while (faultKeyIterator.hasNext()) {
Fault fault = (Fault) faults.get(faultKeyIterator.next());
AxisMessage axisFaultMessage = new AxisMessage();
addDocumentation(axisFaultMessage,fault.getDocumentationElement());
axisFaultMessage.addParameter(FAULT_NAME, fault.getName());
Message faultMessage = fault.getMessage();
if (null != faultMessage) {
axisFaultMessage
.setName(faultMessage.getQName().getLocalPart());
copyExtensibleElements(faultMessage.getExtensibilityElements(),
wsdl4jDefinition, axisFaultMessage, PORT_TYPE_OPERATION_FAULT);
}
// Check if the action is already set as we don't want to override
// it
// with the Default Action Pattern
String action = axisOperation.getFaultAction(fault.getName());
if (action == null) {
action = WSDL11ActionHelper.getActionFromFaultElement(wsdl4jDefinition,
wsdl4jPortType,
wsdl4jOperation, fault);
}
if (action != null) {
axisOperation.addFaultAction(fault.getName(), action);
}
// Also add mapping from Exception name to fault action
String faultMessageName = axisFaultMessage.getName();
if (null != faultMessageName) {
char firstChar = faultMessageName.charAt(0);
String upperChar = String.valueOf(firstChar).toUpperCase();
String nameWithoutFirstChar = faultMessageName.substring(1);
String exceptionClassName = upperChar.concat(nameWithoutFirstChar);
if (log.isDebugEnabled()) {
log.debug("Searching for fault action using faultMessageName = "+faultMessageName+", exceptionClassName = "+exceptionClassName);
}
String faultAction = axisOperation.getFaultAction(exceptionClassName);
if (faultAction == null) {
faultAction = WSDL11ActionHelper.getActionFromFaultElement(wsdl4jDefinition,
wsdl4jPortType,
wsdl4jOperation, fault);
if (log.isDebugEnabled()) {
log.debug("Fault action didn't previously exist, getting it from WSDL: "+faultAction);
}
}
if (faultAction != null) {
axisOperation.addFaultAction(exceptionClassName, faultAction);
axisOperation.addFaultAction(exceptionClassName+"_Exception", faultAction);
if (log.isDebugEnabled()) {
log.debug("Adding fault action entry: "+exceptionClassName+"="+faultAction);
log.debug("Adding fault action entry: "+exceptionClassName+"_Exception"+"="+faultAction);
}
}
}
axisOperation.setFaultMessages(axisFaultMessage);
}
return axisOperation;
}
/**
* Generates a list of wrapper schemas
*
* @param wsdl4jBinding
*/
private Element[] generateWrapperSchema(Map schemaMap,
Binding wsdl4jBinding,
PortType portType) {
List schemaElementList = new ArrayList();
// target namespace for this should be the namespace URI for
// the porttype
String porttypeNamespaceURI = portType.getQName().getNamespaceURI();
// //////////////////////////////////////////////////////////////////////
// if there are any bindings present then we have to process them. we
// have to generate a schema per wsdl4jBinding (that is the safest
// option).
// if not we just resolve to
// the good old port type
// list, in which case we'll generate a schema per porttype
// //////////////////////////////////////////////////////////////////////
// findwrappable operations return either the rpc soap operations or
// Http binding operations
List wrappableBOEList = findWrappableBindingOperations(wsdl4jBinding);
// this method returns all the new schemas created when processing the rpc messages
Map newSchemaMap = createSchemaForPorttype(porttypeNamespaceURI,
wrappableBOEList,
schemaMap);
schemaElementList.addAll(newSchemaMap.values());
return (Element[]) schemaElementList
.toArray(new Element[schemaElementList.size()]);
}
/**
* Create a schema by looking at the port type
*
* @param namespaceURI - namespace of the porttype uri.
* we use this only if a user has not specified a namespace in soap:body
* @param boeListToProcess - List of BindingOperationEntry objects which require wrappering
*
* @return null if there is no element
*/
private Map createSchemaForPorttype(String namespaceURI,
List boeListToProcess,
Map existingSchemaMap) {
// this map is used to keep the newly added schemas
Map newSchemaMap = new HashMap();
// first of all look at the operations list
// we can return immediately if we get the operations list
// as empty
if (boeListToProcess.isEmpty()) {
return newSchemaMap;
}
// loop through the messages. We'll populate thins map with the relevant
// messages
// from the operations
Map messageQnameToMessageMap = new HashMap();
Map boeToInputMessageMap = new HashMap();
Map boeToOutputMessageMap = new HashMap();
// this contains the required namespace imports. the key in this
// map would be the namaspace URI
Map namespaceImportsMap = null;
// list namespace prefix map. This map will include uri -> prefix
Map namespacePrefixMap = null;
// //////////////////////////////////////////////////////////////////////////////////////////////////
// First thing is to populate the message map with the messages to
// process.
// //////////////////////////////////////////////////////////////////////////////////////////////////
// we really need to do this for a single porttype!
BindingOperationEntry boe;
for (int k = 0; k < boeListToProcess.size(); k++) {
boe = (BindingOperationEntry) boeListToProcess.get(k);
Input input = boe.getBindingOperation().getOperation().getInput();
Message message;
if (input != null) {
message = input.getMessage();
messageQnameToMessageMap.put(message.getQName(), message);
boeToInputMessageMap.put(boe, message);
}
Output output = boe.getBindingOperation().getOperation().getOutput();
if (output != null) {
message = output.getMessage();
messageQnameToMessageMap.put(message.getQName(), message);
boeToOutputMessageMap.put(boe, message);
}
// we do not want to process fault messages since they can only be used as document type
// see basic profile 4.4.2
}
// find the xsd prefix
String xsdPrefix = findSchemaPrefix();
// DOM document that will be the ultimate creator
Document document = getDOMDocumentBuilder().newDocument();
Element elementDeclaration;
//loop through the input op map and generate the elements
BindingOperationEntry boEntry;
for (Iterator boeIter = boeToInputMessageMap.keySet().iterator();
boeIter.hasNext();) {
boEntry = (BindingOperationEntry) boeIter.next();
elementDeclaration = document.createElementNS(
XMLSCHEMA_NAMESPACE_URI, xsdPrefix + ":"
+ XML_SCHEMA_ELEMENT_LOCAL_NAME);
elementDeclaration.setAttribute(XSD_NAME, boEntry.getBindingOperation().getName());
//when creating the inner complex type we have to find the parts list from the binding input
BindingInput bindingInput = boEntry.getBindingOperation().getBindingInput();
Message message = (Message) boeToInputMessageMap.get(boEntry);
if (bindingInput != null) {
Collection partsCollection = null;
if (BINDING_TYPE_SOAP.equals(this.bindingType)) {
// first see the body parts list
List bodyPartsList =
getPartsListFromSoapBody(bindingInput.getExtensibilityElements());
partsCollection = message.getOrderedParts(bodyPartsList);
} else {
// i.e http binding
partsCollection = message.getParts().values();
}
List parameterOrder =
boEntry.getBindingOperation().getOperation().getParameterOrdering();
namespaceImportsMap = new HashMap();
namespacePrefixMap = new HashMap();
Node newComplexType = getNewComplextType(document,
xsdPrefix,
partsCollection,
parameterOrder,
false,
namespaceImportsMap,
namespacePrefixMap,
boEntry);
elementDeclaration.appendChild(newComplexType);
String namespaceToUse = namespaceURI;
if (BINDING_TYPE_SOAP.equals(this.bindingType)) {
String bodyNamespace =
getNamespaceFromSoapBody(bindingInput.getExtensibilityElements());
namespaceToUse = bodyNamespace != null ? bodyNamespace : namespaceURI;
}
if (existingSchemaMap.containsKey(namespaceToUse)) {
// i.e this namespace is already exists with the original wsdl schemas
addElementToAnExistingSchema((Element) existingSchemaMap.get(namespaceToUse),
elementDeclaration,
namespacePrefixMap,
namespaceImportsMap,
namespaceToUse);
} else if (newSchemaMap.containsKey(namespaceToUse)) {
// i.e this namespace is with a newly created schema
addElementToAnExistingSchema((Element) newSchemaMap.get(namespaceToUse),
elementDeclaration,
namespacePrefixMap,
namespaceImportsMap,
namespaceToUse);
} else {
// i.e this element namespace has not found yet so
// we have to create new schema for it
Element newSchema = createNewSchemaWithElement(elementDeclaration,
namespacePrefixMap,
namespaceImportsMap,
namespaceToUse,
document,
xsdPrefix);
newSchemaMap.put(namespaceToUse, newSchema);
}
resolvedRpcWrappedElementMap.put(boEntry.getBindingOperation().getName(), new QName(
namespaceToUse, boEntry.getBindingOperation().getName(), AXIS2WRAPPED));
} else {
throw new WSDLProcessingException(
"No binding input is defiend for binding operation ==> "
+ boEntry.getBindingOperation().getName());
}
}
// loop through the output to map and generate the elements
for (Iterator boeIterator = boeToOutputMessageMap.keySet().iterator();
boeIterator.hasNext();) {
boEntry = (BindingOperationEntry) boeIterator.next();
String baseoutputOpName = boEntry.getBindingOperation().getName();
// see basic profile 4.7.19
String outputOpName = baseoutputOpName + WRAPPED_OUTPUTNAME_SUFFIX;
elementDeclaration = document.createElementNS(
XMLSCHEMA_NAMESPACE_URI, xsdPrefix + ":"
+ XML_SCHEMA_ELEMENT_LOCAL_NAME);
elementDeclaration.setAttribute(XSD_NAME, outputOpName);
BindingOutput bindingOutput = boEntry.getBindingOperation().getBindingOutput();
Message message = (Message) boeToOutputMessageMap.get(boEntry);
if (bindingOutput != null) {
Collection partsCollection = null;
if (BINDING_TYPE_SOAP.equals(this.bindingType)) {
// first see the body parts list
List bodyPartsList =
getPartsListFromSoapBody(bindingOutput.getExtensibilityElements());
partsCollection = message.getOrderedParts(bodyPartsList);
} else {
// i.e if http binding
partsCollection = message.getParts().values();
}
List parameterOrder =
boEntry.getBindingOperation().getOperation().getParameterOrdering();
// we have to initialize the hash maps always since we add the elements onece we
// generate it
namespacePrefixMap = new HashMap();
namespaceImportsMap = new HashMap();
Node newComplexType = getNewComplextType(document,
xsdPrefix,
partsCollection,
parameterOrder,
true,
namespaceImportsMap,
namespacePrefixMap,
boEntry);
elementDeclaration.appendChild(newComplexType);
String namespaceToUse = namespaceURI;
if (BINDING_TYPE_SOAP.equals(this.bindingType)) {
String bodyNamespace =
getNamespaceFromSoapBody(bindingOutput.getExtensibilityElements());
namespaceToUse = bodyNamespace != null ? bodyNamespace : namespaceURI;
}
if (existingSchemaMap.containsKey(namespaceToUse)) {
// i.e this namespace is already exists with the original wsdl schemas
addElementToAnExistingSchema((Element) existingSchemaMap.get(namespaceToUse),
elementDeclaration,
namespacePrefixMap,
namespaceImportsMap,
namespaceToUse);
} else if (newSchemaMap.containsKey(namespaceToUse)) {
// i.e this namespace is with a newly created schema
addElementToAnExistingSchema((Element) newSchemaMap.get(namespaceToUse),
elementDeclaration,
namespacePrefixMap,
namespaceImportsMap,
namespaceToUse);
} else {
// i.e this element namespace has not found yet so
// we have to create new schema for it
Element newSchema = createNewSchemaWithElement(elementDeclaration,
namespacePrefixMap,
namespaceImportsMap,
namespaceToUse,
document,
xsdPrefix);
newSchemaMap.put(namespaceToUse, newSchema);
}
resolvedRpcWrappedElementMap.put(outputOpName, new QName(
namespaceToUse, outputOpName, AXIS2WRAPPED));
} else {
throw new WSDLProcessingException(
"No binding out put is defined for binding operation ==>" +
boEntry.getBindingOperation().getName());
}
}
return newSchemaMap;
}
private void addElementToAnExistingSchema(Element schemaElement,
Element newElement,
Map namespacePrefixMap,
Map namespaceImportsMap,
String targetNamespace) {
Document ownerDocument = schemaElement.getOwnerDocument();
String newElementName = newElement.getAttribute(XSD_NAME);
// check whether this element already exists.
NodeList nodeList = schemaElement.getChildNodes();
Element nodeElement = null;
for (int i = 1; i < nodeList.getLength(); i++) {
if (nodeList.item(i) instanceof Element){
nodeElement = (Element) nodeList.item(i);
if (nodeElement.getLocalName().equals(XML_SCHEMA_ELEMENT_LOCAL_NAME)){
if (nodeElement.getAttribute(XSD_NAME).equals(newElementName)){
// if the element already exists we do not add this element
// and just return.
return;
}
}
}
}
// loop through the namespace declarations first and add them
String[] nameSpaceDeclarationArray = (String[]) namespacePrefixMap
.keySet().toArray(new String[namespacePrefixMap.size()]);
for (int i = 0; i < nameSpaceDeclarationArray.length; i++) {
String s = nameSpaceDeclarationArray[i];
checkAndAddNamespaceDeclarations(s, namespacePrefixMap,
schemaElement);
}
// add imports - check whether it is the targetnamespace before
// adding
Element[] namespaceImports = (Element[]) namespaceImportsMap
.values().toArray(new Element[namespaceImportsMap.size()]);
for (int i = 0; i < namespaceImports.length; i++) {
if (!targetNamespace.equals(namespaceImports[i]
.getAttribute(NAMESPACE_URI))) {
schemaElement.appendChild(ownerDocument.importNode(
namespaceImports[i], true));
}
}
schemaElement.appendChild(ownerDocument.importNode(newElement, true));
}
private Element createNewSchemaWithElement(Element newElement,
Map namespacePrefixMap,
Map namespaceImportsMap,
String targetNamespace,
Document document,
String xsdPrefix) {
Element schemaElement = document.createElementNS(
XMLSCHEMA_NAMESPACE_URI, xsdPrefix + ":"
+ XML_SCHEMA_LOCAL_NAME);
// loop through the namespace declarations first
String[] nameSpaceDeclarationArray = (String[]) namespacePrefixMap
.keySet().toArray(new String[namespacePrefixMap.size()]);
for (int i = 0; i < nameSpaceDeclarationArray.length; i++) {
String s = nameSpaceDeclarationArray[i];
schemaElement.setAttributeNS(XML_NAMESPACE_URI,
NAMESPACE_DECLARATION_PREFIX
+ namespacePrefixMap.get(s).toString(), s);
}
if (schemaElement.getAttributeNS(XML_NAMESPACE_URI, xsdPrefix).length() == 0) {
schemaElement.setAttributeNS(XML_NAMESPACE_URI,
NAMESPACE_DECLARATION_PREFIX + xsdPrefix,
XMLSCHEMA_NAMESPACE_URI);
}
// add the targetNamespace
schemaElement.setAttributeNS(XML_NAMESPACE_URI, XMLNS_AXIS2WRAPPED, targetNamespace);
schemaElement.setAttribute(XSD_TARGETNAMESPACE, targetNamespace);
schemaElement.setAttribute(XSD_ELEMENT_FORM_DEFAULT, XSD_UNQUALIFIED);
// add imports
Element[] namespaceImports = (Element[]) namespaceImportsMap
.values().toArray(new Element[namespaceImportsMap.size()]);
for (int i = 0; i < namespaceImports.length; i++) {
schemaElement.appendChild(namespaceImports[i]);
}
schemaElement.appendChild(newElement);
return schemaElement;
}
private List getPartsListFromSoapBody(List extensibilityElements) {
List partsList = null;
ExtensibilityElement extElement;
for (Iterator iter = extensibilityElements.iterator(); iter.hasNext();) {
extElement = (ExtensibilityElement) iter.next();
if (log.isDebugEnabled()) {
log.debug("Extensibility Element type is:" + extElement.getElementType());
log.debug("Extensibility Element class is:" + extElement.getClass().getName());
}
// SOAP 1.1 body element found!
if (extElement instanceof SOAPBody) {
SOAPBody soapBody = (SOAPBody) extElement;
partsList = soapBody.getParts();
} else if (extElement instanceof SOAP12Body) {
SOAP12Body soapBody = (SOAP12Body) extElement;
partsList = soapBody.getParts();
} else if (extElement instanceof MIMEMultipartRelated) {
MIMEMultipartRelated minMimeMultipartRelated = (MIMEMultipartRelated) extElement;
List mimePartsList = minMimeMultipartRelated.getMIMEParts();
MIMEPart mimePart = null;
Object object;
List mimePartElements;
ExtensibilityElement mimePartExtensibilityElement;
for (Iterator mimePartsIter = mimePartsList.iterator(); mimePartsIter.hasNext();) {
object = mimePartsIter.next();
if (object instanceof MIMEPart) {
mimePart = (MIMEPart) object;
mimePartElements = mimePart.getExtensibilityElements();
for (Iterator mimePartElementsIter = mimePartElements.iterator(); mimePartElementsIter.hasNext();)
{
mimePartExtensibilityElement = (ExtensibilityElement) mimePartElementsIter.next();
if (mimePartExtensibilityElement instanceof SOAPBody) {
SOAPBody soapBody = (SOAPBody) mimePartExtensibilityElement;
partsList = soapBody.getParts();
} else if (mimePartExtensibilityElement instanceof SOAP12Body) {
SOAP12Body soapBody = (SOAP12Body) mimePartExtensibilityElement;
partsList = soapBody.getParts();
}
}
}
}
}
}
if (partsList == null) {
log.debug("SOAP body parts have not been set. All the parts in the message were added to the message.");
}
return partsList;
}
private String getNamespaceFromSoapBody(List extensibilityElements) {
ExtensibilityElement extElement;
String namespace = null;
for (Iterator iter = extensibilityElements.iterator(); iter.hasNext();) {
extElement = (ExtensibilityElement) iter.next();
// SOAP 1.1 body element found!
if (extElement instanceof SOAPBody) {
SOAPBody soapBody = (SOAPBody) extElement;
namespace = soapBody.getNamespaceURI();
} else if (extElement instanceof SOAP12Body) {
SOAP12Body soapBody = (SOAP12Body) extElement;
namespace = soapBody.getNamespaceURI();
}
}
return namespace;
}
/**
* creates a new shema complex element according to the elements sequence difined
* this parts list is always for a message refering from the
* soap rpc type operation
*
* @param document
* @param xsdPrefix
* @param partsCollection - parts to be added
* @param parameterOrder - param Order list if it is given
* @param isOutMessage
* @param namespaceImportsMap
* @param namespacePrefixMap
* @param boe BindingOperationEntry for this partCollection
* @return new element
*/
private Element getNewComplextType(Document document,
String xsdPrefix,
Collection partsCollection,
List parameterOrder,
boolean isOutMessage,
Map namespaceImportsMap,
Map namespacePrefixMap,
BindingOperationEntry boe) {
// add the complex type
Element newComplexType = document.createElementNS(
XMLSCHEMA_NAMESPACE_URI, xsdPrefix + ":"
+ XML_SCHEMA_COMPLEX_TYPE_LOCAL_NAME);
Element cmplxTypeSequence = document.createElementNS(
XMLSCHEMA_NAMESPACE_URI, xsdPrefix + ":"
+ XML_SCHEMA_SEQUENCE_LOCAL_NAME);
Part part;
if ((parameterOrder == null) || (parameterOrder.size() == 0)) {
// no parameter order then just add the elements in the parts collection
for (Iterator partsIter = partsCollection.iterator(); partsIter.hasNext();) {
part = (Part) partsIter.next();
// the part name
addPartToElement(part,
document,
xsdPrefix,
namespaceImportsMap,
namespacePrefixMap,
cmplxTypeSequence,
isOutMessage,
boe);
}
} else {
// i.e an parts order is given
// first populate all the parts to a map
Map partsMap = new HashMap();
for (Iterator partsIter = partsCollection.iterator(); partsIter.hasNext();) {
part = (Part) partsIter.next();
partsMap.put(part.getName(), part);
}
String partName;
for (Iterator paramOrderIter = parameterOrder.iterator(); paramOrderIter.hasNext();) {
partName = (String) paramOrderIter.next();
part = (Part) partsMap.get(partName);
if (part != null) {
addPartToElement(part,
document,
xsdPrefix,
namespaceImportsMap,
namespacePrefixMap,
cmplxTypeSequence,
isOutMessage,
boe);
partsMap.remove(partName);
}
}
// if this is an output message then we have to set the
// return type if exists
if (isOutMessage) {
if (partsMap.size() > 0) {
if (partsMap.size() == 1) {
part = (Part) partsMap.values().iterator().next();
// change the name of this part
// this is the return type and its name should be result
// part.setName("result");
addPartToElement(part,
document,
xsdPrefix,
namespaceImportsMap,
namespacePrefixMap,
cmplxTypeSequence,
isOutMessage,
boe);
} else {
throw new WSDLProcessingException("the parameter order can left atmost" +
" one part");
}
}
}
}
newComplexType.appendChild(cmplxTypeSequence);
return newComplexType;
}
/**
* @param part
* @param document
* @param xsdPrefix
* @param namespaceImportsMap
* @param namespacePrefixMap
* @param cmplxTypeSequence
* @param isOutMessage (true is part is referenced by the output clause)
* @param boe BindingOperationEntry that caused the creation of this part.
*/
private void addPartToElement(Part part,
Document document,
String xsdPrefix,
Map namespaceImportsMap,
Map namespacePrefixMap,
Element cmplxTypeSequence,
boolean isOutMessage,
BindingOperationEntry boe) {
Element child;
String elementName = part.getName();
// the type name
QName schemaTypeName = part.getTypeName();
if (schemaTypeName != null) {
child = document.createElementNS(XMLSCHEMA_NAMESPACE_URI,
xsdPrefix + ":" + XML_SCHEMA_ELEMENT_LOCAL_NAME);
// always child attribute should be in no namespace
child.setAttribute("form", "unqualified");
child.setAttribute("nillable", "true");
String prefix;
if (XMLSCHEMA_NAMESPACE_URI.equals(schemaTypeName.getNamespaceURI())) {
prefix = xsdPrefix;
if(log.isDebugEnabled()) {
log.debug("Unable to find a namespace for " + xsdPrefix + ". Creating a new namespace attribute");
}
cmplxTypeSequence.setAttributeNS("http://www.w3.org/2000/xmlns/",
"xmlns:" + xsdPrefix,
XMLSCHEMA_NAMESPACE_URI);
} else {
// this schema is a third party one. So we need to have
// an import statement in our generated schema
String uri = schemaTypeName.getNamespaceURI();
if (!namespaceImportsMap.containsKey(uri)) {
// create Element for namespace import
Element namespaceImport = document.createElementNS(
XMLSCHEMA_NAMESPACE_URI, xsdPrefix + ":"
+ XML_SCHEMA_IMPORT_LOCAL_NAME);
namespaceImport.setAttribute(NAMESPACE_URI, uri);
// add this to the map
namespaceImportsMap.put(uri, namespaceImport);
// we also need to associate this uri with a prefix
// and include that prefix
// in the schema's namspace declarations. So add
// theis particular namespace to the
// prefix map as well
prefix = getTemporaryNamespacePrefix();
namespacePrefixMap.put(uri, prefix);
} else {
// this URI should be already in the namspace prefix
// map
prefix = (String) namespacePrefixMap.get(uri);
}
}
child.setAttribute(XSD_NAME, elementName);
child.setAttribute(XSD_TYPE, prefix + ":" + schemaTypeName.getLocalPart());
cmplxTypeSequence.appendChild(child);
} else {
String bindingOperationName = boe.getBindingOperation().getName();
String partName = part.getName();
if (boe.isRPC()) {
// see the basic profile 4.4.1 for rpc-literal.
// messages parts can have only types
throw new WSDLProcessingException(
"The binding operation " + bindingOperationName + " is RPC/literal. " +
"The message parts for this operation must use the type " +
"attribute as specificed by " +
"WS-I Basic Profile specification (4.4.1). Message part, " +
partName + ", violates" +
"this rule. Please remove the element attribute " +
"and use the type attribute.");
} else {
// The presense of an element means that a wrapper xsd element is not needed.
boe.setWrappedOutput(false);
if (log.isDebugEnabled()) {
log.debug("The binding operation " + bindingOperationName +
" references message part " +
partName + ". This part does not use the " +
"type attribute, so a wrappering element is not added.");
}
}
}
}
/**
* @param prefixMap
*/
private void checkAndAddNamespaceDeclarations(String namespace,
Map prefixMap, Element schemaElement) {
// get the attribute for the current namespace
String prefix = (String) prefixMap.get(namespace);
// A prefix must be found at this point!
String existingURL = schemaElement.getAttributeNS(XML_NAMESPACE_URI,
NAMESPACE_DECLARATION_PREFIX + prefix);
if (existingURL == null || existingURL.length() == 0) {
// there is no existing URL by that prefix - declare a new namespace
schemaElement.setAttributeNS(XML_NAMESPACE_URI,
NAMESPACE_DECLARATION_PREFIX + prefix, namespace);
} else if (existingURL.equals(namespace)) {
// this namespace declaration is already there with the same prefix
// ignore it
} else {
// there is a different namespace declared in the given prefix
// change the prefix in the prefix map to a new one and declare it
// create a prefix
String generatedPrefix = "ns" + prefixCounter++;
while (prefixMap.containsKey(generatedPrefix)) {
generatedPrefix = "ns" + prefixCounter++;
}
schemaElement.setAttributeNS(XML_NAMESPACE_URI,
NAMESPACE_DECLARATION_PREFIX + generatedPrefix, namespace);
// add to the map
prefixMap.put(namespace, generatedPrefix);
}
}
/**
* Read the WSDL file given the inputstream for the WSDL source
*
* @param in
* @throws WSDLException
*/
private Definition readInTheWSDLFile(InputStream in) throws WSDLException {
WSDLReader reader = WSDLUtil.newWSDLReaderWithPopulatedExtensionRegistry();
// switch off the verbose mode for all usecases
reader.setFeature(JAVAX_WSDL_VERBOSE_MODE_KEY, false);
reader.setFeature("javax.wsdl.importDocuments", true);
Definition def;
// if the custem resolver is present then use it
if (customWSDLResolver != null) {
// make sure the wsdl definition has the URI for the base document set
def = reader.readWSDL(customWSDLResolver);
def.setDocumentBaseURI(customWSDLResolver.getBaseURI());
return def;
} else {
Document doc;
try {
doc = XMLUtils.newDocument(in);
} catch (ParserConfigurationException e) {
throw new WSDLException(WSDLException.PARSER_ERROR,
"Parser Configuration Error", e);
} catch (SAXException e) {
throw new WSDLException(WSDLException.PARSER_ERROR,
"Parser SAX Error", e);
} catch (IOException e) {
throw new WSDLException(WSDLException.INVALID_WSDL, "IO Error",
e);
}
// Log when and from where the WSDL is loaded.
if (log.isDebugEnabled()) {
log.debug("Reading 1.1 WSDL with base uri = " + getBaseUri());
log.debug(" the document base uri = " + getDocumentBaseUri());
log.trace(" the stack at this point is: " + stackToString());
}
def = reader.readWSDL(getBaseUri(), doc);
def.setDocumentBaseURI(getDocumentBaseUri());
return def;
}
}
/**
* Get the Extensible elements form wsdl4jExtensibleElements
* Vector
if any and copy them to Component
* Note - SOAP body extensible element will be processed differently
*
* @param wsdl4jExtensibleElements
* @param description where is the ext element (port , portype , biding)
* @param wsdl4jDefinition
* @param originOfExtensibilityElements -
* this will indicate the place this extensibility element came
* from.
*/
private void copyExtensibleElements(List wsdl4jExtensibleElements,
Definition wsdl4jDefinition, AxisDescription description,
String originOfExtensibilityElements) throws AxisFault {
ExtensibilityElement wsdl4jExtensibilityElement;
for (Iterator iterator = wsdl4jExtensibleElements.iterator(); iterator.hasNext();) {
wsdl4jExtensibilityElement = (ExtensibilityElement) iterator.next();
if (wsdl4jExtensibilityElement instanceof UnknownExtensibilityElement) {
UnknownExtensibilityElement unknown =
(UnknownExtensibilityElement) (wsdl4jExtensibilityElement);
QName type = unknown.getElementType();
//
if (Constants.isPolicyElement(type)) {
if (isTraceEnabled) {
log.trace("copyExtensibleElements:: PolicyElement found " + unknown);
}
Policy policy = (Policy) PolicyUtil.getPolicyComponent(unknown.getElement());
description.getPolicySubject().attachPolicy(policy);
// int attachmentScope =
// getPolicyAttachmentPoint(description, originOfExtensibilityElements);
// if (attachmentScope > -1) {
// description.getPolicyInclude().addPolicyElement(
// attachmentScope, policy);
// }
//
} else if (Constants.isPolicyRef(type)) {
if (isTraceEnabled) {
log.trace("copyExtensibleElements:: PolicyReference found " + unknown);
}
PolicyReference policyReference = (PolicyReference) PolicyUtil
.getPolicyComponent(unknown.getElement());
description.getPolicySubject().attachPolicyReference(policyReference);
// int attachmentScope =
// getPolicyAttachmentPoint(description, originOfExtensibilityElements);
// if (attachmentScope > -1) {
// description.getPolicyInclude().addPolicyRefElement(
// attachmentScope, policyReference);
// }
} else if (AddressingConstants.Final.WSAW_USING_ADDRESSING
.equals(type)
|| AddressingConstants.Submission.WSAW_USING_ADDRESSING
.equals(unknown.getElementType())) {
if (isTraceEnabled) {
log.trace("copyExtensibleElements:: wsaw:UsingAddressing found " + unknown);
}
// FIXME We need to set this the appropriate Axis Description AxisEndpoint or
// AxisBinding .
if (originOfExtensibilityElements.equals(PORT)
|| originOfExtensibilityElements.equals(BINDING)) {
if (Boolean.TRUE.equals(unknown.getRequired())) {
AddressingHelper.setAddressingRequirementParemeterValue(axisService, AddressingConstants.ADDRESSING_REQUIRED);
} else {
AddressingHelper.setAddressingRequirementParemeterValue(axisService, AddressingConstants.ADDRESSING_OPTIONAL);
}
}
} else if (wsdl4jExtensibilityElement.getElementType() != null &&
wsdl4jExtensibilityElement.getElementType().getNamespaceURI().equals(
org.apache.axis2.namespace.Constants.FORMAT_BINDING)) {
Element typeMapping = unknown.getElement();
NodeList typeMaps = typeMapping.getElementsByTagNameNS(
org.apache.axis2.namespace.Constants.FORMAT_BINDING,
"typeMap");
int count = typeMaps.getLength();
HashMap typeMapper = new HashMap();
for (int index = 0; index < count; index++) {
Node node = typeMaps.item(index);
NamedNodeMap attributes = node.getAttributes();
Node typeName = attributes.getNamedItem("typeName");
if (typeName != null) {
String prefix = getPrefix(typeName.getNodeValue());
if (prefix != null) {
String ns = (String) wsdl4jDefinition.getNamespaces().get(prefix);
if (ns != null) {
Node formatType = attributes.getNamedItem("formatType");
typeMapper.put(new QName(ns, getTypeName(
typeName.getNodeValue())), formatType.getNodeValue());
}
}
}
}
} else if (wsdl4jExtensibilityElement.getElementType() != null &&
wsdl4jExtensibilityElement.getElementType().getNamespaceURI().equals(
org.apache.axis2.namespace.Constants.JAVA_NS)) {
Element unknowJavaElement = unknown.getElement();
if (unknowJavaElement.getLocalName().equals("address") ) {
NamedNodeMap nameAttributes = unknowJavaElement.getAttributes();
Node node = nameAttributes.getNamedItem("className");
Parameter serviceClass = new Parameter();
serviceClass.setName("className");
serviceClass.setValue(node.getNodeValue());
axisService.addParameter(serviceClass);
Parameter transportName = new Parameter();
transportName.setName("TRANSPORT_NAME");
transportName.setValue("java");
axisService.addParameter(transportName);
}
} else {
// Ignore this element - it is a totally unknown element
if (isTraceEnabled) {
log.trace("copyExtensibleElements:: Unknown Extensibility Element found " +
unknown);
}
}
} else if (wsdl4jExtensibilityElement instanceof SOAP12Address) {
SOAP12Address soapAddress = (SOAP12Address) wsdl4jExtensibilityElement;
if (description instanceof AxisEndpoint) {
setEndpointURL((AxisEndpoint) description, soapAddress.getLocationURI());
}
} else if (wsdl4jExtensibilityElement instanceof SOAPAddress) {
SOAPAddress soapAddress = (SOAPAddress) wsdl4jExtensibilityElement;
if (description instanceof AxisEndpoint) {
setEndpointURL((AxisEndpoint) description, soapAddress.getLocationURI());
}
} else if (wsdl4jExtensibilityElement instanceof HTTPAddress) {
HTTPAddress httpAddress = (HTTPAddress) wsdl4jExtensibilityElement;
if (description instanceof AxisEndpoint) {
setEndpointURL((AxisEndpoint) description, httpAddress.getLocationURI());
}
} else if (wsdl4jExtensibilityElement instanceof Schema) {
Schema schema = (Schema) wsdl4jExtensibilityElement;
// just add this schema - no need to worry about the imported
// ones
axisService.addSchema(getXMLSchema(schema.getElement(), schema
.getDocumentBaseURI()));
} else if (wsdl4jExtensibilityElement instanceof SOAP12Operation) {
SOAP12Operation soapOperation = (SOAP12Operation) wsdl4jExtensibilityElement;
AxisBindingOperation axisBindingOperation = (AxisBindingOperation) description;
String style = soapOperation.getStyle();
if (style != null) {
axisBindingOperation.setProperty(WSDLConstants.WSDL_1_1_STYLE, style);
}
String soapActionURI = soapOperation.getSoapActionURI();
if (this.isCodegen && ((soapActionURI == null) || (soapActionURI.equals("")))) {
soapActionURI = axisBindingOperation.getAxisOperation().getInputAction();
}
if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled())
log.debug("WSDL Binding Operation: " + axisBindingOperation.getName() +
", SOAPAction: " + soapActionURI);
if (soapActionURI != null && !soapActionURI.equals("")) {
axisBindingOperation
.setProperty(WSDL2Constants.ATTR_WSOAP_ACTION, soapActionURI);
axisBindingOperation.getAxisOperation().setSoapAction(soapActionURI);
if (!isServerSide) {
axisBindingOperation.getAxisOperation().setOutputAction(soapActionURI);
}
axisService.mapActionToOperation(soapActionURI,
axisBindingOperation.getAxisOperation());
}
} else if (wsdl4jExtensibilityElement instanceof SOAPOperation) {
SOAPOperation soapOperation = (SOAPOperation) wsdl4jExtensibilityElement;
AxisBindingOperation axisBindingOperation = (AxisBindingOperation) description;
String style = soapOperation.getStyle();
if (style != null) {
axisBindingOperation.setProperty(WSDLConstants.WSDL_1_1_STYLE, style);
}
String soapAction = soapOperation.getSoapActionURI();
if (this.isCodegen && ((soapAction == null) || (soapAction.equals("")))) {
soapAction = axisBindingOperation.getAxisOperation().getInputAction();
}
if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled())
log.debug("WSDL Binding Operation: " + axisBindingOperation.getName() +
", SOAPAction: " + soapAction);
if (soapAction != null && !soapAction.equals("")) {
axisBindingOperation.setProperty(WSDL2Constants.ATTR_WSOAP_ACTION, soapAction);
axisBindingOperation.getAxisOperation().setSoapAction(soapAction);
if (!isServerSide) {
axisBindingOperation.getAxisOperation().setOutputAction(soapAction);
}
axisService.mapActionToOperation(soapAction,
axisBindingOperation.getAxisOperation());
}
} else if (wsdl4jExtensibilityElement instanceof HTTPOperation) {
HTTPOperation httpOperation = (HTTPOperation) wsdl4jExtensibilityElement;
AxisBindingOperation axisBindingOperation = (AxisBindingOperation) description;
String httpLocation = httpOperation.getLocationURI();
if (httpLocation != null) {
// change the template to make it same as WSDL 2 template
httpLocation = httpLocation.replaceAll("\\(", "{");
httpLocation = httpLocation.replaceAll("\\)", "}");
axisBindingOperation
.setProperty(WSDL2Constants.ATTR_WHTTP_LOCATION, httpLocation);
}
axisBindingOperation.setProperty(WSDL2Constants.ATTR_WHTTP_INPUT_SERIALIZATION,
HTTPConstants.MEDIA_TYPE_TEXT_XML);
} else if (wsdl4jExtensibilityElement instanceof SOAP12Header) {
SOAP12Header soapHeader = (SOAP12Header) wsdl4jExtensibilityElement;
SOAPHeaderMessage headerMessage = new SOAPHeaderMessage();
headerMessage.setNamespaceURI(soapHeader.getNamespaceURI());
headerMessage.setUse(soapHeader.getUse());
Boolean required = soapHeader.getRequired();
if (required != null) {
headerMessage.setRequired(required.booleanValue());
}
if (wsdl4jDefinition != null) {
// find the relevant schema part from the messages
Message msg = wsdl4jDefinition.getMessage(soapHeader
.getMessage());
if (msg == null) {
msg = getMessage(wsdl4jDefinition, soapHeader
.getMessage(), new HashSet());
}
if (msg == null) {
// TODO i18n this
throw new AxisFault("message "
+ soapHeader.getMessage()
+ " not found in the WSDL ");
}
Part msgPart = msg.getPart(soapHeader.getPart());
if (msgPart == null) {
// TODO i18n this
throw new AxisFault("message part "
+ soapHeader.getPart()
+ " not found in the WSDL ");
}
// see basic profile 4.4.2 Bindings and Faults header, fault and headerfaults
// can only have elements
headerMessage.setElement(msgPart.getElementName());
}
headerMessage.setMessage(soapHeader.getMessage());
headerMessage.setPart(soapHeader.getPart());
if (description instanceof AxisBindingMessage) {
AxisBindingMessage bindingMessage = (AxisBindingMessage) description;
List soapHeaders =
(List) bindingMessage.getProperty(WSDL2Constants.ATTR_WSOAP_HEADER);
if (soapHeaders == null) {
soapHeaders = new ArrayList();
bindingMessage.setProperty(WSDL2Constants.ATTR_WSOAP_HEADER, soapHeaders);
}
soapHeaders.add(headerMessage);
}
} else if (wsdl4jExtensibilityElement instanceof SOAPHeader) {
SOAPHeader soapHeader = (SOAPHeader) wsdl4jExtensibilityElement;
SOAPHeaderMessage headerMessage = new SOAPHeaderMessage();
headerMessage.setNamespaceURI(soapHeader.getNamespaceURI());
headerMessage.setUse(soapHeader.getUse());
Boolean required = soapHeader.getRequired();
if (null != required) {
headerMessage.setRequired(required.booleanValue());
}
if (null != wsdl4jDefinition) {
// find the relevant schema part from the messages
Message msg = wsdl4jDefinition.getMessage(soapHeader
.getMessage());
if (msg == null) {
msg = getMessage(wsdl4jDefinition, soapHeader
.getMessage(), new HashSet());
}
if (msg == null) {
// todo i18n this
throw new AxisFault("message "
+ soapHeader.getMessage()
+ " not found in the WSDL ");
}
Part msgPart = msg.getPart(soapHeader.getPart());
if (msgPart == null) {
// todo i18n this
throw new AxisFault("message part "
+ soapHeader.getPart()
+ " not found in the WSDL ");
}
headerMessage.setElement(msgPart.getElementName());
}
headerMessage.setMessage(soapHeader.getMessage());
headerMessage.setPart(soapHeader.getPart());
if (description instanceof AxisBindingMessage) {
AxisBindingMessage bindingMessage = (AxisBindingMessage) description;
List soapHeaders =
(List) bindingMessage.getProperty(WSDL2Constants.ATTR_WSOAP_HEADER);
if (soapHeaders == null) {
soapHeaders = new ArrayList();
bindingMessage.setProperty(WSDL2Constants.ATTR_WSOAP_HEADER, soapHeaders);
}
soapHeaders.add(headerMessage);
}
} else if (wsdl4jExtensibilityElement instanceof SOAPBinding) {
SOAPBinding soapBinding = (SOAPBinding) wsdl4jExtensibilityElement;
AxisBinding axisBinding = (AxisBinding) description;
axisBinding.setType(soapBinding.getTransportURI());
axisBinding.setProperty(WSDL2Constants.ATTR_WSOAP_VERSION,
SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI);
String style = soapBinding.getStyle();
if (style != null) {
axisBinding.setProperty(WSDLConstants.WSDL_1_1_STYLE, style);
}
} else if (wsdl4jExtensibilityElement instanceof SOAP12Binding) {
SOAP12Binding soapBinding = (SOAP12Binding) wsdl4jExtensibilityElement;
AxisBinding axisBinding = (AxisBinding) description;
axisBinding.setProperty(WSDL2Constants.ATTR_WSOAP_VERSION,
SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);
String style = soapBinding.getStyle();
if (style != null) {
axisBinding.setProperty(WSDLConstants.WSDL_1_1_STYLE, style);
}
String transportURI = soapBinding.getTransportURI();
axisBinding.setType(transportURI);
} else if (wsdl4jExtensibilityElement instanceof HTTPBinding) {
HTTPBinding httpBinding = (HTTPBinding) wsdl4jExtensibilityElement;
AxisBinding axisBinding = (AxisBinding) description;
// set the binding style same as the wsd2 to process smoothly
axisBinding.setType(WSDL2Constants.URI_WSDL2_HTTP);
axisBinding.setProperty(WSDL2Constants.ATTR_WHTTP_METHOD, httpBinding.getVerb());
} else if (wsdl4jExtensibilityElement instanceof MIMEContent) {
if (description instanceof AxisBindingMessage) {
MIMEContent mimeContent = (MIMEContent) wsdl4jExtensibilityElement;
String messageSerialization = mimeContent.getType();
AxisBindingMessage bindingMessage = (AxisBindingMessage) description;
setMessageSerialization(
(AxisBindingOperation)bindingMessage.getParent(),
originOfExtensibilityElements, messageSerialization);
}
} else if (wsdl4jExtensibilityElement instanceof MIMEMimeXml) {
if (description instanceof AxisBindingMessage) {
AxisBindingMessage bindingMessage = (AxisBindingMessage) description;
setMessageSerialization(
(AxisBindingOperation)bindingMessage.getParent(),
originOfExtensibilityElements,
HTTPConstants.MEDIA_TYPE_TEXT_XML);
}
} else if (wsdl4jExtensibilityElement instanceof HTTPUrlEncoded) {
if (description instanceof AxisBindingMessage) {
AxisBindingMessage bindingMessage = (AxisBindingMessage) description;
setMessageSerialization(
(AxisBindingOperation)bindingMessage.getParent(),
originOfExtensibilityElements,
HTTPConstants.MEDIA_TYPE_X_WWW_FORM);
}
}
}
}
private static void setMessageSerialization(AxisBindingOperation bindingOperation,
String originOfExtensibilityElements,
String messageSerialization) {
if (bindingOperation != null) {
if (BINDING_OPERATION_INPUT.equals(originOfExtensibilityElements)) {
bindingOperation.setProperty(
WSDL2Constants.ATTR_WHTTP_INPUT_SERIALIZATION,
messageSerialization);
} else if (BINDING_OPERATION_OUTPUT.equals(originOfExtensibilityElements)) {
bindingOperation.setProperty(
WSDL2Constants.ATTR_WHTTP_OUTPUT_SERIALIZATION,
messageSerialization);
}
}
}
/**
* Look deeper in the imports to find the requested Message. Use a HashSet to make
* sure we don't traverse the same Definition object twice (avoid recursion).
*
* @param definition
* @param message
* @param instances
* @return
*/
private Message getMessage(Definition definition, QName message, Set seen) {
Message msg = definition.getMessage(message);
if (msg != null) {
if (log.isDebugEnabled()) {
log.debug("getMessage returning = " + ((message.getLocalPart() != null) ? message.getLocalPart(): "NULL"));
}
return msg;
}
seen.add(definition);
Iterator iter = definition.getImports().values().iterator();
while (iter.hasNext()) {
Vector values = (Vector) iter.next();
for (Iterator valuesIter = values.iterator(); valuesIter.hasNext();) {
Import wsdlImport = (Import) valuesIter.next();
Definition innerDefinition = wsdlImport.getDefinition();
if (seen.contains(innerDefinition)) {
continue; // Skip seen
}
Message result = getMessage(innerDefinition, message, seen);
if (result != null) {
return result;
}
}
}
if (log.isDebugEnabled()) {
log.debug("getMessage: Unable to find message, returning NULL");
}
return null;
}
private int getPolicyAttachmentPoint(AxisDescription description,
String originOfExtensibilityElements) {
int result = -1; // Attachment Point Not Identified
if (SERVICE.equals(originOfExtensibilityElements)) {
result = PolicyInclude.SERVICE_POLICY;
} else if (PORT.equals(originOfExtensibilityElements)) {
result = PolicyInclude.PORT_POLICY;
} else if (BINDING.equals(originOfExtensibilityElements)) {
result = PolicyInclude.BINDING_POLICY;
} else if (BINDING_OPERATION.equals(originOfExtensibilityElements)) {
result = PolicyInclude.BINDING_OPERATION_POLICY;
} else if (BINDING_OPERATION_INPUT.equals(originOfExtensibilityElements)) {
result = PolicyInclude.BINDING_INPUT_POLICY;
} else if (BINDING_OPERATION_OUTPUT.equals(originOfExtensibilityElements)) {
result = PolicyInclude.BINDING_OUTPUT_POLICY;
} else if (PORT_TYPE.equals(originOfExtensibilityElements)) {
result = PolicyInclude.PORT_TYPE_POLICY;
} else if (PORT_TYPE_OPERATION.equals(originOfExtensibilityElements)) {
result = PolicyInclude.OPERATION_POLICY;
} else if (PORT_TYPE_OPERATION_INPUT.equals(originOfExtensibilityElements)) {
result = PolicyInclude.INPUT_POLICY;
} else if (PORT_TYPE_OPERATION_OUTPUT.equals(originOfExtensibilityElements)) {
result = PolicyInclude.OUTPUT_POLICY;
}
if (isTraceEnabled) {
log.trace("getPolicyAttachmentPoint:: axisDescription=" + description +
" extensibilityPoint=" + originOfExtensibilityElements + " result=" + result);
}
return result;
}
/**
* Look for the wrappable operations depending on the style
*
* @param binding
* @return List of BindingOperationEntry objects
*/
private List findWrappableBindingOperations(Binding binding) {
// first find the global style declaration.
// for a SOAP binding this can be only rpc or document
// as per the WSDL spec (section 3.4) the default style is document
// now we have to handle the http bindings case as well
//
boolean isRPC = false;
boolean isSOAPBinding = false;
boolean isHttpBinding = false;
List extElements = binding.getExtensibilityElements();
for (int i = 0; i < extElements.size(); i++) {
if (extElements.get(i) instanceof SOAPBinding) {
// we have a global SOAP binding!
isSOAPBinding = true;
SOAPBinding soapBinding = (SOAPBinding) extElements.get(i);
if (RPC_STYLE.equals(soapBinding.getStyle())) {
// set the global style to rpc
isRPC = true;
}
this.bindingType = BINDING_TYPE_SOAP;
break;
} else if (extElements.get(i) instanceof SOAP12Binding) {
// we have a global SOAP binding!
isSOAPBinding = true;
SOAP12Binding soapBinding = (SOAP12Binding) extElements.get(i);
if (RPC_STYLE.equals(soapBinding.getStyle())) {
// set the global style to rpc
isRPC = true;
}
this.bindingType = BINDING_TYPE_SOAP;
break;
} else if (extElements.get(i) instanceof HTTPBinding) {
isHttpBinding = true;
this.bindingType = BINDING_TYPE_HTTP;
}
}
if (log.isDebugEnabled()) {
log.debug("Binding Name =" + binding.getQName());
log.debug(" isSOAPBinding =" + isSOAPBinding );
log.debug(" isHttpBinding =" + isHttpBinding );
log.debug(" isRPC =" + isRPC );
}
// go through every operation and get their styles.
// each one can have a style override from the global
// styles. Depending on the style add the relevant operations
// to the return list
List returnList = new ArrayList();
if (isHttpBinding || isSOAPBinding) {
BindingOperation bindingOp;
for (Iterator bindingOperationsIterator =
binding.getBindingOperations().iterator(); bindingOperationsIterator.hasNext();)
{
bindingOp = (BindingOperation) bindingOperationsIterator.next();
if (log.isDebugEnabled()) {
log.debug(" Binding Operation =" + bindingOp.getName());
}
if (isSOAPBinding) {
String style = getSOAPStyle(bindingOp);
if (log.isDebugEnabled()) {
log.debug(" SOAPStyle =" + style);
}
if (style == null) {
// no style specified
// use the global style to determine whether to put this one or
// not
if (isRPC) {
if (log.isDebugEnabled()) {
log.debug(" schema wrappering required");
}
BindingOperationEntry boe =
new BindingOperationEntry(bindingOp,
true,
false,
style,
true);
returnList.add(boe);
}
} else if (RPC_STYLE.equals(style)) {
// add to the list
if (log.isDebugEnabled()) {
log.debug(" schema wrappering required");
}
BindingOperationEntry boe =
new BindingOperationEntry(bindingOp,
true,
false,
style,
true);
returnList.add(boe);
}
// if not RPC we just leave it - default is doc
} else {
// i.e an http binding then we have to add the operation any way
if (log.isDebugEnabled()) {
log.debug(" schema wrappering required");
}
BindingOperationEntry boe =
new BindingOperationEntry(bindingOp,
false,
true,
null,
false);
returnList.add(boe);
}
}
}
// if the binding is not either soap or http binding then we return and empty list
// set this to the global list
wrappableBOEs = returnList;
return returnList;
}
/**
* Guess the MEP based on the order of messages
*
* @param operation
* @throws AxisFault
*/
private String getMEP(Operation operation) throws AxisFault {
OperationType operationType = operation.getStyle();
if (isServerSide) {
if (operationType != null) {
if (operationType.equals(OperationType.REQUEST_RESPONSE)) {
return WSDL2Constants.MEP_URI_IN_OUT;
}
if (operationType.equals(OperationType.ONE_WAY)) {
if (operation.getFaults().size() > 0) {
return WSDL2Constants.MEP_URI_ROBUST_IN_ONLY;
}
return WSDL2Constants.MEP_URI_IN_ONLY;
}
if (operationType.equals(OperationType.NOTIFICATION)) {
return WSDL2Constants.MEP_URI_OUT_ONLY;
}
if (operationType.equals(OperationType.SOLICIT_RESPONSE)) {
return WSDL2Constants.MEP_URI_OUT_IN;
}
throw new AxisFault("Cannot Determine the MEP");
}
} else {
if (operationType != null) {
if (operationType.equals(OperationType.REQUEST_RESPONSE)) {
return WSDL2Constants.MEP_URI_OUT_IN;
}
if (operationType.equals(OperationType.ONE_WAY)) {
return WSDL2Constants.MEP_URI_OUT_ONLY;
}
if (operationType.equals(OperationType.NOTIFICATION)) {
return WSDL2Constants.MEP_URI_IN_ONLY;
}
if (operationType.equals(OperationType.SOLICIT_RESPONSE)) {
return WSDL2Constants.MEP_URI_IN_OUT;
}
throw new AxisFault("Cannot Determine the MEP");
}
}
throw new AxisFault("Cannot Determine the MEP");
}
/**
* Copies the extension attributes
*
* @param extAttributes
* @param description
* @param origin
*/
private void copyExtensionAttributes(Map extAttributes,
AxisDescription description, String origin) {
QName key;
QName value;
for (Iterator iterator = extAttributes.keySet().iterator(); iterator
.hasNext();) {
key = (QName) iterator.next();
if (Constants.URI_POLICY_NS.equals(key.getNamespaceURI())
&& "PolicyURIs".equals(key.getLocalPart())) {
value = (QName) extAttributes.get(key);
String policyURIs = value.getLocalPart();
if (policyURIs.length() != 0) {
String[] uris = policyURIs.split(" ");
PolicyReference ref;
for (int i = 0; i < uris.length; i++) {
ref = new PolicyReference();
ref.setURI(uris[i]);
if (PORT_TYPE.equals(origin)
|| PORT_TYPE_OPERATION.equals(origin)
|| PORT_TYPE_OPERATION_INPUT.equals(origin)
|| PORT_TYPE_OPERATION_OUTPUT.equals(origin)) {
if (description != null) {
PolicySubject subject = description.getPolicySubject();
if (subject != null) {
subject.attachPolicyReference(ref);
}
}
}
}
}
}
}
}
/**
* Process the policy definitions
*
* @param definition
*/
private void processPoliciesInDefintion(Definition definition) {
processPoliciesInDefintion(definition, new HashSet());
}
/**
* Process the policy definitions
*
* @param definition
*/
private void processPoliciesInDefintion(Definition definition, Set visitedWSDLs) {
visitedWSDLs.add(definition.getDocumentBaseURI());
List extElements = definition.getExtensibilityElements();
ExtensibilityElement extElement;
UnknownExtensibilityElement unknown = null;
Policy policy = null;
for (Iterator iterator = extElements.iterator(); iterator.hasNext();) {
extElement = (ExtensibilityElement) iterator.next();
if (extElement instanceof UnknownExtensibilityElement) {
unknown = (UnknownExtensibilityElement) extElement;
if (Constants.isPolicyElement(unknown.getElementType())) {
policy = (Policy) PolicyUtil.getPolicyComponent(unknown.getElement());
String key;
if ((key = policy.getName()) != null || (key = policy.getId()) != null) {
axisService.registerPolicy(key, policy);
// registry.register(key, policy);
// registry.register("#" + key, policy);
}
}
}
}
// include policices in other imported wsdls
Iterator iter = definition.getImports().values().iterator();
Vector values = null;
Import wsdlImport = null;
for (; iter.hasNext();) {
values = (Vector) iter.next();
for (Iterator valuesIter = values.iterator(); valuesIter.hasNext();) {
wsdlImport = (Import) valuesIter.next();
Definition innerDefinition = wsdlImport.getDefinition();
// find the binding recursively
if(!visitedWSDLs.contains(innerDefinition.getDocumentBaseURI())) {
processPoliciesInDefintion(innerDefinition, visitedWSDLs);
}
}
}
}
private void setEndpointURL(AxisEndpoint axisEndpoint, String endpointURL) throws AxisFault {
axisEndpoint.setEndpointURL(endpointURL);
try {
URL url = new URL(endpointURL);
axisEndpoint.setTransportInDescription(url.getProtocol());
} catch (Exception e) {
log.debug(e.getMessage(),e);
}
}
/**
* Inner class declaration for the processing exceptions
*/
public static class WSDLProcessingException extends RuntimeException {
public WSDLProcessingException() {
}
public WSDLProcessingException(String message) {
super(message);
}
public WSDLProcessingException(Throwable cause) {
super(cause);
}
public WSDLProcessingException(String message, Throwable cause) {
super(message, cause);
}
}
public boolean isAllPorts() {
return isAllPorts;
}
public void setAllPorts(boolean allPorts) {
isAllPorts = allPorts;
}
// private void processPoliciesInDefinition() {
//
// Object obj;
// for (Iterator iterator = wsdl4jDefinition.getExtensibilityElements().iterator(); iterator.hasNext();) {
// obj = iterator.next();
//
// if (obj instanceof UnknownExtensibilityElement) {
// Element e = ((UnknownExtensibilityElement) obj).getElement();
// if (WSDLConstants.WSDL11Constants.POLICY.getNamespaceURI().equals(e.getNamespaceURI()) &&
// WSDLConstants.WSDL11Constants.POLICY.getLocalPart().equals(e.getLocalName())) {
// Policy p = (Policy) PolicyUtil.getPolicyComponent(e);
// reg.register(p.getId(), p);
// }
// }
// }
// }
/**
* This method is to split attribute like abc:cde and get the prefix part of it
* so the method will retuen abc if the ":" is present in the the string else it
* will return null
*
* @param attributeValue : String
* @return String
*/
public static String getPrefix(String attributeValue) {
if (attributeValue != null) {
int splitIdex = attributeValue.indexOf(':');
if (splitIdex > 0) {
return attributeValue.substring(0, splitIdex);
}
}
return null;
}
public static String getTypeName(String attributeValue) {
if (attributeValue != null) {
int splitIdex = attributeValue.indexOf(':');
if (splitIdex > 0) {
return attributeValue.substring(splitIdex + 1);
} else {
return attributeValue;
}
}
return null;
}
/**
* returns the wsld defintion for the given component.
* @param definition
* @param qname
* @param componentType
* @param visitedWSDLs
* @return definition containing the component.
*/
private Definition getParentDefinition(Definition definition,
QName qname,
int componentType,
Set visitedWSDLs){
visitedWSDLs.add(definition.getDocumentBaseURI());
Definition newParentDefinition = null;
// first find through imports
Iterator iter = definition.getImports().values().iterator();
Vector values = null;
Import wsdlImport = null;
for (; iter.hasNext();) {
values = (Vector) iter.next();
for (Iterator valuesIter = values.iterator(); valuesIter.hasNext();) {
wsdlImport = (Import) valuesIter.next();
Definition innerDefinition = wsdlImport.getDefinition();
if (!visitedWSDLs.contains(innerDefinition.getDocumentBaseURI())){
newParentDefinition = getParentDefinition(innerDefinition,qname,componentType,visitedWSDLs);
if (newParentDefinition != null){
break;
}
}
}
if (newParentDefinition != null) {
break;
}
}
// if it not available in imports we check for the current definition.
if (newParentDefinition == null) {
// this can be in a imported wsdl
if (isComponetAvailable(definition, qname, componentType)) {
newParentDefinition = definition;
}
}
return newParentDefinition;
}
private boolean isComponetAvailable(Definition definition,
QName qname,
int componentType){
boolean isAvailable = false;
switch (componentType){
case COMPONENT_BINDING : {
isAvailable = (definition.getBinding(qname) != null) &&
(definition.getBinding(qname).getPortType() != null);
break;
}
case COMPONENT_PORT_TYPE : {
isAvailable = (definition.getPortType(qname) != null);
break;
}
case COMPONENT_MESSAGE : {
isAvailable = (definition.getMessage(qname) != null);
break;
}
}
return isAvailable;
}
/**
* Find BindingOperationEntry
* @param boes List of BindingOperationEntry
* @param bo BindingOperation
* @return BindingOperation or null
*/
private BindingOperationEntry find(List boes, BindingOperation bo) {
for (int i=0; i < boes.size(); i++) {
BindingOperationEntry boe = (BindingOperationEntry) boes.get(i);
if (boe.getBindingOperation() == bo) {
return boe;
}
}
return null;
}
/**
* BindingOperation plus state information
*/
class BindingOperationEntry {
private BindingOperation bindingOperation;
private boolean isSOAPBinding;
private boolean isHTTPBinding;
private String soapStyle;
private boolean isRPC;
private boolean wrappedInput = true;
private boolean wrappedOutput = true;
public BindingOperationEntry(BindingOperation bindingOperation, boolean isSOAPBinding, boolean isHTTPBinding, String soapStyle, boolean isRPC) {
super();
this.bindingOperation = bindingOperation;
this.isSOAPBinding = isSOAPBinding;
this.isHTTPBinding = isHTTPBinding;
this.soapStyle = soapStyle;
this.isRPC = isRPC;
}
public boolean isHTTPBinding() {
return isHTTPBinding;
}
public boolean isSOAPBinding() {
return isSOAPBinding;
}
public String getSoapStyle() {
return soapStyle;
}
public boolean isRPC() {
return isRPC;
}
public BindingOperation getBindingOperation() {
return bindingOperation;
}
/**
* @return true if wrapper xsd is used
*/
public boolean isWrappedInput() {
return wrappedInput;
}
/**
* @param wrappedInput indicate if wrapper xsd is needed
*/
public void setWrappedInput(boolean wrappedInput) {
this.wrappedInput = wrappedInput;
}
/**
* @return true if wrapper xsd is needed for the output message
*/
public boolean isWrappedOutput() {
return wrappedOutput;
}
/**
* @param wrappedOutput indicate if wrapper xsd is needed on the output message
*/
public void setWrappedOutput(boolean wrappedOutput) {
this.wrappedOutput = wrappedOutput;
}
}
}