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.teststeps;
14  
15  import java.io.IOException;
16  import java.io.InputStream;
17  import java.net.MalformedURLException;
18  import java.net.URL;
19  import java.util.Collections;
20  import java.util.Enumeration;
21  import java.util.List;
22  import java.util.Map;
23  
24  import javax.swing.ImageIcon;
25  
26  import com.eviware.soapui.config.PropertiesStepConfig;
27  import com.eviware.soapui.config.TestStepConfig;
28  import com.eviware.soapui.impl.wsdl.MutableTestPropertyHolder;
29  import com.eviware.soapui.impl.wsdl.support.XmlBeansPropertiesTestPropertyHolder;
30  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
31  import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
32  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
33  import com.eviware.soapui.model.testsuite.TestCaseRunContext;
34  import com.eviware.soapui.model.testsuite.TestCaseRunner;
35  import com.eviware.soapui.model.testsuite.TestProperty;
36  import com.eviware.soapui.model.testsuite.TestPropertyListener;
37  import com.eviware.soapui.model.testsuite.TestStepResult;
38  import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus;
39  import com.eviware.soapui.support.StringUtils;
40  import com.eviware.soapui.support.UISupport;
41  import com.eviware.soapui.support.resolver.ResolveContext;
42  import com.eviware.soapui.support.types.StringList;
43  
44  /***
45   * TestStep that holds an arbitrary number of custom properties
46   * 
47   * @author ole.matzura
48   */
49  
50  public class WsdlPropertiesTestStep extends WsdlTestStep implements MutableTestPropertyHolder
51  {
52  	private PropertiesStepConfig propertiesStepConfig;
53  	private ImageIcon okIcon;
54  	private ImageIcon failedIcon;
55  	private XmlBeansPropertiesTestPropertyHolder propertyHolderSupport;
56  	private BeanPathPropertySupport sourceProperty;
57  	private BeanPathPropertySupport targetProperty;
58  
59  	public static final String SOURCE_PROPERTY = WsdlPropertiesTestStep.class.getName() + "@source";
60  	public static final String TARGET_PROPERTY = WsdlPropertiesTestStep.class.getName() + "@target";
61  
62  	public WsdlPropertiesTestStep( WsdlTestCase testCase, TestStepConfig config, boolean forLoadTest )
63  	{
64  		super( testCase, config, true, forLoadTest );
65  
66  		if( !forLoadTest )
67  		{
68  			okIcon = UISupport.createImageIcon( "/properties_step.gif" );
69  			failedIcon = UISupport.createImageIcon( "/properties_step_failed.gif" );
70  
71  			setIcon( okIcon );
72  		}
73  
74  		if( config.getConfig() == null )
75  		{
76  			propertiesStepConfig = ( PropertiesStepConfig )config.addNewConfig().changeType( PropertiesStepConfig.type );
77  			propertiesStepConfig.addNewProperties();
78  			propertiesStepConfig.setCreateMissingOnLoad( true );
79  		}
80  		else
81  		{
82  			propertiesStepConfig = ( PropertiesStepConfig )config.getConfig().changeType( PropertiesStepConfig.type );
83  			if( !propertiesStepConfig.isSetProperties() )
84  			{
85  				propertiesStepConfig.addNewProperties();
86  			}
87  
88  			if( !propertiesStepConfig.isSetSaveFirst() )
89  				propertiesStepConfig.setSaveFirst( true );
90  		}
91  
92  		propertyHolderSupport = new XmlBeansPropertiesTestPropertyHolder( this, propertiesStepConfig.getProperties() );
93  		sourceProperty = new BeanPathPropertySupport( this, propertiesStepConfig, "source" );
94  		targetProperty = new BeanPathPropertySupport( this, propertiesStepConfig, "target" );
95  	}
96  
97  	public TestStepResult run( TestCaseRunner testRunner, TestCaseRunContext testRunContext )
98  	{
99  		WsdlTestStepResult result = new WsdlTestStepResult( this );
100 
101 		if( okIcon != null )
102 			setIcon( okIcon );
103 
104 		result.setStatus( TestStepStatus.OK );
105 		result.startTimer();
106 
107 		if( isSaveFirst() )
108 			saveDuringRun( result, testRunContext );
109 
110 		String source = sourceProperty.expand( testRunContext );
111 		if( StringUtils.hasContent( source ) )
112 		{
113 			try
114 			{
115 				int cnt = loadProperties( source, isCreateMissingOnLoad() );
116 
117 				result.setStatus( TestStepStatus.OK );
118 				result.addMessage( "Loaded " + cnt + " properties from [" + source + "]" );
119 			}
120 			catch( IOException e )
121 			{
122 				result.stopTimer();
123 				result.addMessage( "Failed to load properties from [" + source + "]" );
124 				result.setStatus( TestStepStatus.FAILED );
125 				result.setError( e );
126 
127 				if( failedIcon != null )
128 					setIcon( failedIcon );
129 			}
130 		}
131 
132 		if( !isSaveFirst() )
133 			saveDuringRun( result, testRunContext );
134 
135 		result.stopTimer();
136 
137 		return result;
138 	}
139 
140 	private boolean saveDuringRun( WsdlTestStepResult result, TestCaseRunContext context )
141 	{
142 		String target = targetProperty.expand( context );
143 		if( StringUtils.hasContent( target ) )
144 		{
145 			try
146 			{
147 				int cnt = saveProperties( target );
148 
149 				result.setStatus( TestStepStatus.OK );
150 				result.addMessage( "Saved " + cnt + " properties to [" + target + "]" );
151 			}
152 			catch( IOException e )
153 			{
154 				result.stopTimer();
155 				result.addMessage( "Failed to save properties to [" + target + "]" );
156 				result.setStatus( TestStepStatus.FAILED );
157 				result.setError( e );
158 
159 				if( failedIcon != null )
160 					setIcon( failedIcon );
161 
162 				return false;
163 			}
164 		}
165 
166 		return true;
167 	}
168 
169 	private int saveProperties( String target ) throws IOException
170 	{
171 		return propertyHolderSupport.saveTo( System.getProperty( target, target ) );
172 	}
173 
174 	private int loadProperties( String source, boolean createMissing ) throws IOException
175 	{
176 		// override methods so propertynames are returned in readorder
177 		java.util.Properties props = new java.util.Properties()
178 		{
179 			public StringList names = new StringList();
180 
181 			@Override
182 			public synchronized Object put( Object key, Object value )
183 			{
184 				names.add( key.toString() );
185 				return super.put( key, value );
186 			}
187 
188 			@Override
189 			public Enumeration<?> propertyNames()
190 			{
191 				return Collections.enumeration( names );
192 			}
193 		};
194 
195 		InputStream in = getPropertiesInputStream( source );
196 		props.load( in );
197 		in.close();
198 
199 		int cnt = 0;
200 		Enumeration<?> names = props.propertyNames();
201 		while( names.hasMoreElements() )
202 		{
203 			String name = names.nextElement().toString();
204 			TestProperty property = getProperty( name );
205 			if( property != null )
206 			{
207 				property.setValue( props.get( name ).toString() );
208 				cnt++ ;
209 			}
210 			else if( createMissing )
211 			{
212 				addProperty( name ).setValue( props.get( name ).toString() );
213 				cnt++ ;
214 			}
215 		}
216 
217 		return cnt;
218 	}
219 
220 	private InputStream getPropertiesInputStream( String source ) throws IOException
221 	{
222 		String fileProperty = System.getProperty( source );
223 		if( fileProperty != null )
224 			source = fileProperty;
225 
226 		URL url;
227 
228 		try
229 		{
230 			url = new URL( source );
231 		}
232 		catch( MalformedURLException e )
233 		{
234 			url = new URL( "file:" + source );
235 		}
236 
237 		return url.openStream();
238 	}
239 
240 	public TestProperty getTestStepPropertyAt( int index )
241 	{
242 		return propertyHolderSupport.getPropertyAt( index );
243 	}
244 
245 	public int getStepPropertyCount()
246 	{
247 		return propertyHolderSupport.getPropertyCount();
248 	}
249 
250 	public String getSource()
251 	{
252 		return sourceProperty.get();
253 	}
254 
255 	public void setSource( String source )
256 	{
257 		sourceProperty.set( source, true );
258 	}
259 
260 	public String getTarget()
261 	{
262 		return targetProperty.get();
263 	}
264 
265 	public String getLabel()
266 	{
267 		String str = super.getName() + " (" + getPropertyCount() + ")";
268 
269 		if( isDisabled() )
270 			str += " (disabled)";
271 
272 		return str;
273 	}
274 
275 	public void setTarget( String target )
276 	{
277 		targetProperty.set( target, true );
278 	}
279 
280 	public void resetConfigOnMove( TestStepConfig config )
281 	{
282 		super.resetConfigOnMove( config );
283 
284 		propertiesStepConfig = ( PropertiesStepConfig )config.getConfig().changeType( PropertiesStepConfig.type );
285 		propertyHolderSupport.resetPropertiesConfig( propertiesStepConfig.getProperties() );
286 		sourceProperty.setConfig( propertiesStepConfig );
287 		targetProperty.setConfig( propertiesStepConfig );
288 	}
289 
290 	public int loadProperties( boolean createMissing ) throws IOException
291 	{
292 		return loadProperties( sourceProperty.expand(), createMissing );
293 	}
294 
295 	public int saveProperties() throws IOException
296 	{
297 		String target = PropertyExpander.expandProperties( this, targetProperty.expand() );
298 		return saveProperties( target );
299 	}
300 
301 	public boolean isCreateMissingOnLoad()
302 	{
303 		return propertiesStepConfig.getCreateMissingOnLoad();
304 	}
305 
306 	public void setCreateMissingOnLoad( boolean b )
307 	{
308 		propertiesStepConfig.setCreateMissingOnLoad( b );
309 	}
310 
311 	public boolean isSaveFirst()
312 	{
313 		return propertiesStepConfig.getSaveFirst();
314 	}
315 
316 	public void setSaveFirst( boolean b )
317 	{
318 		propertiesStepConfig.setSaveFirst( b );
319 	}
320 
321 	public boolean isDiscardValuesOnSave()
322 	{
323 		return propertiesStepConfig.getDiscardValuesOnSave();
324 	}
325 
326 	public void setDiscardValuesOnSave( boolean b )
327 	{
328 		propertiesStepConfig.setDiscardValuesOnSave( b );
329 	}
330 
331 	public void setPropertyValue( String name, String value )
332 	{
333 		if( isCreateMissingOnLoad() && getProperty( name ) == null )
334 			addProperty( name );
335 
336 		propertyHolderSupport.setPropertyValue( name, value );
337 	}
338 
339 	@Override
340 	public void beforeSave()
341 	{
342 		super.beforeSave();
343 
344 		if( isDiscardValuesOnSave() )
345 		{
346 			clearPropertyValues();
347 		}
348 	}
349 
350 	public void clearPropertyValues()
351 	{
352 		for( TestProperty property : propertyHolderSupport.getProperties().values() )
353 			property.setValue( null );
354 	}
355 
356 	public boolean renameProperty( String name, String newName )
357 	{
358 		return PropertyExpansionUtils.renameProperty( propertyHolderSupport.getProperty( name ), newName, getTestCase() ) != null;
359 	}
360 
361 	public TestProperty addProperty( String name )
362 	{
363 		String oldLabel = getLabel();
364 
365 		TestProperty property = propertyHolderSupport.addProperty( name );
366 		notifyPropertyChanged( WsdlTestStep.LABEL_PROPERTY, oldLabel, getLabel() );
367 
368 		return property;
369 	}
370 
371 	public void addTestPropertyListener( TestPropertyListener listener )
372 	{
373 		propertyHolderSupport.addTestPropertyListener( listener );
374 	}
375 
376 	public Map<String, TestProperty> getProperties()
377 	{
378 		return propertyHolderSupport.getProperties();
379 	}
380 
381 	public TestProperty getProperty( String name )
382 	{
383 		return propertyHolderSupport.getProperty( name );
384 	}
385 
386 	public TestProperty getPropertyAt( int index )
387 	{
388 		return propertyHolderSupport.getPropertyAt( index );
389 	}
390 
391 	public List<TestProperty> getPropertyList()
392 	{
393 		return propertyHolderSupport.getPropertyList();
394 	}
395 
396 	public int getPropertyCount()
397 	{
398 		return propertyHolderSupport.getPropertyCount();
399 	}
400 
401 	public String[] getPropertyNames()
402 	{
403 		return propertyHolderSupport.getPropertyNames();
404 	}
405 
406 	public String getPropertyValue( String name )
407 	{
408 		return propertyHolderSupport.getPropertyValue( name );
409 	}
410 
411 	public TestProperty removeProperty( String propertyName )
412 	{
413 		String oldLabel = getLabel();
414 
415 		TestProperty result = propertyHolderSupport.removeProperty( propertyName );
416 		notifyPropertyChanged( WsdlTestStep.LABEL_PROPERTY, oldLabel, getLabel() );
417 		return result;
418 	}
419 
420 	public void removeTestPropertyListener( TestPropertyListener listener )
421 	{
422 		propertyHolderSupport.removeTestPropertyListener( listener );
423 	}
424 
425 	public boolean hasProperty( String name )
426 	{
427 		return propertyHolderSupport.hasProperty( name );
428 	}
429 
430 	@Override
431 	public void resolve( ResolveContext<?> context )
432 	{
433 		super.resolve( context );
434 
435 		targetProperty.resolveFile( context, "Missing target property file", "properties",
436 				"Properties Files (*.properties)", true );
437 		sourceProperty.resolveFile( context, "Missing source property file", "properties",
438 				"Properties Files (*.properties)", true );
439 	}
440 
441 	public void moveProperty( String propertyName, int targetIndex )
442 	{
443 		propertyHolderSupport.moveProperty( propertyName, targetIndex );
444 	}
445 
446 	public String getSource( boolean expand )
447 	{
448 		return expand ? sourceProperty.expand() : getSource();
449 	}
450 
451 	public String getTarget( boolean expand )
452 	{
453 		return expand ? targetProperty.expand() : getTarget();
454 	}
455 }