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