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.mock;
14  
15  import java.io.File;
16  import java.io.IOException;
17  import java.net.InetAddress;
18  import java.net.UnknownHostException;
19  import java.util.ArrayList;
20  import java.util.Arrays;
21  import java.util.Collections;
22  import java.util.HashSet;
23  import java.util.List;
24  import java.util.Set;
25  
26  import javax.servlet.http.HttpServletRequest;
27  import javax.servlet.http.HttpServletResponse;
28  import javax.swing.ImageIcon;
29  
30  import com.eviware.soapui.SoapUI;
31  import com.eviware.soapui.config.MockOperationConfig;
32  import com.eviware.soapui.config.MockOperationDocumentConfig;
33  import com.eviware.soapui.config.MockServiceConfig;
34  import com.eviware.soapui.config.TestCaseConfig;
35  import com.eviware.soapui.impl.wsdl.AbstractTestPropertyHolderWsdlModelItem;
36  import com.eviware.soapui.impl.wsdl.WsdlInterface;
37  import com.eviware.soapui.impl.wsdl.WsdlOperation;
38  import com.eviware.soapui.impl.wsdl.WsdlProject;
39  import com.eviware.soapui.impl.wsdl.support.ModelItemIconAnimator;
40  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
41  import com.eviware.soapui.impl.wsdl.teststeps.BeanPathPropertySupport;
42  import com.eviware.soapui.model.ModelItem;
43  import com.eviware.soapui.model.iface.Operation;
44  import com.eviware.soapui.model.mock.MockOperation;
45  import com.eviware.soapui.model.mock.MockResult;
46  import com.eviware.soapui.model.mock.MockRunListener;
47  import com.eviware.soapui.model.mock.MockRunner;
48  import com.eviware.soapui.model.mock.MockService;
49  import com.eviware.soapui.model.mock.MockServiceListener;
50  import com.eviware.soapui.model.project.Project;
51  import com.eviware.soapui.model.support.ModelSupport;
52  import com.eviware.soapui.support.StringUtils;
53  import com.eviware.soapui.support.UISupport;
54  import com.eviware.soapui.support.resolver.ResolveContext;
55  import com.eviware.soapui.support.resolver.ResolveDialog;
56  import com.eviware.soapui.support.scripting.ScriptEnginePool;
57  import com.eviware.soapui.support.scripting.SoapUIScriptEngine;
58  import com.eviware.soapui.support.scripting.SoapUIScriptEngineRegistry;
59  
60  /***
61   * A MockService for simulation WsdlInterfaces and their operations
62   * 
63   * @author ole.matzura
64   */
65  
66  public class WsdlMockService extends AbstractTestPropertyHolderWsdlModelItem<MockServiceConfig> implements MockService
67  {
68  	private static final String REQUIRE_SOAP_VERSION = WsdlMockService.class.getName() + "@require-soap-version";
69  	private static final String REQUIRE_SOAP_ACTION = WsdlMockService.class.getName() + "@require-soap-action";
70  
71  	public final static String START_SCRIPT_PROPERTY = WsdlMockService.class.getName() + "@startScript";
72  	public final static String STOP_SCRIPT_PROPERTY = WsdlMockService.class.getName() + "@stopScript";
73  	public static final String INCOMING_WSS = WsdlMockService.class.getName() + "@incoming-wss";
74  	public static final String OUGOING_WSS = WsdlMockService.class.getName() + "@outgoing-wss";
75  
76  	private List<WsdlMockOperation> mockOperations = new ArrayList<WsdlMockOperation>();
77  	private Set<MockRunListener> mockRunListeners = new HashSet<MockRunListener>();
78  	private Set<MockServiceListener> mockServiceListeners = new HashSet<MockServiceListener>();
79  	private MockServiceIconAnimator iconAnimator;
80  	private WsdlMockRunner mockRunner;
81  	private SoapUIScriptEngine startScriptEngine;
82  	private SoapUIScriptEngine stopScriptEngine;
83  	private BeanPathPropertySupport docrootProperty;
84  	private ScriptEnginePool onRequestScriptEnginePool;
85  	private ScriptEnginePool afterRequestScriptEnginePool;
86  	private WsdlMockOperation faultMockOperation;
87  
88  	public WsdlMockService( Project project, MockServiceConfig config )
89  	{
90  		super( config, project, "/mockService.gif" );
91  
92  		List<MockOperationConfig> testStepConfigs = config.getMockOperationList();
93  		for( MockOperationConfig tsc : testStepConfigs )
94  		{
95  			WsdlMockOperation testStep = new WsdlMockOperation( this, tsc );
96  			mockOperations.add( testStep );
97  		}
98  
99  		if( !config.isSetPort() || config.getPort() < 1 )
100 			config.setPort( 8080 );
101 
102 		if( !config.isSetPath() )
103 			config.setPath( "/" );
104 
105 		if( !getSettings().isSet( REQUIRE_SOAP_ACTION ) )
106 			setRequireSoapAction( true );
107 
108 		try
109 		{
110 			if( !config.isSetHost() || !StringUtils.hasContent( config.getHost() ) )
111 				config.setHost( InetAddress.getLocalHost().getHostName() );
112 		}
113 		catch( UnknownHostException e )
114 		{
115 			SoapUI.logError( e );
116 		}
117 
118 		iconAnimator = new MockServiceIconAnimator();
119 		addMockRunListener( iconAnimator );
120 
121 		for( MockRunListener listener : SoapUI.getListenerRegistry().getListeners( MockRunListener.class ) )
122 		{
123 			addMockRunListener( listener );
124 		}
125 
126 		if( !getConfig().isSetProperties() )
127 			getConfig().addNewProperties();
128 
129 		setPropertiesConfig( getConfig().getProperties() );
130 		docrootProperty = new BeanPathPropertySupport( this, "docroot" );
131 
132 		if( getConfig().isSetFaultMockOperation() )
133 		{
134 			faultMockOperation = getMockOperationByName( getConfig().getFaultMockOperation() );
135 		}
136 	}
137 
138 	public void addMockRunListener( MockRunListener listener )
139 	{
140 		mockRunListeners.add( listener );
141 	}
142 
143 	public String getPath()
144 	{
145 		return getConfig().getPath();
146 	}
147 
148 	public WsdlMockOperation getMockOperationAt( int index )
149 	{
150 		return mockOperations.get( index );
151 	}
152 
153 	public WsdlMockOperation getMockOperationByName( String name )
154 	{
155 		return ( WsdlMockOperation )getWsdlModelItemByName( mockOperations, name );
156 	}
157 
158 	public int getMockOperationCount()
159 	{
160 		return mockOperations.size();
161 	}
162 
163 	public WsdlProject getProject()
164 	{
165 		return ( WsdlProject )getParent();
166 	}
167 
168 	public int getPort()
169 	{
170 		return getConfig().getPort();
171 	}
172 
173 	public String getHost()
174 	{
175 		return getConfig().getHost();
176 	}
177 
178 	public void setHost( String host )
179 	{
180 		getConfig().setHost( host );
181 	}
182 
183 	public boolean getBindToHostOnly()
184 	{
185 		return getConfig().getBindToHostOnly();
186 	}
187 
188 	public void setBindToHostOnly( boolean bindToHostOnly )
189 	{
190 		getConfig().setBindToHostOnly( bindToHostOnly );
191 	}
192 
193 	public void removeMockRunListener( MockRunListener listener )
194 	{
195 		mockRunListeners.remove( listener );
196 	}
197 
198 	public WsdlMockRunner start( WsdlTestRunContext context ) throws Exception
199 	{
200 		String path = getPath();
201 		if( path == null || path.trim().length() == 0 || path.trim().charAt( 0 ) != '/' )
202 			throw new Exception( "Invalid path; must start with '/'" );
203 
204 		mockRunner = new WsdlMockRunner( this, context );
205 		return mockRunner;
206 	}
207 
208 	public WsdlMockRunner getMockRunner()
209 	{
210 		return mockRunner;
211 	}
212 
213 	public WsdlMockOperation getMockOperation( Operation operation )
214 	{
215 		for( int c = 0; c < getMockOperationCount(); c++ )
216 		{
217 			WsdlMockOperation mockOperation = mockOperations.get( c );
218 			if( mockOperation.getOperation() == operation )
219 				return mockOperation;
220 		}
221 
222 		return null;
223 	}
224 
225 	public WsdlMockOperation addNewMockOperation( WsdlOperation operation )
226 	{
227 		if( getMockOperation( operation ) != null )
228 			return null;
229 
230 		MockOperationConfig config = getConfig().addNewMockOperation();
231 		config.setName( operation.getName() );
232 		WsdlMockOperation mockOperation = new WsdlMockOperation( this, config, operation );
233 
234 		mockOperations.add( mockOperation );
235 		fireMockOperationAdded( mockOperation );
236 
237 		return mockOperation;
238 	}
239 
240 	public void setPort( int port )
241 	{
242 		String oldEndpoint = getLocalEndpoint();
243 
244 		int oldPort = getPort();
245 		if( port != oldPort )
246 		{
247 			getConfig().setPort( port );
248 			notifyPropertyChanged( PORT_PROPERTY, oldPort, port );
249 
250 			for( WsdlInterface iface : getMockedInterfaces() )
251 			{
252 				if( Arrays.asList( iface.getEndpoints() ).contains( oldEndpoint ) )
253 					iface.changeEndpoint( oldEndpoint, getLocalEndpoint() );
254 			}
255 		}
256 	}
257 
258 	public WsdlInterface[] getMockedInterfaces()
259 	{
260 		Set<WsdlInterface> result = new HashSet<WsdlInterface>();
261 
262 		for( WsdlMockOperation mockOperation : mockOperations )
263 		{
264 			WsdlOperation operation = mockOperation.getOperation();
265 			if( operation != null )
266 				result.add( operation.getInterface() );
267 		}
268 
269 		return result.toArray( new WsdlInterface[result.size()] );
270 	}
271 
272 	@Override
273 	public void release()
274 	{
275 		super.release();
276 
277 		for( WsdlMockOperation operation : mockOperations )
278 			operation.release();
279 
280 		mockServiceListeners.clear();
281 
282 		if( onRequestScriptEnginePool != null )
283 			onRequestScriptEnginePool.release();
284 
285 		if( afterRequestScriptEnginePool != null )
286 			afterRequestScriptEnginePool.release();
287 
288 		if( startScriptEngine != null )
289 			startScriptEngine.release();
290 
291 		if( stopScriptEngine != null )
292 			stopScriptEngine.release();
293 	}
294 
295 	public void setPath( String path )
296 	{
297 		String oldEndpoint = getLocalEndpoint();
298 
299 		String oldPath = getPath();
300 		if( !path.equals( oldPath ) )
301 		{
302 			getConfig().setPath( path );
303 			notifyPropertyChanged( PATH_PROPERTY, oldPath, path );
304 
305 			for( WsdlInterface iface : getMockedInterfaces() )
306 			{
307 				if( Arrays.asList( iface.getEndpoints() ).contains( oldEndpoint ) )
308 					iface.changeEndpoint( oldEndpoint, getLocalEndpoint() );
309 			}
310 		}
311 	}
312 
313 	public MockRunListener[] getMockRunListeners()
314 	{
315 		return mockRunListeners.toArray( new MockRunListener[mockRunListeners.size()] );
316 	}
317 
318 	public void removeMockOperation( WsdlMockOperation mockOperation )
319 	{
320 		int ix = mockOperations.indexOf( mockOperation );
321 		if( ix == -1 )
322 			throw new RuntimeException( "Unkonws MockOperation specified to removeMockOperation" );
323 
324 		mockOperations.remove( ix );
325 		fireMockOperationRemoved( mockOperation );
326 		mockOperation.release();
327 		getConfig().removeMockOperation( ix );
328 	}
329 
330 	public void addMockServiceListener( MockServiceListener listener )
331 	{
332 		mockServiceListeners.add( listener );
333 	}
334 
335 	public void removeMockServiceListener( MockServiceListener listener )
336 	{
337 		mockServiceListeners.remove( listener );
338 	}
339 
340 	protected void fireMockOperationAdded( WsdlMockOperation mockOperation )
341 	{
342 		MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners
343 				.size()] );
344 		for( MockServiceListener listener : listeners )
345 		{
346 			listener.mockOperationAdded( mockOperation );
347 		}
348 	}
349 
350 	protected void fireMockOperationRemoved( WsdlMockOperation mockOperation )
351 	{
352 		MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners
353 				.size()] );
354 		for( MockServiceListener listener : listeners )
355 		{
356 			listener.mockOperationRemoved( mockOperation );
357 		}
358 	}
359 
360 	protected void fireMockResponseAdded( WsdlMockResponse mockResponse )
361 	{
362 		MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners
363 				.size()] );
364 		for( MockServiceListener listener : listeners )
365 		{
366 			listener.mockResponseAdded( mockResponse );
367 		}
368 	}
369 
370 	protected void fireMockResponseRemoved( WsdlMockResponse mockResponse )
371 	{
372 		MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners
373 				.size()] );
374 		for( MockServiceListener listener : listeners )
375 		{
376 			listener.mockResponseRemoved( mockResponse );
377 		}
378 	}
379 
380 	@Override
381 	public ImageIcon getIcon()
382 	{
383 		return iconAnimator.getIcon();
384 	}
385 
386 	public WsdlMockOperation getFaultMockOperation()
387 	{
388 		return faultMockOperation;
389 	}
390 
391 	public void setFaultMockOperation( WsdlMockOperation mockOperation )
392 	{
393 		faultMockOperation = mockOperation;
394 		if( faultMockOperation == null )
395 		{
396 			if( getConfig().isSetFaultMockOperation() )
397 			{
398 				getConfig().unsetFaultMockOperation();
399 			}
400 		}
401 		else
402 		{
403 			getConfig().setFaultMockOperation( faultMockOperation.getName() );
404 		}
405 	}
406 
407 	private class MockServiceIconAnimator extends ModelItemIconAnimator<WsdlMockService> implements MockRunListener
408 	{
409 		public MockServiceIconAnimator()
410 		{
411 			super( WsdlMockService.this, "/mockService.gif", "/mockService", 4, "gif" );
412 		}
413 
414 		public MockResult onMockRequest( MockRunner runner, HttpServletRequest request, HttpServletResponse response )
415 		{
416 			return null;
417 		}
418 
419 		public void onMockResult( MockResult result )
420 		{
421 		}
422 
423 		public void onMockRunnerStart( MockRunner mockRunner )
424 		{
425 			start();
426 		}
427 
428 		public void onMockRunnerStop( MockRunner mockRunner )
429 		{
430 			stop();
431 			WsdlMockService.this.mockRunner = null;
432 		}
433 	}
434 
435 	public String getLocalEndpoint()
436 	{
437 		String host = getHost();
438 		if( StringUtils.isNullOrEmpty( host ) )
439 			host = "127.0.0.1";
440 
441 		return "http://" + host + ":" + getPort() + getPath();
442 	}
443 
444 	public boolean isRequireSoapVersion()
445 	{
446 		return getSettings().getBoolean( REQUIRE_SOAP_VERSION );
447 	}
448 
449 	public void setRequireSoapVersion( boolean requireSoapVersion )
450 	{
451 		getSettings().setBoolean( REQUIRE_SOAP_VERSION, requireSoapVersion );
452 	}
453 
454 	public boolean isRequireSoapAction()
455 	{
456 		return getSettings().getBoolean( REQUIRE_SOAP_ACTION );
457 	}
458 
459 	public void setRequireSoapAction( boolean requireSoapAction )
460 	{
461 		getSettings().setBoolean( REQUIRE_SOAP_ACTION, requireSoapAction );
462 	}
463 
464 	public WsdlMockRunner start() throws Exception
465 	{
466 		return start( null );
467 	}
468 
469 	public boolean hasMockOperation( Operation operation )
470 	{
471 		return getMockOperation( operation ) != null;
472 	}
473 
474 	public void setStartScript( String script )
475 	{
476 		String oldScript = getStartScript();
477 
478 		if( !getConfig().isSetStartScript() )
479 			getConfig().addNewStartScript();
480 
481 		getConfig().getStartScript().setStringValue( script );
482 
483 		if( startScriptEngine != null )
484 			startScriptEngine.setScript( script );
485 
486 		notifyPropertyChanged( START_SCRIPT_PROPERTY, oldScript, script );
487 	}
488 
489 	public String getStartScript()
490 	{
491 		return getConfig().isSetStartScript() ? getConfig().getStartScript().getStringValue() : null;
492 	}
493 
494 	public void setStopScript( String script )
495 	{
496 		String oldScript = getStopScript();
497 
498 		if( !getConfig().isSetStopScript() )
499 			getConfig().addNewStopScript();
500 
501 		getConfig().getStopScript().setStringValue( script );
502 		if( stopScriptEngine != null )
503 			stopScriptEngine.setScript( script );
504 
505 		notifyPropertyChanged( STOP_SCRIPT_PROPERTY, oldScript, script );
506 	}
507 
508 	public String getStopScript()
509 	{
510 		return getConfig().isSetStopScript() ? getConfig().getStopScript().getStringValue() : null;
511 	}
512 
513 	public Object runStartScript( WsdlMockRunContext runContext, WsdlMockRunner runner ) throws Exception
514 	{
515 		String script = getStartScript();
516 		if( StringUtils.isNullOrEmpty( script ) )
517 			return null;
518 
519 		if( startScriptEngine == null )
520 		{
521 			startScriptEngine = SoapUIScriptEngineRegistry.create( this );
522 			startScriptEngine.setScript( script );
523 		}
524 
525 		startScriptEngine.setVariable( "context", runContext );
526 		startScriptEngine.setVariable( "mockRunner", runner );
527 		startScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
528 		return startScriptEngine.run();
529 	}
530 
531 	public Object runStopScript( WsdlMockRunContext runContext, WsdlMockRunner runner ) throws Exception
532 	{
533 		String script = getStopScript();
534 		if( StringUtils.isNullOrEmpty( script ) )
535 			return null;
536 
537 		if( stopScriptEngine == null )
538 		{
539 			stopScriptEngine = SoapUIScriptEngineRegistry.create( this );
540 			stopScriptEngine.setScript( script );
541 		}
542 
543 		stopScriptEngine.setVariable( "context", runContext );
544 		stopScriptEngine.setVariable( "mockRunner", runner );
545 		stopScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
546 		return stopScriptEngine.run();
547 	}
548 
549 	public void setOnRequestScript( String script )
550 	{
551 		String oldScript = getOnRequestScript();
552 
553 		if( !getConfig().isSetOnRequestScript() )
554 			getConfig().addNewOnRequestScript();
555 
556 		getConfig().getOnRequestScript().setStringValue( script );
557 
558 		if( onRequestScriptEnginePool != null )
559 			onRequestScriptEnginePool.setScript( script );
560 
561 		notifyPropertyChanged( "onRequestScript", oldScript, script );
562 	}
563 
564 	public String getOnRequestScript()
565 	{
566 		return getConfig().isSetOnRequestScript() ? getConfig().getOnRequestScript().getStringValue() : null;
567 	}
568 
569 	public void setAfterRequestScript( String script )
570 	{
571 		String oldScript = getAfterRequestScript();
572 
573 		if( !getConfig().isSetAfterRequestScript() )
574 			getConfig().addNewAfterRequestScript();
575 
576 		getConfig().getAfterRequestScript().setStringValue( script );
577 		if( afterRequestScriptEnginePool != null )
578 			afterRequestScriptEnginePool.setScript( script );
579 
580 		notifyPropertyChanged( "afterRequestScript", oldScript, script );
581 	}
582 
583 	public String getAfterRequestScript()
584 	{
585 		return getConfig().isSetAfterRequestScript() ? getConfig().getAfterRequestScript().getStringValue() : null;
586 	}
587 
588 	public Object runOnRequestScript( WsdlMockRunContext runContext, WsdlMockRunner runner, WsdlMockRequest mockRequest )
589 			throws Exception
590 	{
591 		String script = getOnRequestScript();
592 		if( StringUtils.isNullOrEmpty( script ) )
593 			return null;
594 
595 		if( onRequestScriptEnginePool == null )
596 		{
597 			onRequestScriptEnginePool = new ScriptEnginePool( this );
598 		}
599 
600 		SoapUIScriptEngine scriptEngine = onRequestScriptEnginePool.getScriptEngine();
601 
602 		try
603 		{
604 			scriptEngine.setVariable( "context", runContext );
605 			scriptEngine.setVariable( "mockRequest", mockRequest );
606 			scriptEngine.setVariable( "mockRunner", runner );
607 			scriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
608 			return scriptEngine.run();
609 		}
610 		finally
611 		{
612 			onRequestScriptEnginePool.returnScriptEngine( scriptEngine );
613 		}
614 	}
615 
616 	public Object runAfterRequestScript( WsdlMockRunContext runContext, WsdlMockRunner runner, MockResult mockResult )
617 			throws Exception
618 	{
619 		String script = getAfterRequestScript();
620 		if( StringUtils.isNullOrEmpty( script ) )
621 			return null;
622 
623 		if( afterRequestScriptEnginePool == null )
624 		{
625 			afterRequestScriptEnginePool = new ScriptEnginePool( this );
626 		}
627 
628 		SoapUIScriptEngine scriptEngine = afterRequestScriptEnginePool.getScriptEngine();
629 
630 		try
631 		{
632 			scriptEngine.setVariable( "context", runContext );
633 			scriptEngine.setVariable( "mockResult", mockResult );
634 			scriptEngine.setVariable( "mockRunner", runner );
635 			scriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
636 			return scriptEngine.run();
637 		}
638 		finally
639 		{
640 			afterRequestScriptEnginePool.returnScriptEngine( scriptEngine );
641 		}
642 	}
643 
644 	public List<? extends ModelItem> getChildren()
645 	{
646 		return mockOperations;
647 	}
648 
649 	public List<MockOperation> getMockOperationList()
650 	{
651 		return Collections.unmodifiableList( new ArrayList<MockOperation>( mockOperations ) );
652 	}
653 
654 	public String getIncomingWss()
655 	{
656 		return getConfig().getIncomingWss();
657 	}
658 
659 	public void setIncomingWss( String incomingWss )
660 	{
661 		String old = getIncomingWss();
662 		getConfig().setIncomingWss( incomingWss );
663 		notifyPropertyChanged( INCOMING_WSS, old, incomingWss );
664 	}
665 
666 	public String getOutgoingWss()
667 	{
668 		return getConfig().getOutgoingWss();
669 	}
670 
671 	public void setOutgoingWss( String outgoingWss )
672 	{
673 		String old = getOutgoingWss();
674 		getConfig().setOutgoingWss( outgoingWss );
675 		notifyPropertyChanged( OUGOING_WSS, old, outgoingWss );
676 	}
677 
678 	public boolean isDispatchResponseMessages()
679 	{
680 		return getConfig().getDispatchResponseMessages();
681 	}
682 
683 	public void setDispatchResponseMessages( boolean dispatchResponseMessages )
684 	{
685 		boolean old = isDispatchResponseMessages();
686 		getConfig().setDispatchResponseMessages( dispatchResponseMessages );
687 		notifyPropertyChanged( "dispatchResponseMessages", old, dispatchResponseMessages );
688 	}
689 
690 	public List<WsdlOperation> getMockedOperations()
691 	{
692 		List<WsdlOperation> result = new ArrayList<WsdlOperation>();
693 
694 		for( WsdlMockOperation mockOperation : mockOperations )
695 			result.add( mockOperation.getOperation() );
696 
697 		return result;
698 	}
699 
700 	public void setDocroot( String docroot )
701 	{
702 		docrootProperty.set( docroot, true );
703 	}
704 
705 	public String getDocroot()
706 	{
707 		return docrootProperty.get();
708 	}
709 
710 	@Override
711 	public void resolve( ResolveContext<?> context )
712 	{
713 		super.resolve( context );
714 		docrootProperty.resolveFile( context, "Missing MockService docroot" );
715 	}
716 
717 	public void replace( WsdlMockOperation mockOperation, MockOperationConfig reloadedMockOperation )
718 	{
719 		int ix = mockOperations.indexOf( mockOperation );
720 		if( ix == -1 )
721 			throw new RuntimeException( "Unkonws MockOperation specified to removeMockOperation" );
722 
723 		mockOperations.remove( ix );
724 		fireMockOperationRemoved( mockOperation );
725 		mockOperation.release();
726 		getConfig().removeMockOperation( ix );
727 
728 		MockOperationConfig newConfig = ( MockOperationConfig )getConfig().insertNewMockOperation( ix ).set(
729 				reloadedMockOperation ).changeType( MockOperationConfig.type );
730 		WsdlMockOperation newOperation = new WsdlMockOperation( this, newConfig );
731 		mockOperations.add( ix, newOperation );
732 		newOperation.afterLoad();
733 		fireMockOperationAdded( newOperation );
734 	}
735 
736 	
737 	public void export(File file)
738 	{
739 		try
740 		{
741 			this.getConfig().newCursor().save( file );
742 		}
743 		catch( IOException e )
744 		{
745 			e.printStackTrace();
746 		}
747 	}
748 
749 	
750 	public void importMockOperation(File file)
751 	{
752 		MockOperationConfig mockOperationNewConfig = null;
753 
754 		if( !file.exists() )
755 		{
756 			UISupport.showErrorMessage( "Error loading mock operation." );
757 			return;
758 		}
759 
760 		try
761 		{
762 			mockOperationNewConfig = MockOperationDocumentConfig.Factory.parse( file ).getMockOperation();
763 		}
764 		catch( Exception e )
765 		{
766 			SoapUI.logError( e );
767 		}
768 
769 		if( mockOperationNewConfig != null )
770 		{
771 			MockOperationConfig newConfig = ( MockOperationConfig )getConfig().addNewMockOperation().set( mockOperationNewConfig ).changeType(
772 					TestCaseConfig.type );
773 			WsdlMockOperation newMockOperation = new WsdlMockOperation(this, newConfig);
774 			ModelSupport.unsetIds( newMockOperation );
775 			newMockOperation.afterLoad();
776 			mockOperations.add( newMockOperation );
777 			fireMockOperationAdded( newMockOperation );
778 
779 			resolveImportedMockOperation( newMockOperation );
780 			
781 		}
782 		else
783 		{
784 			UISupport.showErrorMessage( "Not valild mock operation xml" );
785 		}		
786 	}
787 	
788 	private void resolveImportedMockOperation( WsdlMockOperation mockOperation )
789 	{
790 		ResolveDialog resolver = new ResolveDialog( "Validate MockOperation", "Checks MockOperation for inconsistencies", null );
791 		resolver.setShowOkMessage( false );
792 		resolver.resolve( mockOperation );
793 	}
794 
795 }