/*
* soapUI, copyright (C) 2004-2011 eviware.com
*
* soapUI is free software; you can redistribute it and/or modify it under the
* terms of version 2.1 of the GNU Lesser General Public License as published by
* the Free Software Foundation.
*
* soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details at gnu.org.
*/
package com.eviware.soapui.impl.wsdl.support.policy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.wsdl.Definition;
import javax.wsdl.extensions.ElementExtensible;
import javax.xml.namespace.QName;
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 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;
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();
}
}
}
}