View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2007 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.impl.wsdl.mock;
14  
15  import groovy.lang.GroovyShell;
16  
17  import java.util.ArrayList;
18  import java.util.HashSet;
19  import java.util.List;
20  import java.util.Set;
21  
22  import javax.servlet.http.HttpServletRequest;
23  import javax.servlet.http.HttpServletResponse;
24  import javax.swing.ImageIcon;
25  
26  import com.eviware.soapui.config.MockOperationConfig;
27  import com.eviware.soapui.config.MockServiceConfig;
28  import com.eviware.soapui.impl.actions.ShowDesktopPanelAction;
29  import com.eviware.soapui.impl.wsdl.AbstractWsdlModelItem;
30  import com.eviware.soapui.impl.wsdl.WsdlOperation;
31  import com.eviware.soapui.impl.wsdl.WsdlProject;
32  import com.eviware.soapui.impl.wsdl.actions.mockservice.AddNewMockOperationAction;
33  import com.eviware.soapui.impl.wsdl.actions.mockservice.CloneMockServiceAction;
34  import com.eviware.soapui.impl.wsdl.actions.mockservice.RemoveMockServiceAction;
35  import com.eviware.soapui.impl.wsdl.actions.mockservice.RenameMockServiceAction;
36  import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
37  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
38  import com.eviware.soapui.impl.wsdl.support.ModelItemIconAnimator;
39  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
40  import com.eviware.soapui.model.iface.Operation;
41  import com.eviware.soapui.model.mock.MockResult;
42  import com.eviware.soapui.model.mock.MockRunListener;
43  import com.eviware.soapui.model.mock.MockRunner;
44  import com.eviware.soapui.model.mock.MockService;
45  import com.eviware.soapui.model.mock.MockServiceListener;
46  import com.eviware.soapui.model.project.Project;
47  import com.eviware.soapui.support.ScriptingSupport;
48  import com.eviware.soapui.support.action.ActionSupport;
49  
50  public class WsdlMockService extends AbstractWsdlModelItem<MockServiceConfig> implements MockService
51  {
52  	private static final String REQUIRE_SOAP_VERSION = WsdlMockService.class.getName() + "@require-soap-version";
53  	private List<WsdlMockOperation> mockOperations = new ArrayList<WsdlMockOperation>();
54     private Set<MockRunListener> mockRunListeners = new HashSet<MockRunListener>();
55     private Set<MockServiceListener> mockServiceListeners = new HashSet<MockServiceListener>();
56     private MockServiceIconAnimator iconAnimator;
57  	private WsdlMockRunner mockRunner;
58  	private GroovyShell shell;
59  	
60  	public WsdlMockService( Project project, MockServiceConfig config)
61  	{
62  		super( config, project, "/mockService.gif" );
63  		
64  		List<MockOperationConfig> testStepConfigs = config.getMockOperationList();
65        for (MockOperationConfig tsc : testStepConfigs )
66        {
67           WsdlMockOperation testStep = new WsdlMockOperation( this, tsc );
68           mockOperations.add( testStep );
69        }
70        
71        if( !config.isSetPort() || config.getPort() < 1 )
72        	config.setPort( 8080 );
73        
74        if( !config.isSetPath() )
75        	config.setPath( "/" );
76        
77        addAction( new ShowDesktopPanelAction( "Open MockService Editor", 
78           		"Opens the MockService Editor for this MockService", this ));
79       // addAction( new MockServiceOptionsAction( this ));
80        addAction( ActionSupport.SEPARATOR_ACTION );
81        addAction( new AddNewMockOperationAction( this ));
82        addAction( new CloneMockServiceAction( this ));
83        addAction( ActionSupport.SEPARATOR_ACTION );
84        addAction( new RenameMockServiceAction( this ) );
85        addAction( new RemoveMockServiceAction( this ) );
86        addAction( ActionSupport.SEPARATOR_ACTION );
87        addAction( new ShowOnlineHelpAction( HelpUrls.MOCKSERVICE_HELP_URL ));
88        
89        iconAnimator = new MockServiceIconAnimator();
90        addMockRunListener( iconAnimator );
91        
92        shell = ScriptingSupport.createGroovyShell( null );
93  	}
94  
95  	public void addMockRunListener( MockRunListener listener )
96  	{
97  		mockRunListeners.add( listener );
98  	}
99  
100 	public String getPath()
101 	{
102 		return getConfig().getPath();
103 	}
104 
105 	public WsdlMockOperation getMockOperationAt( int index )
106 	{
107 		return mockOperations.get( index );
108 	}
109 
110 	public WsdlMockOperation getMockOperationByName( String name )
111 	{
112 		return ( WsdlMockOperation ) getWsdlModelItemByName( mockOperations, name );
113 	}
114 
115 	public int getMockOperationCount()
116 	{
117 		return mockOperations.size();
118 	}
119 
120 	public WsdlProject getProject()
121 	{
122 		return ( WsdlProject ) getParent();
123 	}
124 
125 	public int getPort()
126 	{
127 		return getConfig().getPort();
128 	}
129 
130 	public void removeMockRunListener( MockRunListener listener )
131 	{
132 		mockRunListeners.remove( listener );
133 	}
134 
135 	public WsdlMockRunner start( WsdlTestRunContext context ) throws Exception
136 	{
137 		String path = getPath();
138 		if( path == null || path.trim().length() == 0 || path.trim().charAt( 0 ) != '/' )
139 			throw new Exception( "Invalid path; must start with '/'");
140 		
141 		mockRunner = new WsdlMockRunner( this, context );
142 		return mockRunner;
143 	}
144 
145 	public WsdlMockRunner getMockRunner()
146 	{
147 		return mockRunner;
148 	}
149 
150 	public boolean hasMockOperation( Operation operation )
151 	{
152 		for( int c = 0; c < getMockOperationCount(); c++ )
153 		{
154 			WsdlMockOperation mockOperation = mockOperations.get( c );
155 			if( mockOperation.getOperation() == operation )
156 				return true;
157 		}
158 		
159 		return false;
160 	}
161 
162 	public WsdlMockOperation addNewMockOperation( WsdlOperation operation )
163 	{
164 		if( hasMockOperation( operation ))
165 			return null;
166 		
167 		MockOperationConfig config = getConfig().addNewMockOperation();
168 		config.setName( operation.getName() );
169 		WsdlMockOperation mockOperation = new WsdlMockOperation( this, config, operation );
170 		
171 		mockOperations.add( mockOperation );
172 		fireMockOperationAdded( mockOperation );
173 		
174 		return mockOperation;
175 	}
176 
177 	public void setPort( int port )
178 	{
179 		int oldPort = getPort();
180 		if( port != oldPort )
181 		{
182 			getConfig().setPort( port );
183 			notifyPropertyChanged( PORT_PROPERTY, oldPort, port );
184 		}
185 	}
186 
187 	public void release()
188 	{
189 		super.release();
190 		
191 		for( WsdlMockOperation operation : mockOperations )
192 			operation.release();
193 	}
194 	
195 	public void setPath( String path )
196 	{
197 		String oldPath = getPath();
198 		if( !path.equals( oldPath ))
199 		{
200 			getConfig().setPath( path );
201 			notifyPropertyChanged( PATH_PROPERTY, oldPath, path );
202 		}
203 	}
204 
205 	public MockRunListener [] getMockRunListeners()
206 	{
207 		return mockRunListeners.toArray( new MockRunListener[mockRunListeners.size()] );
208 	}
209 
210 	public void removeMockOperation( WsdlMockOperation mockOperation )
211 	{
212 		int ix = mockOperations.indexOf( mockOperation );
213 		if( ix == -1 )
214 			throw new RuntimeException( "Unkonws MockOperation specified to removeMockOperation" );
215 		
216 		mockOperations.remove( ix );
217 		fireMockOperationRemoved( mockOperation );
218 		mockOperation.release();
219 		getConfig().removeMockOperation( ix );
220 	}
221 
222 	public void addMockServiceListener( MockServiceListener listener )
223 	{
224 		mockServiceListeners.add(  listener  );
225 	}
226 
227 	public void removeMockServiceListener( MockServiceListener listener )
228 	{
229 		mockServiceListeners.remove( listener );
230 	}
231 	
232 	protected void fireMockOperationAdded( WsdlMockOperation mockOperation )
233 	{
234 		MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners.size()] );
235 		for( MockServiceListener listener : listeners )
236 		{
237 			listener.mockOperationAdded( mockOperation );
238 		}
239 	}
240 	
241 	protected void fireMockOperationRemoved( WsdlMockOperation mockOperation )
242 	{
243 		MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners.size()] );
244 		for( MockServiceListener listener : listeners )
245 		{
246 			listener.mockOperationRemoved( mockOperation );
247 		}
248 	}
249 	
250 	protected void fireMockResponseAdded( WsdlMockResponse mockResponse )
251 	{
252 		MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners.size()] );
253 		for( MockServiceListener listener : listeners )
254 		{
255 			listener.mockResponseAdded( mockResponse );
256 		}
257 	}
258 	
259 	protected void fireMockResponseRemoved( WsdlMockResponse mockResponse )
260 	{
261 		MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners.size()] );
262 		for( MockServiceListener listener : listeners )
263 		{
264 			listener.mockResponseRemoved( mockResponse );
265 		}
266 	}
267 
268 	@Override
269 	public ImageIcon getIcon()
270 	{
271 		return iconAnimator.getIcon();
272 	}
273 
274 	private class MockServiceIconAnimator extends ModelItemIconAnimator implements MockRunListener
275 	{
276 		public MockServiceIconAnimator()
277 		{
278 			super( WsdlMockService.this, "/mockService.gif", 
279 					new String[] {"/mockService_1.gif", "/mockService_2.gif",
280 						"/mockService_3.gif", "/mockService_4.gif"} );
281 		}
282 
283 		public void onMockRequest( MockRunner runner, HttpServletRequest request, HttpServletResponse response )
284 		{
285 		}
286 
287 		public void onMockResult( MockResult result )
288 		{
289 		}
290 
291 		public void onMockRunnerStart( MockRunner mockRunner )
292 		{
293 			start();
294 		}
295 
296 		public void onMockRunnerStop( MockRunner mockRunner )
297 		{
298 			stop();
299 			WsdlMockService.this.mockRunner = null; 
300 		}
301 	}
302 	
303 	public String getLocalEndpoint()
304 	{
305 		return "http://127.0.0.1:" + getPort() + getPath();
306 	}
307 
308 	public GroovyShell getScriptShell()
309 	{
310 		return shell;
311 	}
312 
313 	public boolean isRequireSoapVersion()
314 	{
315 		return getSettings().getBoolean( REQUIRE_SOAP_VERSION );
316 	}
317 	
318 	public void setRequireSoapVersion( boolean requireSoapVersion )
319 	{
320 	   getSettings().setBoolean( REQUIRE_SOAP_VERSION, requireSoapVersion );	
321 	}
322 
323 	public WsdlMockRunner start() throws Exception
324 	{
325 		return start( null );
326 	}
327 }