1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.panels.teststeps;
14
15 import java.awt.BorderLayout;
16 import java.awt.Component;
17 import java.awt.event.ActionEvent;
18 import java.beans.PropertyChangeEvent;
19 import java.util.Date;
20
21 import javax.swing.AbstractAction;
22 import javax.swing.Action;
23 import javax.swing.JButton;
24 import javax.swing.JComponent;
25 import javax.swing.JLabel;
26 import javax.swing.JPanel;
27 import javax.swing.JScrollPane;
28 import javax.swing.JSplitPane;
29 import javax.swing.JTextArea;
30 import javax.swing.JTextField;
31 import javax.swing.text.Document;
32
33 import com.eviware.soapui.SoapUI;
34 import com.eviware.soapui.impl.support.components.ModelItemXmlEditor;
35 import com.eviware.soapui.impl.wsdl.mock.WsdlMockResponse;
36 import com.eviware.soapui.impl.wsdl.mock.WsdlMockResult;
37 import com.eviware.soapui.impl.wsdl.panels.mockoperation.AbstractWsdlMockResponseDesktopPanel;
38 import com.eviware.soapui.impl.wsdl.teststeps.WsdlMockResponseTestStep;
39 import com.eviware.soapui.model.ModelItem;
40 import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
41 import com.eviware.soapui.model.support.TestRunListenerAdapter;
42 import com.eviware.soapui.model.testsuite.Assertable;
43 import com.eviware.soapui.model.testsuite.AssertionError;
44 import com.eviware.soapui.model.testsuite.AssertionsListener;
45 import com.eviware.soapui.model.testsuite.LoadTestRunner;
46 import com.eviware.soapui.model.testsuite.TestAssertion;
47 import com.eviware.soapui.model.testsuite.TestCaseRunContext;
48 import com.eviware.soapui.model.testsuite.TestCaseRunner;
49 import com.eviware.soapui.model.testsuite.TestStep;
50 import com.eviware.soapui.model.testsuite.TestStepResult;
51 import com.eviware.soapui.monitor.support.TestMonitorListenerAdapter;
52 import com.eviware.soapui.support.DocumentListenerAdapter;
53 import com.eviware.soapui.support.ModelItemPropertyEditorModel;
54 import com.eviware.soapui.support.StringUtils;
55 import com.eviware.soapui.support.UISupport;
56 import com.eviware.soapui.support.components.JComponentInspector;
57 import com.eviware.soapui.support.components.JInspectorPanel;
58 import com.eviware.soapui.support.components.JInspectorPanelFactory;
59 import com.eviware.soapui.support.components.JXToolBar;
60 import com.eviware.soapui.support.xml.XmlUtils;
61
62 public class WsdlMockResponseStepDesktopPanel extends
63 AbstractWsdlMockResponseDesktopPanel<WsdlMockResponseTestStep, WsdlMockResponse>
64 {
65 private JTextArea logArea;
66 private AssertionsPanel assertionsPanel;
67 private JTextField portField;
68 private JTextField pathField;
69 private InternalTestRunListener testRunListener;
70 private InternalTestMonitorListener testMonitorListener = new InternalTestMonitorListener();
71 private InternalAssertionsListener assertionsListener = new InternalAssertionsListener();
72 private JInspectorPanel inspectorPanel;
73 private JComponentInspector<JComponent> assertionInspector;
74 private JComponentInspector<JComponent> logInspector;
75 private ModelItemPropertyEditorModel<WsdlMockResponseTestStep> queryEditorModel;
76 private ModelItemPropertyEditorModel<WsdlMockResponseTestStep> matchEditorModel;
77
78 public WsdlMockResponseStepDesktopPanel( WsdlMockResponseTestStep mockResponseStep )
79 {
80 super( mockResponseStep );
81 init( mockResponseStep.getMockResponse() );
82
83 testRunListener = new InternalTestRunListener();
84 mockResponseStep.getTestCase().addTestRunListener( testRunListener );
85
86 SoapUI.getTestMonitor().addTestMonitorListener( testMonitorListener );
87 setEnabled( !SoapUI.getTestMonitor().hasRunningTest( mockResponseStep.getTestCase() ) );
88
89 mockResponseStep.addAssertionsListener( assertionsListener );
90 }
91
92 @Override
93 protected JComponent buildContent()
94 {
95 inspectorPanel = JInspectorPanelFactory.build( super.buildContent() );
96
97 assertionsPanel = buildAssertionsPanel();
98
99 assertionInspector = new JComponentInspector<JComponent>( assertionsPanel, "Assertions ("
100 + getModelItem().getAssertionCount() + ")", "Assertions for this Test Request", true );
101
102 inspectorPanel.addInspector( assertionInspector );
103
104 logInspector = new JComponentInspector<JComponent>( buildLogPanel(), "Request Log (0)", "Log of requests", true );
105 inspectorPanel.addInspector( logInspector );
106
107 inspectorPanel.addInspector( new JComponentInspector<JComponent>( buildQueryMatchPanel(), "Query/Match",
108 "Query/Match configuration", true ) );
109
110 inspectorPanel.setDefaultDividerLocation( 0.6F );
111 inspectorPanel.setCurrentInspector( "Assertions" );
112
113 updateStatusIcon();
114
115 return inspectorPanel.getComponent();
116 }
117
118 private void updateStatusIcon()
119 {
120 Assertable.AssertionStatus status = getModelItem().getAssertionStatus();
121 switch( status )
122 {
123 case FAILED :
124 {
125 assertionInspector.setIcon( UISupport.createImageIcon( "/failed_assertion.gif" ) );
126 inspectorPanel.activate( assertionInspector );
127 break;
128 }
129 case UNKNOWN :
130 {
131 assertionInspector.setIcon( UISupport.createImageIcon( "/unknown_assertion.gif" ) );
132 break;
133 }
134 case VALID :
135 {
136 assertionInspector.setIcon( UISupport.createImageIcon( "/valid_assertion.gif" ) );
137 inspectorPanel.deactivate();
138 break;
139 }
140 }
141 }
142
143 private JComponent buildLogPanel()
144 {
145 logArea = new JTextArea();
146 logArea.setEditable( false );
147 logArea.setToolTipText( "Response Log" );
148
149 JPanel panel = new JPanel( new BorderLayout() );
150 panel.add( new JScrollPane( logArea ), BorderLayout.CENTER );
151
152 return panel;
153 }
154
155 public void setContent( JComponent content )
156 {
157 inspectorPanel.setContentComponent( content );
158 }
159
160 public void removeContent( JComponent content )
161 {
162 inspectorPanel.setContentComponent( null );
163 }
164
165 @Override
166 protected void createToolbar( JXToolBar toolbar )
167 {
168 toolbar.addUnrelatedGap();
169 toolbar.addFixed( new JLabel( "Path" ) );
170 toolbar.addRelatedGap();
171 pathField = new JTextField( getModelItem().getPath(), 15 );
172 pathField.getDocument().addDocumentListener( new DocumentListenerAdapter()
173 {
174
175 @Override
176 public void update( Document document )
177 {
178 getModelItem().setPath( pathField.getText() );
179 }
180 } );
181
182 toolbar.addFixed( pathField );
183
184 toolbar.addUnrelatedGap();
185 toolbar.addFixed( new JLabel( "Port" ) );
186 toolbar.addRelatedGap();
187 portField = new JTextField( String.valueOf( getModelItem().getPort() ), 5 );
188 portField.getDocument().addDocumentListener( new DocumentListenerAdapter()
189 {
190
191 @Override
192 public void update( Document document )
193 {
194 try
195 {
196 getModelItem().setPort( Integer.parseInt( portField.getText() ) );
197 }
198 catch( NumberFormatException e )
199 {
200 }
201 }
202 } );
203
204 toolbar.addFixed( portField );
205 }
206
207 private JComponent buildQueryMatchPanel()
208 {
209 JPanel panel = new JPanel( new BorderLayout() );
210 panel.add( buildQueryMatchToolbar(), BorderLayout.NORTH );
211 JSplitPane splitPane = UISupport.createHorizontalSplit( buildQueryEditor(), buildMatchEditor() );
212 panel.add( splitPane, BorderLayout.CENTER );
213 splitPane.setDividerLocation( 200 );
214 return panel;
215 }
216
217 private Component buildMatchEditor()
218 {
219 JPanel panel = new JPanel( new BorderLayout() );
220
221 matchEditorModel = new ModelItemPropertyEditorModel<WsdlMockResponseTestStep>( getModelItem(), "match" );
222 panel.add( UISupport.getEditorFactory().buildXmlEditor( matchEditorModel ), BorderLayout.CENTER );
223
224 UISupport.addTitledBorder( panel, "Matching Value" );
225
226 return panel;
227 }
228
229 private Component buildQueryEditor()
230 {
231 JPanel panel = new JPanel( new BorderLayout() );
232
233 queryEditorModel = new ModelItemPropertyEditorModel<WsdlMockResponseTestStep>( getModelItem(), "query" );
234 panel.add( UISupport.getEditorFactory().buildXPathEditor( queryEditorModel ), BorderLayout.CENTER );
235
236 UISupport.addTitledBorder( panel, "XPath Query" );
237
238 return panel;
239 }
240
241 protected JXToolBar buildQueryMatchToolbar()
242 {
243 JXToolBar toolBar = UISupport.createSmallToolbar();
244 toolBar.addFixed( new JButton( new SelectFromCurrentAction() ) );
245 return toolBar;
246 }
247
248 public class SelectFromCurrentAction extends AbstractAction
249 {
250 public SelectFromCurrentAction()
251 {
252 super( "Select from current" );
253 putValue( Action.SHORT_DESCRIPTION,
254 "Selects the Query XPath expression from the last request Match field" );
255 }
256
257 public void actionPerformed( ActionEvent arg0 )
258 {
259 if( getModelItem().getLastResult() != null &&
260 getModelItem().getLastResult().getMockRequest() != null && StringUtils.hasContent( getModelItem().getQuery() ) )
261 {
262 getModelItem().setMatch( XmlUtils.getXPathValue( getModelItem().getLastResult().getMockRequest().getRequestContent(),
263 PropertyExpander.expandProperties( getModelItem(), getModelItem().getQuery() )));
264 }
265 }
266 }
267
268 private AssertionsPanel buildAssertionsPanel()
269 {
270 assertionsPanel = new AssertionsPanel( getModelItem() )
271 {
272 protected void selectError( AssertionError error )
273 {
274 ModelItemXmlEditor<?, ?> editor = getResponseEditor();
275 editor.requestFocus();
276 }
277 };
278
279 return assertionsPanel;
280 }
281
282 @Override
283 public boolean onClose( boolean canCancel )
284 {
285 getModelItem().getTestCase().removeTestRunListener( testRunListener );
286 SoapUI.getTestMonitor().removeTestMonitorListener( testMonitorListener );
287 assertionsPanel.release();
288
289 queryEditorModel.release();
290 matchEditorModel.release();
291
292 inspectorPanel.release();
293
294 getModelItem().removeAssertionsListener( assertionsListener );
295 return super.onClose( canCancel );
296 }
297
298 public void setEnabled( boolean enabled )
299 {
300 super.setEnabled( enabled );
301
302 pathField.setEnabled( enabled );
303 portField.setEnabled( enabled );
304 }
305
306 public boolean dependsOn( ModelItem modelItem )
307 {
308 return modelItem == getModelItem() || modelItem == getModelItem().getTestCase()
309 || modelItem == getModelItem().getOperation() || modelItem == getModelItem().getOperation().getInterface()
310 || modelItem == getModelItem().getTestCase().getTestSuite()
311 || modelItem == getModelItem().getTestCase().getTestSuite().getProject();
312 }
313
314 public class InternalTestRunListener extends TestRunListenerAdapter
315 {
316 @Override
317 public void afterRun( TestCaseRunner testRunner, TestCaseRunContext runContext )
318 {
319 setEnabled( true );
320 }
321
322 @Override
323 public void beforeRun( TestCaseRunner testRunner, TestCaseRunContext runContext )
324 {
325 setEnabled( false );
326 }
327
328 @Override
329 public void beforeStep( TestCaseRunner testRunner, TestCaseRunContext runContext, TestStep testStep )
330 {
331 if( testStep == getModelItem() )
332 {
333 logArea.setText( logArea.getText() + new Date( System.currentTimeMillis() ).toString()
334 + ": Waiting for request on http://127.0.0.1:" + getModelItem().getPort() + getModelItem().getPath()
335 + "\r\n" );
336 }
337 }
338
339 @Override
340 public void afterStep( TestCaseRunner testRunner, TestCaseRunContext runContext, TestStepResult result )
341 {
342 if( result.getTestStep() == getModelItem() )
343 {
344 String msg = new Date( result.getTimeStamp() ).toString() + ": Handled request in " + result.getTimeTaken()
345 + "ms";
346 logArea.setText( logArea.getText() + msg + "\r\n" );
347 }
348 }
349 }
350
351 private class InternalTestMonitorListener extends TestMonitorListenerAdapter
352 {
353 public void loadTestFinished( LoadTestRunner runner )
354 {
355 setEnabled( !SoapUI.getTestMonitor().hasRunningTest( getModelItem().getTestCase() ) );
356 }
357
358 public void loadTestStarted( LoadTestRunner runner )
359 {
360 if( runner.getLoadTest().getTestCase() == getModelItem().getTestCase() )
361 setEnabled( false );
362 }
363
364 public void testCaseFinished( TestCaseRunner runner )
365 {
366 setEnabled( !SoapUI.getTestMonitor().hasRunningTest( getModelItem().getTestCase() ) );
367 }
368
369 public void testCaseStarted( TestCaseRunner runner )
370 {
371 if( runner.getTestCase() == getModelItem().getTestCase() )
372 setEnabled( false );
373 }
374 }
375
376 public void propertyChange( PropertyChangeEvent evt )
377 {
378 super.propertyChange( evt );
379
380 if( evt.getPropertyName().equals( WsdlMockResponseTestStep.STATUS_PROPERTY ) )
381 updateStatusIcon();
382 }
383
384 @SuppressWarnings("unused")
385 private final class DeclareNamespacesAction extends AbstractAction
386 {
387 public DeclareNamespacesAction()
388 {
389 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/declareNs.gif" ) );
390 putValue( Action.SHORT_DESCRIPTION,
391 "Declare available response/request namespaces in source/target expressions" );
392 }
393
394 public void actionPerformed( ActionEvent e )
395 {
396 try
397 {
398 WsdlMockResult lastResult = getMockResponse().getMockResult();
399 String content = null;
400 if( lastResult == null )
401 {
402 if( !UISupport.confirm( "Missing last result, declare from default request instead?",
403 "Declare Namespaces" ) )
404 {
405 return;
406 }
407
408 content = getMockResponse().getMockOperation().getOperation().createRequest( true );
409 }
410 else
411 {
412 content = lastResult.getMockRequest().getRequestContent();
413 }
414
415 String path = getModelItem().getQuery();
416 if( path == null )
417 path = "";
418
419 getModelItem().setQuery( XmlUtils.declareXPathNamespaces( content ) + path );
420 }
421 catch( Exception e1 )
422 {
423 UISupport.showErrorMessage( e1 );
424 }
425 }
426 }
427
428 private final class InternalAssertionsListener implements AssertionsListener
429 {
430 public void assertionAdded( TestAssertion assertion )
431 {
432 assertionInspector.setTitle( "Assertions (" + getModelItem().getAssertionCount() + ")" );
433 }
434
435 public void assertionRemoved( TestAssertion assertion )
436 {
437 assertionInspector.setTitle( "Assertions (" + getModelItem().getAssertionCount() + ")" );
438 }
439
440 public void assertionMoved( TestAssertion assertion, int ix, int offset )
441 {
442 assertionInspector.setTitle( "Assertions (" + getModelItem().getAssertionCount() + ")" );
443 }
444 }
445 }