View Javadoc

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