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