/*
* 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.policy;
import com.eviware.soapui.impl.support.definition.InterfaceDefinitionPart;
import com.eviware.soapui.impl.wsdl.support.wsa.WsaUtils;
import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlContext;
import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.xml.XmlUtils;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.w3.x2007.x05.addressing.metadata.AddressingDocument.Addressing;
import org.w3c.dom.Element;
import org.xmlsoap.schemas.ws.x2004.x09.policy.OptionalType;
import org.xmlsoap.schemas.ws.x2004.x09.policy.Policy;
import org.xmlsoap.schemas.ws.x2004.x09.policy.PolicyDocument;
import javax.wsdl.Definition;
import javax.wsdl.extensions.ElementExtensible;
import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class PolicyUtils {
public final static String WS_XMLSOAP_POLICY_NAMESPACE = "http://schemas.xmlsoap.org/ws/2004/09/policy";
public final static String WS_W3_POLICY_NAMESPACE = "http://www.w3.org/ns/ws-policy";
public final static String WS_SECURITY_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
public static List<Policy> getPolicies(WsdlContext wsdlContext) {
List<Policy> policies = new ArrayList<Policy>();
try {
List<InterfaceDefinitionPart> parts = wsdlContext.getDefinitionCache().getDefinitionParts();
for (int i = 0; i < parts.size(); i++) {
InterfaceDefinitionPart part = parts.get(i);
String content = part.getContent();
// XmlObject xml = XmlObject.Factory.parse( content );
XmlObject xml = XmlUtils.createXmlObject(content);
// include paths for both namespaces
XmlObject[] paths = xml.selectPath("declare namespace wsp='" + WS_W3_POLICY_NAMESPACE + "';"
+ "//wsp:Policy");
List<XmlObject> listOfXmlObjcts = Arrays.asList(paths);
XmlObject[] paths1 = xml.selectPath("declare namespace wsp='" + WS_XMLSOAP_POLICY_NAMESPACE + "';"
+ "//wsp:Policy");
listOfXmlObjcts.addAll(Arrays.asList(paths1));
paths = (XmlObject[]) listOfXmlObjcts.toArray();
for (XmlObject obj : paths) {
String xx = obj.xmlText(new XmlOptions().setSaveOuter());
PolicyDocument policyDocument = PolicyDocument.Factory.parse(xx);
org.xmlsoap.schemas.ws.x2004.x09.policy.Policy polc = (org.xmlsoap.schemas.ws.x2004.x09.policy.Policy) policyDocument
.getPolicy();
policies.add(polc);
// List<Addressing> addressingList = polc.getAddressingList();
// Addressing a = null;
// if (addressingList.size() > 0 )
// {
// a = addressingList.get(0);
// }
// AnonymousResponses ar = null;
// List<AnonymousResponses> anList =
// polc.getAnonymousResponsesList();
// if (anList.size() > 0)
// {
// ar = anList.get(0);
// }
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static boolean isAddressing(Policy policy) {
if (policy.getAddressingList().size() > 0) {
return true;
}
return false;
}
public static List<Policy> getAddressingPolicies(WsdlContext wsdlContext) {
List<Policy> addressingPolicies = new ArrayList<Policy>();
List<Policy> policies = getPolicies(wsdlContext);
for (Policy policy : policies) {
if (isAddressing(policy)) {
addressingPolicies.add(policy);
}
}
return addressingPolicies;
}
/*
* Functions currently not used, initially intended for policy to be
* normalized first
*/
// public static Policy normalize(Policy policy) {
// 1.Start with the Element Information Item E (as defined in the XML
// Information Set [XML Information Set]) of the policy expression.
// The [namespace name] of E is always "http://www.w3.org/ns/ws-policy". In
// the base case, the [local name] property of E is "Policy";
// in the recursive case, the [local name] property of E is "Policy",
// "ExactlyOne", or "All".
//
// 2.Expand Element Information Items (as defined in the XML Information Set
// [XML Information Set]) in the [children] property of E that
// are policy references per Section 4.3.5 Policy Inclusion.
//
// 3.Convert each Element Information Item C in the [children] property of E
// into normal form.
// List<OperatorContentType> eoList = policy.getExactlyOneList();
// ExactlyOneDocument.Factory.newInstance();
//
// 3.1 If the [namespace name] property of C is
// "http://www.w3.org/ns/ws-policy" and the [local name] property of C is
// "Policy",
// "ExactlyOne", or "All", C is an expression of a policy operator; normalize
// C by recursively applying this procedure.
//
// 3.2 Otherwise the Element Information Item C is an assertion; normalize C
// per Sections 4.3.1 Optional Policy Assertions and 4.3.2
// Policy Assertion Nesting.
//
// 4.Apply the policy operator indicated by E to the normalized Element
// Information Items in its [children] property and co1.nstruct a
// normal form per Section 4.3.3 Policy Operators and 4.1 Normal Form Policy
// Expression.
//
// return policy;
// }
/*
* Functions currently not used, initially intended for policy to be
* normalized first
*/
// public static Element normalize(Element policy)
// {
// // if (!StringUtils.isNullOrEmpty(nameSpace) &&
// !StringUtils.isNullOrEmpty(localName))
// // {
// NodeList nl = policy.getChildNodes();
// List<Element> listElms = new ArrayList<Element>();
// for( int c = 0; c < nl.getLength(); c++ )
// {
// Node item = nl.item( c );
// if( item.getParentNode() == policy && item.getNodeType() ==
// Node.ELEMENT_NODE )
// listElms.add( (Element) item );
// }
//
// for (int i = 0; i < listElms.size(); i++)
// {
// Element elm = listElms.get(i);
// Element newElm = null;
// String nameSpace = elm.getNamespaceURI();
// String localName = elm.getLocalName();
// if (nameSpace.equals(WS_W3_POLICY_NAMESPACE)
// && (localName.equals("Policy") || localName.equals("All") ||
// localName.equals("ExactlyOne")))
// {
// newElm = normalize(elm);
//
// } else {
//
// Element allElm =
// elm.getOwnerDocument().createElementNS(WS_W3_POLICY_NAMESPACE, "All");
// allElm.appendChild(elm);
//
// Element exactlyOneElm =
// elm.getOwnerDocument().createElementNS(WS_W3_POLICY_NAMESPACE,
// "ExactlyOne");
// exactlyOneElm.appendChild(allElm);
//
// String optional = elm.getAttributeNS(WS_W3_POLICY_NAMESPACE, "Optional");
// if (!StringUtils.isNullOrEmpty(optional) && optional.equals("true"))
// {
// Element allElmEmpty =
// elm.getOwnerDocument().createElementNS(WS_W3_POLICY_NAMESPACE, "All");
// exactlyOneElm.appendChild(allElmEmpty);
// }
//
// newElm = exactlyOneElm;
// }
// elm.getParentNode().replaceChild(elm, newElm);
// }
// // }
//
// return policy;
// }
public static Policy getAttachedPolicy(ElementExtensible item, Definition def) {
Policy rtnPolicy = null;
String usedPolicyNamespace = PolicyUtils.WS_W3_POLICY_NAMESPACE;
Element[] policyReferences = WsdlUtils.getExentsibilityElements(item, new QName(
PolicyUtils.WS_W3_POLICY_NAMESPACE, "PolicyReference"));
if (policyReferences.length <= 0) {
policyReferences = WsdlUtils.getExentsibilityElements(item, new QName(
PolicyUtils.WS_XMLSOAP_POLICY_NAMESPACE, "PolicyReference"));
usedPolicyNamespace = PolicyUtils.WS_XMLSOAP_POLICY_NAMESPACE;
}
if (policyReferences.length > 0) {
String policyId = policyReferences[0].getAttribute("URI");
if (!StringUtils.isNullOrEmpty(policyId)) {
Element[] policies = WsdlUtils.getExentsibilityElements(def, new QName(usedPolicyNamespace, "Policy"));
Element policy = null;
for (int i = 0; i < policies.length; i++) {
policy = policies[i];
String policyIdx = policy.getAttributeNS(WS_SECURITY_NAMESPACE, "Id");
if (policyId.equals("#" + policyIdx)) {
rtnPolicy = getPolicy(policy, usedPolicyNamespace);
continue;
}
}
}
} else {
// get policies of item itself
Element[] itemPolicies = WsdlUtils.getExentsibilityElements(item, new QName(usedPolicyNamespace, "Policy"));
if (itemPolicies.length > 0) {
for (int i = 0; i < itemPolicies.length; i++) {
Element policy = itemPolicies[i];
rtnPolicy = getPolicy(policy, usedPolicyNamespace);
}
}
}
return rtnPolicy;
}
public static Policy getPolicy(Element policy, String usedPolicyNamespace) {
// policy = PolicyUtils.normalize(policy);
Policy newPolicy = null;
// check for ExactlyOne and All
// TODO ExactlyOne and All are idempotent all empty ones should be skipped
// and found the real ones
Element exactlyOne = XmlUtils.getFirstChildElementNS(policy, usedPolicyNamespace, "ExactlyOne");
if (exactlyOne != null) {
Element all = XmlUtils.getFirstChildElementNS(exactlyOne, usedPolicyNamespace, "All");
if (all != null) {
newPolicy = getAddressingPolicy(all, usedPolicyNamespace);
}
} else {
newPolicy = getAddressingPolicy(policy, usedPolicyNamespace);
}
return newPolicy;
}
private static Policy getAddressingPolicy(Element wsamAddressingElm, String usedPolicyNamespace) {
// check if found reference is addressing policy
Element wsAddressing = XmlUtils.getFirstChildElementNS(wsamAddressingElm, WsaUtils.WS_A_NAMESPACE_200705,
"Addressing");
Element addressingPolicy = null;
Policy newPolicy = PolicyDocument.Factory.newInstance().addNewPolicy();
Addressing newAddressing = null;
if (wsAddressing != null) {
newAddressing = newPolicy.addNewAddressing();
String optional = wsAddressing.getAttributeNS(usedPolicyNamespace, "Optional");
if (!StringUtils.isNullOrEmpty(optional) && optional.equals(OptionalType.TRUE.toString())) {
newAddressing.setOptional(OptionalType.TRUE);
} else {
newAddressing.setOptional(OptionalType.FALSE);
}
addressingPolicy = XmlUtils.getFirstChildElementNS(wsAddressing, usedPolicyNamespace, "Policy");
if (addressingPolicy != null) {
Element exactlyOne = XmlUtils.getFirstChildElementNS(addressingPolicy, usedPolicyNamespace, "ExactlyOne");
if (exactlyOne != null) {
Element all = XmlUtils.getFirstChildElementNS(exactlyOne, usedPolicyNamespace, "All");
if (all != null) {
getAddressingAnonymous(all, newAddressing);
}
} else {
getAddressingAnonymous(addressingPolicy, newAddressing);
}
}
}
Element usingAddressing = XmlUtils.getFirstChildElementNS(wsamAddressingElm, WsaUtils.WS_A_NAMESPACE_200605,
"UsingAddressing");
if (usingAddressing != null) {
// add UsingAddressing to policy
newPolicy.addNewUsingAddressing();
}
return newPolicy;
}
private static void getAddressingAnonymous(Element addressingPolicy, Addressing newAddressing) {
Policy innerPolicy = newAddressing.addNewPolicy();
// check if policy has Anonymous
Element anonymousElm = XmlUtils.getFirstChildElementNS(addressingPolicy, new QName(
WsaUtils.WS_A_NAMESPACE_200705, "AnonymousResponses"));
if (anonymousElm != null) {
innerPolicy.addNewAnonymousResponses();
} else {
Element nonAnonymousElement = XmlUtils.getFirstChildElementNS(addressingPolicy, new QName(
WsaUtils.WS_A_NAMESPACE_200705, "NonAnonymousResponses"));
if (nonAnonymousElement != null) {
innerPolicy.addNewNonAnonymousResponses();
}
}
}
}