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.testcase;
14  
15  import java.io.File;
16  import java.io.IOException;
17  import java.util.ArrayList;
18  import java.util.HashMap;
19  import java.util.HashSet;
20  import java.util.List;
21  import java.util.Map;
22  import java.util.Set;
23  
24  import org.apache.log4j.Logger;
25  
26  import com.eviware.soapui.SoapUI;
27  import com.eviware.soapui.config.LoadTestConfig;
28  import com.eviware.soapui.config.TestCaseConfig;
29  import com.eviware.soapui.config.TestStepConfig;
30  import com.eviware.soapui.config.WsrmVersionTypeConfig;
31  import com.eviware.soapui.impl.wsdl.AbstractTestPropertyHolderWsdlModelItem;
32  import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
33  import com.eviware.soapui.impl.wsdl.loadtest.LoadTestAssertion;
34  import com.eviware.soapui.impl.wsdl.loadtest.WsdlLoadTest;
35  import com.eviware.soapui.impl.wsdl.loadtest.assertions.TestStepStatusAssertion;
36  import com.eviware.soapui.impl.wsdl.panels.teststeps.amf.AMFTestRunListener;
37  import com.eviware.soapui.impl.wsdl.support.wsrm.WsrmTestRunListener;
38  import com.eviware.soapui.impl.wsdl.support.wsrm.WsrmUtils;
39  import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStep;
40  import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestStepFactory;
41  import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestStepRegistry;
42  import com.eviware.soapui.model.ModelItem;
43  import com.eviware.soapui.model.support.ModelSupport;
44  import com.eviware.soapui.model.testsuite.LoadTest;
45  import com.eviware.soapui.model.testsuite.TestCase;
46  import com.eviware.soapui.model.testsuite.TestCaseRunContext;
47  import com.eviware.soapui.model.testsuite.TestCaseRunner;
48  import com.eviware.soapui.model.testsuite.TestRunListener;
49  import com.eviware.soapui.model.testsuite.TestStep;
50  import com.eviware.soapui.support.StringUtils;
51  import com.eviware.soapui.support.UISupport;
52  import com.eviware.soapui.support.action.swing.ActionList;
53  import com.eviware.soapui.support.action.swing.DefaultActionList;
54  import com.eviware.soapui.support.resolver.ResolveDialog;
55  import com.eviware.soapui.support.scripting.SoapUIScriptEngine;
56  import com.eviware.soapui.support.scripting.SoapUIScriptEngineRegistry;
57  import com.eviware.soapui.support.types.StringToObjectMap;
58  
59  /***
60   * TestCase implementation for WSDL projects
61   * 
62   * @author Ole.Matzura
63   */
64  
65  public class WsdlTestCase extends AbstractTestPropertyHolderWsdlModelItem<TestCaseConfig> implements TestCase
66  {
67  	private final static Logger logger = Logger.getLogger( WsdlTestCase.class );
68  	public final static String KEEP_SESSION_PROPERTY = WsdlTestCase.class.getName() + "@keepSession";
69  	public final static String FAIL_ON_ERROR_PROPERTY = WsdlTestCase.class.getName() + "@failOnError";
70  	public final static String FAIL_ON_ERRORS_PROPERTY = WsdlTestCase.class.getName() + "@failOnErrors";
71  	public final static String DISCARD_OK_RESULTS = WsdlTestCase.class.getName() + "@discardOkResults";
72  	public final static String SETUP_SCRIPT_PROPERTY = WsdlTestCase.class.getName() + "@setupScript";
73  	public final static String TEARDOWN_SCRIPT_PROPERTY = WsdlTestCase.class.getName() + "@tearDownScript";
74  	public static final String TIMEOUT_PROPERTY = WsdlTestCase.class.getName() + "@timeout";
75  	public static final String SEARCH_PROPERTIES_PROPERTY = WsdlTestCase.class.getName() + "@searchProperties";
76  
77  	private final WsdlTestSuite testSuite;
78  	private List<WsdlTestStep> testSteps = new ArrayList<WsdlTestStep>();
79  	private List<WsdlLoadTest> loadTests = new ArrayList<WsdlLoadTest>();
80  	private Set<TestRunListener> testRunListeners = new HashSet<TestRunListener>();
81  	private DefaultActionList createActions;
82  	private final boolean forLoadTest;
83  	private SoapUIScriptEngine setupScriptEngine;
84  	private SoapUIScriptEngine tearDownScriptEngine;
85  
86  	public WsdlTestCase( WsdlTestSuite testSuite, TestCaseConfig config, boolean forLoadTest )
87  	{
88  		super( config, testSuite, "/testCase.gif" );
89  
90  		this.testSuite = testSuite;
91  		this.forLoadTest = forLoadTest;
92  
93  		List<TestStepConfig> testStepConfigs = config.getTestStepList();
94  		List<TestStepConfig> removed = new ArrayList<TestStepConfig>();
95  		for( TestStepConfig tsc : testStepConfigs )
96  		{
97  			WsdlTestStep testStep = createTestStepFromConfig( tsc );
98  			if( testStep != null )
99  			{
100 				ensureUniqueName( testStep );
101 				testSteps.add( testStep );
102 			}
103 			else
104 				removed.add( tsc );
105 		}
106 
107 		// if( removed.size() > 0 )
108 		// {
109 		// testStepConfigs.removeAll( removed );
110 		// config.setTestStepArray( testStepConfigs.toArray( new TestStepConfig[]
111 		// {} ) );
112 		// }
113 
114 		if( !forLoadTest )
115 		{
116 			List<LoadTestConfig> loadTestConfigs = config.getLoadTestList();
117 			for( LoadTestConfig tsc : loadTestConfigs )
118 			{
119 				WsdlLoadTest loadTest = buildLoadTest( tsc );
120 				loadTests.add( loadTest );
121 			}
122 		}
123 
124 		// init default configs
125 		if( !config.isSetFailOnError() )
126 			config.setFailOnError( true );
127 
128 		if( !config.isSetFailTestCaseOnErrors() )
129 			config.setFailTestCaseOnErrors( true );
130 
131 		if( !config.isSetKeepSession() )
132 			config.setKeepSession( false );
133 
134 		if( !config.isSetMaxResults() )
135 			config.setMaxResults( 0 );
136 
137 		for( TestRunListener listener : SoapUI.getListenerRegistry().getListeners( TestRunListener.class ) )
138 		{
139 			addTestRunListener( listener );
140 		}
141 
142 		if( !getConfig().isSetProperties() )
143 			getConfig().addNewProperties();
144 
145 		setPropertiesConfig( getConfig().getProperties() );
146 
147 		WsrmTestRunListener wsrmListener = new WsrmTestRunListener();
148 
149 		addTestRunListener( wsrmListener );
150 		addTestRunListener( new AMFTestRunListener() );
151 	}
152 
153 	public WsdlLoadTest buildLoadTest( LoadTestConfig tsc )
154 	{
155 		return new WsdlLoadTest( this, tsc );
156 	}
157 
158 	public boolean getKeepSession()
159 	{
160 		return getConfig().getKeepSession();
161 	}
162 
163 	public void setKeepSession( boolean keepSession )
164 	{
165 		boolean old = getKeepSession();
166 		if( old != keepSession )
167 		{
168 			getConfig().setKeepSession( keepSession );
169 			notifyPropertyChanged( KEEP_SESSION_PROPERTY, old, keepSession );
170 		}
171 	}
172 
173 	public void setSetupScript( String script )
174 	{
175 		String oldScript = getSetupScript();
176 
177 		if( !getConfig().isSetSetupScript() )
178 			getConfig().addNewSetupScript();
179 
180 		getConfig().getSetupScript().setStringValue( script );
181 		if( setupScriptEngine != null )
182 			setupScriptEngine.setScript( script );
183 
184 		notifyPropertyChanged( SETUP_SCRIPT_PROPERTY, oldScript, script );
185 	}
186 
187 	public String getSetupScript()
188 	{
189 		return getConfig().isSetSetupScript() ? getConfig().getSetupScript().getStringValue() : null;
190 	}
191 
192 	public void setTearDownScript( String script )
193 	{
194 		String oldScript = getTearDownScript();
195 
196 		if( !getConfig().isSetTearDownScript() )
197 			getConfig().addNewTearDownScript();
198 
199 		getConfig().getTearDownScript().setStringValue( script );
200 		if( tearDownScriptEngine != null )
201 			tearDownScriptEngine.setScript( script );
202 
203 		notifyPropertyChanged( TEARDOWN_SCRIPT_PROPERTY, oldScript, script );
204 	}
205 
206 	public String getTearDownScript()
207 	{
208 		return getConfig().isSetTearDownScript() ? getConfig().getTearDownScript().getStringValue() : null;
209 	}
210 
211 	public boolean getFailOnError()
212 	{
213 		return getConfig().getFailOnError();
214 	}
215 
216 	public boolean getFailTestCaseOnErrors()
217 	{
218 		return getConfig().getFailTestCaseOnErrors();
219 	}
220 
221 	public void setFailOnError( boolean failOnError )
222 	{
223 		boolean old = getFailOnError();
224 		if( old != failOnError )
225 		{
226 			getConfig().setFailOnError( failOnError );
227 			notifyPropertyChanged( FAIL_ON_ERROR_PROPERTY, old, failOnError );
228 		}
229 	}
230 
231 	public void setFailTestCaseOnErrors( boolean failTestCaseOnErrors )
232 	{
233 		boolean old = getFailTestCaseOnErrors();
234 		if( old != failTestCaseOnErrors )
235 		{
236 			getConfig().setFailTestCaseOnErrors( failTestCaseOnErrors );
237 			notifyPropertyChanged( FAIL_ON_ERRORS_PROPERTY, old, failTestCaseOnErrors );
238 		}
239 	}
240 
241 	public boolean getSearchProperties()
242 	{
243 		return getConfig().getSearchProperties();
244 	}
245 
246 	public void setSearchProperties( boolean searchProperties )
247 	{
248 		boolean old = getSearchProperties();
249 		if( old != searchProperties )
250 		{
251 			getConfig().setSearchProperties( searchProperties );
252 			notifyPropertyChanged( SEARCH_PROPERTIES_PROPERTY, old, searchProperties );
253 		}
254 	}
255 
256 	public boolean getDiscardOkResults()
257 	{
258 		return getConfig().getDiscardOkResults();
259 	}
260 
261 	public void setDiscardOkResults( boolean discardOkResults )
262 	{
263 		boolean old = getDiscardOkResults();
264 		if( old != discardOkResults )
265 		{
266 			getConfig().setDiscardOkResults( discardOkResults );
267 			notifyPropertyChanged( DISCARD_OK_RESULTS, old, discardOkResults );
268 		}
269 	}
270 
271 	public int getMaxResults()
272 	{
273 		return getConfig().getMaxResults();
274 	}
275 
276 	public void setMaxResults( int maxResults )
277 	{
278 		int old = getMaxResults();
279 		if( old != maxResults )
280 		{
281 			getConfig().setMaxResults( maxResults );
282 			notifyPropertyChanged( "maxResults", old, maxResults );
283 		}
284 	}
285 
286 	private WsdlTestStep createTestStepFromConfig( TestStepConfig tsc )
287 	{
288 		WsdlTestStepFactory factory = WsdlTestStepRegistry.getInstance().getFactory( tsc.getType() );
289 		if( factory != null )
290 		{
291 			WsdlTestStep testStep = factory.buildTestStep( this, tsc, forLoadTest );
292 			return testStep;
293 		}
294 		else
295 		{
296 			logger.error( "Failed to create test step for [" + tsc.getName() + "]" );
297 			return null;
298 		}
299 	}
300 
301 	private boolean ensureUniqueName( WsdlTestStep testStep )
302 	{
303 		String name = testStep.getName();
304 		while( name == null || getTestStepByName( name ) != null )
305 		{
306 			if( name == null )
307 				name = testStep.getName();
308 			else
309 			{
310 				int cnt = 0;
311 
312 				while( getTestStepByName( name ) != null )
313 				{
314 					cnt++ ;
315 					name = testStep.getName() + " " + cnt;
316 				}
317 
318 				if( cnt == 0 )
319 					break;
320 			}
321 
322 			name = UISupport.prompt( "TestStep name must be unique, please specify new name for step\n" + "["
323 					+ testStep.getName() + "] in TestCase [" + getTestSuite().getProject().getName() + "->"
324 					+ getTestSuite().getName() + "->" + getName() + "]", "Change TestStep name", name );
325 
326 			if( name == null )
327 				return false;
328 		}
329 
330 		if( !name.equals( testStep.getName() ) )
331 			testStep.setName( name );
332 
333 		return true;
334 	}
335 
336 	public WsdlLoadTest addNewLoadTest( String name )
337 	{
338 		WsdlLoadTest loadTest = buildLoadTest( getConfig().addNewLoadTest() );
339 		loadTest.setStartDelay( 0 );
340 		loadTest.setName( name );
341 		loadTests.add( loadTest );
342 
343 		loadTest.addAssertion( TestStepStatusAssertion.STEP_STATUS_TYPE, LoadTestAssertion.ANY_TEST_STEP, false );
344 
345 		( getTestSuite() ).fireLoadTestAdded( loadTest );
346 
347 		return loadTest;
348 	}
349 
350 	public void removeLoadTest( WsdlLoadTest loadTest )
351 	{
352 		int ix = loadTests.indexOf( loadTest );
353 
354 		loadTests.remove( ix );
355 
356 		try
357 		{
358 			( getTestSuite() ).fireLoadTestRemoved( loadTest );
359 		}
360 		finally
361 		{
362 			loadTest.release();
363 			getConfig().removeLoadTest( ix );
364 		}
365 	}
366 
367 	public WsdlTestSuite getTestSuite()
368 	{
369 		return testSuite;
370 	}
371 
372 	public WsdlTestStep cloneStep( WsdlTestStep testStep, String name )
373 	{
374 		return testStep.clone( this, name );
375 	}
376 
377 	public WsdlTestStep getTestStepAt( int index )
378 	{
379 		return testSteps.get( index );
380 	}
381 
382 	public int getTestStepCount()
383 	{
384 		return testSteps.size();
385 	}
386 
387 	public WsdlLoadTest getLoadTestAt( int index )
388 	{
389 		return loadTests.get( index );
390 	}
391 
392 	public LoadTest getLoadTestByName( String loadTestName )
393 	{
394 		return ( LoadTest )getWsdlModelItemByName( loadTests, loadTestName );
395 	}
396 
397 	public int getLoadTestCount()
398 	{
399 		return loadTests.size();
400 	}
401 
402 	public WsdlTestStep addTestStep( TestStepConfig stepConfig )
403 	{
404 		return insertTestStep( stepConfig, -1, true );
405 	}
406 
407 	public WsdlTestStep addTestStep( String type, String name )
408 	{
409 		TestStepConfig newStepConfig = WsdlTestStepRegistry.getInstance().getFactory( type ).createNewTestStep( this,
410 				name );
411 		if( newStepConfig != null )
412 		{
413 			return addTestStep( newStepConfig );
414 		}
415 		else
416 			return null;
417 	}
418 
419 	public WsdlTestStep insertTestStep( String type, String name, int index )
420 	{
421 		TestStepConfig newStepConfig = WsdlTestStepRegistry.getInstance().getFactory( type ).createNewTestStep( this,
422 				name );
423 		if( newStepConfig != null )
424 		{
425 			return insertTestStep( newStepConfig, index, false );
426 		}
427 		else
428 			return null;
429 	}
430 
431 	public WsdlTestStep importTestStep( WsdlTestStep testStep, String name, int index, boolean createCopy )
432 	{
433 		testStep.beforeSave();
434 		TestStepConfig newStepConfig = ( TestStepConfig )testStep.getConfig().copy();
435 		newStepConfig.setName( name );
436 
437 		WsdlTestStep result = insertTestStep( newStepConfig, index, createCopy );
438 		if( result == null )
439 			return null;
440 
441 		if( createCopy )
442 			ModelSupport.unsetIds( result );
443 
444 		resolveTestCase();
445 		return result;
446 	}
447 
448 	private void resolveTestCase()
449 	{
450 		ResolveDialog resolver = new ResolveDialog( "Validate TestCase", "Checks TestCase for inconsistencies", null );
451 		resolver.setShowOkMessage( false );
452 		resolver.resolve( this );
453 	}
454 
455 	public WsdlTestStep[] importTestSteps( WsdlTestStep[] testSteps, int index, boolean createCopies )
456 	{
457 		TestStepConfig[] newStepConfigs = new TestStepConfig[testSteps.length];
458 
459 		for( int c = 0; c < testSteps.length; c++ )
460 		{
461 			testSteps[c].beforeSave();
462 			newStepConfigs[c] = ( TestStepConfig )testSteps[c].getConfig().copy();
463 		}
464 
465 		WsdlTestStep[] result = insertTestSteps( newStepConfigs, index, createCopies );
466 
467 		resolveTestCase();
468 		return result;
469 	}
470 
471 	public WsdlTestStep insertTestStep( TestStepConfig stepConfig, int ix )
472 	{
473 		return insertTestStep( stepConfig, ix, true );
474 	}
475 
476 	public WsdlTestStep insertTestStep( TestStepConfig stepConfig, int ix, boolean clearIds )
477 	{
478 		TestStepConfig newStepConfig = ix == -1 ? getConfig().addNewTestStep() : getConfig().insertNewTestStep( ix );
479 		newStepConfig.set( stepConfig );
480 		WsdlTestStep testStep = createTestStepFromConfig( newStepConfig );
481 
482 		if( !ensureUniqueName( testStep ) )
483 		{
484 			testStep.release();
485 			getConfig().getTestStepList().remove( newStepConfig );
486 			return null;
487 		}
488 
489 		if( clearIds )
490 			ModelSupport.unsetIds( testStep );
491 
492 		if( ix == -1 )
493 			testSteps.add( testStep );
494 		else
495 			testSteps.add( ix, testStep );
496 
497 		testStep.afterLoad();
498 
499 		if( getTestSuite() != null )
500 			( getTestSuite() ).fireTestStepAdded( testStep, ix == -1 ? testSteps.size() - 1 : ix );
501 
502 		notifyPropertyChanged( "testSteps", null, testStep );
503 
504 		return testStep;
505 	}
506 
507 	public WsdlTestStep[] insertTestSteps( TestStepConfig[] stepConfig, int ix, boolean clearIds )
508 	{
509 		WsdlTestStep[] result = new WsdlTestStep[stepConfig.length];
510 
511 		for( int c = 0; c < stepConfig.length; c++ )
512 		{
513 			TestStepConfig newStepConfig = ix == -1 ? getConfig().addNewTestStep() : getConfig()
514 					.insertNewTestStep( ix + c );
515 			newStepConfig.set( stepConfig[c] );
516 			WsdlTestStep testStep = createTestStepFromConfig( newStepConfig );
517 
518 			if( !ensureUniqueName( testStep ) )
519 				return null;
520 
521 			if( clearIds )
522 				ModelSupport.unsetIds( testStep );
523 
524 			if( ix == -1 )
525 				testSteps.add( testStep );
526 			else
527 				testSteps.add( ix + c, testStep );
528 
529 			result[c] = testStep;
530 		}
531 
532 		for( int c = 0; c < result.length; c++ )
533 		{
534 			result[c].afterLoad();
535 
536 			if( getTestSuite() != null )
537 				( getTestSuite() ).fireTestStepAdded( result[c], getIndexOfTestStep( result[c] ) );
538 
539 			notifyPropertyChanged( "testSteps", null, result[c] );
540 		}
541 
542 		return result;
543 	}
544 
545 	public void removeTestStep( WsdlTestStep testStep )
546 	{
547 		int ix = testSteps.indexOf( testStep );
548 		if( ix == -1 )
549 		{
550 			logger.error( "TestStep [" + testStep.getName() + "] passed to removeTestStep in testCase [" + getName()
551 					+ "] not found" );
552 			return;
553 		}
554 
555 		testSteps.remove( ix );
556 
557 		try
558 		{
559 			( getTestSuite() ).fireTestStepRemoved( testStep, ix );
560 		}
561 		finally
562 		{
563 			notifyPropertyChanged( "testSteps", testStep, null );
564 
565 			testStep.release();
566 
567 			for( int c = 0; c < getConfig().sizeOfTestStepArray(); c++ )
568 			{
569 				if( testStep.getConfig() == getConfig().getTestStepArray( c ) )
570 				{
571 					getConfig().removeTestStep( c );
572 					break;
573 				}
574 			}
575 		}
576 	}
577 
578 	public WsdlTestCaseRunner run( StringToObjectMap properties, boolean async )
579 	{
580 		WsdlTestCaseRunner runner = new WsdlTestCaseRunner( this, properties );
581 		runner.start( async );
582 		return runner;
583 	}
584 
585 	public void addTestRunListener( TestRunListener listener )
586 	{
587 		if( listener == null )
588 			throw new RuntimeException( "listener must not be null" );
589 
590 		testRunListeners.add( listener );
591 	}
592 
593 	public void removeTestRunListener( TestRunListener listener )
594 	{
595 		testRunListeners.remove( listener );
596 	}
597 
598 	public TestRunListener[] getTestRunListeners()
599 	{
600 		return testRunListeners.toArray( new TestRunListener[testRunListeners.size()] );
601 	}
602 
603 	public Map<String, TestStep> getTestSteps()
604 	{
605 		Map<String, TestStep> result = new HashMap<String, TestStep>();
606 		for( TestStep testStep : testSteps )
607 			result.put( testStep.getName(), testStep );
608 
609 		return result;
610 	}
611 
612 	public Map<String, LoadTest> getLoadTests()
613 	{
614 		Map<String, LoadTest> result = new HashMap<String, LoadTest>();
615 		for( LoadTest loadTest : loadTests )
616 			result.put( loadTest.getName(), loadTest );
617 
618 		return result;
619 	}
620 
621 	public int getIndexOfTestStep( TestStep step )
622 	{
623 		return testSteps.indexOf( step );
624 	}
625 
626 	/***
627 	 * Moves a step by the specified offset, a bit awkward since xmlbeans doesn't
628 	 * support reordering of arrays, we need to create copies of the contained
629 	 * XmlObjects
630 	 * 
631 	 * @param ix
632 	 * @param offset
633 	 */
634 
635 	public void moveTestStep( int ix, int offset )
636 	{
637 		if( offset == 0 )
638 			return;
639 		WsdlTestStep step = testSteps.get( ix );
640 
641 		if( ix + offset >= testSteps.size() )
642 			offset = testSteps.size() - ix - 1;
643 
644 		testSteps.remove( ix );
645 		testSteps.add( ix + offset, step );
646 
647 		TestStepConfig[] configs = new TestStepConfig[testSteps.size()];
648 
649 		TestCaseConfig conf = getConfig();
650 		for( int c = 0; c < testSteps.size(); c++ )
651 		{
652 			if( offset > 0 )
653 			{
654 				if( c < ix )
655 					configs[c] = ( TestStepConfig )conf.getTestStepArray( c ).copy();
656 				else if( c < ( ix + offset ) )
657 					configs[c] = ( TestStepConfig )conf.getTestStepArray( c + 1 ).copy();
658 				else if( c == ix + offset )
659 					configs[c] = ( TestStepConfig )conf.getTestStepArray( ix ).copy();
660 				else
661 					configs[c] = ( TestStepConfig )conf.getTestStepArray( c ).copy();
662 			}
663 			else
664 			{
665 				if( c < ix + offset )
666 					configs[c] = ( TestStepConfig )conf.getTestStepArray( c ).copy();
667 				else if( c == ix + offset )
668 					configs[c] = ( TestStepConfig )conf.getTestStepArray( ix ).copy();
669 				else if( c <= ix )
670 					configs[c] = ( TestStepConfig )conf.getTestStepArray( c - 1 ).copy();
671 				else
672 					configs[c] = ( TestStepConfig )conf.getTestStepArray( c ).copy();
673 			}
674 		}
675 
676 		conf.setTestStepArray( configs );
677 		for( int c = 0; c < configs.length; c++ )
678 		{
679 			( testSteps.get( c ) ).resetConfigOnMove( conf.getTestStepArray( c ) );
680 		}
681 
682 		( getTestSuite() ).fireTestStepMoved( step, ix, offset );
683 	}
684 
685 	public int getIndexOfLoadTest( LoadTest loadTest )
686 	{
687 		return loadTests.indexOf( loadTest );
688 	}
689 
690 	public int getTestStepIndexByName( String stepName )
691 	{
692 		for( int c = 0; c < testSteps.size(); c++ )
693 		{
694 			if( testSteps.get( c ).getName().equals( stepName ) )
695 				return c;
696 		}
697 
698 		return -1;
699 	}
700 
701 	@SuppressWarnings( "unchecked" )
702 	public <T extends TestStep> T findPreviousStepOfType( TestStep referenceStep, Class<T> stepClass )
703 	{
704 		int currentStepIndex = getIndexOfTestStep( referenceStep );
705 		int ix = currentStepIndex - 1;
706 		while( ix >= 0 && !stepClass.isAssignableFrom( getTestStepAt( ix ).getClass() ) )
707 		{
708 			ix-- ;
709 		}
710 
711 		return ( T )( ix < 0 ? null : getTestStepAt( ix ) );
712 	}
713 
714 	@SuppressWarnings( "unchecked" )
715 	public <T extends TestStep> T findNextStepOfType( TestStep referenceStep, Class<T> stepClass )
716 	{
717 		int currentStepIndex = getIndexOfTestStep( referenceStep );
718 		int ix = currentStepIndex + 1;
719 		while( ix < getTestStepCount() && !stepClass.isAssignableFrom( getTestStepAt( ix ).getClass() ) )
720 		{
721 			ix++ ;
722 		}
723 
724 		return ( T )( ix >= getTestStepCount() ? null : getTestStepAt( ix ) );
725 	}
726 
727 	public List<TestStep> getTestStepList()
728 	{
729 		List<TestStep> result = new ArrayList<TestStep>();
730 		for( TestStep step : testSteps )
731 			result.add( step );
732 
733 		return result;
734 	}
735 
736 	@SuppressWarnings( "unchecked" )
737 	public <T extends TestStep> List<T> getTestStepsOfType( Class<T> stepType )
738 	{
739 		List<T> result = new ArrayList<T>();
740 		for( TestStep step : testSteps )
741 			if( step.getClass().isAssignableFrom( stepType ) )
742 				result.add( ( T )step );
743 
744 		return result;
745 	}
746 
747 	public WsdlTestStep getTestStepByName( String stepName )
748 	{
749 		return ( WsdlTestStep )getWsdlModelItemByName( testSteps, stepName );
750 	}
751 
752 	public WsdlLoadTest cloneLoadTest( WsdlLoadTest loadTest, String name )
753 	{
754 		loadTest.beforeSave();
755 
756 		LoadTestConfig loadTestConfig = getConfig().addNewLoadTest();
757 		loadTestConfig.set( loadTest.getConfig().copy() );
758 
759 		WsdlLoadTest newLoadTest = buildLoadTest( loadTestConfig );
760 		newLoadTest.setName( name );
761 		ModelSupport.unsetIds( newLoadTest );
762 		newLoadTest.afterLoad();
763 		loadTests.add( newLoadTest );
764 
765 		( getTestSuite() ).fireLoadTestAdded( newLoadTest );
766 
767 		return newLoadTest;
768 	}
769 
770 	@Override
771 	public void release()
772 	{
773 		super.release();
774 
775 		for( WsdlTestStep testStep : testSteps )
776 			testStep.release();
777 
778 		for( WsdlLoadTest loadTest : loadTests )
779 			loadTest.release();
780 
781 		testRunListeners.clear();
782 
783 		if( setupScriptEngine != null )
784 			setupScriptEngine.release();
785 
786 		if( tearDownScriptEngine != null )
787 			tearDownScriptEngine.release();
788 	}
789 
790 	public ActionList getCreateActions()
791 	{
792 		return createActions;
793 	}
794 
795 	public void resetConfigOnMove( TestCaseConfig testCaseConfig )
796 	{
797 		setConfig( testCaseConfig );
798 		int mod = 0;
799 
800 		List<TestStepConfig> configs = getConfig().getTestStepList();
801 		for( int c = 0; c < configs.size(); c++ )
802 		{
803 			if( WsdlTestStepRegistry.getInstance().hasFactory( configs.get( c ) ) )
804 			{
805 				( testSteps.get( c - mod ) ).resetConfigOnMove( configs.get( c ) );
806 			}
807 			else
808 				mod++ ;
809 		}
810 
811 		List<LoadTestConfig> loadTestConfigs = getConfig().getLoadTestList();
812 		for( int c = 0; c < loadTestConfigs.size(); c++ )
813 		{
814 			loadTests.get( c ).resetConfigOnMove( loadTestConfigs.get( c ) );
815 		}
816 
817 		setPropertiesConfig( testCaseConfig.getProperties() );
818 	}
819 
820 	public List<LoadTest> getLoadTestList()
821 	{
822 		List<LoadTest> result = new ArrayList<LoadTest>();
823 		for( LoadTest loadTest : loadTests )
824 			result.add( loadTest );
825 
826 		return result;
827 	}
828 
829 	public Object runSetupScript( TestCaseRunContext runContext, TestCaseRunner runner ) throws Exception
830 	{
831 		String script = getSetupScript();
832 		if( StringUtils.isNullOrEmpty( script ) )
833 			return null;
834 
835 		if( setupScriptEngine == null )
836 		{
837 			setupScriptEngine = SoapUIScriptEngineRegistry.create( this );
838 			setupScriptEngine.setScript( script );
839 		}
840 
841 		setupScriptEngine.setVariable( "testCase", this );
842 		setupScriptEngine.setVariable( "context", runContext );
843 		setupScriptEngine.setVariable( "testRunner", runner );
844 		setupScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
845 		return setupScriptEngine.run();
846 	}
847 
848 	public Object runTearDownScript( TestCaseRunContext runContext, TestCaseRunner runner ) throws Exception
849 	{
850 		String script = getTearDownScript();
851 		if( StringUtils.isNullOrEmpty( script ) )
852 			return null;
853 
854 		if( tearDownScriptEngine == null )
855 		{
856 			tearDownScriptEngine = SoapUIScriptEngineRegistry.create( this );
857 			tearDownScriptEngine.setScript( script );
858 		}
859 
860 		tearDownScriptEngine.setVariable( "context", runContext );
861 		tearDownScriptEngine.setVariable( "testCase", this );
862 		tearDownScriptEngine.setVariable( "testRunner", runner );
863 		tearDownScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
864 		return tearDownScriptEngine.run();
865 	}
866 
867 	public List<? extends ModelItem> getChildren()
868 	{
869 		List<ModelItem> result = new ArrayList<ModelItem>();
870 		result.addAll( getTestStepList() );
871 		result.addAll( getLoadTestList() );
872 		return result;
873 	}
874 
875 	@Override
876 	public void setName( String name )
877 	{
878 		String oldLabel = getLabel();
879 
880 		super.setName( name );
881 
882 		String label = getLabel();
883 		if( oldLabel != null && !oldLabel.equals( label ) )
884 		{
885 			notifyPropertyChanged( LABEL_PROPERTY, oldLabel, label );
886 		}
887 	}
888 
889 	public String getLabel()
890 	{
891 		String name = getName();
892 		if( isDisabled() )
893 			return name + " (disabled)";
894 		else
895 			return name;
896 	}
897 
898 	public boolean isDisabled()
899 	{
900 		return getConfig().getDisabled();
901 	}
902 
903 	public void setDisabled( boolean disabled )
904 	{
905 		String oldLabel = getLabel();
906 
907 		boolean oldDisabled = isDisabled();
908 		if( oldDisabled == disabled )
909 			return;
910 
911 		if( disabled )
912 			getConfig().setDisabled( disabled );
913 		else if( getConfig().isSetDisabled() )
914 			getConfig().unsetDisabled();
915 
916 		notifyPropertyChanged( DISABLED_PROPERTY, oldDisabled, disabled );
917 
918 		String label = getLabel();
919 		if( !oldLabel.equals( label ) )
920 			notifyPropertyChanged( LABEL_PROPERTY, oldLabel, label );
921 	}
922 
923 	public long getTimeout()
924 	{
925 		return getConfig().getTimeout();
926 	}
927 
928 	public void setTimeout( long timeout )
929 	{
930 		long old = getTimeout();
931 		getConfig().setTimeout( timeout );
932 		notifyPropertyChanged( TIMEOUT_PROPERTY, old, timeout );
933 	}
934 
935 	public void exportTestCase( File file )
936 	{
937 		try
938 		{
939 			this.getConfig().newCursor().save( file );
940 		}
941 		catch( IOException e )
942 		{
943 			e.printStackTrace();
944 		}
945 	}
946 
947 	public void afterCopy( WsdlTestSuite oldTestSuite, WsdlTestCase oldTestCase )
948 	{
949 		for( WsdlTestStep testStep : testSteps )
950 			testStep.afterCopy( oldTestSuite, oldTestCase );
951 	}
952 
953 	public void setWsrmEnabled( boolean enabled )
954 	{
955 		getConfig().setWsrmEnabled( enabled );
956 	}
957 
958 	public void setWsrmAckTo( String ackTo )
959 	{
960 		getConfig().setWsrmAckTo( ackTo );
961 	}
962 
963 	public void setWsrmExpires( Long expires )
964 	{
965 		getConfig().setWsrmExpires( expires );
966 	}
967 
968 	public void setWsrmVersion( String version )
969 	{
970 		getConfig().setWsrmVersion( WsrmVersionTypeConfig.Enum.forString( version ) );
971 	}
972 
973 	public boolean getWsrmEnabled()
974 	{
975 		return getConfig().getWsrmEnabled();
976 	}
977 
978 	public String getWsrmAckTo()
979 	{
980 		return getConfig().getWsrmAckTo();
981 	}
982 
983 	public long getWsrmExpires()
984 	{
985 		return getConfig().getWsrmExpires();
986 	}
987 
988 	public String getWsrmVersion()
989 	{
990 		if( getConfig().getWsrmVersion() == null )
991 			return WsrmVersionTypeConfig.X_1_0.toString();
992 		return getConfig().getWsrmVersion().toString();
993 	}
994 
995 	public String getWsrmVersionNamespace()
996 	{
997 		return WsrmUtils.getWsrmVersionNamespace( getConfig().getWsrmVersion() );
998 	}
999 
1000 	public void setAmfAuthorisation( boolean enabled )
1001 	{
1002 		getConfig().setAmfAuthorisation( enabled );
1003 	}
1004 
1005 	public boolean getAmfAuthorisation()
1006 	{
1007 		return getConfig().getAmfAuthorisation();
1008 	}
1009 
1010 	public void setAmfLogin( String login )
1011 	{
1012 		getConfig().setAmfLogin( login );
1013 	}
1014 
1015 	public String getAmfLogin()
1016 	{
1017 		if( getConfig().getAmfLogin() == null )
1018 			return "";
1019 		else
1020 			return getConfig().getAmfLogin();
1021 	}
1022 
1023 	public void setAmfPassword( String password )
1024 	{
1025 		getConfig().setAmfPassword( password );
1026 	}
1027 
1028 	public String getAmfPassword()
1029 	{
1030 		if( getConfig().getAmfPassword() == null )
1031 			return "";
1032 		else
1033 			return getConfig().getAmfPassword();
1034 	}
1035 
1036 	public void setAmfEndpoint( String endpoint )
1037 	{
1038 		getConfig().setAmfEndpoint( endpoint );
1039 	}
1040 
1041 	public String getAmfEndpoint()
1042 	{
1043 		if( getConfig().getAmfEndpoint() == null )
1044 			return "";
1045 		else
1046 			return getConfig().getAmfEndpoint();
1047 	}
1048 
1049 }