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