1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.mock;
14
15 import com.eviware.soapui.SoapUI;
16 import com.eviware.soapui.config.MockOperationConfig;
17 import com.eviware.soapui.config.MockOperationDispatchStyleConfig;
18 import com.eviware.soapui.config.MockResponseConfig;
19 import com.eviware.soapui.impl.wsdl.AbstractWsdlModelItem;
20 import com.eviware.soapui.impl.wsdl.WsdlInterface;
21 import com.eviware.soapui.impl.wsdl.WsdlOperation;
22 import com.eviware.soapui.impl.wsdl.mock.dispatch.MockOperationDispatchRegistry;
23 import com.eviware.soapui.impl.wsdl.mock.dispatch.MockOperationDispatcher;
24 import com.eviware.soapui.impl.wsdl.support.CompressedStringSupport;
25 import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils;
26 import com.eviware.soapui.model.ModelItem;
27 import com.eviware.soapui.model.iface.Interface;
28 import com.eviware.soapui.model.iface.Operation;
29 import com.eviware.soapui.model.mock.MockOperation;
30 import com.eviware.soapui.model.mock.MockResponse;
31 import com.eviware.soapui.model.support.InterfaceListenerAdapter;
32 import com.eviware.soapui.model.support.ProjectListenerAdapter;
33 import com.eviware.soapui.settings.WsdlSettings;
34 import com.eviware.soapui.support.UISupport;
35 import org.apache.log4j.Logger;
36
37 import javax.swing.*;
38 import java.beans.PropertyChangeEvent;
39 import java.beans.PropertyChangeListener;
40 import java.util.ArrayList;
41 import java.util.List;
42
43 /***
44 * A WsdlMockOperation in a WsdlMockService
45 *
46 * @author ole.matzura
47 */
48
49 public class WsdlMockOperation extends AbstractWsdlModelItem<MockOperationConfig> implements MockOperation, PropertyChangeListener
50 {
51 private final static Logger log = Logger.getLogger( WsdlMockOperation.class );
52
53 public final static String DISPATCH_STYLE_PROPERTY = WsdlMockOperation.class.getName() + "@dispatchstyle";
54 public final static String DEFAULT_RESPONSE_PROPERTY = WsdlMockOperation.class.getName() + "@defaultresponse";
55 public final static String DISPATCH_PATH_PROPERTY = WsdlMockOperation.class.getName() + "@dispatchpath";
56 public final static String OPERATION_PROPERTY = WsdlMockOperation.class.getName() + "@operation";
57
58 private WsdlOperation operation;
59 private MockOperationDispatcher dispatcher;
60 private List<WsdlMockResponse> responses = new ArrayList<WsdlMockResponse>();
61 private InternalInterfaceListener interfaceListener = new InternalInterfaceListener();
62 private InternalProjectListener projectListener = new InternalProjectListener();
63 private ImageIcon oneWayIcon;
64 private ImageIcon notificationIcon;
65 private ImageIcon solicitResponseIcon;
66
67 public WsdlMockOperation( WsdlMockService mockService, MockOperationConfig config )
68 {
69 super( config, mockService, "/mockOperation.gif" );
70
71 Interface iface = mockService.getProject().getInterfaceByName( config.getInterface() );
72 if( iface == null )
73 {
74 SoapUI.log.warn( "Missing interface [" + config.getInterface() +
75 "] for MockOperation in project" );
76 }
77 else
78 {
79 operation = (WsdlOperation) iface.getOperationByName( config.getOperation() );
80 }
81
82 List<MockResponseConfig> responseConfigs = config.getResponseList();
83 for( MockResponseConfig responseConfig : responseConfigs )
84 {
85 WsdlMockResponse wsdlMockResponse = new WsdlMockResponse( this, responseConfig );
86 wsdlMockResponse.addPropertyChangeListener( this );
87 responses.add( wsdlMockResponse );
88 }
89
90 initData( config );
91 }
92
93 private void initData( MockOperationConfig config )
94 {
95 if( !config.isSetName() )
96 config.setName( operation == null ? "<missing operation>" : operation.getName() );
97
98 if( !config.isSetDefaultResponse() && responses.size() > 0 )
99 setDefaultResponse( responses.get( 0 ).getName() );
100
101 if( !config.isSetDispatchStyle() )
102 config.setDispatchStyle( MockOperationDispatchStyleConfig.SEQUENCE );
103
104 if( !getConfig().isSetDispatchConfig() )
105 getConfig().addNewDispatchConfig();
106
107 dispatcher = MockOperationDispatchRegistry.buildDispatcher( config.getDispatchStyle().toString(), this );
108
109 if( operation != null )
110 {
111 operation.getInterface().getProject().addProjectListener( projectListener );
112 operation.getInterface().addInterfaceListener( interfaceListener );
113 operation.getInterface().addPropertyChangeListener( WsdlInterface.NAME_PROPERTY, this );
114 }
115
116 oneWayIcon = UISupport.createImageIcon( "/onewaymockoperation.gif" );
117 notificationIcon = UISupport.createImageIcon( "/mocknotificationoperation.gif" );
118 solicitResponseIcon = UISupport.createImageIcon( "/mocksolicitresponseoperation.gif" );
119 }
120
121 public WsdlMockOperation( WsdlMockService mockService, MockOperationConfig config, WsdlOperation operation )
122 {
123 super( config, mockService, "/mockOperation.gif" );
124 this.operation = operation;
125
126 config.setInterface( operation.getInterface().getName() );
127 config.setOperation( operation.getName() );
128
129 initData( config );
130 interfaceListener = new InternalInterfaceListener();
131 }
132
133 @Override
134 public ImageIcon getIcon()
135 {
136 if( operation != null )
137 {
138 if( isOneWay() )
139 {
140 return oneWayIcon;
141 }
142 else if( isNotification() )
143 {
144 return notificationIcon;
145 }
146 else if( isSolicitResponse() )
147 {
148 return solicitResponseIcon;
149 }
150 }
151
152 return super.getIcon();
153 }
154
155 public WsdlMockService getMockService()
156 {
157 return (WsdlMockService) getParent();
158 }
159
160 public WsdlMockResponse getMockResponseAt( int index )
161 {
162 return responses.get( index );
163 }
164
165 public WsdlOperation getOperation()
166 {
167 return operation;
168 }
169
170 public WsdlMockResponse getMockResponseByName( String name )
171 {
172 return (WsdlMockResponse) getWsdlModelItemByName( responses, name );
173 }
174
175 public int getMockResponseCount()
176 {
177 return responses.size();
178 }
179
180 public WsdlMockResponse addNewMockResponse( MockResponseConfig responseConfig )
181 {
182 WsdlMockResponse mockResponse = new WsdlMockResponse( this, responseConfig );
183
184 responses.add( mockResponse );
185 if( responses.size() == 1 )
186 setDefaultResponse( mockResponse.getName() );
187
188
189 WsdlUtils.setDefaultWsaAction( mockResponse.getWsaConfig(), true );
190
191 ( getMockService() ).fireMockResponseAdded( mockResponse );
192 notifyPropertyChanged( "mockResponses", null, mockResponse );
193
194 return mockResponse;
195 }
196
197 public WsdlMockResponse addNewMockResponse( String name, boolean createResponse )
198 {
199 MockResponseConfig responseConfig = getConfig().addNewResponse();
200 responseConfig.setName( name );
201 responseConfig.addNewResponseContent();
202
203 if( createResponse && getOperation() != null && getOperation().isBidirectional() )
204 {
205 boolean createOptional = SoapUI.getSettings().getBoolean( WsdlSettings.XML_GENERATION_ALWAYS_INCLUDE_OPTIONAL_ELEMENTS );
206 CompressedStringSupport.setString( responseConfig.getResponseContent(), getOperation().createResponse( createOptional ) );
207 }
208
209 return addNewMockResponse( responseConfig );
210 }
211
212 public void removeMockResponse( WsdlMockResponse mockResponse )
213 {
214 int ix = responses.indexOf( mockResponse );
215 responses.remove( ix );
216 mockResponse.removePropertyChangeListener( this );
217
218 try
219 {
220 ( getMockService() ).fireMockResponseRemoved( mockResponse );
221 }
222 finally
223 {
224 mockResponse.release();
225 getConfig().removeResponse( ix );
226 }
227 }
228
229 public WsdlMockResult dispatchRequest( WsdlMockRequest request ) throws DispatchException
230 {
231 try
232 {
233 request.setOperation( getOperation() );
234 WsdlMockResult result = new WsdlMockResult( request );
235
236 if( getMockResponseCount() == 0 )
237 throw new DispatchException( "Missing MockResponse(s) in MockOperation [" + getName() + "]" );
238
239 result.setMockOperation( this );
240 WsdlMockResponse response = dispatcher.selectMockResponse( request, result );
241 if( response == null )
242 {
243 response = getMockResponseByName( getDefaultResponse() );
244 }
245
246 if( response == null )
247 {
248 throw new DispatchException( "Failed to find MockResponse" );
249 }
250
251 result.setMockResponse( response );
252 response.execute( request, result );
253
254 return result;
255 }
256 catch( Throwable e )
257 {
258 if( e instanceof DispatchException )
259 throw (DispatchException) e;
260 else
261 throw new DispatchException( e );
262 }
263 }
264
265 @Override
266 public void release()
267 {
268 super.release();
269
270 if( dispatcher != null )
271 dispatcher.release();
272
273 for( WsdlMockResponse response : responses )
274 {
275 response.removePropertyChangeListener( this );
276 response.release();
277 }
278
279 if( operation != null )
280 {
281 operation.getInterface().getProject().removeProjectListener( projectListener );
282 operation.getInterface().removeInterfaceListener( interfaceListener );
283 operation.getInterface().removePropertyChangeListener( WsdlInterface.NAME_PROPERTY, this );
284 }
285 }
286
287 public String getDispatchStyle()
288 {
289 return String.valueOf( getConfig().isSetDispatchStyle() ? getConfig().getDispatchStyle() : MockOperationDispatchStyleConfig.SEQUENCE );
290 }
291
292 public MockOperationDispatcher setDispatchStyle( String dispatchStyle )
293 {
294 String old = getDispatchStyle();
295 if( dispatcher != null && dispatchStyle.equals( old ) )
296 return dispatcher;
297
298 getConfig().setDispatchStyle( MockOperationDispatchStyleConfig.Enum.forString( dispatchStyle ) );
299
300 if( dispatcher != null )
301 {
302 dispatcher.release();
303 }
304
305 if( !getConfig().isSetDispatchConfig() )
306 getConfig().addNewDispatchConfig();
307
308 dispatcher = MockOperationDispatchRegistry.buildDispatcher( dispatchStyle, this );
309
310 notifyPropertyChanged( DISPATCH_STYLE_PROPERTY, old, dispatchStyle );
311
312 return dispatcher;
313 }
314
315 public String getDispatchPath()
316 {
317 return getConfig().getDispatchPath();
318 }
319
320 public void setDispatchPath( String dispatchPath )
321 {
322 String old = getDispatchPath();
323 getConfig().setDispatchPath( dispatchPath );
324 notifyPropertyChanged( DISPATCH_PATH_PROPERTY, old, dispatchPath );
325 }
326
327 public String getWsdlOperationName()
328 {
329 return operation == null ? null : operation.getName();
330 }
331
332 public String getDefaultResponse()
333 {
334 return getConfig().getDefaultResponse();
335 }
336
337 public void setDefaultResponse( String defaultResponse )
338 {
339 String old = getDefaultResponse();
340 getConfig().setDefaultResponse( defaultResponse );
341 notifyPropertyChanged( DEFAULT_RESPONSE_PROPERTY, old, defaultResponse );
342 }
343
344 public List<MockResponse> getMockResponses()
345 {
346 return new ArrayList<MockResponse>( responses );
347 }
348
349 public void propertyChange( PropertyChangeEvent arg0 )
350 {
351 if( arg0.getPropertyName().equals( WsdlMockResponse.NAME_PROPERTY ) )
352 {
353 if( arg0.getOldValue().equals( getDefaultResponse() ) )
354 setDefaultResponse( arg0.getNewValue().toString() );
355 }
356 else if( arg0.getPropertyName().equals( WsdlInterface.NAME_PROPERTY ) )
357 {
358 getConfig().setInterface( arg0.getNewValue().toString() );
359 }
360 }
361
362 public WsdlMockResult getLastMockResult()
363 {
364 WsdlMockResult result = null;
365
366 for( WsdlMockResponse response : responses )
367 {
368 WsdlMockResult mockResult = response.getMockResult();
369 if( mockResult != null )
370 {
371 if( result == null || result.getTimestamp() > mockResult.getTimestamp() )
372 result = mockResult;
373 }
374 }
375
376 return result;
377 }
378
379 public void setOperation( WsdlOperation operation )
380 {
381 WsdlOperation oldOperation = getOperation();
382
383 if( operation == null )
384 {
385 getConfig().unsetInterface();
386 getConfig().unsetOperation();
387 }
388 else
389 {
390 getConfig().setInterface( operation.getInterface().getName() );
391 getConfig().setOperation( operation.getName() );
392 }
393
394 this.operation = operation;
395
396 notifyPropertyChanged( OPERATION_PROPERTY, oldOperation, operation );
397 }
398
399 public MockOperationDispatcher getMockOperationDispatcher()
400 {
401 return dispatcher;
402 }
403
404 private class InternalInterfaceListener extends InterfaceListenerAdapter
405 {
406 @Override
407 public void operationUpdated( Operation operation )
408 {
409 if( operation == WsdlMockOperation.this.operation )
410 getConfig().setOperation( operation.getName() );
411 }
412
413 @Override
414 public void operationRemoved( Operation operation )
415 {
416 if( operation == WsdlMockOperation.this.operation )
417 getMockService().removeMockOperation( WsdlMockOperation.this );
418 }
419 }
420
421 private class InternalProjectListener extends ProjectListenerAdapter
422 {
423 @Override
424 public void interfaceRemoved( Interface iface )
425 {
426 if( operation.getInterface() == iface )
427 getMockService().removeMockOperation( WsdlMockOperation.this );
428 }
429
430 @Override
431 public void interfaceUpdated( Interface iface )
432 {
433 if( operation.getInterface() == iface )
434 getConfig().setInterface( iface.getName() );
435 }
436 }
437
438 public boolean isOneWay()
439 {
440 return operation == null ? false : operation.isOneWay();
441 }
442
443 public boolean isNotification()
444 {
445 return operation == null ? false : operation.isNotification();
446 }
447
448 public boolean isSolicitResponse()
449 {
450 return operation == null ? false : operation.isSolicitResponse();
451 }
452
453 public boolean isUnidirectional()
454 {
455 return operation == null ? false : operation.isUnidirectional();
456 }
457
458 public boolean isBidirectional()
459 {
460 return !isUnidirectional();
461 }
462
463 public List<? extends ModelItem> getChildren()
464 {
465 return responses;
466 }
467 }