View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.impl.wsdl.support.policy;
14  
15  import java.util.ArrayList;
16  import java.util.Arrays;
17  import java.util.List;
18  
19  import javax.wsdl.Definition;
20  import javax.wsdl.extensions.ElementExtensible;
21  import javax.xml.namespace.QName;
22  
23  import org.apache.xmlbeans.XmlObject;
24  import org.apache.xmlbeans.XmlOptions;
25  import org.w3.x2007.x05.addressing.metadata.AddressingDocument.Addressing;
26  import org.w3c.dom.Element;
27  import org.xmlsoap.schemas.ws.x2004.x09.policy.OptionalType;
28  import org.xmlsoap.schemas.ws.x2004.x09.policy.Policy;
29  import org.xmlsoap.schemas.ws.x2004.x09.policy.PolicyDocument;
30  
31  import com.eviware.soapui.impl.support.definition.InterfaceDefinitionPart;
32  import com.eviware.soapui.impl.wsdl.support.wsa.WsaUtils;
33  import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlContext;
34  import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils;
35  import com.eviware.soapui.support.StringUtils;
36  import com.eviware.soapui.support.xml.XmlUtils;
37  
38  public class PolicyUtils
39  {
40  	public final static String WS_XMLSOAP_POLICY_NAMESPACE = "http://schemas.xmlsoap.org/ws/2004/09/policy";
41  	public final static String WS_W3_POLICY_NAMESPACE = "http://www.w3.org/ns/ws-policy";
42  	public final static String WS_SECURITY_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
43  
44  	public static List<Policy> getPolicies( WsdlContext wsdlContext )
45  	{
46  
47  		List<Policy> policies = new ArrayList<Policy>();
48  		try
49  		{
50  			List<InterfaceDefinitionPart> parts = wsdlContext.getDefinitionCache().getDefinitionParts();
51  			for( int i = 0; i < parts.size(); i++ )
52  			{
53  				InterfaceDefinitionPart part = parts.get( i );
54  				String content = part.getContent();
55  				XmlObject xml = XmlObject.Factory.parse( content );
56  				// include paths for both namespaces
57  				XmlObject[] paths = xml.selectPath( "declare namespace wsp='" + WS_W3_POLICY_NAMESPACE + "';"
58  						+ "//wsp:Policy" );
59  				List<XmlObject> listOfXmlObjcts = Arrays.asList( paths );
60  
61  				XmlObject[] paths1 = xml.selectPath( "declare namespace wsp='" + WS_XMLSOAP_POLICY_NAMESPACE + "';"
62  						+ "//wsp:Policy" );
63  				listOfXmlObjcts.addAll( Arrays.asList( paths1 ) );
64  				paths = ( XmlObject[] )listOfXmlObjcts.toArray();
65  
66  				for( XmlObject obj : paths )
67  				{
68  					String xx = obj.xmlText( new XmlOptions().setSaveOuter() );
69  					PolicyDocument policyDocument = PolicyDocument.Factory.parse( xx );
70  					org.xmlsoap.schemas.ws.x2004.x09.policy.Policy polc = ( org.xmlsoap.schemas.ws.x2004.x09.policy.Policy )policyDocument
71  							.getPolicy();
72  					policies.add( polc );
73  					// List<Addressing> addressingList = polc.getAddressingList();
74  					// Addressing a = null;
75  					// if (addressingList.size() > 0 )
76  					// {
77  					// a = addressingList.get(0);
78  					// }
79  					// AnonymousResponses ar = null;
80  					// List<AnonymousResponses> anList =
81  					// polc.getAnonymousResponsesList();
82  					// if (anList.size() > 0)
83  					// {
84  					// ar = anList.get(0);
85  					// }
86  
87  				}
88  
89  			}
90  		}
91  		catch( Exception e )
92  		{
93  			// TODO Auto-generated catch block
94  			e.printStackTrace();
95  		}
96  
97  		return null;
98  	}
99  
100 	public static boolean isAddressing( Policy policy )
101 	{
102 
103 		if( policy.getAddressingList().size() > 0 )
104 		{
105 			return true;
106 		}
107 
108 		return false;
109 	}
110 
111 	public static List<Policy> getAddressingPolicies( WsdlContext wsdlContext )
112 	{
113 		List<Policy> addressingPolicies = new ArrayList<Policy>();
114 		List<Policy> policies = getPolicies( wsdlContext );
115 		for( Policy policy : policies )
116 		{
117 			if( isAddressing( policy ) )
118 			{
119 				addressingPolicies.add( policy );
120 			}
121 		}
122 		return addressingPolicies;
123 	}
124 
125 	/*
126 	 * Functions currently not used, initially intended for policy to be
127 	 * normalized first
128 	 */
129 	// public static Policy normalize(Policy policy) {
130 	// 1.Start with the Element Information Item E (as defined in the XML
131 	// Information Set [XML Information Set]) of the policy expression.
132 	// The [namespace name] of E is always "http://www.w3.org/ns/ws-policy". In
133 	// the base case, the [local name] property of E is "Policy";
134 	// in the recursive case, the [local name] property of E is "Policy",
135 	// "ExactlyOne", or "All".
136 	//
137 	// 2.Expand Element Information Items (as defined in the XML Information Set
138 	// [XML Information Set]) in the [children] property of E that
139 	// are policy references per Section 4.3.5 Policy Inclusion.
140 	//
141 	// 3.Convert each Element Information Item C in the [children] property of E
142 	// into normal form.
143 	// List<OperatorContentType> eoList = policy.getExactlyOneList();
144 	// ExactlyOneDocument.Factory.newInstance();
145 	//
146 	// 3.1 If the [namespace name] property of C is
147 	// "http://www.w3.org/ns/ws-policy" and the [local name] property of C is
148 	// "Policy",
149 	// "ExactlyOne", or "All", C is an expression of a policy operator; normalize
150 	// C by recursively applying this procedure.
151 	//
152 	// 3.2 Otherwise the Element Information Item C is an assertion; normalize C
153 	// per Sections 4.3.1 Optional Policy Assertions and 4.3.2
154 	// Policy Assertion Nesting.
155 	//
156 	// 4.Apply the policy operator indicated by E to the normalized Element
157 	// Information Items in its [children] property and co1.nstruct a
158 	// normal form per Section 4.3.3 Policy Operators and 4.1 Normal Form Policy
159 	// Expression.
160 	//
161 
162 	// return policy;
163 	// }
164 	/*
165 	 * Functions currently not used, initially intended for policy to be
166 	 * normalized first
167 	 */
168 	// public static Element normalize(Element policy)
169 	// {
170 	// // if (!StringUtils.isNullOrEmpty(nameSpace) &&
171 	// !StringUtils.isNullOrEmpty(localName))
172 	// // {
173 	// NodeList nl = policy.getChildNodes();
174 	// List<Element> listElms = new ArrayList<Element>();
175 	// for( int c = 0; c < nl.getLength(); c++ )
176 	// {
177 	// Node item = nl.item( c );
178 	// if( item.getParentNode() == policy && item.getNodeType() ==
179 	// Node.ELEMENT_NODE )
180 	// listElms.add( (Element) item );
181 	// }
182 	//      
183 	// for (int i = 0; i < listElms.size(); i++)
184 	// {
185 	// Element elm = listElms.get(i);
186 	// Element newElm = null;
187 	// String nameSpace = elm.getNamespaceURI();
188 	// String localName = elm.getLocalName();
189 	// if (nameSpace.equals(WS_W3_POLICY_NAMESPACE)
190 	// && (localName.equals("Policy") || localName.equals("All") ||
191 	// localName.equals("ExactlyOne")))
192 	// {
193 	// newElm = normalize(elm);
194 	//
195 	// } else {
196 	//				
197 	// Element allElm =
198 	// elm.getOwnerDocument().createElementNS(WS_W3_POLICY_NAMESPACE, "All");
199 	// allElm.appendChild(elm);
200 	//
201 	// Element exactlyOneElm =
202 	// elm.getOwnerDocument().createElementNS(WS_W3_POLICY_NAMESPACE,
203 	// "ExactlyOne");
204 	// exactlyOneElm.appendChild(allElm);
205 	//				
206 	// String optional = elm.getAttributeNS(WS_W3_POLICY_NAMESPACE, "Optional");
207 	// if (!StringUtils.isNullOrEmpty(optional) && optional.equals("true"))
208 	// {
209 	// Element allElmEmpty =
210 	// elm.getOwnerDocument().createElementNS(WS_W3_POLICY_NAMESPACE, "All");
211 	// exactlyOneElm.appendChild(allElmEmpty);
212 	// }
213 	//				
214 	// newElm = exactlyOneElm;
215 	// }
216 	// elm.getParentNode().replaceChild(elm, newElm);
217 	// }
218 	// // }
219 	//
220 	// return policy;
221 	// }
222 	public static Policy getAttachedPolicy( ElementExtensible item, Definition def )
223 	{
224 
225 		Policy rtnPolicy = null;
226 		String usedPolicyNamespace = PolicyUtils.WS_W3_POLICY_NAMESPACE;
227 		Element[] policyReferences = WsdlUtils.getExentsibilityElements( item, new QName(
228 				PolicyUtils.WS_W3_POLICY_NAMESPACE, "PolicyReference" ) );
229 		if( policyReferences.length <= 0 )
230 		{
231 			policyReferences = WsdlUtils.getExentsibilityElements( item, new QName(
232 					PolicyUtils.WS_XMLSOAP_POLICY_NAMESPACE, "PolicyReference" ) );
233 			usedPolicyNamespace = PolicyUtils.WS_XMLSOAP_POLICY_NAMESPACE;
234 		}
235 		if( policyReferences.length > 0 )
236 		{
237 			String policyId = policyReferences[0].getAttribute( "URI" );
238 			if( !StringUtils.isNullOrEmpty( policyId ) )
239 			{
240 				Element[] policies = WsdlUtils.getExentsibilityElements( def, new QName( usedPolicyNamespace, "Policy" ) );
241 				Element policy = null;
242 				for( int i = 0; i < policies.length; i++ )
243 				{
244 					policy = policies[i];
245 					String policyIdx = policy.getAttributeNS( WS_SECURITY_NAMESPACE, "Id" );
246 					if( policyId.equals( "#" + policyIdx ) )
247 					{
248 						rtnPolicy = getPolicy( policy, usedPolicyNamespace );
249 						continue;
250 					}
251 
252 				}
253 			}
254 		}
255 		else
256 		{
257 			// get policies of item itself
258 			Element[] itemPolicies = WsdlUtils.getExentsibilityElements( item, new QName( usedPolicyNamespace, "Policy" ) );
259 			if( itemPolicies.length > 0 )
260 			{
261 				for( int i = 0; i < itemPolicies.length; i++ )
262 				{
263 					Element policy = itemPolicies[i];
264 					rtnPolicy = getPolicy( policy, usedPolicyNamespace );
265 
266 				}
267 			}
268 		}
269 		return rtnPolicy;
270 	}
271 
272 	public static Policy getPolicy( Element policy, String usedPolicyNamespace )
273 	{
274 		// policy = PolicyUtils.normalize(policy);
275 
276 		Policy newPolicy = null;
277 		// check for ExactlyOne and All
278 		// TODO ExactlyOne and All are idempotent all empty ones should be skipped
279 		// and found the real ones
280 		Element exactlyOne = XmlUtils.getFirstChildElementNS( policy, usedPolicyNamespace, "ExactlyOne" );
281 		if( exactlyOne != null )
282 		{
283 			Element all = XmlUtils.getFirstChildElementNS( exactlyOne, usedPolicyNamespace, "All" );
284 			if( all != null )
285 			{
286 				newPolicy = getAddressingPolicy( all, usedPolicyNamespace );
287 			}
288 		}
289 		else
290 		{
291 			newPolicy = getAddressingPolicy( policy, usedPolicyNamespace );
292 		}
293 		return newPolicy;
294 	}
295 
296 	private static Policy getAddressingPolicy( Element wsamAddressingElm, String usedPolicyNamespace )
297 	{
298 		// check if found reference is addressing policy
299 		Element wsAddressing = XmlUtils.getFirstChildElementNS( wsamAddressingElm, WsaUtils.WS_A_NAMESPACE_200705,
300 				"Addressing" );
301 		Element addressingPolicy = null;
302 		Policy newPolicy = PolicyDocument.Factory.newInstance().addNewPolicy();
303 		Addressing newAddressing = null;
304 		if( wsAddressing != null )
305 		{
306 			newAddressing = newPolicy.addNewAddressing();
307 			String optional = wsAddressing.getAttributeNS( usedPolicyNamespace, "Optional" );
308 			if( !StringUtils.isNullOrEmpty( optional ) && optional.equals( OptionalType.TRUE.toString() ) )
309 			{
310 				newAddressing.setOptional( OptionalType.TRUE );
311 			}
312 			else
313 			{
314 				newAddressing.setOptional( OptionalType.FALSE );
315 			}
316 			addressingPolicy = XmlUtils.getFirstChildElementNS( wsAddressing, usedPolicyNamespace, "Policy" );
317 			if( addressingPolicy != null )
318 			{
319 				Element exactlyOne = XmlUtils.getFirstChildElementNS( addressingPolicy, usedPolicyNamespace, "ExactlyOne" );
320 				if( exactlyOne != null )
321 				{
322 					Element all = XmlUtils.getFirstChildElementNS( exactlyOne, usedPolicyNamespace, "All" );
323 					if( all != null )
324 					{
325 						getAddressingAnonymous( all, newAddressing );
326 					}
327 				}
328 				else
329 				{
330 					getAddressingAnonymous( addressingPolicy, newAddressing );
331 				}
332 
333 			}
334 		}
335 		Element usingAddressing = XmlUtils.getFirstChildElementNS( wsamAddressingElm, WsaUtils.WS_A_NAMESPACE_200605,
336 				"UsingAddressing" );
337 		if( usingAddressing != null )
338 		{
339 			// add UsingAddressing to policy
340 			newPolicy.addNewUsingAddressing();
341 		}
342 		return newPolicy;
343 	}
344 
345 	private static void getAddressingAnonymous( Element addressingPolicy, Addressing newAddressing )
346 	{
347 		Policy innerPolicy = newAddressing.addNewPolicy();
348 		// check if policy has Anonymous
349 		Element anonymousElm = XmlUtils.getFirstChildElementNS( addressingPolicy, new QName(
350 				WsaUtils.WS_A_NAMESPACE_200705, "AnonymousResponses" ) );
351 		if( anonymousElm != null )
352 		{
353 			innerPolicy.addNewAnonymousResponses();
354 		}
355 		else
356 		{
357 			Element nonAnonymousElement = XmlUtils.getFirstChildElementNS( addressingPolicy, new QName(
358 					WsaUtils.WS_A_NAMESPACE_200705, "NonAnonymousResponses" ) );
359 			if( nonAnonymousElement != null )
360 			{
361 				innerPolicy.addNewNonAnonymousResponses();
362 			}
363 		}
364 	}
365 }