1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.panels.teststeps;
14
15 import com.eviware.soapui.SoapUI;
16 import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
17 import com.eviware.soapui.impl.wsdl.panels.support.TestRunComponentEnabler;
18 import com.eviware.soapui.impl.wsdl.panels.teststeps.support.GotoTestStepsComboBoxModel;
19 import com.eviware.soapui.impl.wsdl.submit.transports.http.WsdlResponse;
20 import com.eviware.soapui.impl.wsdl.support.HelpUrls;
21 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
22 import com.eviware.soapui.impl.wsdl.teststeps.WsdlGotoTestStep;
23 import com.eviware.soapui.impl.wsdl.teststeps.WsdlGotoTestStep.GotoCondition;
24 import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep;
25 import com.eviware.soapui.model.ModelItem;
26 import com.eviware.soapui.model.support.TestRunListenerAdapter;
27 import com.eviware.soapui.model.testsuite.TestRunContext;
28 import com.eviware.soapui.model.testsuite.TestRunner;
29 import com.eviware.soapui.model.testsuite.TestStepResult;
30 import com.eviware.soapui.support.DocumentListenerAdapter;
31 import com.eviware.soapui.support.StringUtils;
32 import com.eviware.soapui.support.UISupport;
33 import com.eviware.soapui.support.components.*;
34 import com.eviware.soapui.support.log.JLogList;
35 import com.eviware.soapui.support.xml.XmlUtils;
36 import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
37
38 import javax.swing.*;
39 import javax.swing.event.ListSelectionEvent;
40 import javax.swing.event.ListSelectionListener;
41 import javax.swing.text.Document;
42 import java.awt.*;
43 import java.awt.event.ActionEvent;
44 import java.util.Date;
45
46 /***
47 * DesktopPanel for WsdlGotoTestSteps
48 *
49 * @author Ole.Matzura
50 */
51
52 public class GotoStepDesktopPanel extends ModelItemDesktopPanel<WsdlGotoTestStep>
53 {
54 private final WsdlGotoTestStep gotoStep;
55 private DefaultListModel listModel;
56 private JList conditionList;
57 private JTextArea expressionArea;
58 private JButton copyButton;
59 private JButton deleteButton;
60 private JButton declareButton;
61 private GotoTestStepsComboBoxModel testStepsModel;
62 private JComboBox testStepsCombo;
63 private JButton testConditionButton;
64 private TestRunComponentEnabler componentEnabler;
65 private GotoCondition currentCondition;
66 private JButton renameButton;
67 private JButton runButton;
68 private JButton addButton;
69 private JLogList logList;
70 private InternalTestRunListener testRunListener = new InternalTestRunListener();
71 private JInspectorPanel inspectorPanel;
72
73 public GotoStepDesktopPanel(WsdlGotoTestStep testStep)
74 {
75 super( testStep );
76 this.gotoStep = testStep;
77 componentEnabler = new TestRunComponentEnabler( testStep.getTestCase() );
78 gotoStep.getTestCase().addTestRunListener( testRunListener );
79
80 buildUI();
81 }
82
83 public TestRunComponentEnabler getComponentEnabler()
84 {
85 return componentEnabler;
86 }
87
88 public JList getConditionList()
89 {
90 return conditionList;
91 }
92
93 public JButton getCopyButton()
94 {
95 return copyButton;
96 }
97
98 public JButton getDeclareButton()
99 {
100 return declareButton;
101 }
102
103 public JButton getDeleteButton()
104 {
105 return deleteButton;
106 }
107
108 public JTextArea getExpressionArea()
109 {
110 return expressionArea;
111 }
112
113 public WsdlGotoTestStep getGotoStep()
114 {
115 return gotoStep;
116 }
117
118 public DefaultListModel getListModel()
119 {
120 return listModel;
121 }
122
123 public JButton getTestConditionButton()
124 {
125 return testConditionButton;
126 }
127
128 public JComboBox getTestStepsCombo()
129 {
130 return testStepsCombo;
131 }
132
133 public GotoTestStepsComboBoxModel getTestStepsModel()
134 {
135 return testStepsModel;
136 }
137
138 private void buildUI()
139 {
140 JSplitPane splitPane = UISupport.createHorizontalSplit();
141 splitPane.setLeftComponent( buildConditionList() );
142
143 splitPane.setRightComponent( buildExpressionArea() );
144 splitPane.setResizeWeight( 0.1 );
145 splitPane.setDividerLocation( 120 );
146
147 inspectorPanel = JInspectorPanelFactory.build( splitPane );
148 inspectorPanel.addInspector( new JComponentInspector<JComponent>( buildLog(), "Log", "A log of evaluated conditions", true ) );
149
150 add( inspectorPanel.getComponent(), BorderLayout.CENTER );
151
152 setBorder( BorderFactory.createEmptyBorder( 3, 3, 3, 3 ));
153 setPreferredSize( new Dimension( 550, 300 ));
154
155 if( listModel.getSize() > 0 )
156 conditionList.setSelectedIndex( 0 );
157
158 componentEnabler.add( conditionList );
159 componentEnabler.add( expressionArea );
160 componentEnabler.add( testStepsCombo );
161 componentEnabler.add( testConditionButton );
162 componentEnabler.add( copyButton );
163 componentEnabler.add( declareButton );
164 componentEnabler.add( deleteButton );
165 componentEnabler.add( addButton );
166 componentEnabler.add( runButton );
167 componentEnabler.add( renameButton );
168 }
169
170 private JComponent buildLog()
171 {
172 logList = new JLogList( "ConditionLog" + getModelItem().getName() );
173 return logList;
174 }
175
176 private JPanel buildExpressionArea()
177 {
178 expressionArea = new JUndoableTextArea();
179 expressionArea.setEnabled( false );
180 expressionArea.getDocument().addDocumentListener( new SourceAreaDocumentListener());
181
182 JPanel expressionPanel = new JPanel( new BorderLayout() );
183 JScrollPane scrollPane = new JScrollPane( expressionArea );
184 UISupport.addTitledBorder( scrollPane, "Condition XPath Expression" );
185
186 expressionPanel.add( scrollPane, BorderLayout.CENTER );
187 expressionPanel.add( buildConditionToolbar(), BorderLayout.NORTH );
188 expressionPanel.add( buildTargetToolbar(), BorderLayout.SOUTH );
189 return expressionPanel;
190 }
191
192 private JPanel buildConditionList()
193 {
194 listModel = new DefaultListModel();
195
196 for( int c = 0; c < gotoStep.getConditionCount(); c++ )
197 {
198 listModel.addElement( gotoStep.getConditionAt( c ).getName() );
199 }
200
201 conditionList = new JList( listModel );
202 conditionList.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
203 conditionList.addListSelectionListener( new ConditionListSelectionListener());
204
205 JScrollPane listScrollPane = new JScrollPane( conditionList );
206 UISupport.addTitledBorder( listScrollPane, "Conditions" );
207
208 JPanel p = new JPanel( new BorderLayout() );
209 p.add( buildConditionListToolbar(), BorderLayout.NORTH );
210 p.add( listScrollPane, BorderLayout.CENTER );
211 return p;
212 }
213
214 private Component buildConditionListToolbar()
215 {
216 JXToolBar toolbar = UISupport.createSmallToolbar();
217
218 addButton = UISupport.createToolbarButton( new AddAction() );
219 toolbar.addFixed( addButton );
220 copyButton = UISupport.createToolbarButton( new CopyAction() );
221 copyButton.setEnabled( false );
222 toolbar.addFixed( copyButton);
223 deleteButton = UISupport.createToolbarButton( new DeleteAction() );
224 deleteButton.setEnabled( false );
225 toolbar.addFixed( deleteButton);
226 renameButton = UISupport.createToolbarButton( new RenameAction() );
227 renameButton.setEnabled( false );
228 toolbar.addFixed( renameButton);
229 return toolbar;
230 }
231
232 private Component buildConditionToolbar()
233 {
234 JXToolBar toolbar = UISupport.createSmallToolbar();
235
236 declareButton = UISupport.createToolbarButton( new DeclareNamespacesAction() );
237 declareButton.setEnabled( false );
238 toolbar.addFixed( declareButton);
239 runButton = UISupport.createToolbarButton( new RunAction() );
240 toolbar.addFixed( runButton);
241
242 toolbar.addGlue();
243 toolbar.addFixed( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.GOTOSTEPEDITOR_HELP_URL )));
244 return toolbar;
245 }
246
247 protected JXToolBar buildTargetToolbar()
248 {
249 JXToolBar builder = UISupport.createSmallToolbar();
250 testStepsModel = new GotoTestStepsComboBoxModel( gotoStep.getTestCase(), null );
251 testStepsCombo = new JComboBox( testStepsModel );
252 testStepsCombo.setToolTipText( "The step the test case will go to if the current condition is true" );
253 testStepsCombo.setEnabled( false );
254 builder.addFixed( new JLabel( "<html><b>Target step:</b></html>"));
255 builder.addRelatedGap();
256 builder.addFixed( testStepsCombo );
257 builder.addGlue();
258 testConditionButton = new JButton( new TestConditionAction() );
259 testConditionButton.setEnabled( false );
260 builder.addFixed( testConditionButton);
261 builder.setBorder( BorderFactory.createEmptyBorder( 3, 3, 3, 3 ));
262 return builder;
263 }
264
265 private final class SourceAreaDocumentListener extends DocumentListenerAdapter
266 {
267 @Override
268 public void update( Document document )
269 {
270 int ix = conditionList.getSelectedIndex();
271 if( ix != -1 )
272 {
273 gotoStep.getConditionAt( ix ).setExpression( expressionArea.getText() );
274 }
275 }
276 }
277
278 private final class ConditionListSelectionListener implements ListSelectionListener
279 {
280 public void valueChanged(ListSelectionEvent e)
281 {
282 int ix = conditionList.getSelectedIndex();
283 if( ix == -1 )
284 {
285 expressionArea.setText( "" );
286 testStepsModel.setCondition( null );
287 currentCondition = null;
288 }
289 else
290 {
291 currentCondition = gotoStep.getConditionAt( ix );
292 expressionArea.setText( currentCondition.getExpression() );
293 testStepsModel.setCondition( currentCondition );
294 }
295
296 boolean b = ix != -1;
297 enableEditComponents( b );
298 }
299 }
300
301 private final class AddAction extends AbstractAction
302 {
303 public AddAction()
304 {
305 putValue( Action.SHORT_DESCRIPTION, "Adds a new Conditionr" );
306 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/add_property.gif" ));
307 }
308
309 public void actionPerformed(ActionEvent e)
310 {
311 String name = UISupport.prompt( "Specify name for condition", "Add Condition", "Condition " +
312 (gotoStep.getConditionCount()+1) );
313 if( name == null || name.trim().length() == 0 ) return;
314
315 gotoStep.addCondition( name );
316
317 listModel.addElement( name );
318 conditionList.setSelectedIndex( listModel.getSize()-1 );
319 }
320 }
321
322 private final class CopyAction extends AbstractAction
323 {
324 public CopyAction()
325 {
326 putValue( Action.SHORT_DESCRIPTION, "Copies the selected Condition" );
327 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/clone_request.gif" ));
328 }
329
330 public void actionPerformed(ActionEvent e)
331 {
332 int ix = conditionList.getSelectedIndex();
333 GotoCondition config = gotoStep.getConditionAt( ix );
334
335 String name = UISupport.prompt( "Specify name for condition", "Copy Condition", config.getName() );
336 if( name == null || name.trim().length() == 0 ) return;
337
338 GotoCondition condition = gotoStep.addCondition( name );
339 condition.setExpression( config.getExpression() );
340 condition.setTargetStep( config.getTargetStep() );
341 condition.setType( config.getType() );
342
343 listModel.addElement( name );
344 conditionList.setSelectedIndex( listModel.getSize()-1 );
345 }
346 }
347
348 private final class DeleteAction extends AbstractAction
349 {
350 public DeleteAction()
351 {
352 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/remove_property.gif" ));
353 putValue( Action.SHORT_DESCRIPTION, "Deletes the selected Condition" );
354 }
355
356 public void actionPerformed(ActionEvent e)
357 {
358 if( UISupport.confirm( "Delete selected condition", "Delete Condition" ))
359 {
360 int ix = conditionList.getSelectedIndex();
361
362 conditionList.setSelectedIndex( -1 );
363
364 gotoStep.removeConditionAt( ix );
365 listModel.remove( ix );
366
367 if( listModel.getSize() > 0 )
368 {
369 conditionList.setSelectedIndex( ix > listModel.getSize()-1 ? listModel.getSize()-1 : ix );
370 }
371 }
372 }
373 }
374
375 private final class RenameAction extends AbstractAction
376 {
377 public RenameAction()
378 {
379 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/rename.gif" ));
380 putValue( Action.SHORT_DESCRIPTION, "Renames the selected Condition" );
381 }
382
383 public void actionPerformed(ActionEvent e)
384 {
385 int ix = conditionList.getSelectedIndex();
386 GotoCondition config = gotoStep.getConditionAt( ix );
387
388 String name = UISupport.prompt( "Specify name for condition", "Copy Condition", config.getName() );
389 if( name == null || name.trim().length() == 0 ) return;
390
391 config.setName( name );
392 listModel.setElementAt( name, ix );
393 }
394 }
395
396 private final class DeclareNamespacesAction extends AbstractAction
397 {
398 public DeclareNamespacesAction()
399 {
400 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/declareNs.gif" ));
401 putValue( Action.SHORT_DESCRIPTION, "Declare available response namespaces in condition expression" );
402 }
403
404 public void actionPerformed(ActionEvent e)
405 {
406 try
407 {
408 WsdlTestRequestStep previousStep = (WsdlTestRequestStep) gotoStep.getTestCase().findPreviousStepOfType(
409 gotoStep, WsdlTestRequestStep.class );
410
411 if (previousStep != null )
412 {
413 WsdlResponse response = previousStep.getTestRequest().getResponse();
414 String xml = response == null ? null : response.getContentAsString();
415 if ( xml != null && xml.trim().length() > 0)
416 {
417 expressionArea.setText(XmlUtils.declareXPathNamespaces(xml)
418 + expressionArea.getText());
419 }
420 else
421 {
422 UISupport.showErrorMessage( "Missing response in previous request step [" + previousStep.getName() + "]" );
423 }
424 }
425 else
426 {
427 UISupport.showErrorMessage( "Missing previous request step" );
428 }
429 }
430 catch (Exception e1)
431 {
432 SoapUI.logError( e1 );
433 }
434 }
435 }
436
437 private final class RunAction extends AbstractAction
438 {
439 public RunAction()
440 {
441 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_all.gif" ));
442 putValue( Action.SHORT_DESCRIPTION, "Runs the current conditions against the previous response" );
443 }
444
445 public void actionPerformed(ActionEvent e)
446 {
447 if( listModel.getSize() == 0 )
448 {
449 UISupport.showErrorMessage( "Missing conditions!" );
450 return;
451 }
452
453 WsdlTestRequestStep previousStep = (WsdlTestRequestStep) gotoStep.getTestCase().findPreviousStepOfType(
454 gotoStep, WsdlTestRequestStep.class );
455
456 if( previousStep == null )
457 {
458 UISupport.showErrorMessage( "Missing previous request step" );
459 }
460 else
461 {
462 if( previousStep.getTestRequest().getResponse() == null ||
463 StringUtils.isNullOrEmpty( previousStep.getTestRequest().getResponse().getContentAsString()) )
464 {
465 UISupport.showErrorMessage( "Missing response in previous message" );
466 return;
467 }
468
469 WsdlTestRunContext context = new WsdlTestRunContext( gotoStep );
470 GotoCondition target = gotoStep.runConditions( previousStep, context );
471 if( target == null )
472 {
473 logList.addLine( "No condition true for current response in [" + previousStep.getName() + "]" );
474 }
475 else
476 {
477 logList.addLine( "Condition triggered for go to [" + target.getTargetStep() + "]" );
478 }
479
480 inspectorPanel.setCurrentInspector( "Log" );
481 }
482 }
483 }
484
485 private final class TestConditionAction extends AbstractAction
486 {
487 public TestConditionAction()
488 {
489 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run.gif" ));
490 putValue( Action.SHORT_DESCRIPTION, "Runs the current condition against the previous response and shows the result" );
491 }
492
493 public void actionPerformed(ActionEvent e)
494 {
495 WsdlTestRequestStep previousStep = (WsdlTestRequestStep) gotoStep.getTestCase().findPreviousStepOfType(
496 gotoStep, WsdlTestRequestStep.class );
497
498 if( previousStep == null )
499 {
500 UISupport.showErrorMessage( "Missing previous request step" );
501 }
502 else
503 {
504 if( previousStep.getTestRequest().getResponse() == null ||
505 previousStep.getTestRequest().getResponse().getContentAsString().trim().length() == 0 )
506 {
507 UISupport.showErrorMessage( "Missing response in previous request step [" +
508 previousStep.getName() + "]" );
509 return;
510 }
511
512 try
513 {
514 GotoCondition condition = gotoStep.getConditionAt( conditionList.getSelectedIndex() );
515 WsdlTestRunContext context = new WsdlTestRunContext( gotoStep );
516 boolean evaluate = condition.evaluate( previousStep, context );
517 if( !evaluate )
518 {
519 UISupport.showInfoMessage( "Condition not true for current response in [" + previousStep.getName() + "]" );
520 }
521 else
522 {
523 UISupport.showInfoMessage( "Condition true for current response in [" + previousStep.getName() + "]" );
524 }
525 }
526 catch (Exception e1)
527 {
528 UISupport.showErrorMessage( "Error checking condition: " + e1.getMessage() );
529 }
530 }
531 }
532 }
533
534 public boolean onClose( boolean canCancel )
535 {
536 super.release();
537 componentEnabler.release();
538 gotoStep.getTestCase().removeTestRunListener( testRunListener );
539 testStepsModel.release();
540
541 return true;
542 }
543
544 public JComponent getComponent()
545 {
546 return this;
547 }
548
549 public boolean dependsOn(ModelItem modelItem)
550 {
551 return modelItem == gotoStep || modelItem == gotoStep.getTestCase() ||
552 modelItem == gotoStep.getTestCase().getTestSuite() ||
553 modelItem == gotoStep.getTestCase().getTestSuite().getProject();
554 }
555
556 public GotoCondition getCurrentCondition()
557 {
558 return currentCondition;
559 }
560
561 protected void enableEditComponents( boolean b )
562 {
563 expressionArea.setEnabled( b );
564 testStepsCombo.setEnabled( b );
565 copyButton.setEnabled( b );
566 deleteButton.setEnabled( b );
567 declareButton.setEnabled( b );
568 testConditionButton.setEnabled( b );
569 renameButton.setEnabled( b );
570 }
571
572 private class InternalTestRunListener extends TestRunListenerAdapter
573 {
574 @Override
575 public void afterStep( TestRunner testRunner, TestRunContext runContext, TestStepResult result )
576 {
577 if( result.getTestStep() == gotoStep )
578 {
579 logList.addLine( new Date( result.getTimeStamp() ).toString() + ": " + result.getMessages()[0] );
580 inspectorPanel.setCurrentInspector( "Log" );
581 }
582 }
583 }
584 }