View Javadoc

1   /*
2    * soapUI, copyright (C) 2004-2009 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.beans.PropertyChangeEvent;
16  import java.beans.PropertyChangeListener;
17  import java.util.ArrayList;
18  import java.util.Collection;
19  import java.util.HashMap;
20  import java.util.List;
21  import java.util.Map;
22  
23  import javax.swing.ImageIcon;
24  
25  import org.apache.log4j.Logger;
26  
27  import com.eviware.soapui.SoapUI;
28  import com.eviware.soapui.config.MockOperationDispatchStyleConfig;
29  import com.eviware.soapui.config.MockResponseConfig;
30  import com.eviware.soapui.config.MockResponseStepConfig;
31  import com.eviware.soapui.config.MockServiceConfig;
32  import com.eviware.soapui.config.TestAssertionConfig;
33  import com.eviware.soapui.config.TestStepConfig;
34  import com.eviware.soapui.impl.wsdl.AbstractWsdlModelItem;
35  import com.eviware.soapui.impl.wsdl.WsdlInterface;
36  import com.eviware.soapui.impl.wsdl.WsdlOperation;
37  import com.eviware.soapui.impl.wsdl.WsdlProject;
38  import com.eviware.soapui.impl.wsdl.WsdlSubmitContext;
39  import com.eviware.soapui.impl.wsdl.mock.WsdlMockOperation;
40  import com.eviware.soapui.impl.wsdl.mock.WsdlMockResponse;
41  import com.eviware.soapui.impl.wsdl.mock.WsdlMockResult;
42  import com.eviware.soapui.impl.wsdl.mock.WsdlMockRunner;
43  import com.eviware.soapui.impl.wsdl.mock.dispatch.QueryMatchMockOperationDispatcher;
44  import com.eviware.soapui.impl.wsdl.panels.mockoperation.WsdlMockResultMessageExchange;
45  import com.eviware.soapui.impl.wsdl.support.ModelItemIconAnimator;
46  import com.eviware.soapui.impl.wsdl.support.assertions.AssertableConfig;
47  import com.eviware.soapui.impl.wsdl.support.assertions.AssertedXPathsContainer;
48  import com.eviware.soapui.impl.wsdl.support.assertions.AssertionsSupport;
49  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
50  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
51  import com.eviware.soapui.impl.wsdl.teststeps.assertions.TestAssertionRegistry;
52  import com.eviware.soapui.impl.wsdl.teststeps.assertions.TestAssertionRegistry.AssertableType;
53  import com.eviware.soapui.model.ModelItem;
54  import com.eviware.soapui.model.iface.Interface;
55  import com.eviware.soapui.model.iface.Operation;
56  import com.eviware.soapui.model.iface.SubmitContext;
57  import com.eviware.soapui.model.mock.MockResult;
58  import com.eviware.soapui.model.mock.MockRunner;
59  import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
60  import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
61  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContainer;
62  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
63  import com.eviware.soapui.model.support.DefaultTestStepProperty;
64  import com.eviware.soapui.model.support.InterfaceListenerAdapter;
65  import com.eviware.soapui.model.support.MockRunListenerAdapter;
66  import com.eviware.soapui.model.support.ModelSupport;
67  import com.eviware.soapui.model.support.ProjectListenerAdapter;
68  import com.eviware.soapui.model.support.TestRunListenerAdapter;
69  import com.eviware.soapui.model.support.TestStepBeanProperty;
70  import com.eviware.soapui.model.testsuite.Assertable;
71  import com.eviware.soapui.model.testsuite.AssertedXPath;
72  import com.eviware.soapui.model.testsuite.AssertionError;
73  import com.eviware.soapui.model.testsuite.AssertionsListener;
74  import com.eviware.soapui.model.testsuite.LoadTestRunner;
75  import com.eviware.soapui.model.testsuite.OperationTestStep;
76  import com.eviware.soapui.model.testsuite.RequestAssertedMessageExchange;
77  import com.eviware.soapui.model.testsuite.TestAssertion;
78  import com.eviware.soapui.model.testsuite.TestCaseRunContext;
79  import com.eviware.soapui.model.testsuite.TestCaseRunner;
80  import com.eviware.soapui.model.testsuite.TestStep;
81  import com.eviware.soapui.model.testsuite.TestStepResult;
82  import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus;
83  import com.eviware.soapui.support.StringUtils;
84  import com.eviware.soapui.support.resolver.ChangeOperationResolver;
85  import com.eviware.soapui.support.resolver.ImportInterfaceResolver;
86  import com.eviware.soapui.support.resolver.RemoveTestStepResolver;
87  import com.eviware.soapui.support.resolver.ResolveContext;
88  import com.eviware.soapui.support.resolver.ResolveContext.PathToResolve;
89  import com.eviware.soapui.support.types.StringToStringMap;
90  
91  public class WsdlMockResponseTestStep extends WsdlTestStepWithProperties implements OperationTestStep,
92  		PropertyChangeListener, Assertable, PropertyExpansionContainer
93  {
94  	private final static Logger log = Logger.getLogger( WsdlMockResponseTestStep.class );
95  
96  	public static final String STATUS_PROPERTY = WsdlMockResponseTestStep.class.getName() + "@status";
97  	public static final String TIMEOUT_PROPERTY = WsdlMockResponseTestStep.class.getName() + "@timeout";
98  
99  	private MockResponseStepConfig mockResponseStepConfig;
100 	private MockResponseConfig mockResponseConfig;
101 	private WsdlMockOperation mockOperation;
102 	private WsdlTestMockService mockService;
103 	private WsdlMockRunner mockRunner;
104 	private WsdlMockResponse mockResponse;
105 	private WsdlMockResult lastResult;
106 
107 	private AssertionsSupport assertionsSupport;
108 	private InternalMockRunListener mockRunListener;
109 	private StartStepMockRunListener startStepMockRunListener;
110 
111 	private final InternalProjectListener projectListener = new InternalProjectListener();
112 	private final InternalInterfaceListener interfaceListener = new InternalInterfaceListener();
113 	private final InternalTestRunListener testRunListener = new InternalTestRunListener();
114 	private WsdlInterface iface;
115 	private AssertionStatus oldStatus;
116 
117 	private ModelItemIconAnimator<WsdlMockResponseTestStep> iconAnimator;
118 	private WsdlMockResponse testMockResponse;
119 	private WsdlTestStep startTestStep;
120 
121 	public WsdlMockResponseTestStep( WsdlTestCase testCase, TestStepConfig config, boolean forLoadTest )
122 	{
123 		super( testCase, config, true, forLoadTest );
124 
125 		if( config.getConfig() != null )
126 		{
127 			mockResponseStepConfig = ( MockResponseStepConfig )config.getConfig().changeType( MockResponseStepConfig.type );
128 			mockResponseConfig = mockResponseStepConfig.getResponse();
129 		}
130 		else
131 		{
132 			mockResponseStepConfig = ( MockResponseStepConfig )config.addNewConfig().changeType(
133 					MockResponseStepConfig.type );
134 			mockResponseConfig = mockResponseStepConfig.addNewResponse();
135 		}
136 
137 		initAssertions();
138 		initMockObjects( testCase );
139 
140 		if( !forLoadTest )
141 		{
142 			if( iface != null )
143 			{
144 				iface.getProject().addProjectListener( projectListener );
145 				iface.addInterfaceListener( interfaceListener );
146 			}
147 
148 			iconAnimator = new ModelItemIconAnimator<WsdlMockResponseTestStep>( this, "/mockResponseStep.gif",
149 					"/exec_mockResponse", 4, "gif" );
150 		}
151 
152 		// init properties
153 		initProperties();
154 
155 		testCase.addTestRunListener( testRunListener );
156 		testCase.addPropertyChangeListener( this );
157 	}
158 
159 	@Override
160 	public void afterLoad()
161 	{
162 		super.afterLoad();
163 
164 		if( mockResponseStepConfig.isSetStartStep() )
165 		{
166 			startTestStep = getTestCase().getTestStepByName( mockResponseStepConfig.getStartStep() );
167 			if( startTestStep != null )
168 			{
169 				startTestStep.addPropertyChangeListener( this );
170 			}
171 		}
172 	}
173 
174 	private void initProperties()
175 	{
176 		if( mockResponse != null )
177 		{
178 			addProperty( new TestStepBeanProperty( "Response", false, mockResponse, "responseContent", this ) );
179 		}
180 
181 		addProperty( new DefaultTestStepProperty( "Request", true, new DefaultTestStepProperty.PropertyHandlerAdapter()
182 		{
183 			public String getValue( DefaultTestStepProperty property )
184 			{
185 				WsdlMockResult mockResult = mockResponse == null ? null : mockResponse.getMockResult();
186 				return mockResult == null ? null : mockResult.getMockRequest().getRequestContent();
187 			}
188 		}, this ) );
189 	}
190 
191 	@Override
192 	public ImageIcon getIcon()
193 	{
194 		return iconAnimator == null ? null : iconAnimator.getIcon();
195 	}
196 
197 	private void initAssertions()
198 	{
199 		assertionsSupport = new AssertionsSupport( this, new AssertableConfig()
200 		{
201 
202 			public TestAssertionConfig addNewAssertion()
203 			{
204 				return mockResponseStepConfig.addNewAssertion();
205 			}
206 
207 			public List<TestAssertionConfig> getAssertionList()
208 			{
209 				return mockResponseStepConfig.getAssertionList();
210 			}
211 
212 			public void removeAssertion( int ix )
213 			{
214 				mockResponseStepConfig.removeAssertion( ix );
215 			}
216 
217 			public TestAssertionConfig insertAssertion( TestAssertionConfig source, int ix )
218 			{
219 				TestAssertionConfig conf = mockResponseStepConfig.insertNewAssertion( ix );
220 				conf.set( source );
221 				return conf;
222 			}
223 		} );
224 	}
225 
226 	private void initMockObjects( WsdlTestCase testCase )
227 	{
228 		MockServiceConfig mockServiceConfig = MockServiceConfig.Factory.newInstance();
229 		mockServiceConfig.setPath( mockResponseStepConfig.getPath() );
230 		mockServiceConfig.setPort( mockResponseStepConfig.getPort() );
231 		mockServiceConfig.setHost( mockResponseStepConfig.getHost() );
232 
233 		mockService = new WsdlTestMockService( this, mockServiceConfig );
234 		mockService.setName( getName() );
235 
236 		iface = ( WsdlInterface )testCase.getTestSuite().getProject().getInterfaceByName(
237 				mockResponseStepConfig.getInterface() );
238 		if( iface == null )
239 		{
240 		}
241 		else
242 		{
243 			iface.addInterfaceListener( interfaceListener );
244 
245 			mockOperation = mockService.addNewMockOperation( iface.getOperationByName( mockResponseStepConfig
246 					.getOperation() ) );
247 
248 			if( mockResponseStepConfig.getHandleFault() )
249 				mockService.setFaultMockOperation( mockOperation );
250 
251 			if( mockResponseStepConfig.getHandleResponse() )
252 				mockService.setDispatchResponseMessages( true );
253 
254 			mockResponse = mockOperation.addNewMockResponse( "MockResponse", false );
255 			mockResponse.setConfig( mockResponseConfig );
256 
257 			mockOperation.setDefaultResponse( mockResponse.getName() );
258 
259 			mockResponse.addPropertyChangeListener( this );
260 			mockResponse.getWsaConfig().addPropertyChangeListener( this );
261 		}
262 	}
263 
264 	public void resetConfigOnMove( TestStepConfig config )
265 	{
266 		super.resetConfigOnMove( config );
267 
268 		mockResponseStepConfig = ( MockResponseStepConfig )config.getConfig().changeType( MockResponseStepConfig.type );
269 		mockResponseConfig = mockResponseStepConfig.getResponse();
270 		mockResponse.setConfig( mockResponseConfig );
271 		assertionsSupport.refresh();
272 	}
273 
274 	@Override
275 	public boolean cancel()
276 	{
277 		if( mockRunner != null )
278 		{
279 			mockRunner.stop();
280 			mockRunner = null;
281 		}
282 
283 		if( mockRunListener != null )
284 		{
285 			mockRunListener.cancel();
286 		}
287 
288 		return true;
289 	}
290 
291 	@Override
292 	public void prepare( TestCaseRunner testRunner, TestCaseRunContext testRunContext ) throws Exception
293 	{
294 		super.prepare( testRunner, testRunContext );
295 
296 		LoadTestRunner loadTestRunner = ( LoadTestRunner )testRunContext
297 				.getProperty( TestCaseRunContext.LOAD_TEST_RUNNER );
298 		mockRunListener = new InternalMockRunListener();
299 
300 		for( TestAssertion assertion : getAssertionList() )
301 		{
302 			assertion.prepare( testRunner, testRunContext );
303 		}
304 
305 		if( loadTestRunner == null )
306 		{
307 			mockService.addMockRunListener( mockRunListener );
308 			mockRunner = mockService.start( ( WsdlTestRunContext )testRunContext );
309 		}
310 		else
311 		{
312 			synchronized( STATUS_PROPERTY )
313 			{
314 				mockRunner = ( WsdlMockRunner )testRunContext.getProperty( "sharedMockServiceRunner" );
315 				if( mockRunner == null )
316 				{
317 					mockService.addMockRunListener( mockRunListener );
318 					mockRunner = mockService.start( ( WsdlTestRunContext )testRunContext );
319 				}
320 				else
321 				{
322 					mockRunner.getMockService().addMockRunListener( mockRunListener );
323 				}
324 			}
325 		}
326 
327 		if( startTestStep instanceof WsdlMockResponseTestStep )
328 		{
329 			System.out.println( "Adding StartStepMockRunListener from [" + getName() + "] to [" + startTestStep.getName()
330 					+ "]" );
331 			startStepMockRunListener = new StartStepMockRunListener( testRunContext,
332 					( WsdlMockResponseTestStep )startTestStep );
333 		}
334 	}
335 
336 	protected void initTestMockResponse( TestCaseRunContext testRunContext )
337 	{
338 		if( StringUtils.hasContent( getQuery() ) && StringUtils.hasContent( getMatch() ) )
339 		{
340 			String name = "MockResponse" + Math.random();
341 			testMockResponse = mockOperation.addNewMockResponse( name, false );
342 			testMockResponse.setConfig( ( MockResponseConfig )mockResponse.getConfig().copy() );
343 			testMockResponse.setName( name );
344 
345 			QueryMatchMockOperationDispatcher dispatcher = ( QueryMatchMockOperationDispatcher )mockOperation
346 					.setDispatchStyle( MockOperationDispatchStyleConfig.QUERY_MATCH.toString() );
347 
348 			for( QueryMatchMockOperationDispatcher.Query query : dispatcher.getQueries() )
349 				dispatcher.deleteQuery( query );
350 
351 			mockOperation.setDefaultResponse( null );
352 
353 			QueryMatchMockOperationDispatcher.Query query = dispatcher.addQuery( "Match" );
354 			query.setQuery( PropertyExpander.expandProperties( testRunContext, getQuery() ) );
355 			query.setMatch( PropertyExpander.expandProperties( testRunContext, getMatch() ) );
356 			query.setResponse( testMockResponse.getName() );
357 		}
358 		else
359 		{
360 			testMockResponse = mockResponse;
361 			testMockResponse.setMockResult( null );
362 		}
363 	}
364 
365 	public TestStepResult run( TestCaseRunner testRunner, TestCaseRunContext context )
366 	{
367 		LoadTestRunner loadTestRunner = ( LoadTestRunner )context.getProperty( TestCaseRunContext.LOAD_TEST_RUNNER );
368 		if( loadTestRunner == null )
369 		{
370 			return internalRun( ( WsdlTestRunContext )context );
371 		}
372 		else
373 		{
374 			// block other threads during loadtesting -> this should be improved!
375 			synchronized( STATUS_PROPERTY )
376 			{
377 				if( loadTestRunner.getStatus() == LoadTestRunner.Status.RUNNING )
378 				{
379 					return internalRun( ( WsdlTestRunContext )context );
380 				}
381 				else
382 				{
383 					WsdlSingleMessageExchangeTestStepResult result = new WsdlSingleMessageExchangeTestStepResult( this );
384 					result.setStatus( TestStepStatus.UNKNOWN );
385 					return result;
386 				}
387 			}
388 		}
389 	}
390 
391 	private TestStepResult internalRun( WsdlTestRunContext context )
392 	{
393 		iconAnimator.start();
394 		WsdlSingleMessageExchangeTestStepResult result = new WsdlSingleMessageExchangeTestStepResult( this );
395 
396 		try
397 		{
398 			this.lastResult = null;
399 			mockResponse.setMockResult( null );
400 			
401 			result.startTimer();
402 
403 			if( !mockRunListener.hasResult() )
404 			{
405 				if( testMockResponse == null )
406 					initTestMockResponse( context );
407 
408 				long timeout = getTimeout();
409 				synchronized( mockRunListener )
410 				{
411 					mockRunListener.waitForRequest( timeout );
412 				}
413 			}
414 
415 			result.stopTimer();
416 			if( mockRunner != null && mockRunner.isRunning() )
417 				mockRunner.stop();
418 
419 			AssertedWsdlMockResultMessageExchange messageExchange = new AssertedWsdlMockResultMessageExchange(
420 					mockRunListener.getLastResult() );
421 			result.setMessageExchange( messageExchange );
422 
423 			if( mockRunListener.getLastResult() != null )
424 			{
425 				lastResult = mockRunListener.getLastResult();
426 				mockResponse.setMockResult( lastResult );
427 
428 				context.setProperty( AssertedXPathsContainer.ASSERTEDXPATHSCONTAINER_PROPERTY, messageExchange );
429 				assertResult( lastResult, context );
430 			}
431 
432 			if( mockRunListener.getLastResult() == null )
433 			{
434 				if( mockRunListener.isCanceled() )
435 				{
436 					result.setStatus( TestStepStatus.CANCELED );
437 				}
438 				else
439 				{
440 					result.setStatus( TestStepStatus.FAILED );
441 					result.addMessage( "Timeout occured after " + getTimeout() + " milliseconds" );
442 				}
443 			}
444 			else
445 			{
446 				AssertionStatus status = getAssertionStatus();
447 				if( status == AssertionStatus.FAILED )
448 				{
449 					result.setStatus( TestStepStatus.FAILED );
450 
451 					if( getAssertionCount() == 0 )
452 					{
453 						result.addMessage( "Invalid/empty request" );
454 					}
455 					else
456 						for( int c = 0; c < getAssertionCount(); c++ )
457 						{
458 							WsdlMessageAssertion assertion = getAssertionAt( c );
459 							AssertionError[] errors = assertion.getErrors();
460 							if( errors != null )
461 							{
462 								for( AssertionError error : errors )
463 								{
464 									result.addMessage( "[" + assertion.getName() + "] " + error.getMessage() );
465 								}
466 							}
467 						}
468 				}
469 				else
470 				{
471 					result.setStatus( TestStepStatus.OK );
472 				}
473 
474 				mockRunListener.setLastResult( null );
475 			}
476 		}
477 		catch( Exception e )
478 		{
479 			result.stopTimer();
480 			result.setStatus( TestStepStatus.FAILED );
481 			result.setError( e );
482 			SoapUI.logError( e );
483 		}
484 		finally
485 		{
486 			iconAnimator.stop();
487 		}
488 
489 		return result;
490 	}
491 
492 	private void assertResult( WsdlMockResult result, SubmitContext context )
493 	{
494 		if( oldStatus == null )
495 			oldStatus = getAssertionStatus();
496 
497 		for( int c = 0; c < getAssertionCount(); c++ )
498 		{
499 			WsdlMessageAssertion assertion = getAssertionAt( c );
500 			if( !assertion.isDisabled() )
501 			{
502 				assertion.assertRequest( new WsdlMockResultMessageExchange( result, getMockResponse() ), context );
503 			}
504 		}
505 
506 		AssertionStatus newStatus = getAssertionStatus();
507 		if( newStatus != oldStatus )
508 		{
509 			notifyPropertyChanged( STATUS_PROPERTY, oldStatus, newStatus );
510 			oldStatus = newStatus;
511 		}
512 	}
513 
514 	@Override
515 	public void finish( TestCaseRunner testRunner, TestCaseRunContext testRunContext )
516 	{
517 		if( mockRunListener != null )
518 		{
519 			mockService.removeMockRunListener( mockRunListener );
520 			mockRunListener = null;
521 		}
522 
523 		if( startStepMockRunListener != null )
524 		{
525 			startStepMockRunListener.release();
526 			startStepMockRunListener = null;
527 		}
528 
529 		if( testMockResponse != null )
530 		{
531 			if( testMockResponse != mockResponse )
532 			{
533 				mockOperation.removeMockResponse( testMockResponse );
534 			}
535 
536 			testMockResponse = null;
537 		}
538 
539 		if( mockRunner != null )
540 		{
541 			if( mockRunner.isRunning() )
542 			{
543 				mockRunner.stop();
544 			}
545 
546 			mockRunner = null;
547 		}
548 	}
549 
550 	public WsdlMockResult getLastResult()
551 	{
552 		return lastResult;
553 	}
554 
555 	public class InternalMockRunListener extends MockRunListenerAdapter
556 	{
557 		private boolean canceled;
558 		private boolean waiting;
559 		private WsdlMockResult lastResult;
560 
561 		public synchronized void onMockResult( MockResult result )
562 		{
563 			// is this for us?
564 			if( this.lastResult == null && waiting
565 					&& result.getMockResponse() == testMockResponse )
566 			{
567 				waiting = false;
568 				System.out.println( "Got mockrequest to [" + getName() + "]" );
569 				// save
570 				this.lastResult = (WsdlMockResult)result;
571 				notifyPropertyChanged( "lastResult", null, lastResult );
572 
573 				// stop runner -> NO, we can't stop, mockengine is still writing
574 				// response..
575 				// mockRunner.stop();
576 
577 				// testMockResponse.setMockResult( null );
578 
579 				
580 				synchronized( this )
581 				{
582 					notifyAll();
583 				}
584 			}
585 		}
586 
587 		public void setLastResult( WsdlMockResult lastResult )
588 		{
589 			this.lastResult = lastResult;
590 		}
591 
592 		public void cancel()
593 		{
594 			canceled = true;
595 			if( waiting )
596 			{
597 				synchronized( this )
598 				{
599 					notifyAll();
600 				}
601 			}
602 			// mockRunListener.onMockResult( null );
603 		}
604 
605 		public WsdlMockResult getLastResult()
606 		{
607 			return lastResult;
608 		}
609 
610 		public boolean isCanceled()
611 		{
612 			return canceled;
613 		}
614 
615 		public boolean hasResult()
616 		{
617 			return lastResult != null;
618 		}
619 
620 		public boolean isWaiting()
621 		{
622 			return waiting;
623 		}
624 
625 		public void setWaiting( boolean waiting )
626 		{
627 			this.waiting = waiting;
628 		}
629 
630 		public void waitForRequest( long timeout ) throws InterruptedException
631 		{
632 			waiting = true;
633 			wait( timeout );
634 		}
635 
636 		@Override
637 		public void onMockRunnerStart( MockRunner mockRunner )
638 		{
639 			waiting = false;
640 			lastResult = null;
641 			canceled = false;
642 		}
643 	}
644 
645 	public WsdlMockResponse getMockResponse()
646 	{
647 		return mockResponse;
648 	}
649 
650 	public void setPort( int port )
651 	{
652 		int old = getPort();
653 		mockService.setPort( port );
654 		mockResponseStepConfig.setPort( port );
655 		notifyPropertyChanged( "port", old, port );
656 	}
657 
658 	public String getPath()
659 	{
660 		return mockResponseStepConfig.getPath();
661 	}
662 
663 	public String getHost()
664 	{
665 		return mockResponseStepConfig.getHost();
666 	}
667 
668 	public long getContentLength()
669 	{
670 		return mockResponse == null ? 0 : mockResponse.getContentLength();
671 	}
672 
673 	public int getPort()
674 	{
675 		return mockResponseStepConfig.getPort();
676 	}
677 
678 	public String getEncoding()
679 	{
680 		return mockResponse.getEncoding();
681 	}
682 
683 	public void setEncoding( String encoding )
684 	{
685 		String old = getEncoding();
686 		mockResponse.setEncoding( encoding );
687 		notifyPropertyChanged( "encoding", old, encoding );
688 	}
689 
690 	public boolean isMtomEnabled()
691 	{
692 		return mockResponse.isMtomEnabled();
693 	}
694 
695 	public void setMtomEnabled( boolean enabled )
696 	{
697 		if( isMtomEnabled() == enabled )
698 			return;
699 		mockResponse.setMtomEnabled( enabled );
700 
701 		notifyPropertyChanged( "mtomEnabled", !enabled, enabled );
702 	}
703 
704 	public String getOutgoingWss()
705 	{
706 		return mockResponse.getOutgoingWss();
707 	}
708 
709 	public void setOutgoingWss( String outgoingWss )
710 	{
711 		String old = getOutgoingWss();
712 		mockResponse.setOutgoingWss( outgoingWss );
713 		notifyPropertyChanged( "outgoingWss", old, outgoingWss );
714 	}
715 
716 	public void setQuery( String s )
717 	{
718 		String old = getQuery();
719 		mockResponseStepConfig.setQuery( s );
720 		notifyPropertyChanged( "query", old, s );
721 	}
722 
723 	public String getQuery()
724 	{
725 		return mockResponseStepConfig.getQuery();
726 	}
727 
728 	public String getMatch()
729 	{
730 		return mockResponseStepConfig.getMatch();
731 	}
732 
733 	public void setMatch( String s )
734 	{
735 		String old = getMatch();
736 		mockResponseStepConfig.setMatch( s );
737 		notifyPropertyChanged( "match", old, s );
738 	}
739 
740 	public boolean isForceMtom()
741 	{
742 		return mockResponse.isForceMtom();
743 	}
744 
745 	public void setForceMtom( boolean forceMtom )
746 	{
747 		mockResponse.setForceMtom( forceMtom );
748 	}
749 
750 	public boolean isInlineFilesEnabled()
751 	{
752 		return mockResponse.isInlineFilesEnabled();
753 	}
754 
755 	public void setInlineFilesEnabled( boolean inlineFilesEnabled )
756 	{
757 		mockResponse.setInlineFilesEnabled( inlineFilesEnabled );
758 	}
759 
760 	public String getStartStep()
761 	{
762 		return startTestStep == null ? "" : startTestStep.getName();
763 	}
764 
765 	public void setStartStep( String startStep )
766 	{
767 		String old = getStartStep();
768 		if( startTestStep != null )
769 		{
770 			startTestStep.removePropertyChangeListener( this );
771 			startTestStep = null;
772 		}
773 
774 		if( startStep != null )
775 		{
776 			startTestStep = getTestCase().getTestStepByName( startStep );
777 			if( startTestStep != null )
778 			{
779 				startTestStep.addPropertyChangeListener( this );
780 			}
781 		}
782 
783 		mockResponseStepConfig.setStartStep( startStep );
784 		notifyPropertyChanged( "startStep", old, startStep );
785 	}
786 
787 	public boolean isMultipartEnabled()
788 	{
789 		return mockResponse.isMultipartEnabled();
790 	}
791 
792 	public void setMultipartEnabled( boolean enabled )
793 	{
794 		mockResponse.setMultipartEnabled( enabled );
795 	}
796 
797 	public boolean isHandleFault()
798 	{
799 		return mockResponseStepConfig.getHandleFault();
800 	}
801 
802 	public void setHandleFault( boolean handleFault )
803 	{
804 		mockResponseStepConfig.setHandleFault( handleFault );
805 		if( mockService != null )
806 			mockService.setFaultMockOperation( handleFault ? mockOperation : null );
807 	}
808 
809 	public boolean isHandleResponse()
810 	{
811 		return mockResponseStepConfig.getHandleResponse();
812 	}
813 
814 	public void setHandleResponse( boolean handleResponse )
815 	{
816 		mockResponseStepConfig.setHandleResponse( handleResponse );
817 		if( mockService != null )
818 			mockService.setDispatchResponseMessages( handleResponse );
819 	}
820 
821 	public long getResponseDelay()
822 	{
823 		return mockResponse.getResponseDelay();
824 	}
825 
826 	public void setResponseDelay( long delay )
827 	{
828 		mockResponse.setResponseDelay( delay );
829 	}
830 
831 	public String getResponseHttpStatus()
832 	{
833 		return mockResponse.getResponseHttpStatus();
834 	}
835 
836 	public void setResponseHttpStatus( String httpStatus )
837 	{
838 		mockResponse.setResponseHttpStatus( httpStatus );
839 	}
840 
841 	public boolean isEncodeAttachments()
842 	{
843 		return mockResponse.isEncodeAttachments();
844 	}
845 
846 	public boolean isRemoveEmptyContent()
847 	{
848 		return mockResponse.isRemoveEmptyContent();
849 	}
850 
851 	public boolean isStripWhitespaces()
852 	{
853 		return mockResponse.isStripWhitespaces();
854 	}
855 
856 	public void setEncodeAttachments( boolean encodeAttachments )
857 	{
858 		mockResponse.setEncodeAttachments( encodeAttachments );
859 	}
860 
861 	public void setRemoveEmptyContent( boolean removeEmptyContent )
862 	{
863 		mockResponse.setRemoveEmptyContent( removeEmptyContent );
864 	}
865 
866 	public void setStripWhitespaces( boolean stripWhitespaces )
867 	{
868 		mockResponse.setStripWhitespaces( stripWhitespaces );
869 	}
870 
871 	public void setPath( String path )
872 	{
873 		mockService.setPath( path );
874 		mockResponseStepConfig.setPath( path );
875 	}
876 
877 	public void setHost( String host )
878 	{
879 		mockService.setHost( host );
880 		mockResponseStepConfig.setHost( host );
881 	}
882 
883 	public void propertyChange( PropertyChangeEvent evt )
884 	{
885 		if( evt.getSource() == mockResponse || evt.getSource() == mockResponse.getWsaConfig() )
886 		{
887 			if( !evt.getPropertyName().equals( WsdlMockResponse.ICON_PROPERTY ) )
888 			{
889 				mockResponse.beforeSave();
890 				mockResponseConfig.set( mockResponse.getConfig() );
891 			}
892 
893 			notifyPropertyChanged( evt.getPropertyName(), evt.getOldValue(), evt.getNewValue() );
894 		}
895 		else if( evt.getSource() == getTestCase() && evt.getPropertyName().equals( "testSteps" )
896 				&& evt.getNewValue() == null && evt.getOldValue() == startTestStep && startTestStep != null )
897 		{
898 			setStartStep( null );
899 		}
900 		else if( evt.getSource() == startTestStep && evt.getPropertyName().equals( WsdlTestStep.NAME_PROPERTY ) )
901 		{
902 			mockResponseStepConfig.setStartStep( String.valueOf( evt.getNewValue() ) );
903 		}
904 	}
905 
906 	public WsdlMessageAssertion addAssertion( String assertionName )
907 	{
908 		PropertyChangeNotifier notifier = new PropertyChangeNotifier();
909 
910 		try
911 		{
912 			TestAssertionConfig assertionConfig = mockResponseStepConfig.addNewAssertion();
913 			assertionConfig.setType( TestAssertionRegistry.getInstance().getAssertionTypeForName( assertionName ) );
914 
915 			WsdlMessageAssertion assertion = assertionsSupport.addWsdlAssertion( assertionConfig );
916 			assertionsSupport.fireAssertionAdded( assertion );
917 
918 			if( getMockResponse().getMockResult() != null )
919 			{
920 				assertion.assertRequest( new WsdlMockResultMessageExchange( getMockResponse().getMockResult(),
921 						getMockResponse() ), new WsdlSubmitContext( this ) );
922 				notifier.notifyChange();
923 			}
924 
925 			return assertion;
926 		}
927 		catch( Exception e )
928 		{
929 			SoapUI.logError( e );
930 			return null;
931 		}
932 	}
933 
934 	public void addAssertionsListener( AssertionsListener listener )
935 	{
936 		assertionsSupport.addAssertionsListener( listener );
937 	}
938 
939 	public WsdlMessageAssertion getAssertionAt( int c )
940 	{
941 		return assertionsSupport.getAssertionAt( c );
942 	}
943 
944 	public int getAssertionCount()
945 	{
946 		return assertionsSupport.getAssertionCount();
947 	}
948 
949 	public void removeAssertionsListener( AssertionsListener listener )
950 	{
951 		assertionsSupport.removeAssertionsListener( listener );
952 	}
953 
954 	public AssertionStatus getAssertionStatus()
955 	{
956 		AssertionStatus currentStatus = AssertionStatus.UNKNOWN;
957 		int cnt = getAssertionCount();
958 		if( cnt == 0 )
959 			return currentStatus;
960 
961 		if( mockResponse.getMockResult() != null )
962 		{
963 			if( mockResponse.getMockResult().getMockRequest() == null )
964 			{
965 				currentStatus = AssertionStatus.FAILED;
966 			}
967 		}
968 		else
969 			return currentStatus;
970 
971 		for( int c = 0; c < cnt; c++ )
972 		{
973 			WsdlMessageAssertion assertion = getAssertionAt( c );
974 			if( assertion.isDisabled() )
975 				continue;
976 
977 			if( assertion.getStatus() == AssertionStatus.FAILED )
978 			{
979 				currentStatus = AssertionStatus.FAILED;
980 				break;
981 			}
982 		}
983 
984 		if( currentStatus == AssertionStatus.UNKNOWN )
985 			currentStatus = AssertionStatus.VALID;
986 
987 		return currentStatus;
988 	}
989 
990 	public void removeAssertion( TestAssertion assertion )
991 	{
992 		PropertyChangeNotifier notifier = new PropertyChangeNotifier();
993 
994 		try
995 		{
996 			assertionsSupport.removeAssertion( ( WsdlMessageAssertion )assertion );
997 		}
998 		finally
999 		{
1000 			( ( WsdlMessageAssertion )assertion ).release();
1001 			notifier.notifyChange();
1002 		}
1003 	}
1004 
1005 	public TestAssertion moveAssertion( int ix, int offset )
1006 	{
1007 		PropertyChangeNotifier notifier = new PropertyChangeNotifier();
1008 		WsdlMessageAssertion assertion = getAssertionAt( ix );
1009 		try
1010 		{
1011 			return assertionsSupport.moveAssertion( ix, offset );
1012 		}
1013 		finally
1014 		{
1015 			( ( WsdlMessageAssertion )assertion ).release();
1016 			notifier.notifyChange();
1017 		}
1018 	}
1019 
1020 	public String getAssertableContent()
1021 	{
1022 		WsdlMockResult mockResult = getMockResponse().getMockResult();
1023 		return mockResult == null ? null : mockResult.getMockRequest().getRequestContent();
1024 	}
1025 
1026 	public TestStep getTestStep()
1027 	{
1028 		return this;
1029 	}
1030 
1031 	@Override
1032 	public void setName( String name )
1033 	{
1034 		super.setName( name );
1035 		if( mockService != null )
1036 			mockService.setName( getName() );
1037 	}
1038 
1039 	public WsdlInterface getInterface()
1040 	{
1041 		return getOperation().getInterface();
1042 	}
1043 
1044 	public WsdlOperation getOperation()
1045 	{
1046 		return getMockResponse().getMockOperation().getOperation();
1047 	}
1048 
1049 	public void setInterface( String string )
1050 	{
1051 		WsdlInterface iface = ( WsdlInterface )getTestCase().getTestSuite().getProject().getInterfaceByName( string );
1052 		if( iface != null )
1053 		{
1054 			mockResponseStepConfig.setInterface( iface.getName() );
1055 			WsdlOperation operation = iface.getOperationAt( 0 );
1056 			mockResponseStepConfig.setOperation( operation.getName() );
1057 			mockOperation.setOperation( operation );
1058 		}
1059 	}
1060 
1061 	public void setOperation( String string )
1062 	{
1063 		WsdlOperation operation = getInterface().getOperationByName( string );
1064 		if( operation != null )
1065 		{
1066 			mockResponseStepConfig.setOperation( string );
1067 			mockOperation.setOperation( operation );
1068 		}
1069 	}
1070 
1071 	private class PropertyChangeNotifier
1072 	{
1073 		private AssertionStatus oldStatus;
1074 		private ImageIcon oldIcon;
1075 
1076 		public PropertyChangeNotifier()
1077 		{
1078 			oldStatus = getAssertionStatus();
1079 			oldIcon = getIcon();
1080 		}
1081 
1082 		public void notifyChange()
1083 		{
1084 			AssertionStatus newStatus = getAssertionStatus();
1085 			ImageIcon newIcon = getIcon();
1086 
1087 			if( oldStatus != newStatus )
1088 				notifyPropertyChanged( STATUS_PROPERTY, oldStatus, newStatus );
1089 
1090 			if( oldIcon != newIcon )
1091 				notifyPropertyChanged( ICON_PROPERTY, oldIcon, getIcon() );
1092 		}
1093 	}
1094 
1095 	@Override
1096 	public void release()
1097 	{
1098 		super.release();
1099 		assertionsSupport.release();
1100 
1101 		if( mockResponse != null )
1102 		{
1103 			mockResponse.removePropertyChangeListener( this );
1104 			mockResponse.getWsaConfig().removePropertyChangeListener( this );
1105 		}
1106 
1107 		if( mockService != null )
1108 		{
1109 			mockService.release();
1110 		}
1111 
1112 		if( iface != null )
1113 		{
1114 			iface.getProject().removeProjectListener( projectListener );
1115 			iface.removeInterfaceListener( interfaceListener );
1116 		}
1117 
1118 		getTestCase().removeTestRunListener( testRunListener );
1119 		getTestCase().removePropertyChangeListener( this );
1120 
1121 		if( startTestStep != null )
1122 		{
1123 			startTestStep.removePropertyChangeListener( this );
1124 		}
1125 
1126 		if( lastResult != null )
1127 		{
1128 			lastResult = null;
1129 		}
1130 	}
1131 
1132 	public AssertableType getAssertableType()
1133 	{
1134 		return AssertableType.REQUEST;
1135 	}
1136 
1137 	@Override
1138 	public Collection<Interface> getRequiredInterfaces()
1139 	{
1140 		ArrayList<Interface> result = new ArrayList<Interface>();
1141 		result.add( getInterface() );
1142 		return result;
1143 	}
1144 
1145 	public String getDefaultSourcePropertyName()
1146 	{
1147 		return "Response";
1148 	}
1149 
1150 	public String getDefaultTargetPropertyName()
1151 	{
1152 		return "Request";
1153 	}
1154 
1155 	@Override
1156 	public void beforeSave()
1157 	{
1158 		super.beforeSave();
1159 
1160 		if( mockResponse != null )
1161 		{
1162 			mockResponse.beforeSave();
1163 			mockResponseConfig.set( mockResponse.getConfig() );
1164 		}
1165 	}
1166 
1167 	public long getTimeout()
1168 	{
1169 		return mockResponseStepConfig.getTimeout();
1170 	}
1171 
1172 	public void setTimeout( long timeout )
1173 	{
1174 		long old = getTimeout();
1175 		mockResponseStepConfig.setTimeout( timeout );
1176 		notifyPropertyChanged( TIMEOUT_PROPERTY, old, timeout );
1177 	}
1178 
1179 	@Override
1180 	public boolean dependsOn( AbstractWsdlModelItem<?> modelItem )
1181 	{
1182 		return modelItem == getOperation().getInterface();
1183 	}
1184 
1185 	public class InternalProjectListener extends ProjectListenerAdapter
1186 	{
1187 		public void interfaceRemoved( Interface iface )
1188 		{
1189 			if( getOperation() != null && getOperation().getInterface().equals( iface ) )
1190 			{
1191 				log.debug( "Removing test step due to removed interface" );
1192 				( getTestCase() ).removeTestStep( WsdlMockResponseTestStep.this );
1193 			}
1194 		}
1195 	}
1196 
1197 	public class InternalInterfaceListener extends InterfaceListenerAdapter
1198 	{
1199 		public void operationRemoved( Operation operation )
1200 		{
1201 			if( operation == getOperation() )
1202 			{
1203 				log.debug( "Removing test step due to removed operation" );
1204 				( getTestCase() ).removeTestStep( WsdlMockResponseTestStep.this );
1205 			}
1206 		}
1207 
1208 		@Override
1209 		public void operationUpdated( Operation operation )
1210 		{
1211 			if( operation == getOperation() )
1212 			{
1213 				setOperation( operation.getName() );
1214 			}
1215 		}
1216 	}
1217 
1218 	public WsdlMessageAssertion cloneAssertion( TestAssertion source, String name )
1219 	{
1220 		TestAssertionConfig conf = mockResponseStepConfig.addNewAssertion();
1221 		conf.set( ( ( WsdlMessageAssertion )source ).getConfig() );
1222 		conf.setName( name );
1223 
1224 		WsdlMessageAssertion result = assertionsSupport.addWsdlAssertion( conf );
1225 		assertionsSupport.fireAssertionAdded( result );
1226 		return result;
1227 	}
1228 
1229 	public List<TestAssertion> getAssertionList()
1230 	{
1231 		return new ArrayList<TestAssertion>( assertionsSupport.getAssertionList() );
1232 	}
1233 
1234 	@Override
1235 	public List<? extends ModelItem> getChildren()
1236 	{
1237 		return assertionsSupport.getAssertionList();
1238 	}
1239 
1240 	public PropertyExpansion[] getPropertyExpansions()
1241 	{
1242 		List<PropertyExpansion> result = new ArrayList<PropertyExpansion>();
1243 
1244 		result.addAll( PropertyExpansionUtils.extractPropertyExpansions( this, mockResponse, "responseContent" ) );
1245 
1246 		StringToStringMap responseHeaders = mockResponse.getResponseHeaders();
1247 		for( String key : responseHeaders.keySet() )
1248 		{
1249 			result.addAll( PropertyExpansionUtils.extractPropertyExpansions( this, new ResponseHeaderHolder(
1250 					responseHeaders, key ), "value" ) );
1251 		}
1252 		mockResponse.addWsaPropertyExpansions( result, mockResponse.getWsaConfig(), this );
1253 
1254 		return result.toArray( new PropertyExpansion[result.size()] );
1255 	}
1256 
1257 	public class ResponseHeaderHolder
1258 	{
1259 		private final StringToStringMap valueMap;
1260 		private final String key;
1261 
1262 		public ResponseHeaderHolder( StringToStringMap valueMap, String key )
1263 		{
1264 			this.valueMap = valueMap;
1265 			this.key = key;
1266 		}
1267 
1268 		public String getValue()
1269 		{
1270 			return valueMap.get( key );
1271 		}
1272 
1273 		public void setValue( String value )
1274 		{
1275 			valueMap.put( key, value );
1276 			mockResponse.setResponseHeaders( valueMap );
1277 		}
1278 	}
1279 
1280 	public WsdlMessageAssertion getAssertionByName( String name )
1281 	{
1282 		return assertionsSupport.getAssertionByName( name );
1283 	}
1284 
1285 	public Map<String, TestAssertion> getAssertions()
1286 	{
1287 		Map<String, TestAssertion> result = new HashMap<String, TestAssertion>();
1288 
1289 		for( TestAssertion assertion : getAssertionList() )
1290 			result.put( assertion.getName(), assertion );
1291 
1292 		return result;
1293 	}
1294 
1295 	private class AssertedWsdlMockResultMessageExchange extends WsdlMockResultMessageExchange implements
1296 			RequestAssertedMessageExchange, AssertedXPathsContainer
1297 	{
1298 		private List<AssertedXPath> assertedXPaths;
1299 
1300 		public AssertedWsdlMockResultMessageExchange( WsdlMockResult mockResult )
1301 		{
1302 			super( mockResult, mockResult == null ? null : mockResult.getMockResponse() );
1303 		}
1304 
1305 		public AssertedXPath[] getAssertedXPathsForRequest()
1306 		{
1307 			return assertedXPaths == null ? new AssertedXPath[0] : assertedXPaths
1308 					.toArray( new AssertedXPath[assertedXPaths.size()] );
1309 		}
1310 
1311 		public void addAssertedXPath( AssertedXPath assertedXPath )
1312 		{
1313 			if( assertedXPaths == null )
1314 				assertedXPaths = new ArrayList<AssertedXPath>();
1315 
1316 			assertedXPaths.add( assertedXPath );
1317 		}
1318 	}
1319 
1320 	public String getDefaultAssertableContent()
1321 	{
1322 		return getOperation().createRequest( true );
1323 	}
1324 
1325 	@SuppressWarnings( "unchecked" )
1326 	@Override
1327 	public void resolve( ResolveContext<?> context )
1328 	{
1329 		super.resolve( context );
1330 
1331 		if( mockOperation == null )
1332 		{
1333 			if( context.hasThisModelItem( this, "Missing Operation in Project", mockResponseStepConfig.getInterface()
1334 					+ "/" + mockResponseStepConfig.getOperation() ) )
1335 				return;
1336 			context.addPathToResolve( this, "Missing Operation in Project",
1337 					mockResponseStepConfig.getInterface() + "/" + mockResponseStepConfig.getOperation() ).addResolvers(
1338 					new RemoveTestStepResolver( this ), new ImportInterfaceResolver( this )
1339 					{
1340 
1341 						@Override
1342 						protected boolean update()
1343 						{
1344 							initMockObjects( getTestCase() );
1345 							initProperties();
1346 							setDisabled( false );
1347 							return true;
1348 						}
1349 					}, new ChangeOperationResolver( this, "Operation" )
1350 					{
1351 
1352 						@Override
1353 						public boolean update()
1354 						{
1355 							WsdlOperation operation = ( WsdlOperation )getSelectedOperation();
1356 							setInterface( operation.getInterface().getName() );
1357 							setOperation( operation.getName() );
1358 							initMockObjects( getTestCase() );
1359 							initProperties();
1360 							setDisabled( false );
1361 							return true;
1362 						}
1363 
1364 						protected Interface[] getInterfaces( WsdlProject project )
1365 						{
1366 							List<WsdlInterface> interfaces = ModelSupport.getChildren( project, WsdlInterface.class );
1367 							return interfaces.toArray( new Interface[interfaces.size()] );
1368 
1369 						}
1370 
1371 					} );
1372 		}
1373 		else
1374 		{
1375 			mockOperation.resolve( context );
1376 			if( context.hasThisModelItem( this, "Missing Operation in Project", mockResponseStepConfig.getInterface()
1377 					+ "/" + mockResponseStepConfig.getOperation() ) )
1378 			{
1379 				PathToResolve path = context.getPath( this, "Missing Operation in Project", mockResponseStepConfig
1380 						.getInterface()
1381 						+ "/" + mockResponseStepConfig.getOperation() );
1382 				path.setSolved( true );
1383 			}
1384 		}
1385 	}
1386 
1387 	private class InternalTestRunListener extends TestRunListenerAdapter
1388 	{
1389 		@Override
1390 		public void beforeStep( TestCaseRunner testRunner, TestCaseRunContext runContext, TestStep testStep )
1391 		{
1392 			if( runContext.getCurrentStep() == startTestStep && testMockResponse == null )
1393 			{
1394 				if( startTestStep instanceof WsdlMockResponseTestStep )
1395 				{
1396 					// WsdlMockResponseTestStep testStep = (WsdlMockResponseTestStep)
1397 					// startTestStep;
1398 					//
1399 					// if( testStep.getLastResult() != null )
1400 					// {
1401 					// System.out.println( "StartStep [" + testStep.getName() +
1402 					// "] already has result; preparing [" + getName() + "]" );
1403 					// initTestMockResponse( runContext );
1404 					// mockRunListener.setWaiting( true );
1405 					// }
1406 					// else
1407 					// {
1408 					// System.out.println( "Adding StartStepMockRunListener from [" +
1409 					// getName() + "] to [" + startTestStep.getName() + "]" );
1410 					// startStepMockRunListener = new StartStepMockRunListener(
1411 					// runContext, (WsdlMockResponseTestStep) startTestStep );
1412 					// }
1413 				}
1414 				else
1415 				{
1416 					initTestMockResponse( runContext );
1417 					mockRunListener.setWaiting( true );
1418 				}
1419 			}
1420 		}
1421 	}
1422 
1423 	private class StartStepMockRunListener implements PropertyChangeListener
1424 	{
1425 		private TestCaseRunContext runContext;
1426 		private WsdlMockResponseTestStep wsdlMockResponseTestStep;
1427 
1428 		public StartStepMockRunListener( TestCaseRunContext runContext, WsdlMockResponseTestStep wsdlMockResponseTestStep )
1429 		{
1430 			this.runContext = runContext;
1431 			this.wsdlMockResponseTestStep = wsdlMockResponseTestStep;
1432 			wsdlMockResponseTestStep.addPropertyChangeListener( "lastResult", this );
1433 		}
1434 
1435 		public void release()
1436 		{
1437 			wsdlMockResponseTestStep.removePropertyChangeListener( "lastResult", this );
1438 			wsdlMockResponseTestStep = null;
1439 			runContext = null;
1440 		}
1441 
1442 		public void propertyChange( PropertyChangeEvent evt )
1443 		{
1444 			System.out.println( "Starting to listen for request to " + getName() );
1445 			initTestMockResponse( runContext );
1446 			mockRunListener.setWaiting( true );
1447 		}
1448 	}
1449 
1450 }