View Javadoc

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