/*
* SoapUI, Copyright (C) 2004-2016 SmartBear Software
*
* Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent
* versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://ec.europa.eu/idabc/eupl
*
* Unless required by applicable law or agreed to in writing, software distributed under the Licence is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the Licence for the specific language governing permissions and limitations
* under the Licence.
*/
package com.eviware.soapui.impl.wsdl.support.wsdl;
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.config.AnonymousTypeConfig;
import com.eviware.soapui.config.DefinitionCacheConfig;
import com.eviware.soapui.config.DefinitionCacheTypeConfig;
import com.eviware.soapui.config.DefintionPartConfig;
import com.eviware.soapui.config.WsaVersionTypeConfig;
import com.eviware.soapui.impl.support.definition.DefinitionLoader;
import com.eviware.soapui.impl.wsdl.WsdlInterface;
import com.eviware.soapui.impl.wsdl.WsdlOperation;
import com.eviware.soapui.impl.wsdl.WsdlRequest;
import com.eviware.soapui.impl.wsdl.submit.WsdlMessageExchange;
import com.eviware.soapui.impl.wsdl.support.Constants;
import com.eviware.soapui.impl.wsdl.support.policy.PolicyUtils;
import com.eviware.soapui.impl.wsdl.support.soap.SoapUtils;
import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
import com.eviware.soapui.impl.wsdl.support.wsa.WsaConfig;
import com.eviware.soapui.impl.wsdl.support.wsa.WsaUtils;
import com.eviware.soapui.impl.wsdl.support.xsd.SchemaUtils;
import com.eviware.soapui.settings.WsaSettings;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.types.StringList;
import com.eviware.soapui.support.xml.XmlUtils;
import com.ibm.wsdl.util.xml.QNameUtils;
import com.ibm.wsdl.xml.WSDLReaderImpl;
import com.ibm.wsdl.xml.WSDLWriterImpl;
import org.apache.log4j.Logger;
import org.apache.xmlbeans.SchemaGlobalElement;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlString;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import javax.wsdl.Binding;
import javax.wsdl.BindingFault;
import javax.wsdl.BindingInput;
import javax.wsdl.BindingOperation;
import javax.wsdl.BindingOutput;
import javax.wsdl.Definition;
import javax.wsdl.Fault;
import javax.wsdl.Input;
import javax.wsdl.Message;
import javax.wsdl.Operation;
import javax.wsdl.Output;
import javax.wsdl.Part;
import javax.wsdl.Port;
import javax.wsdl.Service;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.AttributeExtensible;
import javax.wsdl.extensions.ElementExtensible;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.extensions.ExtensionDeserializer;
import javax.wsdl.extensions.ExtensionRegistry;
import javax.wsdl.extensions.UnknownExtensibilityElement;
import javax.wsdl.extensions.mime.MIMEContent;
import javax.wsdl.extensions.mime.MIMEMultipartRelated;
import javax.wsdl.extensions.mime.MIMEPart;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.wsdl.extensions.soap.SOAPBinding;
import javax.wsdl.extensions.soap.SOAPBody;
import javax.wsdl.extensions.soap.SOAPFault;
import javax.wsdl.extensions.soap.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.SOAP12Fault;
import javax.wsdl.extensions.soap12.SOAP12Header;
import javax.wsdl.extensions.soap12.SOAP12Operation;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Wsdl-related tools
*
* @author Ole.Matzura
*/
public class WsdlUtils {
private final static Logger log = Logger.getLogger(WsdlUtils.class);
private static WSDLReader wsdlReader;
private final static String WSDL_NAMESPACE = "http://schemas.xmlsoap.org/wsdl/";
public static <T extends ExtensibilityElement> T getExtensiblityElement(List<?> list, Class<T> clazz) {
List<T> elements = getExtensiblityElements(list, clazz);
return elements.isEmpty() ? null : elements.get(0);
}
public static <T extends ExtensibilityElement> List<T> getExtensiblityElements(List list, Class<T> clazz) {
List<T> result = new ArrayList<T>();
for (Iterator<T> i = list.iterator(); i.hasNext(); ) {
T elm = i.next();
if (clazz.isAssignableFrom(elm.getClass())) {
result.add(elm);
}
}
return result;
}
public static Element[] getExentsibilityElements(ElementExtensible item, QName qname) {
if (item == null) {
return new Element[0];
}
List<Element> result = new ArrayList<Element>();
List<?> list = item.getExtensibilityElements();
for (Iterator<?> i = list.iterator(); i.hasNext(); ) {
ExtensibilityElement elm = (ExtensibilityElement) i.next();
if (elm.getElementType().equals(qname) && elm instanceof UnknownExtensibilityElement) {
result.add(((UnknownExtensibilityElement) elm).getElement());
}
}
return result.toArray(new Element[result.size()]);
}
public static String[] getExentsibilityAttributes(AttributeExtensible item, QName qname) {
if (item == null) {
return new String[0];
}
StringList result = new StringList();
Map map = item.getExtensionAttributes();
for (Iterator<?> i = map.keySet().iterator(); i.hasNext(); ) {
QName name = (QName) i.next();
if (name.equals(qname)) {
result.add(map.get(name).toString());
}
}
return result.toStringArray();
}
public static String getSoapAction(BindingOperation operation) {
List list = operation.getExtensibilityElements();
SOAPOperation soapOperation = WsdlUtils.getExtensiblityElement(list, SOAPOperation.class);
if (soapOperation != null) {
return soapOperation.getSoapActionURI();
}
SOAP12Operation soap12Operation = WsdlUtils.getExtensiblityElement(list, SOAP12Operation.class);
if (soap12Operation != null) {
return soap12Operation.getSoapActionURI();
}
return null;
}
public static String[] getEndpointsForBinding(Definition definition, Binding binding) {
List<String> result = new ArrayList<String>();
Map map = definition.getAllServices();
for (Iterator i = map.values().iterator(); i.hasNext(); ) {
Service service = (Service) i.next();
Map portMap = service.getPorts();
for (Iterator i2 = portMap.values().iterator(); i2.hasNext(); ) {
Port port = (Port) i2.next();
if (port.getBinding() == binding) {
String endpoint = WsdlUtils.getSoapEndpoint(port);
if (endpoint != null) {
result.add(endpoint);
}
}
}
}
return result.toArray(new String[result.size()]);
}
public static Binding findBindingForOperation(Definition definition, BindingOperation bindingOperation) {
Map services = definition.getAllServices();
Iterator<Service> s = services.values().iterator();
while (s.hasNext()) {
Map ports = s.next().getPorts();
Iterator<Port> p = ports.values().iterator();
while (p.hasNext()) {
Binding binding = p.next().getBinding();
List bindingOperations = binding.getBindingOperations();
for (Iterator iter = bindingOperations.iterator(); iter.hasNext(); ) {
BindingOperation op = (BindingOperation) iter.next();
if (op.getName().equals(bindingOperation.getName())) {
return binding;
}
}
}
}
Map bindings = definition.getAllBindings();
Iterator<QName> names = bindings.keySet().iterator();
while (names.hasNext()) {
Binding binding = definition.getBinding(names.next());
List bindingOperations = binding.getBindingOperations();
for (Iterator iter = bindingOperations.iterator(); iter.hasNext(); ) {
BindingOperation op = (BindingOperation) iter.next();
if (op.getName().equals(bindingOperation.getName())) {
return binding;
}
}
}
return null;
}
public static BindingOperation findBindingOperation(Definition definition, String operationName) {
Map services = definition.getAllServices();
for (Iterator i = services.keySet().iterator(); i.hasNext(); ) {
QName qName = (QName) i.next();
Service service = definition.getService(qName);
Map ports = service.getPorts();
for (Iterator iterator = ports.keySet().iterator(); iterator.hasNext(); ) {
String key = (String) iterator.next();
Port port = service.getPort(key);
BindingOperation bindingOperation = port.getBinding().getBindingOperation(operationName, null, null);
if (bindingOperation != null) {
return bindingOperation;
}
}
}
Map bindings = definition.getAllBindings();
for (Iterator i = bindings.keySet().iterator(); i.hasNext(); ) {
Object key = i.next();
Binding binding = (Binding) bindings.get(key);
BindingOperation bindingOperation = binding.getBindingOperation(operationName, null, null);
if (bindingOperation != null) {
return bindingOperation;
}
}
return null;
}
public static boolean isInputSoapEncoded(BindingOperation bindingOperation) {
if (bindingOperation == null) {
return false;
}
BindingInput bindingInput = bindingOperation.getBindingInput();
if (bindingInput == null) {
return false;
}
SOAPBody soapBody = WsdlUtils.getExtensiblityElement(bindingInput.getExtensibilityElements(), SOAPBody.class);
if (soapBody != null) {
return soapBody.getUse() != null
&& soapBody.getUse().equalsIgnoreCase("encoded")
&& (soapBody.getEncodingStyles() == null || soapBody.getEncodingStyles().contains(
"http://schemas.xmlsoap.org/soap/encoding/"));
}
SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement(bindingInput.getExtensibilityElements(),
SOAP12Body.class);
if (soap12Body != null) {
return soap12Body.getUse() != null
&& soap12Body.getUse().equalsIgnoreCase("encoded")
&& (soap12Body.getEncodingStyle() == null || soap12Body.getEncodingStyle().equals(
"http://schemas.xmlsoap.org/soap/encoding/"));
}
return false;
}
public static boolean isOutputSoapEncoded(BindingOperation bindingOperation) {
if (bindingOperation == null) {
return false;
}
BindingOutput bindingOutput = bindingOperation.getBindingOutput();
if (bindingOutput == null) {
return false;
}
SOAPBody soapBody = WsdlUtils.getExtensiblityElement(bindingOutput.getExtensibilityElements(), SOAPBody.class);
if (soapBody != null) {
return soapBody.getUse() != null
&& soapBody.getUse().equalsIgnoreCase("encoded")
&& (soapBody.getEncodingStyles() == null || soapBody.getEncodingStyles().contains(
"http://schemas.xmlsoap.org/soap/encoding/"));
}
SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement(bindingOutput.getExtensibilityElements(),
SOAP12Body.class);
if (soap12Body != null) {
return soap12Body.getUse() != null
&& soap12Body.getUse().equalsIgnoreCase("encoded")
&& (soap12Body.getEncodingStyle() == null || soap12Body.getEncodingStyle().equals(
"http://schemas.xmlsoap.org/soap/encoding/"));
}
return false;
}
public static boolean isRpc(Definition definition, BindingOperation bindingOperation) {
SOAPOperation soapOperation = WsdlUtils.getExtensiblityElement(bindingOperation.getExtensibilityElements(),
SOAPOperation.class);
if (soapOperation != null && soapOperation.getStyle() != null) {
return soapOperation.getStyle().equalsIgnoreCase("rpc");
}
SOAP12Operation soap12Operation = WsdlUtils.getExtensiblityElement(bindingOperation.getExtensibilityElements(),
SOAP12Operation.class);
if (soap12Operation != null && soap12Operation.getStyle() != null) {
return soap12Operation.getStyle().equalsIgnoreCase("rpc");
}
Binding binding = findBindingForOperation(definition, bindingOperation);
if (binding == null) {
log.error("Failed to find binding for operation [" + bindingOperation.getName() + "] in definition ["
+ definition.getDocumentBaseURI() + "]");
return false;
}
return isRpc(binding);
}
public static boolean isRpc(Binding binding) {
SOAPBinding soapBinding = WsdlUtils
.getExtensiblityElement(binding.getExtensibilityElements(), SOAPBinding.class);
if (soapBinding != null) {
return "rpc".equalsIgnoreCase(soapBinding.getStyle());
}
SOAP12Binding soap12Binding = WsdlUtils.getExtensiblityElement(binding.getExtensibilityElements(),
SOAP12Binding.class);
if (soap12Binding != null) {
return "rpc".equalsIgnoreCase(soap12Binding.getStyle());
}
return false;
}
/**
* Returns a list of parts for the specifed operation, either as specified in
* body or all
*/
public static Part[] getInputParts(BindingOperation operation) {
List<Part> result = new ArrayList<Part>();
Input input = operation.getOperation().getInput();
if (input == null || operation.getBindingInput() == null) {
return new Part[0];
}
Message msg = input.getMessage();
if (msg != null) {
SOAPBody soapBody = WsdlUtils.getExtensiblityElement(operation.getBindingInput().getExtensibilityElements(),
SOAPBody.class);
if (soapBody == null || soapBody.getParts() == null) {
SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement(operation.getBindingInput()
.getExtensibilityElements(), SOAP12Body.class);
if (soap12Body == null || soap12Body.getParts() == null) {
if (msg != null) {
result.addAll(msg.getOrderedParts(null));
}
} else {
Iterator i = soap12Body.getParts().iterator();
while (i.hasNext()) {
String partName = (String) i.next();
Part part = msg.getPart(partName);
result.add(part);
}
}
} else {
Iterator i = soapBody.getParts().iterator();
while (i.hasNext()) {
String partName = (String) i.next();
Part part = msg.getPart(partName);
result.add(part);
}
}
} else {
}
return result.toArray(new Part[result.size()]);
}
public static boolean isAttachmentInputPart(Part part, BindingOperation operation) {
return getInputMultipartContent(part, operation).length > 0;
}
public static boolean isAttachmentOutputPart(Part part, BindingOperation operation) {
return getOutputMultipartContent(part, operation).length > 0;
}
public static MIMEContent[] getOutputMultipartContent(Part part, BindingOperation operation) {
BindingOutput output = operation.getBindingOutput();
if (output == null) {
return new MIMEContent[0];
}
MIMEMultipartRelated multipartOutput = WsdlUtils.getExtensiblityElement(output.getExtensibilityElements(),
MIMEMultipartRelated.class);
return getContentParts(part, multipartOutput);
}
public static MIMEContent[] getInputMultipartContent(Part part, BindingOperation operation) {
BindingInput bindingInput = operation.getBindingInput();
if (bindingInput == null) {
return new MIMEContent[0];
}
MIMEMultipartRelated multipartInput = WsdlUtils.getExtensiblityElement(bindingInput.getExtensibilityElements(),
MIMEMultipartRelated.class);
return getContentParts(part, multipartInput);
}
public static MIMEContent[] getContentParts(Part part, MIMEMultipartRelated multipart) {
List<MIMEContent> result = new ArrayList<MIMEContent>();
if (multipart != null) {
List<MIMEPart> parts = multipart.getMIMEParts();
for (int c = 0; c < parts.size(); c++) {
List<MIMEContent> contentParts = WsdlUtils.getExtensiblityElements(parts.get(c)
.getExtensibilityElements(), MIMEContent.class);
for (MIMEContent content : contentParts) {
if (content.getPart().equals(part.getName())) {
result.add(content);
}
}
}
}
return result.toArray(new MIMEContent[result.size()]);
}
public static Part[] getFaultParts(BindingOperation bindingOperation, String faultName) throws Exception {
List<Part> result = new ArrayList<Part>();
BindingFault bindingFault = bindingOperation.getBindingFault(faultName);
SOAPFault soapFault = WsdlUtils.getExtensiblityElement(bindingFault.getExtensibilityElements(), SOAPFault.class);
Operation operation = bindingOperation.getOperation();
if (soapFault != null && soapFault.getName() != null) {
Fault fault = operation.getFault(soapFault.getName());
if (fault == null) {
throw new Exception("Missing Fault [" + soapFault.getName() + "] in operation [" + operation.getName()
+ "]");
}
result.addAll(fault.getMessage().getOrderedParts(null));
} else {
SOAP12Fault soap12Fault = WsdlUtils.getExtensiblityElement(bindingFault.getExtensibilityElements(),
SOAP12Fault.class);
if (soap12Fault != null && soap12Fault.getName() != null) {
Fault fault = operation.getFault(soap12Fault.getName());
if (fault != null && fault.getMessage() != null) {
result.addAll(fault.getMessage().getOrderedParts(null));
}
} else {
Fault fault = operation.getFault(faultName);
if (fault != null && fault.getMessage() != null) {
result.addAll(fault.getMessage().getOrderedParts(null));
}
}
}
return result.toArray(new Part[result.size()]);
}
public static String findSoapFaultPartName(SoapVersion soapVersion, BindingOperation bindingOperation,
String message) throws Exception {
if (WsdlUtils.isOutputSoapEncoded(bindingOperation)) {
throw new Exception("SOAP-Encoded messages not supported");
}
// XmlObject xml = XmlObject.Factory.parse( message );
XmlObject xml = XmlUtils.createXmlObject(message);
XmlObject[] msgPaths = xml.selectPath("declare namespace env='" + soapVersion.getEnvelopeNamespace() + "';"
+ "$this/env:Envelope/env:Body/env:Fault");
if (msgPaths.length == 0) {
return null;
}
XmlObject msgXml = msgPaths[0];
Map faults = bindingOperation.getBindingFaults();
for (Iterator<BindingFault> i = faults.values().iterator(); i.hasNext(); ) {
BindingFault bindingFault = i.next();
String faultName = bindingFault.getName();
Part[] faultParts = WsdlUtils.getFaultParts(bindingOperation, faultName);
Part part = faultParts[0];
QName elementName = part.getElementName();
if (elementName != null) {
XmlObject[] faultPaths = msgXml.selectPath("declare namespace env='" + soapVersion.getEnvelopeNamespace()
+ "';" + "declare namespace ns='" + elementName.getNamespaceURI() + "';" + "//env:Fault/detail/ns:"
+ elementName.getLocalPart());
if (faultPaths.length == 1) {
return faultName;
}
}
// this is not allowed by Basic Profile.. remove?
else if (part.getTypeName() != null) {
QName typeName = part.getTypeName();
XmlObject[] faultPaths = msgXml.selectPath("declare namespace env='" + soapVersion.getEnvelopeNamespace()
+ "';" + "declare namespace ns='" + typeName.getNamespaceURI() + "';" + "//env:Fault/detail/ns:"
+ part.getName());
if (faultPaths.length == 1) {
return faultName;
}
}
}
return null;
}
public static Part[] getOutputParts(BindingOperation operation) {
BindingOutput bindingOutput = operation.getBindingOutput();
if (bindingOutput == null) {
return new Part[0];
}
List<Part> result = new ArrayList<Part>();
Output output = operation.getOperation().getOutput();
if (output == null) {
return new Part[0];
}
Message msg = output.getMessage();
if (msg != null) {
SOAPBody soapBody = WsdlUtils
.getExtensiblityElement(bindingOutput.getExtensibilityElements(), SOAPBody.class);
if (soapBody == null || soapBody.getParts() == null) {
SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement(bindingOutput.getExtensibilityElements(),
SOAP12Body.class);
if (soap12Body == null || soap12Body.getParts() == null) {
result.addAll(msg.getOrderedParts(null));
} else {
Iterator i = soap12Body.getParts().iterator();
while (i.hasNext()) {
String partName = (String) i.next();
Part part = msg.getPart(partName);
result.add(part);
}
}
} else {
Iterator i = soapBody.getParts().iterator();
while (i.hasNext()) {
String partName = (String) i.next();
Part part = msg.getPart(partName);
result.add(part);
}
}
} else {
log.warn("Missing output message for binding operation [" + operation.getName() + "]");
}
return result.toArray(new Part[result.size()]);
}
public static boolean isMultipartRequest(Definition definition, BindingOperation bindingOperation) {
return WsdlUtils.getExtensiblityElement(bindingOperation.getBindingInput().getExtensibilityElements(),
MIMEMultipartRelated.class) != null;
}
public static String getUsingAddressing(ElementExtensible item) {
String version = WsaVersionTypeConfig.NONE.toString();
Element[] usingAddressingElements = WsdlUtils.getExentsibilityElements(item, new QName(
"http://www.w3.org/2006/05/addressing/wsdl", "UsingAddressing"));
if (usingAddressingElements.length == 0) {
usingAddressingElements = WsdlUtils.getExentsibilityElements(item, new QName(
"http://www.w3.org/2006/02/addressing/wsdl", "UsingAddressing"));
}
if (usingAddressingElements.length != 0) {
// this should resolve wsdl version, not addressing version??? what is
// the connection?
String addressingVersion = usingAddressingElements[0].getAttributeNS(WSDL_NAMESPACE, "required");
if (addressingVersion != null && addressingVersion.equals("true")) {
version = WsaVersionTypeConfig.X_200508.toString();
}
}
return version;
}
private static String checkIfWsaPolicy(String version, Element policy) {
// Policy builtPolicy = new
// WsaPolicy().buildPolicy(policy.getTextContent());
// policy = WsaPolicy.normalize(policy);
// check if found reference is addressing policy
// Element wsAddressing = XmlUtils.getFirstChildElementNS(policy,
// WsaUtils.WSAM_NAMESPACE, "Addressing");
// Element addressingPolicy = null;
// if (wsAddressing != null)
// {
// String optional =
// wsAddressing.getAttributeNS(WsaPolicy.WS_POLICY_NAMESPACE, "Optional");
// addressingPolicy = XmlUtils.getFirstChildElementNS(wsAddressing,
// WsaPolicy.WS_POLICY_NAMESPACE, "Policy");
// if (addressingPolicy != null)
// {
// if (StringUtils.isNullOrEmpty(optional) || optional.equals("false") ||
// (optional.equals("true") &&
// SoapUI.getSettings().getBoolean(WsaSettings.ENABLE_FOR_OPTIONAL)) )
// {
// version = WsaVersionTypeConfig.X_200508.toString();
// }
// //check if policy has Anonymous
// Element anonymousElm =
// XmlUtils.getFirstChildElementNS(addressingPolicy, new
// QName(WsaPolicy.WSAM_NAMESPACE,"AnonymousResponses"));
// if (anonymousElm != null)
// {
// //TODO anonymous = required
// } else {
// Element nonAnonymousElement =
// XmlUtils.getFirstChildElementNS(addressingPolicy, new
// QName(WsaPolicy.WSAM_NAMESPACE,"NonAnonymousResponses"));
// if (nonAnonymousElement != null)
// {
// //TODO anonymous = prohibited
// }
// }
// }
// }
return version;
}
public static String getWsaPolicyAnonymous(Element policy) {
String version = WsaVersionTypeConfig.NONE.toString();
String anonymous = AnonymousTypeConfig.OPTIONAL.toString();
// check if found reference is addressing policy
Element wsAddressing = XmlUtils.getFirstChildElementNS(policy, WsaUtils.WS_A_NAMESPACE_200705, "Addressing");
Element addressingPolicy = null;
if (wsAddressing != null) {
String optional = wsAddressing.getAttributeNS(PolicyUtils.WS_W3_POLICY_NAMESPACE, "Optional");
addressingPolicy = XmlUtils
.getFirstChildElementNS(wsAddressing, PolicyUtils.WS_W3_POLICY_NAMESPACE, "Policy");
if (addressingPolicy != null) {
if (StringUtils.isNullOrEmpty(optional) || optional.equals("false")
|| (optional.equals("true") && SoapUI.getSettings().getBoolean(WsaSettings.ENABLE_FOR_OPTIONAL))) {
version = WsaVersionTypeConfig.X_200508.toString();
}
// check if policy has Anonymous
Element anonymousElm = XmlUtils.getFirstChildElementNS(addressingPolicy, new QName(
WsaUtils.WS_A_NAMESPACE_200705, "AnonymousResponses"));
if (anonymousElm != null) {
anonymous = AnonymousTypeConfig.REQUIRED.toString();
} else {
Element nonAnonymousElement = XmlUtils.getFirstChildElementNS(addressingPolicy, new QName(
WsaUtils.WS_A_NAMESPACE_200705, "NonAnonymousResponses"));
if (nonAnonymousElement != null) {
anonymous = AnonymousTypeConfig.PROHIBITED.toString();
}
}
}
}
return anonymous;
}
public static String getSoapEndpoint(Port port) {
SOAPAddress soapAddress = WsdlUtils.getExtensiblityElement(port.getExtensibilityElements(), SOAPAddress.class);
if (soapAddress != null && StringUtils.hasContent(soapAddress.getLocationURI())) {
try {
return URLDecoder.decode(soapAddress.getLocationURI(), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return soapAddress.getLocationURI();
}
}
SOAP12Address soap12Address = WsdlUtils.getExtensiblityElement(port.getExtensibilityElements(),
SOAP12Address.class);
if (soap12Address != null && StringUtils.hasContent(soap12Address.getLocationURI())) {
try {
return URLDecoder.decode(soap12Address.getLocationURI(), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return soap12Address.getLocationURI();
}
}
return null;
}
public static boolean replaceSoapEndpoint(Port port, String endpoint) {
SOAPAddress soapAddress = WsdlUtils.getExtensiblityElement(port.getExtensibilityElements(), SOAPAddress.class);
if (soapAddress != null) {
soapAddress.setLocationURI(endpoint);
return true;
}
SOAP12Address soap12Address = WsdlUtils.getExtensiblityElement(port.getExtensibilityElements(),
SOAP12Address.class);
if (soap12Address != null) {
soap12Address.setLocationURI(endpoint);
return true;
}
return false;
}
public static String getSoapBodyNamespace(List<?> list) {
SOAPBody soapBody = WsdlUtils.getExtensiblityElement(list, SOAPBody.class);
if (soapBody != null) {
return soapBody.getNamespaceURI();
}
SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement(list, SOAP12Body.class);
if (soap12Body != null) {
return soap12Body.getNamespaceURI();
}
return null;
}
public static final class NonSchemaImportingWsdlReaderImpl extends WSDLReaderImpl {
@SuppressWarnings("unchecked")
@Override
protected ExtensibilityElement parseSchema(Class parentType, Element el, Definition def, ExtensionRegistry extReg)
throws WSDLException {
QName elementType = QNameUtils.newQName(el);
ExtensionDeserializer exDS = extReg.queryDeserializer(parentType, elementType);
// Now unmarshall the DOM element.
ExtensibilityElement ee = exDS.unmarshall(parentType, elementType, el, def, extReg);
return ee;
}
}
/**
* A SOAP-Header wrapper
*
* @author ole.matzura
*/
public interface SoapHeader {
public QName getMessage();
public String getPart();
}
/**
* SOAP 1.1 Header implementation
*
* @author ole.matzura
*/
public static class Soap11Header implements SoapHeader {
private final SOAPHeader soapHeader;
public Soap11Header(SOAPHeader soapHeader) {
this.soapHeader = soapHeader;
}
public QName getMessage() {
return soapHeader.getMessage();
}
public String getPart() {
return soapHeader.getPart();
}
}
/**
* SOAP 1.2 Header implementation
*
* @author ole.matzura
*/
public static class Soap12Header implements SoapHeader {
private final SOAP12Header soapHeader;
public Soap12Header(SOAP12Header soapHeader) {
this.soapHeader = soapHeader;
}
public QName getMessage() {
return soapHeader.getMessage();
}
public String getPart() {
return soapHeader.getPart();
}
}
public static List<SoapHeader> getSoapHeaders(List list) {
List<SoapHeader> result = new ArrayList<SoapHeader>();
List<SOAPHeader> soapHeaders = WsdlUtils.getExtensiblityElements(list, SOAPHeader.class);
if (soapHeaders != null && !soapHeaders.isEmpty()) {
for (SOAPHeader header : soapHeaders) {
result.add(new Soap11Header(header));
}
} else {
List<SOAP12Header> soap12Headers = WsdlUtils.getExtensiblityElements(list, SOAP12Header.class);
if (soap12Headers != null && !soap12Headers.isEmpty()) {
for (SOAP12Header header : soap12Headers) {
result.add(new Soap12Header(header));
}
}
}
return result;
}
public static synchronized Definition readDefinition(String wsdlUrl) throws Exception {
if (wsdlReader == null) {
WSDLFactory factory = WSDLFactory.newInstance();
wsdlReader = factory.newWSDLReader();
wsdlReader.setFeature("javax.wsdl.verbose", true);
wsdlReader.setFeature("javax.wsdl.importDocuments", true);
}
return wsdlReader.readWSDL(new UrlWsdlLoader(wsdlUrl));
}
public static SchemaType getSchemaTypeForPart(WsdlContext wsdlContext, javax.wsdl.Part part) throws Exception {
SchemaType schemaType = null;
QName elementName = part.getElementName();
if (elementName != null) {
SchemaGlobalElement elm = wsdlContext.getSchemaTypeLoader().findElement(elementName);
if (elm != null) {
schemaType = elm.getType();
} else {
WsdlRequest.log.error("Could not find element [" + elementName + "] specified in part [" + part.getName()
+ "]");
}
} else {
QName typeName = part.getTypeName();
if (typeName != null) {
schemaType = wsdlContext.getSchemaTypeLoader().findType(typeName);
if (schemaType == null) {
WsdlRequest.log.error("Could not find type [" + typeName + "] specified in part [" + part.getName()
+ "]");
}
}
}
return schemaType;
}
public static SchemaGlobalElement getSchemaElementForPart(WsdlContext wsdlContext, javax.wsdl.Part part)
throws Exception {
QName elementName = part.getElementName();
if (elementName != null) {
return wsdlContext.getSchemaTypeLoader().findElement(elementName);
}
return null;
}
public static String replacePortEndpoint(WsdlInterface iface, InputSource inputSource, String endpoint)
throws WSDLException {
WSDLReader wsdlReader = new NonSchemaImportingWsdlReaderImpl();
wsdlReader.setFeature("javax.wsdl.verbose", true);
wsdlReader.setFeature("javax.wsdl.importDocuments", false);
Definition definition = wsdlReader.readWSDL(null, inputSource);
boolean updated = false;
Map map = definition.getServices();
for (Iterator i = map.values().iterator(); i.hasNext(); ) {
Service service = (Service) i.next();
Map portMap = service.getPorts();
for (Iterator i2 = portMap.values().iterator(); i2.hasNext(); ) {
Port port = (Port) i2.next();
if (port.getBinding().getQName().equals(iface.getBindingName())) {
if (replaceSoapEndpoint(port, endpoint)) {
updated = true;
}
}
}
}
if (updated) {
StringWriter writer = new StringWriter();
Map nsMap = definition.getNamespaces();
if (!nsMap.values().contains(Constants.SOAP_HTTP_BINDING_NS)) {
definition.addNamespace("soaphttp", Constants.SOAP_HTTP_BINDING_NS);
}
new WSDLWriterImpl().writeWSDL(definition, writer);
return writer.toString();
}
return null;
}
public static BindingOperation findBindingOperation(Binding binding, String bindingOperationName, String inputName,
String outputName) {
if (binding == null) {
return null;
}
if (inputName == null) {
inputName = ":none";
}
if (outputName == null) {
outputName = ":none";
}
BindingOperation result = binding.getBindingOperation(bindingOperationName, inputName, outputName);
if (result == null && (inputName.equals(":none") || outputName.equals(":none"))) {
// fall back to this behaviour for WSDL4j 1.5.0 compatibility
result = binding.getBindingOperation(bindingOperationName, inputName.equals(":none") ? null : inputName,
outputName.equals(":none") ? null : outputName);
}
return result;
}
public static boolean isHeaderInputPart(Part part, Message message, BindingOperation bindingOperation) {
List<SOAPHeader> headers = WsdlUtils.getExtensiblityElements(bindingOperation.getBindingInput()
.getExtensibilityElements(), SOAPHeader.class);
if (headers == null || headers.isEmpty()) {
return false;
}
for (SOAPHeader header : headers) {
if (message.getQName().equals(header.getMessage()) && part.getName().equals(header.getPart())) {
return true;
}
}
return false;
}
public static boolean isHeaderOutputPart(Part part, Message message, BindingOperation bindingOperation) {
BindingOutput bindingOutput = bindingOperation.getBindingOutput();
List<SOAPHeader> headers = bindingOutput == null ? null : WsdlUtils.getExtensiblityElements(
bindingOutput.getExtensibilityElements(), SOAPHeader.class);
if (headers == null || headers.isEmpty()) {
return false;
}
for (SOAPHeader header : headers) {
if (message.getQName().equals(header.getMessage()) && part.getName().equals(header.getPart())) {
return true;
}
}
return false;
}
public static DefinitionCacheConfig cacheWsdl(DefinitionLoader loader) throws Exception {
DefinitionCacheConfig definitionCache = DefinitionCacheConfig.Factory.newInstance();
definitionCache.setRootPart(loader.getBaseURI());
definitionCache.setType(DefinitionCacheTypeConfig.TEXT);
Map<String, XmlObject> urls = SchemaUtils.getDefinitionParts(loader);
for (Map.Entry<String, XmlObject> urlEntry : urls.entrySet()) {
DefintionPartConfig definitionPart = definitionCache.addNewPart();
String url = urlEntry.getKey();
definitionPart.setUrl(url);
XmlObject xmlObject = urlEntry.getValue();
Node domNode = xmlObject.getDomNode();
if (domNode.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) {
Node node = domNode.getFirstChild();
if (node.getNodeType() == Node.TEXT_NODE) {
domNode = XmlUtils.parseXml(node.getNodeValue());
xmlObject = XmlUtils.createXmlObject(domNode);
}
}
Element contentElement = ((Document) domNode).getDocumentElement();
Node newDomNode = definitionPart.addNewContent().getDomNode();
newDomNode.appendChild(newDomNode.getOwnerDocument().createTextNode(xmlObject.toString()));
definitionPart.setType(contentElement.getNamespaceURI());
}
return definitionCache;
}
public static void getAnonymous(WsdlOperation wsdlOperation) {
String anonymous = "";
Element[] anonymousElements = WsdlUtils.getExentsibilityElements(wsdlOperation.getBindingOperation(), new QName(
"http://www.w3.org/2006/05/addressing/wsdl", "Anonymous"));
if (anonymousElements.length == 0) {
anonymousElements = WsdlUtils.getExentsibilityElements(wsdlOperation.getBindingOperation(), new QName(
"http://www.w3.org/2006/02/addressing/wsdl", "Anonymous"));
}
if (anonymousElements != null && anonymousElements.length > 0) {
anonymous = XmlUtils.getElementText(anonymousElements[0]);
}
wsdlOperation.setAnonymous(anonymous);
}
public static String getDefaultWsaAction(WsdlOperation operation, boolean output) {
// SOAP 1.1 specific handling
if (operation.getInterface().getSoapVersion() == SoapVersion.Soap11
&& StringUtils.hasContent(operation.getAction())
&& SoapUI.getSettings().getBoolean(WsaSettings.SOAP_ACTION_OVERRIDES_WSA_ACTION)) {
return operation.getAction();
}
try {
if (operation.getBindingOperation() == null || operation.getBindingOperation().getOperation() == null) {
return null;
}
AttributeExtensible attributeExtensible = output ? operation.getBindingOperation().getOperation().getOutput()
: operation.getBindingOperation().getOperation().getInput();
if (attributeExtensible == null) {
return null;
}
String[] attrs;
for (String namespace : WsaUtils.wsaNamespaces) {
attrs = WsdlUtils.getExentsibilityAttributes(attributeExtensible, new QName(namespace, "Action"));
if (attrs != null && attrs.length > 0) {
return attrs[0];
}
}
WsdlInterface iface = operation.getInterface();
Definition definition = iface.getWsdlContext().getDefinition();
String targetNamespace = WsdlUtils.getTargetNamespace(definition);
String portTypeName = iface.getBinding().getPortType().getQName().getLocalPart();
String operationName = operation.getName();
if (!StringUtils.isNullOrEmpty(operationName)) {
Operation op = iface.getBinding().getPortType().getOperation(operationName, null, null);
if (op != null) {
attributeExtensible = output ? op.getOutput() : op.getInput();
attrs = WsdlUtils.getExentsibilityAttributes(attributeExtensible, new QName(
WsaUtils.WS_A_NAMESPACE_200705, "Action"));
if (attrs != null && attrs.length > 0) {
return attrs[0];
}
}
}
String operationInOutName = output ? operation.getOutputName() : operation.getInputName();
if (operationInOutName == null) {
operationInOutName = operation.getName() + (output ? "Response" : "Request");
}
StringBuffer result = new StringBuffer(targetNamespace);
if (targetNamespace.length() > 0 && targetNamespace.charAt(targetNamespace.length() - 1) != '/'
&& portTypeName.charAt(0) != '/') {
result.append('/');
}
result.append(portTypeName);
if (portTypeName.charAt(portTypeName.length() - 1) != '/' && operationInOutName.charAt(0) != '/') {
result.append('/');
}
result.append(operationInOutName);
return result.toString();
} catch (Exception e) {
e.printStackTrace();
log.warn(e.toString());
return null;
}
}
public static void setDefaultWsaAction(WsaConfig wsaConfig, boolean output) {
String defaultAction = getDefaultWsaAction(wsaConfig.getWsaContainer().getOperation(), output);
if (StringUtils.hasContent(defaultAction)) {
wsaConfig.setAction(defaultAction);
}
}
public static String getRequestWsaMessageId(WsdlMessageExchange messageExchange, String wsaVersionNameSpace) {
String requestMessageId = null;
try {
// XmlObject xmlObject = XmlObject.Factory.parse(
// messageExchange.getRequestContent() );
XmlObject xmlObject = XmlUtils.createXmlObject(messageExchange.getRequestContent());
SoapVersion soapVersion = messageExchange.getOperation().getInterface().getSoapVersion();
Element header = (Element) SoapUtils.getHeaderElement(xmlObject, soapVersion, true).getDomNode();
Element msgNode = XmlUtils.getFirstChildElementNS(header, wsaVersionNameSpace, "MessageID");
if (msgNode != null) {
requestMessageId = XmlUtils.getElementText(msgNode);
}
} catch (XmlException e) {
e.printStackTrace();
log.warn(e.toString());
return null;
}
return requestMessageId;
}
public static NodeList getRequestReplyToRefProps(WsdlMessageExchange messageExchange, String wsaVersionNameSpace) {
try {
// XmlObject xmlObject = XmlObject.Factory.parse(
// messageExchange.getRequestContent() );
XmlObject xmlObject = XmlUtils.createXmlObject(messageExchange.getRequestContent());
SoapVersion soapVersion = messageExchange.getOperation().getInterface().getSoapVersion();
Element header = (Element) SoapUtils.getHeaderElement(xmlObject, soapVersion, true).getDomNode();
Element replyToNode = XmlUtils.getFirstChildElementNS(header, wsaVersionNameSpace, "ReplyTo");
Element replyRefParamsNode = XmlUtils.getFirstChildElementNS(replyToNode, wsaVersionNameSpace,
"ReferenceParameters");
if (replyRefParamsNode != null) {
return XmlUtils.getChildElements(replyRefParamsNode);
}
} catch (XmlException e) {
e.printStackTrace();
log.warn(e.toString());
}
return null;
}
public static NodeList getRequestFaultToRefProps(WsdlMessageExchange messageExchange, String wsaVersionNameSpace) {
try {
XmlObject xmlObject = XmlUtils.createXmlObject(messageExchange.getRequestContent());
SoapVersion soapVersion = messageExchange.getOperation().getInterface().getSoapVersion();
Element header = (Element) SoapUtils.getHeaderElement(xmlObject, soapVersion, true).getDomNode();
Element faultToNode = XmlUtils.getFirstChildElementNS(header, wsaVersionNameSpace, "FaultTo");
Element faultRefParamsNode = XmlUtils.getFirstChildElementNS(faultToNode, wsaVersionNameSpace,
"ReferenceParameters");
if (faultRefParamsNode != null) {
return XmlUtils.getChildElements(faultRefParamsNode);
}
} catch (XmlException e) {
e.printStackTrace();
log.warn(e.toString());
}
return null;
}
public static String getFaultCode(WsdlMessageExchange messageExchange) {
try {
XmlObject xmlObject = XmlUtils.createXmlObject(messageExchange.getResponseContent());
SoapVersion soapVersion = messageExchange.getOperation().getInterface().getSoapVersion();
Element body = (Element) SoapUtils.getBodyElement(xmlObject, soapVersion).getDomNode();
Element soapenvFault = XmlUtils.getFirstChildElementNS(body, "http://schemas.xmlsoap.org/soap/envelope/",
"Fault");
Element faultCode = XmlUtils.getFirstChildElement(soapenvFault, "faultcode");
if (faultCode != null) {
return XmlUtils.getElementText(faultCode);
}
} catch (XmlException e) {
e.printStackTrace();
log.warn(e.toString());
}
return null;
}
public static String getTargetNamespace(Definition definition) {
return definition.getTargetNamespace() == null ? XMLConstants.NULL_NS_URI : definition.getTargetNamespace();
}
public static SchemaType generateRpcBodyType(WsdlOperation operation) {
return XmlString.type;
}
}