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