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 java.util.ArrayList;
16  import java.util.Arrays;
17  import java.util.HashSet;
18  import java.util.List;
19  import java.util.Set;
20  
21  import javax.servlet.http.HttpServletRequest;
22  import javax.servlet.http.HttpServletResponse;
23  import javax.swing.ImageIcon;
24  
25  import com.eviware.soapui.SoapUI;
26  import com.eviware.soapui.config.MockOperationConfig;
27  import com.eviware.soapui.config.MockServiceConfig;
28  import com.eviware.soapui.impl.wsdl.AbstractWsdlModelItem;
29  import com.eviware.soapui.impl.wsdl.WsdlInterface;
30  import com.eviware.soapui.impl.wsdl.WsdlOperation;
31  import com.eviware.soapui.impl.wsdl.WsdlProject;
32  import com.eviware.soapui.impl.wsdl.support.ModelItemIconAnimator;
33  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
34  import com.eviware.soapui.model.iface.Operation;
35  import com.eviware.soapui.model.mock.MockResult;
36  import com.eviware.soapui.model.mock.MockRunListener;
37  import com.eviware.soapui.model.mock.MockRunner;
38  import com.eviware.soapui.model.mock.MockService;
39  import com.eviware.soapui.model.mock.MockServiceListener;
40  import com.eviware.soapui.model.project.Project;
41  
42  /***
43   * A MockService for simulation WsdlInterfaces and their operations
44   * 
45   * @author ole.matzura
46   */
47  
48  public class WsdlMockService extends AbstractWsdlModelItem<MockServiceConfig> implements MockService
49  {
50  	private static final String REQUIRE_SOAP_VERSION = WsdlMockService.class.getName() + "@require-soap-version";
51  	private List<WsdlMockOperation> mockOperations = new ArrayList<WsdlMockOperation>();
52     private Set<MockRunListener> mockRunListeners = new HashSet<MockRunListener>();
53     private Set<MockServiceListener> mockServiceListeners = new HashSet<MockServiceListener>();
54     private MockServiceIconAnimator iconAnimator;
55  	private WsdlMockRunner mockRunner;
56  	
57  	public WsdlMockService( Project project, MockServiceConfig config)
58  	{
59  		super( config, project, "/mockService.gif" );
60  		
61  		List<MockOperationConfig> testStepConfigs = config.getMockOperationList();
62        for (MockOperationConfig tsc : testStepConfigs )
63        {
64           WsdlMockOperation testStep = new WsdlMockOperation( this, tsc );
65           mockOperations.add( testStep );
66        }
67        
68        if( !config.isSetPort() || config.getPort() < 1 )
69        	config.setPort( 8080 );
70        
71        if( !config.isSetPath() )
72        	config.setPath( "/" );
73        
74        iconAnimator = new MockServiceIconAnimator();
75        addMockRunListener( iconAnimator );
76        
77        for (MockRunListener listener : SoapUI.getListenerRegistry().getListeners( MockRunListener.class ))
78        {
79            addMockRunListener(listener);
80        }
81  	}
82  
83  	public void addMockRunListener( MockRunListener listener )
84  	{
85  		mockRunListeners.add( listener );
86  	}
87  
88  	public String getPath()
89  	{
90  		return getConfig().getPath();
91  	}
92  
93  	public WsdlMockOperation getMockOperationAt( int index )
94  	{
95  		return mockOperations.get( index );
96  	}
97  
98  	public WsdlMockOperation getMockOperationByName( String name )
99  	{
100 		return ( WsdlMockOperation ) getWsdlModelItemByName( mockOperations, name );
101 	}
102 
103 	public int getMockOperationCount()
104 	{
105 		return mockOperations.size();
106 	}
107 
108 	public WsdlProject getProject()
109 	{
110 		return ( WsdlProject ) getParent();
111 	}
112 
113 	public int getPort()
114 	{
115 		return getConfig().getPort();
116 	}
117 
118 	public void removeMockRunListener( MockRunListener listener )
119 	{
120 		mockRunListeners.remove( listener );
121 	}
122 
123 	public WsdlMockRunner start( WsdlTestRunContext context ) throws Exception
124 	{
125 		String path = getPath();
126 		if( path == null || path.trim().length() == 0 || path.trim().charAt( 0 ) != '/' )
127 			throw new Exception( "Invalid path; must start with '/'");
128 		
129 		mockRunner = new WsdlMockRunner( this, context );
130 		return mockRunner;
131 	}
132 
133 	public WsdlMockRunner getMockRunner()
134 	{
135 		return mockRunner;
136 	}
137 
138 	public WsdlMockOperation getMockOperation( Operation operation )
139 	{
140 		for( int c = 0; c < getMockOperationCount(); c++ )
141 		{
142 			WsdlMockOperation mockOperation = mockOperations.get( c );
143 			if( mockOperation.getOperation() == operation )
144 				return mockOperation;
145 		}
146 		
147 		return null;
148 	}
149 
150 	public WsdlMockOperation addNewMockOperation( WsdlOperation operation )
151 	{
152 		if( getMockOperation( operation ) != null )
153 			return null;
154 		
155 		MockOperationConfig config = getConfig().addNewMockOperation();
156 		config.setName( operation.getName() );
157 		WsdlMockOperation mockOperation = new WsdlMockOperation( this, config, operation );
158 		
159 		mockOperations.add( mockOperation );
160 		fireMockOperationAdded( mockOperation );
161 		
162 		return mockOperation;
163 	}
164 
165 	public void setPort( int port )
166 	{
167 		String oldEndpoint = getLocalEndpoint();
168 		
169 		int oldPort = getPort();
170 		if( port != oldPort )
171 		{
172 			getConfig().setPort( port );
173 			notifyPropertyChanged( PORT_PROPERTY, oldPort, port );
174 
175 			for( WsdlInterface iface : getMockedInterfaces())
176 			{
177 				if( Arrays.asList( iface.getEndpoints() ).contains( oldEndpoint ))
178 					iface.changeEndpoint( oldEndpoint, getLocalEndpoint() );
179 			}
180 		}
181 	}
182 
183 	public WsdlInterface [] getMockedInterfaces()
184 	{
185 		Set<WsdlInterface> result = new HashSet<WsdlInterface>();
186 		
187 		for( WsdlMockOperation mockOperation : mockOperations )
188 		{
189 			WsdlOperation operation = mockOperation.getOperation();
190 			if( operation != null )
191 				result.add( operation.getInterface() );
192 		}
193 		
194 		return result.toArray( new WsdlInterface[result.size()] );
195 	}
196 
197 	public void release()
198 	{
199 		super.release();
200 		
201 		for( WsdlMockOperation operation : mockOperations )
202 			operation.release();
203 		
204 		mockServiceListeners.clear();
205 	}
206 	
207 	public void setPath( String path )
208 	{
209 		String oldEndpoint = getLocalEndpoint();
210 		
211 		String oldPath = getPath();
212 		if( !path.equals( oldPath ))
213 		{
214 			getConfig().setPath( path );
215 			notifyPropertyChanged( PATH_PROPERTY, oldPath, path );
216 			
217 			for( WsdlInterface iface : getMockedInterfaces())
218 			{
219 				if( Arrays.asList( iface.getEndpoints() ).contains( oldEndpoint ))
220 					iface.changeEndpoint( oldEndpoint, getLocalEndpoint() );
221 			}
222 		}
223 	}
224 
225 	public MockRunListener [] getMockRunListeners()
226 	{
227 		return mockRunListeners.toArray( new MockRunListener[mockRunListeners.size()] );
228 	}
229 
230 	public void removeMockOperation( WsdlMockOperation mockOperation )
231 	{
232 		int ix = mockOperations.indexOf( mockOperation );
233 		if( ix == -1 )
234 			throw new RuntimeException( "Unkonws MockOperation specified to removeMockOperation" );
235 		
236 		mockOperations.remove( ix );
237 		fireMockOperationRemoved( mockOperation );
238 		mockOperation.release();
239 		getConfig().removeMockOperation( ix );
240 	}
241 
242 	public void addMockServiceListener( MockServiceListener listener )
243 	{
244 		mockServiceListeners.add(  listener  );
245 	}
246 
247 	public void removeMockServiceListener( MockServiceListener listener )
248 	{
249 		mockServiceListeners.remove( listener );
250 	}
251 	
252 	protected void fireMockOperationAdded( WsdlMockOperation mockOperation )
253 	{
254 		MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners.size()] );
255 		for( MockServiceListener listener : listeners )
256 		{
257 			listener.mockOperationAdded( mockOperation );
258 		}
259 	}
260 	
261 	protected void fireMockOperationRemoved( WsdlMockOperation mockOperation )
262 	{
263 		MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners.size()] );
264 		for( MockServiceListener listener : listeners )
265 		{
266 			listener.mockOperationRemoved( mockOperation );
267 		}
268 	}
269 	
270 	protected void fireMockResponseAdded( WsdlMockResponse mockResponse )
271 	{
272 		MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners.size()] );
273 		for( MockServiceListener listener : listeners )
274 		{
275 			listener.mockResponseAdded( mockResponse );
276 		}
277 	}
278 	
279 	protected void fireMockResponseRemoved( WsdlMockResponse mockResponse )
280 	{
281 		MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners.size()] );
282 		for( MockServiceListener listener : listeners )
283 		{
284 			listener.mockResponseRemoved( mockResponse );
285 		}
286 	}
287 
288 	@Override
289 	public ImageIcon getIcon()
290 	{
291 		return iconAnimator.getIcon();
292 	}
293 
294 	private class MockServiceIconAnimator extends ModelItemIconAnimator implements MockRunListener
295 	{
296 		public MockServiceIconAnimator()
297 		{
298 			super( WsdlMockService.this, "/mockService.gif", 
299 					new String[] {"/mockService_1.gif", "/mockService_2.gif",
300 						"/mockService_3.gif", "/mockService_4.gif"} );
301 		}
302 
303 		public void onMockRequest( MockRunner runner, HttpServletRequest request, HttpServletResponse response )
304 		{
305 		}
306 
307 		public void onMockResult( MockResult result )
308 		{
309 		}
310 
311 		public void onMockRunnerStart( MockRunner mockRunner )
312 		{
313 			start();
314 		}
315 
316 		public void onMockRunnerStop( MockRunner mockRunner )
317 		{
318 			stop();
319 			WsdlMockService.this.mockRunner = null; 
320 		}
321 	}
322 	
323 	public String getLocalEndpoint()
324 	{
325 		return "http://127.0.0.1:" + getPort() + getPath();
326 	}
327 
328 	public boolean isRequireSoapVersion()
329 	{
330 		return getSettings().getBoolean( REQUIRE_SOAP_VERSION );
331 	}
332 	
333 	public void setRequireSoapVersion( boolean requireSoapVersion )
334 	{
335 	   getSettings().setBoolean( REQUIRE_SOAP_VERSION, requireSoapVersion );	
336 	}
337 
338 	public WsdlMockRunner start() throws Exception
339 	{
340 		return start( null );
341 	}
342 
343 	public boolean hasMockOperation( Operation operation )
344 	{
345 		return getMockOperation( operation ) != null;
346 	}
347 
348 	@Override
349 	public void onSave()
350 	{
351 		for( WsdlMockOperation mockOperation : mockOperations )
352 			mockOperation.onSave();
353 	}
354 }