View Javadoc

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