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.Dimension;
17 import java.awt.GridLayout;
18 import java.awt.event.ActionEvent;
19 import java.awt.event.ItemEvent;
20 import java.awt.event.ItemListener;
21 import java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Date;
26 import java.util.List;
27
28 import javax.swing.AbstractAction;
29 import javax.swing.Action;
30 import javax.swing.BorderFactory;
31 import javax.swing.DefaultComboBoxModel;
32 import javax.swing.DefaultListModel;
33 import javax.swing.JButton;
34 import javax.swing.JCheckBox;
35 import javax.swing.JComboBox;
36 import javax.swing.JComponent;
37 import javax.swing.JLabel;
38 import javax.swing.JList;
39 import javax.swing.JPanel;
40 import javax.swing.JScrollPane;
41 import javax.swing.JSplitPane;
42 import javax.swing.JTextArea;
43 import javax.swing.ListSelectionModel;
44 import javax.swing.event.ChangeEvent;
45 import javax.swing.event.ChangeListener;
46 import javax.swing.event.ListSelectionEvent;
47 import javax.swing.event.ListSelectionListener;
48 import javax.swing.table.AbstractTableModel;
49 import javax.swing.text.Document;
50
51 import org.jdesktop.swingx.JXTable;
52
53 import com.eviware.soapui.SoapUI;
54 import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
55 import com.eviware.soapui.impl.wsdl.panels.support.TestRunComponentEnabler;
56 import com.eviware.soapui.impl.wsdl.support.HelpUrls;
57 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
58 import com.eviware.soapui.impl.wsdl.teststeps.PropertyTransfer;
59 import com.eviware.soapui.impl.wsdl.teststeps.TransferResponseValuesTestStep;
60 import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequest;
61 import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep;
62 import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStep;
63 import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStepListener;
64 import com.eviware.soapui.impl.wsdl.teststeps.TransferResponseValuesTestStep.ValueTransferResult;
65 import com.eviware.soapui.model.ModelItem;
66 import com.eviware.soapui.model.support.TestRunListenerAdapter;
67 import com.eviware.soapui.model.support.TestSuiteListenerAdapter;
68 import com.eviware.soapui.model.testsuite.TestRunContext;
69 import com.eviware.soapui.model.testsuite.TestRunner;
70 import com.eviware.soapui.model.testsuite.TestStep;
71 import com.eviware.soapui.model.testsuite.TestStepProperty;
72 import com.eviware.soapui.model.testsuite.TestStepResult;
73 import com.eviware.soapui.support.DocumentListenerAdapter;
74 import com.eviware.soapui.support.UISupport;
75 import com.eviware.soapui.support.components.JComponentInspector;
76 import com.eviware.soapui.support.components.JInspectorPanel;
77 import com.eviware.soapui.support.components.JUndoableTextArea;
78 import com.eviware.soapui.support.components.JXToolBar;
79 import com.eviware.soapui.support.xml.XmlUtils;
80 import com.eviware.soapui.ui.desktop.DesktopPanel;
81 import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
82
83 /***
84 * DesktopPanel for TransferResponseValuesTestStep
85 *
86 * @author Ole.Matzura
87 */
88
89 public class TransferResponseValuesDesktopPanel extends ModelItemDesktopPanel<TransferResponseValuesTestStep>
90 {
91 private final TransferResponseValuesTestStep transferStep;
92 private DefaultListModel listModel;
93 private JList transferList;
94 private JTextArea sourceArea;
95 private JTextArea targetArea;
96 private JButton copyButton;
97 private JButton deleteButton;
98 private JButton declareButton;
99 private JComboBox sourcePropertyCombo;
100 private JComboBox targetPropertyCombo;
101 private JComboBox sourceStepCombo;
102 private JComboBox targetStepCombo;
103 private DefaultComboBoxModel sourceStepModel;
104 private DefaultComboBoxModel targetStepModel;
105 private TestStepNameListener sourceTestStepNameListener;
106 private TestStepNameListener targetStepNameListener;
107 private TestStepPropertiesListener sourceStepPropertiesListener;
108 private TestStepPropertiesListener targetStepPropertiesListener;
109 private TransferPropertyChangeListener transferPropertyChangeListener = new TransferPropertyChangeListener();
110 private boolean selecting;
111 private InternalTestSuiteListener testSuiteListener;
112 private TestRunComponentEnabler componentEnabler;
113 private JCheckBox failTransferCheckBox;
114 private JButton runButton;
115 private JButton renameButton;
116 private JCheckBox setNullCheckBox;
117 private JCheckBox transferTextContentCheckBox;
118 private JCheckBox ignoreEmptyCheckBox;
119 private JCheckBox transferAllCheckBox;
120 private DesktopPanel resultDesktopPanel;
121 private TransfersTableModel transfersTableModel;
122 private InternalTestRunListener testRunListener;
123 private JComponentInspector logInspector;
124 private JCheckBox useXQueryCheckBox;
125 private JButton runAllButton;
126 private JInspectorPanel inspectorPanel;
127
128 public TransferResponseValuesDesktopPanel(TransferResponseValuesTestStep testStep)
129 {
130 super( testStep );
131 this.transferStep = testStep;
132 componentEnabler = new TestRunComponentEnabler( testStep.getTestCase() );
133
134 buildUI();
135
136 testSuiteListener = new InternalTestSuiteListener();
137 transferStep.getTestCase().getTestSuite().addTestSuiteListener( testSuiteListener );
138
139 testRunListener = new InternalTestRunListener();
140 transferStep.getTestCase().addTestRunListener( testRunListener );
141 }
142
143 protected void buildUI()
144 {
145 JSplitPane splitPane = UISupport.createHorizontalSplit();
146
147 listModel = new DefaultListModel();
148
149 for( int c = 0; c < transferStep.getTransferCount(); c++ )
150 {
151 listModel.addElement( transferStep.getTransferAt( c ).getName() );
152 }
153
154 transferList = new JList( listModel );
155 transferList.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
156 transferList.addListSelectionListener( new TransferListSelectionListener());
157 componentEnabler.add( transferList );
158
159 JScrollPane listScrollPane = new JScrollPane( transferList );
160 UISupport.addTitledBorder( listScrollPane, "Transfers" );
161
162 JPanel p = new JPanel( new BorderLayout() );
163 p.add( listScrollPane, BorderLayout.CENTER );
164 p.add( createPropertiesToolbar(), BorderLayout.NORTH );
165
166 splitPane.setLeftComponent( p );
167
168 JSplitPane innerSplit = UISupport.createVerticalSplit();
169 innerSplit.setBorder( null );
170 sourceArea = new JUndoableTextArea();
171 sourceArea.setToolTipText( "XPath selection from source property" );
172 sourceArea.setEnabled( false );
173 sourceArea.getDocument().addDocumentListener( new SourceAreaDocumentListener());
174 componentEnabler.add( sourceArea );
175
176 targetArea = new JUndoableTextArea();
177 targetArea.setToolTipText( "XPath target in target property" );
178 targetArea.setEnabled( false );
179 targetArea.getDocument().addDocumentListener( new TargetAreaDocumentListener());
180 componentEnabler.add( targetArea );
181
182 JPanel sourcePanel = new JPanel( new BorderLayout() );
183 sourcePanel.add( new JScrollPane( sourceArea ), BorderLayout.CENTER );
184 JXToolBar toolbar = createSourceToolbar();
185 sourcePanel.add( toolbar, BorderLayout.NORTH );
186 sourcePanel.setBorder( BorderFactory.createEmptyBorder( 0, 3, 3, 3 ));
187 innerSplit.setTopComponent( sourcePanel );
188
189 JPanel targetPanel = new JPanel( new BorderLayout() );
190 targetPanel.add( new JScrollPane( targetArea ), BorderLayout.CENTER );
191 toolbar = createTargetToolbar();
192 targetPanel.add( toolbar, BorderLayout.NORTH );
193 targetPanel.setBorder( BorderFactory.createEmptyBorder( 0, 3, 3, 3 ));
194
195 innerSplit.setBottomComponent( targetPanel );
196
197 innerSplit.setResizeWeight( 0.5 );
198 innerSplit.setDividerLocation( 0.5 );
199
200 JPanel panel = createTransferOptions();
201
202 JPanel innerPanel = new JPanel( new BorderLayout() );
203 innerPanel.add( innerSplit, BorderLayout.CENTER );
204 innerPanel.add( panel, BorderLayout.SOUTH );
205 innerPanel.add( createConfigToolbar(), BorderLayout.NORTH );
206
207 splitPane.setRightComponent( innerPanel );
208 splitPane.setResizeWeight( 0.1 );
209 splitPane.setDividerLocation( 120 );
210
211 inspectorPanel = new JInspectorPanel( splitPane );
212 logInspector = new JComponentInspector( buildLog(), "Transfer Log (0)", "A log of performed transfers while the editor was open", true );
213 inspectorPanel.addInspector( logInspector );
214 add( inspectorPanel, BorderLayout.CENTER );
215
216 setBorder( BorderFactory.createEmptyBorder( 3, 3, 3, 3 ));
217 setPreferredSize( new Dimension( 550, 400 ));
218
219 if( listModel.getSize() > 0 )
220 transferList.setSelectedIndex( 0 );
221
222 componentEnabler.add( deleteButton );
223 componentEnabler.add( declareButton );
224 componentEnabler.add( runButton );
225 componentEnabler.add( runAllButton );
226 componentEnabler.add( copyButton );
227 componentEnabler.add( renameButton );
228 componentEnabler.add( failTransferCheckBox );
229 componentEnabler.add( setNullCheckBox );
230 componentEnabler.add( transferTextContentCheckBox );
231 componentEnabler.add( ignoreEmptyCheckBox );
232 componentEnabler.add( transferAllCheckBox );
233 componentEnabler.add( useXQueryCheckBox );
234 }
235
236 private JComponent buildLog()
237 {
238 JPanel logPanel = new JPanel( new BorderLayout() );
239
240 transfersTableModel = new TransfersTableModel();
241 JXTable table = new JXTable( transfersTableModel );
242
243 table.setHorizontalScrollEnabled( true );
244 table.packAll();
245
246 JXToolBar toolbar = UISupport.createSmallToolbar();
247 toolbar.add( new ClearLogAction() );
248
249 JScrollPane scrollPane = new JScrollPane( table);
250 scrollPane.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createEmptyBorder( 3, 3, 3, 3 ),
251 scrollPane.getBorder() ));
252
253 logPanel.add( toolbar, BorderLayout.NORTH );
254 logPanel.add( scrollPane, BorderLayout.CENTER );
255
256 return logPanel;
257 }
258
259 protected JXToolBar createPropertiesToolbar()
260 {
261 JXToolBar toolbar = UISupport.createSmallToolbar();
262 toolbar.addFixed( new JButton( new AddAction() ) );
263 deleteButton = new JButton( new DeleteAction() );
264 deleteButton.setEnabled( false );
265 toolbar.addFixed( deleteButton);
266 copyButton = new JButton( new CopyAction() );
267 copyButton.setEnabled( false );
268 toolbar.addFixed( copyButton);
269 renameButton = new JButton( new RenameAction() );
270 renameButton.setEnabled( false );
271 toolbar.addFixed( renameButton);
272 return toolbar;
273 }
274
275 protected JXToolBar createConfigToolbar()
276 {
277 JXToolBar toolbar = UISupport.createToolbar();
278
279 toolbar.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2 ) );
280
281 runButton = new JButton( new RunAction() );
282 runButton.setEnabled( transferList.getSelectedIndex() != -1 );
283 toolbar.addFixed( runButton);
284
285 runAllButton = new JButton( new RunAllAction() );
286 runAllButton.setEnabled( transferStep.getTransferCount() > 0 );
287 toolbar.addFixed( runAllButton);
288
289 declareButton = new JButton( new DeclareNamespacesAction() );
290 declareButton.setEnabled( false );
291 toolbar.addFixed( declareButton);
292 toolbar.addGlue();
293 toolbar.addFixed( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.TRANSFERSTEPEDITOR_HELP_URL )));
294 return toolbar;
295 }
296
297 protected JPanel createTransferOptions()
298 {
299 JPanel panel = new JPanel( new GridLayout( 3, 2 ));
300 failTransferCheckBox = new JCheckBox( "Fail transfer on error", false );
301 failTransferCheckBox.setToolTipText( "Fails the Property Transfer Step if an error occurs" );
302 failTransferCheckBox.addChangeListener( new ChangeListener() {
303
304 public void stateChanged(ChangeEvent e)
305 {
306 PropertyTransfer currentTransfer = getCurrentTransfer();
307 if( currentTransfer != null )
308 {
309 currentTransfer.setFailOnError( failTransferCheckBox.isSelected() );
310 }
311 }} );
312
313 setNullCheckBox = new JCheckBox( "Set null on missing source", false );
314 setNullCheckBox.setToolTipText( "Will set target to null if source is missing or null" );
315 setNullCheckBox.addChangeListener( new ChangeListener() {
316
317 public void stateChanged(ChangeEvent e)
318 {
319 PropertyTransfer currentTransfer = getCurrentTransfer();
320 if( currentTransfer != null )
321 {
322 currentTransfer.setSetNullOnMissingSource( setNullCheckBox.isSelected() );
323 }
324 }} );
325
326 transferTextContentCheckBox = new JCheckBox( "Transfer text content", false );
327 transferTextContentCheckBox.setToolTipText( "Will only transfer text content of source/target elements" );
328 transferTextContentCheckBox.addChangeListener( new ChangeListener() {
329
330 public void stateChanged(ChangeEvent e)
331 {
332 PropertyTransfer currentTransfer = getCurrentTransfer();
333 if( currentTransfer != null )
334 {
335 currentTransfer.setTransferTextContent( transferTextContentCheckBox.isSelected() );
336 }
337 }} );
338
339 ignoreEmptyCheckBox = new JCheckBox( "Ignore empty/missing values", false );
340 ignoreEmptyCheckBox.setToolTipText( "Will not transfer empty or missing values" );
341 ignoreEmptyCheckBox.addChangeListener( new ChangeListener() {
342
343 public void stateChanged(ChangeEvent e)
344 {
345 PropertyTransfer currentTransfer = getCurrentTransfer();
346 if( currentTransfer != null )
347 {
348 currentTransfer.setIgnoreEmpty( ignoreEmptyCheckBox.isSelected() );
349 }
350 }} );
351
352 transferAllCheckBox = new JCheckBox( "Transfer to all", false );
353 transferAllCheckBox.setToolTipText( "Will transfer to all matching target selections" );
354 transferAllCheckBox.addChangeListener( new ChangeListener() {
355
356 public void stateChanged(ChangeEvent e)
357 {
358 PropertyTransfer currentTransfer = getCurrentTransfer();
359 if( currentTransfer != null )
360 {
361 currentTransfer.setTransferToAll( transferAllCheckBox.isSelected() );
362 }
363 }} );
364
365 useXQueryCheckBox = new JCheckBox( "Use XQuery", false );
366 useXQueryCheckBox.setToolTipText( "Interprets the source xpath as an XQuery expression" );
367 useXQueryCheckBox.addChangeListener( new ChangeListener() {
368
369 public void stateChanged(ChangeEvent e)
370 {
371 PropertyTransfer currentTransfer = getCurrentTransfer();
372 if( currentTransfer != null )
373 {
374 currentTransfer.setUseXQuery( useXQueryCheckBox.isSelected() );
375 }
376 }} );
377
378 panel.add( failTransferCheckBox );
379 panel.add( setNullCheckBox );
380 panel.add( transferTextContentCheckBox );
381 panel.add( ignoreEmptyCheckBox );
382 panel.add( transferAllCheckBox );
383 panel.add( useXQueryCheckBox );
384 panel.setBorder( BorderFactory.createEmptyBorder( 3, 3, 3, 3 ) );
385 return panel;
386 }
387
388 protected JXToolBar createTargetToolbar()
389 {
390 JXToolBar toolbar;
391 toolbar = UISupport.createToolbar();
392 toolbar.addSpace( 3 );
393 toolbar.addFixed( new JLabel( "<html><b>Target:</b></html>"));
394 toolbar.addGlue();
395
396 targetStepCombo.setSelectedItem( null );
397 targetStepCombo.setToolTipText( "The step the value will be transferred to" );
398 targetStepCombo.setEnabled( false );
399 targetStepCombo.addItemListener(
400 new StepComboItemListener( targetPropertyCombo, targetStepPropertiesListener ) );
401 targetStepCombo.addItemListener( new ItemListener() {
402
403 public void itemStateChanged(ItemEvent e)
404 {
405 if( e.getStateChange() == ItemEvent.SELECTED && !selecting )
406 {
407 String targetStep = (String) targetStepCombo.getSelectedItem();
408 PropertyTransfer valueTransfer = getCurrentTransfer();
409
410 if( valueTransfer != null )
411 {
412 valueTransfer.setTargetStepName( targetStep );
413 }
414 }
415 }} );
416
417 toolbar.addFixed( new JLabel( "Step:"));
418 toolbar.addRelatedGap();
419 toolbar.add( targetStepCombo );
420 toolbar.addRelatedGap();
421
422 toolbar.addFixed( new JLabel( "Property:"));
423 toolbar.addRelatedGap();
424
425 targetPropertyCombo.setToolTipText( "The property the value will be transferred to" );
426 targetPropertyCombo.setEnabled( false );
427 targetPropertyCombo.addItemListener( new ItemListener() {
428
429 public void itemStateChanged(ItemEvent e)
430 {
431 if( e.getStateChange() == ItemEvent.SELECTED && !selecting )
432 {
433 String targetProperty = (String) targetPropertyCombo.getSelectedItem();
434 PropertyTransfer valueTransfer = getCurrentTransfer();
435
436 if( valueTransfer != null )
437 {
438 valueTransfer.setTargetPropertyName( targetProperty );
439 }
440 }
441 }} );
442
443 toolbar.add( targetPropertyCombo);
444 return toolbar;
445 }
446
447 protected JXToolBar createSourceToolbar()
448 {
449 JXToolBar toolbar = UISupport.createToolbar();
450 toolbar.addSpace( 3 );
451 toolbar.addFixed( new JLabel( "<html><b>Source:</b></html>"));
452 toolbar.addGlue();
453
454 sourcePropertyCombo = new JComboBox();
455 sourceStepModel = new DefaultComboBoxModel();
456 sourceStepCombo = new JComboBox( sourceStepModel );
457 sourceTestStepNameListener = new TestStepNameListener( sourceStepModel );
458
459 componentEnabler.add( sourcePropertyCombo );
460 componentEnabler.add( sourceStepCombo );
461
462 targetPropertyCombo = new JComboBox();
463 targetStepModel = new DefaultComboBoxModel();
464 targetStepCombo = new JComboBox( targetStepModel );
465 targetStepNameListener = new TestStepNameListener( targetStepModel );
466
467 componentEnabler.add( targetPropertyCombo );
468 componentEnabler.add( targetStepCombo );
469
470 sourceStepPropertiesListener = new TestStepPropertiesListener( sourcePropertyCombo );
471 targetStepPropertiesListener = new TestStepPropertiesListener( targetPropertyCombo );
472
473 for( int c = 0; c < transferStep.getTestCase().getTestStepCount(); c++ )
474 {
475 WsdlTestStep testStep = (WsdlTestStep) transferStep.getTestCase().getTestStepAt( c );
476 if( testStep == transferStep )
477 continue;
478
479 testStep.addPropertyChangeListener( TestStep.NAME_PROPERTY, sourceTestStepNameListener);
480 testStep.addPropertyChangeListener( TestStep.NAME_PROPERTY, targetStepNameListener);
481
482 String nm = testStep.getName();
483 sourceStepModel.addElement( nm );
484 targetStepModel.addElement( nm );
485 }
486
487 sourceStepCombo.setSelectedItem( null );
488 sourceStepCombo.setToolTipText( "The step the value will be transferred from" );
489 sourceStepCombo.setEnabled( false );
490 sourceStepCombo.addItemListener(
491 new StepComboItemListener( sourcePropertyCombo, sourceStepPropertiesListener ) );
492 sourceStepCombo.addItemListener( new ItemListener() {
493
494 public void itemStateChanged(ItemEvent e)
495 {
496 if( e.getStateChange() == ItemEvent.SELECTED && !selecting )
497 {
498 String sourceStep = (String) sourceStepCombo.getSelectedItem();
499 PropertyTransfer valueTransfer = getCurrentTransfer();
500
501 if( valueTransfer != null )
502 {
503 valueTransfer.setSourceStepName( sourceStep );
504 }
505 }
506 }} );
507
508 toolbar.addFixed( new JLabel( "Step:"));
509 toolbar.addRelatedGap();
510 toolbar.add( sourceStepCombo );
511 toolbar.addRelatedGap();
512
513 toolbar.addFixed( new JLabel( "Property:"));
514 toolbar.addRelatedGap();
515
516 sourcePropertyCombo.setToolTipText( "The property the value will be transferred from" );
517 sourcePropertyCombo.setEnabled( false );
518 sourcePropertyCombo.addItemListener( new ItemListener() {
519
520 public void itemStateChanged(ItemEvent e)
521 {
522 if( e.getStateChange() == ItemEvent.SELECTED && !selecting )
523 {
524 String sourceProperty = (String) sourcePropertyCombo.getSelectedItem();
525 PropertyTransfer valueTransfer = getCurrentTransfer();
526
527 if( valueTransfer != null )
528 {
529 valueTransfer.setSourcePropertyName( sourceProperty );
530 }
531 }
532 }} );
533
534 toolbar.add( sourcePropertyCombo);
535 return toolbar;
536 }
537
538 public PropertyTransfer getCurrentTransfer()
539 {
540 int ix = transferList.getSelectedIndex();
541 return ix == -1 ? null : transferStep.getTransferAt( ix );
542 }
543
544 /***
545 * Listen for testStep property changes and update properties combo accordingly
546 */
547
548 private static final class TestStepPropertiesListener implements WsdlTestStepListener
549 {
550 private final JComboBox combo;
551
552 public TestStepPropertiesListener(JComboBox combo)
553 {
554 this.combo = combo;
555 }
556
557 public void propertyAdded(String name)
558 {
559 combo.addItem( name );
560 combo.setEnabled( true );
561 }
562
563 public void propertyRemoved(String name)
564 {
565 if( combo.getSelectedItem().equals( name ))
566 combo.setSelectedItem( null );
567
568 combo.removeItem( name );
569 combo.setEnabled( combo.getItemCount() > 0 );
570 }
571
572 public void propertyRenamed(String oldName, String newName)
573 {
574 DefaultComboBoxModel model = (DefaultComboBoxModel) combo.getModel();
575
576 int stepIndex = model.getIndexOf( oldName );
577 if( stepIndex != -1 )
578 {
579 Object selectedItem = model.getSelectedItem();
580
581 model.removeElementAt( stepIndex );
582 model.insertElementAt( newName, stepIndex );
583
584
585 if( selectedItem.equals( oldName ) )
586 model.setSelectedItem( newName );
587 }
588 }
589
590 public void propertyValueChanged(String name, String oldValue, String newValue)
591 {
592 }
593 }
594
595 /***
596 * Listen for teststep changes and update source/target step combos accordingly
597 */
598
599 private final class InternalTestSuiteListener extends TestSuiteListenerAdapter
600 {
601 public void testStepAdded(TestStep testStep, int index)
602 {
603 if( testStep.getTestCase() == transferStep.getTestCase() )
604 {
605 sourceStepModel.addElement( testStep.getName() );
606 targetStepModel.addElement( testStep.getName() );
607
608 testStep.addPropertyChangeListener( TestStep.NAME_PROPERTY, sourceTestStepNameListener);
609 testStep.addPropertyChangeListener( TestStep.NAME_PROPERTY, targetStepNameListener);
610 }
611 }
612
613 public void testStepMoved(TestStep testStep, int fromIndex, int offset)
614 {
615 if( testStep.getTestCase() == transferStep.getTestCase() )
616 {
617 String testStepName = testStep.getName();
618 if( sourceStepModel.getIndexOf( testStepName ) == fromIndex )
619 {
620 String sourceStep = ( String ) sourceStepCombo.getSelectedItem();
621 String sourceProperty = ( String ) sourcePropertyCombo.getSelectedItem();
622
623 sourceStepModel.removeElementAt( fromIndex );
624 if( fromIndex + offset > sourceStepModel.getSize() )
625 sourceStepModel.addElement( testStepName );
626 else
627 sourceStepModel.insertElementAt( testStepName, fromIndex + offset );
628
629 sourceStepCombo.setSelectedItem( sourceStep );
630 sourcePropertyCombo.setSelectedItem( sourceProperty );
631 }
632
633 if( targetStepModel.getIndexOf( testStepName ) == fromIndex )
634 {
635 String targetStep = ( String ) targetStepCombo.getSelectedItem();
636 String targetProperty = ( String ) targetPropertyCombo.getSelectedItem();
637
638 targetStepModel.removeElementAt( fromIndex );
639 if( fromIndex + offset > targetStepModel.getSize() )
640 targetStepModel.addElement( testStepName );
641 else
642 targetStepModel.insertElementAt( testStepName, fromIndex + offset );
643
644 targetStepCombo.setSelectedItem( targetStep );
645 targetPropertyCombo.setSelectedItem( targetProperty );
646 }
647 }
648 }
649
650 public void testStepRemoved(TestStep testStep, int index)
651 {
652 if( testStep.getTestCase() == transferStep.getTestCase() )
653 {
654 sourceStepModel.removeElement( testStep.getName() );
655 targetStepModel.removeElement( testStep.getName() );
656
657 testStep.removePropertyChangeListener( TestStep.NAME_PROPERTY, sourceTestStepNameListener);
658 testStep.removePropertyChangeListener( TestStep.NAME_PROPERTY, targetStepNameListener);
659 }
660 }
661 }
662
663 /***
664 * Listen for testStep name changes and modify comboBox model accordingly
665 */
666
667 private final class TestStepNameListener implements PropertyChangeListener
668 {
669 private final DefaultComboBoxModel model;
670
671 public TestStepNameListener(DefaultComboBoxModel model)
672 {
673 this.model = model;
674 }
675
676 public void propertyChange(PropertyChangeEvent evt)
677 {
678 Object oldItem = evt.getOldValue();
679 int stepIndex = model.getIndexOf( oldItem );
680 if( stepIndex != -1 )
681 {
682 Object selectedItem = model.getSelectedItem();
683 Object newItem = evt.getNewValue();
684
685 selecting = true;
686 model.removeElementAt( stepIndex );
687 model.insertElementAt( newItem, stepIndex );
688 selecting = false;
689
690
691 if( selectedItem.equals( oldItem ) )
692 model.setSelectedItem( newItem );
693 }
694 }
695 }
696
697 /***
698 * Listen to step selections and update properties combo accordingly
699 */
700
701 private final class StepComboItemListener implements ItemListener
702 {
703 private final JComboBox propertyCombo;
704 private final TestStepPropertiesListener testStepPropertiesListener;
705
706 public StepComboItemListener(final JComboBox propertyCombo, TestStepPropertiesListener testStepPropertiesListener)
707 {
708 this.propertyCombo = propertyCombo;
709 this.testStepPropertiesListener = testStepPropertiesListener;
710 }
711
712 public void itemStateChanged(ItemEvent e)
713 {
714 if( e.getStateChange() == ItemEvent.DESELECTED )
715 {
716 WsdlTestStep step = (WsdlTestStep) transferStep.getTestCase().getTestStepByName( (String) e.getItem() );
717 if( step != null )
718 step.removeTestStepListener( testStepPropertiesListener );
719 }
720
721 if( e.getStateChange() == ItemEvent.SELECTED )
722 {
723 String selectedItem = (String) e.getItem();
724 WsdlTestStep step = (WsdlTestStep) transferStep.getTestCase().getTestStepByName( selectedItem );
725
726 String[] propertyNames = step == null ? new String[0] : step.getPropertyNames();
727
728
729 if( propertyCombo == targetPropertyCombo )
730 {
731 List<String> names = new ArrayList<String>();
732 for( String name : propertyNames )
733 {
734 TestStepProperty property = step.getProperty( name );
735 if( !property.isReadOnly() )
736 names.add( property.getName() );
737 }
738
739 propertyNames = names.toArray( new String[names.size()] );
740 }
741
742 propertyCombo.setModel( new DefaultComboBoxModel( propertyNames ));
743 propertyCombo.setEnabled( propertyNames.length > 0 );
744
745 if( propertyCombo == targetPropertyCombo )
746 propertyCombo.setSelectedItem( getCurrentTransfer().getTargetPropertyName() );
747 else
748 propertyCombo.setSelectedItem( getCurrentTransfer().getSourcePropertyName() );
749
750 step.addTestStepListener( testStepPropertiesListener );
751 }
752 else
753 {
754 propertyCombo.removeAllItems();
755 propertyCombo.setEnabled( false );
756 }
757 }
758 }
759
760 /***
761 * Handle updates to source path
762 */
763
764 private final class SourceAreaDocumentListener extends DocumentListenerAdapter
765 {
766 public void update(Document document)
767 {
768 int ix = transferList.getSelectedIndex();
769 if( ix != -1 )
770 {
771 transferStep.getTransferAt( ix ).setSourcePath( sourceArea.getText() );
772 }
773 }
774 }
775
776 /***
777 * Handle updates to target path
778 */
779
780 private final class TargetAreaDocumentListener extends DocumentListenerAdapter
781 {
782 public void update( Document document )
783 {
784 int ix = transferList.getSelectedIndex();
785 if( ix != -1 )
786 {
787 transferStep.getTransferAt( ix ).setTargetPath( targetArea.getText() );
788 }
789 }
790 }
791
792 /***
793 * Listen to selection changes in transfer list and update controls accordingly
794 */
795
796 private final class TransferListSelectionListener implements ListSelectionListener
797 {
798 private PropertyTransfer transfer;
799
800 public void valueChanged(ListSelectionEvent e)
801 {
802 selecting = true;
803
804 if( transfer != null )
805 {
806 transfer.removePropertyChangeListener( transferPropertyChangeListener );
807 }
808
809 transfer = getCurrentTransfer();
810
811 if( transfer == null )
812 {
813 sourceArea.setText( "" );
814 targetArea.setText( "" );
815
816 sourcePropertyCombo.removeAllItems();
817 targetPropertyCombo.removeAllItems();
818
819 sourceStepCombo.setSelectedIndex( -1 );
820 targetStepCombo.setSelectedIndex( -1 );
821 }
822 else
823 {
824 transfer.addPropertyChangeListener( transferPropertyChangeListener );
825
826 sourceArea.setText( transfer.getSourcePath() );
827 targetArea.setText( transfer.getTargetPath() );
828
829 sourceStepCombo.setSelectedItem( transfer.getSourceStepName() );
830 sourcePropertyCombo.setSelectedItem( transfer.getSourcePropertyName() );
831
832 targetStepCombo.setSelectedItem( transfer.getTargetStepName() );
833 targetPropertyCombo.setSelectedItem( transfer.getTargetPropertyName() );
834
835 failTransferCheckBox.setSelected( transfer.getFailOnError() );
836 setNullCheckBox.setSelected( transfer.getSetNullOnMissingSource() );
837 transferTextContentCheckBox.setSelected( transfer.getTransferTextContent() );
838 ignoreEmptyCheckBox.setSelected( transfer.getIgnoreEmpty() );
839 transferAllCheckBox.setSelected( transfer.getTransferToAll() );
840 useXQueryCheckBox.setSelected( transfer.getUseXQuery() );
841 }
842
843 copyButton.setEnabled( transfer != null );
844 renameButton.setEnabled( transfer != null );
845 deleteButton.setEnabled( transfer != null );
846 declareButton.setEnabled( transfer != null );
847 sourceStepCombo.setEnabled( transfer != null );
848 targetStepCombo.setEnabled( transfer != null );
849 sourceArea.setEnabled( transfer != null );
850 targetArea.setEnabled( transfer != null );
851 failTransferCheckBox.setEnabled( transfer != null );
852 setNullCheckBox.setEnabled( transfer != null );
853 transferTextContentCheckBox.setEnabled( transfer != null );
854 ignoreEmptyCheckBox.setEnabled( transfer != null );
855 transferAllCheckBox.setEnabled( transfer != null );
856 useXQueryCheckBox.setEnabled( transfer != null );
857
858 runAllButton.setEnabled( transferList.getModel().getSize() > 0 );
859 runButton.setEnabled( transfer != null );
860
861 sourcePropertyCombo.setEnabled( transfer != null );
862 targetPropertyCombo.setEnabled( transfer != null );
863
864 selecting = false;
865 }
866 }
867
868 /***
869 * Listen to property changes and update UI objects. These may have been triggered by UI so first check
870 * for actual difference so we dont end up in loop.
871 */
872
873 private class TransferPropertyChangeListener implements PropertyChangeListener
874 {
875 public void propertyChange(PropertyChangeEvent evt)
876 {
877 Object newValue = evt.getNewValue();
878
879 if( evt.getPropertyName().equals( PropertyTransfer.SOURCE_PATH_PROPERTY ))
880 {
881 if( !sourceArea.getText().equals( newValue ))
882 sourceArea.setText( (String) newValue );
883 }
884 else if( evt.getPropertyName().equals( PropertyTransfer.TARGET_PATH_PROPERTY ))
885 {
886 if( !targetArea.getText().equals( newValue ))
887 targetArea.setText( (String) newValue );
888 }
889 else if( evt.getPropertyName().equals( PropertyTransfer.SOURCE_STEP_PROPERTY ))
890 {
891 Object selectedItem = sourceStepCombo.getSelectedItem();
892 if( newValue == null || selectedItem == null || !selectedItem.equals( newValue ))
893 {
894 selecting = true;
895 sourceStepCombo.setSelectedItem( newValue );
896 selecting = false;
897 }
898 }
899 else if( evt.getPropertyName().equals( PropertyTransfer.TARGET_STEP_PROPERTY ))
900 {
901 Object selectedItem = targetStepCombo.getSelectedItem();
902 if( newValue == null || selectedItem == null || !selectedItem.equals( newValue ))
903 {
904 selecting = true;
905 targetStepCombo.setSelectedItem( newValue );
906 selecting = false;
907 }
908 }
909 else if( evt.getPropertyName().equals( PropertyTransfer.SOURCE_TYPE_PROPERTY ))
910 {
911 Object selectedItem = sourcePropertyCombo.getSelectedItem();
912 if( selectedItem == null || !selectedItem.equals( newValue ))
913 sourcePropertyCombo.setSelectedItem( newValue );
914 }
915 else if( evt.getPropertyName().equals( PropertyTransfer.TARGET_TYPE_PROPERTY ))
916 {
917 Object selectedItem = targetPropertyCombo.getSelectedItem();
918 if( selectedItem == null || !selectedItem.equals( newValue ))
919 targetPropertyCombo.setSelectedItem( newValue );
920 }
921 }
922 }
923
924 private final class AddAction extends AbstractAction
925 {
926 public AddAction()
927 {
928 putValue( Action.SHORT_DESCRIPTION, "Adds a new Property Transfer" );
929 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/add_property.gif" ));
930 }
931
932 public void actionPerformed(ActionEvent e)
933 {
934 String name = UISupport.prompt( "Specify name for value transfer", "Add Transfer", "" );
935 if( name == null || name.trim().length() == 0 ) return;
936
937 transferStep.addTransfer( name );
938
939 listModel.addElement( name );
940 transferList.setSelectedIndex( listModel.getSize()-1 );
941 }
942 }
943
944 private final class CopyAction extends AbstractAction
945 {
946 public CopyAction()
947 {
948 putValue( Action.SHORT_DESCRIPTION, "Copies the selected Property Transfer" );
949 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/clone_request.gif" ));
950 }
951
952 public void actionPerformed(ActionEvent e)
953 {
954 int ix = transferList.getSelectedIndex();
955 PropertyTransfer config = transferStep.getTransferAt( ix );
956
957 String name = UISupport.prompt( "Specify name for value transfer", "Copy Transfer", config.getName() );
958 if( name == null || name.trim().length() == 0 ) return;
959
960 PropertyTransfer transfer = transferStep.addTransfer( name );
961 transfer.setSourceStepName( config.getSourceStepName() );
962 transfer.setSourcePropertyName( config.getSourcePropertyName() );
963 transfer.setSourcePath( config.getSourcePath() );
964 transfer.setTargetStepName( config.getTargetStepName() );
965 transfer.setTargetPropertyName( config.getTargetPropertyName() );
966 transfer.setTargetPath( config.getTargetPath() );
967
968 listModel.addElement( name );
969 transferList.setSelectedIndex( listModel.getSize()-1 );
970 }
971 }
972
973 private final class DeleteAction extends AbstractAction
974 {
975 public DeleteAction()
976 {
977 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/remove_property.gif" ));
978 putValue( Action.SHORT_DESCRIPTION, "Deletes the selected Property Transfer" );
979 }
980
981 public void actionPerformed(ActionEvent e)
982 {
983 if( UISupport.confirm( "Delete selected transfer", "Delete Transfer" ))
984 {
985 transferList.setSelectedIndex( -1 );
986
987 int ix = transferList.getSelectedIndex();
988 transferStep.removeTransferAt( ix );
989 listModel.remove( ix );
990
991 if( listModel.getSize() > 0 )
992 {
993 transferList.setSelectedIndex( ix > listModel.getSize()-1 ? listModel.getSize()-1 : ix );
994 }
995 }
996 }
997 }
998
999 private final class ClearLogAction extends AbstractAction
1000 {
1001 public ClearLogAction()
1002 {
1003 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/clear_properties.gif" ));
1004 putValue( Action.SHORT_DESCRIPTION, "Clears the property-transfer log" );
1005 }
1006
1007 public void actionPerformed(ActionEvent e)
1008 {
1009 transfersTableModel.clear();
1010 }
1011 }
1012
1013 private final class RenameAction extends AbstractAction
1014 {
1015 public RenameAction()
1016 {
1017 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/rename.gif" ));
1018 putValue( Action.SHORT_DESCRIPTION, "Renames the selected Property Transfer" );
1019 }
1020
1021 public void actionPerformed(ActionEvent e)
1022 {
1023 PropertyTransfer transfer = getCurrentTransfer();
1024
1025 String newName = UISupport.prompt( "Specify new name for transfer", "Rename Transfer", transfer.getName() );
1026
1027 if( newName != null && !transfer.getName().equals( newName ))
1028 {
1029 listModel.setElementAt( newName, transferList.getSelectedIndex() );
1030 transfer.setName( newName );
1031 }
1032 }
1033 }
1034
1035 private final class DeclareNamespacesAction extends AbstractAction
1036 {
1037 public DeclareNamespacesAction()
1038 {
1039 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/declareNs.gif" ));
1040 putValue( Action.SHORT_DESCRIPTION, "Declare available response/request namespaces in source/target expressions" );
1041 }
1042
1043 public void actionPerformed(ActionEvent e)
1044 {
1045 try
1046 {
1047 TestStep previousStep = getCurrentTransfer().getSourceStep();
1048
1049 if ( previousStep instanceof WsdlTestRequestStep )
1050 {
1051 WsdlTestRequest testRequest = ((WsdlTestRequestStep)previousStep).getTestRequest();
1052 sourceArea.setText( XmlUtils.declareXPathNamespaces( testRequest.getOperation().getInterface() ) + sourceArea.getText() );
1053 }
1054 else UISupport.showErrorMessage( "Source step is not a request" );
1055
1056 TestStep nextStep = getCurrentTransfer().getTargetStep();
1057
1058 if (nextStep instanceof WsdlTestRequestStep)
1059 {
1060 WsdlTestRequest testRequest = ((WsdlTestRequestStep)nextStep).getTestRequest();
1061 targetArea.setText( XmlUtils.declareXPathNamespaces( testRequest.getOperation().getInterface()) + targetArea.getText() );
1062 }
1063 else UISupport.showErrorMessage( "Target step is not a request" );
1064 }
1065 catch (Exception e1)
1066 {
1067 UISupport.showErrorMessage( e1 );
1068 }
1069 }
1070 }
1071
1072 private final class RunAllAction extends AbstractAction
1073 {
1074 public RunAllAction()
1075 {
1076 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_all.gif" ));
1077 putValue( Action.SHORT_DESCRIPTION, "Runs all Property Transfers" );
1078 }
1079
1080 public void actionPerformed(ActionEvent e)
1081 {
1082 if( listModel.getSize() == 0 )
1083 {
1084 UISupport.showErrorMessage( "Missing transfers!" );
1085 return;
1086 }
1087
1088 WsdlTestRunContext context = new WsdlTestRunContext( transferStep );
1089 ValueTransferResult result = (ValueTransferResult) transferStep.run( null, context );
1090 transfersTableModel.addResult( result );
1091 }
1092 }
1093
1094 private final class RunAction extends AbstractAction
1095 {
1096 public RunAction()
1097 {
1098 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run.gif" ));
1099 putValue( Action.SHORT_DESCRIPTION, "Runs selected PropertyTransfer" );
1100 }
1101
1102 public void actionPerformed(ActionEvent e)
1103 {
1104 if( transferList.getSelectedIndex() == -1 )
1105 {
1106 UISupport.showErrorMessage( "No transfer selectd!" );
1107 return;
1108 }
1109
1110 WsdlTestRunContext context = new WsdlTestRunContext( transferStep );
1111 ValueTransferResult result = (ValueTransferResult) transferStep.run( null, context, getCurrentTransfer() );
1112 transfersTableModel.addResult( result );
1113 }
1114 }
1115
1116 public boolean onClose( boolean canCancel )
1117 {
1118 super.release();
1119 transferStep.getTestCase().getTestSuite().removeTestSuiteListener( testSuiteListener );
1120 transferStep.getTestCase().removeTestRunListener( testRunListener );
1121
1122 PropertyTransfer transfer = getCurrentTransfer();
1123
1124 if( transfer != null )
1125 {
1126 transfer.removePropertyChangeListener( transferPropertyChangeListener );
1127 }
1128
1129 for( int c = 0; c < transferStep.getTestCase().getTestStepCount(); c++ )
1130 {
1131 WsdlTestStep testStep = (WsdlTestStep) transferStep.getTestCase().getTestStepAt( c );
1132
1133 testStep.removePropertyChangeListener( TestStep.NAME_PROPERTY, sourceTestStepNameListener);
1134 testStep.removePropertyChangeListener( TestStep.NAME_PROPERTY, targetStepNameListener);
1135 }
1136
1137 Object item = sourceStepCombo.getSelectedItem();
1138 if( item != null )
1139 {
1140 WsdlTestStep step = (WsdlTestStep) transferStep.getTestCase().getTestStepByName( (String) item );
1141 if( step != null )
1142 step.removeTestStepListener( sourceStepPropertiesListener );
1143 }
1144
1145 item = targetStepCombo.getSelectedItem();
1146 if( item != null )
1147 {
1148 WsdlTestStep step = (WsdlTestStep) transferStep.getTestCase().getTestStepByName( (String) item );
1149 if( step != null )
1150 step.removeTestStepListener( targetStepPropertiesListener );
1151 }
1152
1153 componentEnabler.release();
1154 if( resultDesktopPanel != null )
1155 SoapUI.getDesktop().closeDesktopPanel( resultDesktopPanel );
1156
1157 return true;
1158 }
1159
1160 public JComponent getComponent()
1161 {
1162 return this;
1163 }
1164
1165 public boolean dependsOn(ModelItem modelItem)
1166 {
1167 return modelItem == transferStep || modelItem == transferStep.getTestCase() ||
1168 modelItem == transferStep.getTestCase().getTestSuite() ||
1169 modelItem == transferStep.getTestCase().getTestSuite().getProject();
1170 }
1171
1172 public boolean selectTransfer(PropertyTransfer transfer)
1173 {
1174 for( int c = 0; c < transferStep.getTransferCount(); c++ )
1175 {
1176 if( transferStep.getTransferAt( c ) == transfer )
1177 {
1178 transferList.setSelectedIndex( c );
1179 return true;
1180 }
1181 }
1182
1183 return false;
1184 }
1185
1186 private class TransfersTableModel extends AbstractTableModel
1187 {
1188 private List<ValueTransferResult> results = new ArrayList<ValueTransferResult>();
1189
1190 public synchronized int getRowCount()
1191 {
1192 int sum = 0;
1193 for( ValueTransferResult result : results )
1194 {
1195 sum += result.getTransferCount();
1196 }
1197
1198 return sum;
1199 }
1200
1201 public synchronized void clear()
1202 {
1203 results.clear();
1204 fireTableDataChanged();
1205 logInspector.setTitle( "Transfer Log (0)" );
1206 }
1207
1208 public synchronized void addResult( ValueTransferResult result )
1209 {
1210 int rowCount = getRowCount();
1211 results.add( result );
1212 fireTableRowsInserted( rowCount, rowCount + result.getTransferCount() );
1213
1214 logInspector.setTitle( "Transfer Log (" + getRowCount() + ")" );
1215 inspectorPanel.activate( logInspector );
1216 }
1217
1218 public int getColumnCount()
1219 {
1220 return 3;
1221 }
1222
1223 public String getColumnName(int column)
1224 {
1225 switch( column )
1226 {
1227 case 0 : return "Timestamp";
1228 case 1 : return "Transfer Name";
1229 case 2 : return "Transferred Values";
1230 }
1231
1232 return null;
1233 }
1234
1235 public synchronized Object getValueAt(int rowIndex, int columnIndex)
1236 {
1237
1238 ValueTransferResult result = null;
1239 int sum = 0;
1240
1241 for( int c = 0; c < results.size(); c++ )
1242 {
1243 if( sum + results.get( c ).getTransferCount() > rowIndex )
1244 {
1245 result = results.get( c );
1246 break;
1247 }
1248 else
1249 {
1250 sum += results.get( c ).getTransferCount();
1251 }
1252 }
1253
1254 if( result != null )
1255 {
1256 switch( columnIndex )
1257 {
1258 case 0 : return new Date( result.getTimeStamp() ).toString();
1259 case 1 : return result.getTransferAt( rowIndex-sum ).getName();
1260 case 2 : return Arrays.toString( result.getTransferredValuesAt( rowIndex-sum ) );
1261 }
1262 }
1263
1264 return null;
1265 }
1266
1267 }
1268
1269 private class InternalTestRunListener extends TestRunListenerAdapter
1270 {
1271 @Override
1272 public void afterStep( TestRunner testRunner, TestRunContext runContext, TestStepResult result )
1273 {
1274 if( result.getTestStep() == transferStep )
1275 {
1276 transfersTableModel.addResult( ( ValueTransferResult ) result );
1277 }
1278 }
1279 }
1280 }