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