View Javadoc

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