View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2009 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.model.propertyexpansion;
14  
15  import java.util.ArrayList;
16  import java.util.Arrays;
17  import java.util.Collection;
18  import java.util.HashSet;
19  import java.util.List;
20  import java.util.Map;
21  import java.util.Set;
22  
23  import org.apache.commons.beanutils.PropertyUtils;
24  import org.apache.log4j.Logger;
25  
26  import com.eviware.soapui.SoapUI;
27  import com.eviware.soapui.impl.support.AbstractHttpRequest;
28  import com.eviware.soapui.impl.support.AbstractHttpRequestInterface;
29  import com.eviware.soapui.impl.wsdl.MutableTestPropertyHolder;
30  import com.eviware.soapui.impl.wsdl.WsdlInterface;
31  import com.eviware.soapui.impl.wsdl.WsdlProject;
32  import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
33  import com.eviware.soapui.impl.wsdl.mock.WsdlMockOperation;
34  import com.eviware.soapui.impl.wsdl.mock.WsdlMockResponse;
35  import com.eviware.soapui.impl.wsdl.mock.WsdlMockService;
36  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
37  import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStep;
38  import com.eviware.soapui.model.ModelItem;
39  import com.eviware.soapui.model.TestPropertyHolder;
40  import com.eviware.soapui.model.mock.MockOperation;
41  import com.eviware.soapui.model.mock.MockResponse;
42  import com.eviware.soapui.model.mock.MockService;
43  import com.eviware.soapui.model.project.Project;
44  import com.eviware.soapui.model.support.SettingsTestPropertyHolder;
45  import com.eviware.soapui.model.testsuite.RenameableTestProperty;
46  import com.eviware.soapui.model.testsuite.TestCase;
47  import com.eviware.soapui.model.testsuite.TestProperty;
48  import com.eviware.soapui.model.testsuite.TestStep;
49  import com.eviware.soapui.model.testsuite.TestSuite;
50  import com.eviware.soapui.support.StringUtils;
51  import com.eviware.soapui.support.UISupport;
52  import com.eviware.soapui.support.types.StringToObjectMap;
53  
54  public class PropertyExpansionUtils
55  {
56  	public final static Logger log = Logger.getLogger( PropertyExpansionUtils.class );
57  
58  	private static SettingsTestPropertyHolder globalTestPropertyHolder;
59  
60  	public static String getGlobalProperty( String propertyName )
61  	{
62  		if( globalTestPropertyHolder == null )
63  		{
64  			initGlobalProperties();
65  		}
66  
67  		return globalTestPropertyHolder.getPropertyValue( propertyName );
68  	}
69  
70  	private synchronized static void initGlobalProperties()
71  	{
72  		globalTestPropertyHolder = new SettingsTestPropertyHolder( SoapUI.getSettings(), null );
73  
74  		String propFile = System.getProperty( "soapui.properties" );
75  		if( StringUtils.hasContent( propFile ) )
76  			globalTestPropertyHolder.addPropertiesFromFile( propFile );
77  	}
78  
79  	public static void saveGlobalProperties()
80  	{
81  		if( globalTestPropertyHolder != null )
82  		{
83  			globalTestPropertyHolder.saveTo( SoapUI.getSettings() );
84  		}
85  	}
86  
87  	/***
88  	 * @deprecated Use {@link PropertyExpander#expandProperties(String)} instead
89  	 */
90  	public static String expandProperties( String content )
91  	{
92  		return PropertyExpander.expandProperties( content );
93  	}
94  
95  	/***
96  	 * @deprecated Use
97  	 *             {@link PropertyExpander#expandProperties(PropertyExpansionContext,String)}
98  	 *             instead
99  	 */
100 	public static String expandProperties( PropertyExpansionContext context, String content )
101 	{
102 		return PropertyExpander.expandProperties( context, content );
103 	}
104 
105 	/***
106 	 * @deprecated Use
107 	 *             {@link PropertyExpander#expandProperties(PropertyExpansionContext,String,boolean)}
108 	 *             instead
109 	 */
110 
111 	public static String expandProperties( PropertyExpansionContext context, String content, boolean entitize )
112 	{
113 		return PropertyExpander.expandProperties( context, content, entitize );
114 	}
115 
116 	/***
117 	 * Checks if a property can be transferred to another specified property via
118 	 * a property-transfer
119 	 */
120 
121 	public static boolean canTransferToProperty( TestProperty source, TestProperty target )
122 	{
123 		return false;
124 	}
125 
126 	/***
127 	 * Checks if a modelItem can acces a specified property via
128 	 * property-expansion
129 	 */
130 
131 	public static boolean canExpandProperty( ModelItem contextModelItem, TestProperty property )
132 	{
133 		ModelItem propertyModelItem = property.getModelItem();
134 
135 		// global / anonymous reference?
136 		if( propertyModelItem == null || propertyModelItem instanceof Project )
137 			return true;
138 
139 		if( contextModelItem instanceof TestSuite )
140 		{
141 			return propertyModelItem == contextModelItem;
142 		}
143 
144 		if( contextModelItem instanceof TestCase )
145 		{
146 			return propertyModelItem == contextModelItem
147 					|| ( propertyModelItem instanceof TestSuite && ( ( TestCase )contextModelItem ).getTestSuite() == propertyModelItem );
148 		}
149 
150 		if( contextModelItem instanceof TestStep )
151 		{
152 			TestStep testStep = ( ( TestStep )contextModelItem );
153 
154 			return propertyModelItem == contextModelItem
155 					|| ( propertyModelItem instanceof TestSuite && testStep.getTestCase().getTestSuite() == propertyModelItem )
156 					|| ( propertyModelItem instanceof TestCase && testStep.getTestCase() == propertyModelItem )
157 					|| ( propertyModelItem instanceof TestStep && testStep.getTestCase() == ( ( TestStep )propertyModelItem )
158 							.getTestCase() );
159 		}
160 
161 		if( contextModelItem instanceof MockService )
162 		{
163 			return propertyModelItem == contextModelItem;
164 		}
165 
166 		if( contextModelItem instanceof MockOperation )
167 		{
168 			return propertyModelItem == contextModelItem
169 					|| ( propertyModelItem instanceof MockService && ( ( MockOperation )contextModelItem ).getMockService() == propertyModelItem );
170 		}
171 
172 		if( contextModelItem instanceof MockResponse )
173 		{
174 			MockResponse testStep = ( ( MockResponse )contextModelItem );
175 
176 			return propertyModelItem == contextModelItem
177 					|| ( propertyModelItem instanceof MockService && testStep.getMockOperation().getMockService() == propertyModelItem )
178 					|| ( propertyModelItem instanceof MockOperation && testStep.getMockOperation() == propertyModelItem )
179 					|| ( propertyModelItem instanceof MockResponse && testStep.getMockOperation() == ( ( MockResponse )propertyModelItem )
180 							.getMockOperation() );
181 		}
182 
183 		System.out
184 				.println( "property " + property.getName() + " can not be transferred to " + contextModelItem.getName() );
185 		return false;
186 	}
187 
188 	public static MutableTestPropertyHolder getGlobalProperties()
189 	{
190 		if( globalTestPropertyHolder == null )
191 		{
192 			initGlobalProperties();
193 		}
194 
195 		return globalTestPropertyHolder;
196 	}
197 
198 	public static MutablePropertyExpansion[] renameProperty( RenameableTestProperty property, String newName,
199 			ModelItem root )
200 	{
201 		UISupport.setHourglassCursor();
202 
203 		try
204 		{
205 			List<MutablePropertyExpansion> result = new ArrayList<MutablePropertyExpansion>();
206 			List<MutablePropertyExpansion> properties = new ArrayList<MutablePropertyExpansion>();
207 
208 			PropertyExpansion[] propertyExpansions = getPropertyExpansions( root, true, true );
209 			for( PropertyExpansion pe : propertyExpansions )
210 			{
211 				MutablePropertyExpansion mpe = ( MutablePropertyExpansion )pe;
212 				if( mpe.getProperty().equals( property ) )
213 				{
214 					mpe.setProperty( property );
215 					properties.add( mpe );
216 				}
217 			}
218 
219 			property.setName( newName );
220 
221 			for( MutablePropertyExpansion mpe : properties )
222 			{
223 				try
224 				{
225 					mpe.update();
226 					result.add( mpe );
227 				}
228 				catch( Exception e )
229 				{
230 					e.printStackTrace();
231 				}
232 			}
233 
234 			return result.toArray( new MutablePropertyExpansion[result.size()] );
235 		}
236 		finally
237 		{
238 			UISupport.resetCursor();
239 		}
240 	}
241 
242 	public static PropertyExpansion[] getPropertyExpansions( ModelItem modelItem, boolean mutableOnly, boolean deep )
243 	{
244 		List<PropertyExpansion> result = new ArrayList<PropertyExpansion>();
245 
246 		if( modelItem instanceof PropertyExpansionContainer )
247 		{
248 			PropertyExpansion[] pes = ( ( PropertyExpansionContainer )modelItem ).getPropertyExpansions();
249 			if( pes != null && pes.length > 0 )
250 			{
251 				for( PropertyExpansion pe : pes )
252 				{
253 					if( mutableOnly && !( pe instanceof MutablePropertyExpansion ) )
254 						continue;
255 
256 					result.add( pe );
257 				}
258 			}
259 		}
260 
261 		if( deep )
262 		{
263 			List<? extends ModelItem> children = modelItem.getChildren();
264 			if( children != null && children.size() > 0 )
265 			{
266 				for( ModelItem child : children )
267 				{
268 					result.addAll( Arrays.asList( getPropertyExpansions( child, mutableOnly, deep ) ) );
269 				}
270 			}
271 		}
272 
273 		return result.toArray( new PropertyExpansion[result.size()] );
274 	}
275 
276 	public static Collection<? extends PropertyExpansion> extractPropertyExpansions( ModelItem modelItem, Object target,
277 			String propertyName )
278 	{
279 		List<PropertyExpansion> result = new ArrayList<PropertyExpansion>();
280 		Set<String> expansions = new HashSet<String>();
281 
282 		try
283 		{
284 			Object property = PropertyUtils.getProperty( target, propertyName );
285 			if( property instanceof String && PropertyUtils.isWriteable( target, propertyName ) )
286 			{
287 				String str = property.toString();
288 
289 				if( !StringUtils.isNullOrEmpty( str ) )
290 				{
291 					int ix = str.indexOf( "${" );
292 					while( ix != -1 )
293 					{
294 						// TODO handle nested property-expansions..
295 						int ix2 = str.indexOf( '}', ix + 2 );
296 						if( ix2 == -1 )
297 							break;
298 
299 						String expansion = str.substring( ix + 2, ix2 );
300 						if( !expansions.contains( expansion ) )
301 						{
302 							MutablePropertyExpansion tp = createMutablePropertyExpansion( expansion, modelItem, target,
303 									propertyName );
304 							if( tp != null )
305 							{
306 								result.add( tp );
307 								expansions.add( expansion );
308 							}
309 						}
310 
311 						str = str.substring( ix2 );
312 						ix = str.indexOf( "${" );
313 					}
314 				}
315 			}
316 		}
317 		catch( Exception e )
318 		{
319 			SoapUI.logError( e );
320 		}
321 
322 		return result;
323 	}
324 
325 	public static MutablePropertyExpansionImpl createMutablePropertyExpansion( String pe, ModelItem modelItem,
326 			Object target, String propertyName )
327 	{
328 		WsdlTestStep testStep = null;
329 		WsdlTestCase testCase = null;
330 		WsdlTestSuite testSuite = null;
331 		WsdlProject project = null;
332 		WsdlMockService mockService = null;
333 		WsdlMockResponse mockResponse = null;
334 		TestPropertyHolder holder = null;
335 
336 		if( modelItem instanceof WsdlTestStep )
337 		{
338 			testStep = ( WsdlTestStep )modelItem;
339 			testCase = testStep.getTestCase();
340 			testSuite = testCase.getTestSuite();
341 			project = testSuite.getProject();
342 		}
343 		else if( modelItem instanceof WsdlTestCase )
344 		{
345 			testCase = ( WsdlTestCase )modelItem;
346 			testSuite = testCase.getTestSuite();
347 			project = testSuite.getProject();
348 		}
349 		else if( modelItem instanceof WsdlTestSuite )
350 		{
351 			testSuite = ( WsdlTestSuite )modelItem;
352 			project = testSuite.getProject();
353 		}
354 		else if( modelItem instanceof WsdlInterface )
355 		{
356 			project = ( ( WsdlInterface )modelItem ).getProject();
357 		}
358 		else if( modelItem instanceof WsdlProject )
359 		{
360 			project = ( WsdlProject )modelItem;
361 		}
362 		else if( modelItem instanceof WsdlMockService )
363 		{
364 			mockService = ( WsdlMockService )modelItem;
365 			project = mockService.getProject();
366 		}
367 		else if( modelItem instanceof AbstractHttpRequestInterface<?> )
368 		{
369 			project = ( ( AbstractHttpRequest<?> )modelItem ).getOperation().getInterface().getProject();
370 		}
371 		else if( modelItem instanceof WsdlMockOperation )
372 		{
373 			mockService = ( ( WsdlMockOperation )modelItem ).getMockService();
374 			project = mockService.getProject();
375 		}
376 		else if( modelItem instanceof WsdlMockResponse )
377 		{
378 			mockResponse = ( WsdlMockResponse )modelItem;
379 			mockService = mockResponse.getMockOperation().getMockService();
380 			project = mockService.getProject();
381 		}
382 
383 		// explicit item reference?
384 		if( pe.startsWith( PropertyExpansion.PROJECT_REFERENCE ) )
385 		{
386 			holder = project;
387 			pe = pe.substring( PropertyExpansion.PROJECT_REFERENCE.length() );
388 		}
389 		else if( pe.startsWith( PropertyExpansion.TESTSUITE_REFERENCE ) )
390 		{
391 			holder = testSuite;
392 			pe = pe.substring( PropertyExpansion.TESTSUITE_REFERENCE.length() );
393 		}
394 		else if( pe.startsWith( PropertyExpansion.TESTCASE_REFERENCE ) )
395 		{
396 			holder = testCase;
397 			pe = pe.substring( PropertyExpansion.TESTCASE_REFERENCE.length() );
398 		}
399 		else if( pe.startsWith( PropertyExpansion.MOCKSERVICE_REFERENCE ) )
400 		{
401 			holder = mockService;
402 			pe = pe.substring( PropertyExpansion.MOCKSERVICE_REFERENCE.length() );
403 		}
404 		else if( pe.startsWith( PropertyExpansion.MOCKRESPONSE_REFERENCE ) )
405 		{
406 			holder = mockResponse;
407 			pe = pe.substring( PropertyExpansion.MOCKRESPONSE_REFERENCE.length() );
408 		}
409 		else if( testCase != null )
410 		{
411 			int sepIx = pe.indexOf( PropertyExpansion.PROPERTY_SEPARATOR );
412 			if( sepIx > 0 )
413 			{
414 				holder = testCase.getTestStepByName( pe.substring( 0, sepIx ) );
415 				if( holder != null )
416 				{
417 					pe = pe.substring( sepIx + 1 );
418 				}
419 			}
420 		}
421 
422 		int sepIx = pe.indexOf( PropertyExpansion.XPATH_SEPARATOR );
423 		String xpath = null;
424 
425 		if( sepIx > 0 )
426 		{
427 			xpath = pe.substring( sepIx + 1 );
428 			pe = pe.substring( 0, sepIx );
429 		}
430 
431 		if( holder == null )
432 			holder = getGlobalProperties();
433 
434 		TestProperty tp = holder.getProperty( pe );
435 		return tp == null ? null : new MutablePropertyExpansionImpl( tp, xpath, target, propertyName );
436 	}
437 
438 	/***
439 	 * @deprecated Use
440 	 *             {@link PropertyExpander#expandProperties(ModelItem,String)}
441 	 *             instead
442 	 */
443 	public static String expandProperties( ModelItem contextModelItem, String content )
444 	{
445 		return PropertyExpander.expandProperties( contextModelItem, content );
446 	}
447 
448 	public static class GlobalPropertyExpansionContext implements PropertyExpansionContext
449 	{
450 		public Object getProperty( String name )
451 		{
452 			return getGlobalProperties().getProperty( name );
453 		}
454 
455 		public void setProperty( String name, Object value )
456 		{
457 			getGlobalProperties().setPropertyValue( name, String.valueOf( value ) );
458 		}
459 
460 		public boolean hasProperty( String name )
461 		{
462 			return getGlobalProperties().hasProperty( name );
463 		}
464 
465 		public Object removeProperty( String name )
466 		{
467 			return getGlobalProperties().removeProperty( name );
468 		}
469 
470 		public String[] getPropertyNames()
471 		{
472 			return getGlobalProperties().getPropertyNames();
473 		}
474 
475 		public ModelItem getModelItem()
476 		{
477 			return null;
478 		}
479 
480 		public String expand( String content )
481 		{
482 			return PropertyExpander.expandProperties( this, content );
483 		}
484 
485 		public StringToObjectMap getProperties()
486 		{
487 			StringToObjectMap result = new StringToObjectMap();
488 			Map<String, TestProperty> props = getGlobalProperties().getProperties();
489 			for( String key : props.keySet() )
490 			{
491 				result.put( key, props.get( key ) );
492 			}
493 
494 			return result;
495 		}
496 	}
497 	
498 	public static boolean containsPropertyExpansion( String str )
499 	{
500 		return str != null && str.indexOf( "${" ) >= 0 && str.indexOf( '}' ) > 2;
501 	}
502 }