View Javadoc

    1   /*
    2    *  soapUI, copyright (C) 2004-2007 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.testcase;
    14
    15  import java.awt.BorderLayout;
    16  import java.awt.Component;
    17  import java.awt.Insets;
    18  import java.awt.Point;
    19  import java.awt.dnd.Autoscroll;
    20  import java.awt.event.ActionEvent;
    21  import java.awt.event.KeyAdapter;
    22  import java.awt.event.KeyEvent;
    23  import java.awt.event.MouseAdapter;
    24  import java.awt.event.MouseEvent;
    25  import java.beans.PropertyChangeEvent;
    26  import java.beans.PropertyChangeListener;
    27
    28  import javax.swing.AbstractAction;
    29  import javax.swing.AbstractListModel;
    30  import javax.swing.Action;
    31  import javax.swing.BorderFactory;
    32  import javax.swing.JLabel;
    33  import javax.swing.JList;
    34  import javax.swing.JMenu;
    35  import javax.swing.JPanel;
    36  import javax.swing.JPopupMenu;
    37  import javax.swing.JSeparator;
    38  import javax.swing.ListCellRenderer;
    39  import javax.swing.ListSelectionModel;
    40  import javax.swing.event.PopupMenuEvent;
    41  import javax.swing.event.PopupMenuListener;
    42
    43  import com.eviware.soapui.SoapUI;
    44  import com.eviware.soapui.config.TestStepConfig;
    45  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
    46  import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStep;
    47  import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestStepFactory;
    48  import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestStepRegistry;
    49  import com.eviware.soapui.model.ModelItem;
    50  import com.eviware.soapui.model.support.TestSuiteListenerAdapter;
    51  import com.eviware.soapui.model.testsuite.TestStep;
    52  import com.eviware.soapui.support.UISupport;
    53  import com.eviware.soapui.support.action.swing.ActionList;
    54  import com.eviware.soapui.support.action.swing.ActionListBuilder;
    55  import com.eviware.soapui.support.action.swing.ActionSupport;
    56  import com.eviware.soapui.support.swing.AutoscrollSupport;
    57
    58  /***
    59   * Panel for displaying and editing a list of TestSteps
    60   *
    61   * @author Ole.Matzura
    62   */
    63
    64  public class TestStepList extends JPanel
    65  {
    66  	private TestStepListModel testStepListModel;
    67  	private JList testStepList;
    68  	private JPopupMenu testListPopup;
    69  	private JMenu appendStepMenu;
    70  	private final WsdlTestCase testCase;
    71
    72  	public TestStepList(WsdlTestCase testCase)
    73  	{
    74  		super(new BorderLayout());
    75  		this.testCase = testCase;
    76
    77  		buildUI();
    78  	}
    79
    80  	public JList getTestStepList()
    81  	{
    82  		return testStepList;
    83  	}
    84
    85  	private void buildUI()
    86  	{
    87  		testStepListModel = new TestStepListModel();
    88  		testStepList = new TestStepJList(testStepListModel);
    89  		testStepList.setCellRenderer(new TestStepCellRenderer());
    90  		testStepList.setFixedCellHeight( 22 );
    91  		testStepList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    92  		testStepList.addKeyListener(new TestStepListKeyHandler());
    93
    94  		testStepList.addMouseListener(new StepListMouseListener());
    95  		testStepList.addMouseListener(new MouseAdapter()
    96  		{
    97  			private int newIndex;
    98  			private int prevIndex;
    99
    100 			public void mouseClicked(MouseEvent e)
    101 			{
    102 				if( e.getButton() != MouseEvent.BUTTON1 )
    103 					return;
    104
    105 				newIndex = testStepList.locationToIndex(e.getPoint());
    106
    107 				if((prevIndex == newIndex) & ( prevIndex != -1))
    108 				{
    109 					testStepList.clearSelection();
    110 					newIndex = -1;
    111 				}
    112
    113 				prevIndex = newIndex;
    114 			}
    115 		} );
    116
    117 		testListPopup = new JPopupMenu();
    118 		testListPopup.addSeparator();
    119
    120 		appendStepMenu = new JMenu("Append Step");
    121
    122 		WsdlTestStepRegistry registry = WsdlTestStepRegistry.getInstance();
    123 		WsdlTestStepFactory[] factories = (WsdlTestStepFactory[]) registry.getFactories();
    124
    125 		for (int c = 0; c < factories.length; c++)
    126 		{
    127 			if (factories[c].canCreate())
    128 				appendStepMenu.add(new InsertTestStepAction(factories[c]));
    129 		}
    130
    131 		testListPopup.add(appendStepMenu);
    132
    133 		testListPopup.addPopupMenuListener(new StepListPopupMenuListener(testCase));
    134 		testStepList.setComponentPopupMenu(testListPopup);
    135
    136 		add( testStepList, BorderLayout.CENTER );
    137 	}
    138
    139 	public void setEnabled(boolean enabled)
    140 	{
    141 		testStepList.setEnabled( enabled );
    142
    143 		super.setEnabled(enabled);
    144 	}
    145
    146 	private final class TestStepListKeyHandler extends KeyAdapter
    147 	{
    148 		public void keyPressed(KeyEvent e)
    149 		{
    150 			if (e.getKeyChar() == KeyEvent.VK_ENTER)
    151 			{
    152 				int ix = testStepList.getSelectedIndex();
    153 				if (ix != -1)
    154 				{
    155 					TestStep testStep = (TestStep) testCase.getTestStepAt(ix);
    156 					UISupport.selectAndShow(testStep);
    157 					e.consume();
    158 				}
    159 			}
    160 			else
    161 			{
    162 				int ix = testStepList.getSelectedIndex();
    163 				if (ix != -1)
    164 				{
    165 					TestStep testStep = (TestStep) testCase.getTestStepAt(ix);
    166 					ActionList actions = ActionListBuilder.buildActions( testStep );
    167 					if( actions != null )
    168 						actions.dispatchKeyEvent( e );
    169 				}
    170 			}
    171 		}
    172 	}
    173
    174 	private final class StepListPopupMenuListener implements PopupMenuListener
    175 	{
    176 		private StepListPopupMenuListener(WsdlTestCase case1)
    177 		{
    178 			super();
    179 		}
    180
    181 		public void popupMenuWillBecomeVisible(PopupMenuEvent e)
    182 		{
    183 			while (testListPopup.getComponentCount() > 1)
    184 				testListPopup.remove(0);
    185
    186 			int ix = testStepList.getSelectedIndex();
    187
    188 			if( SoapUI.getTestMonitor().hasRunningLoadTest( testCase ))
    189 			{
    190 				appendStepMenu.setEnabled( false );
    191
    192 				return;
    193 			}
    194
    195 			appendStepMenu.setEnabled(true);
    196
    197 			if( ix >= 0 )
    198 			{
    199 				testListPopup.insert( new JSeparator(), 0 );
    200 				TestStep testStep = (TestStep) testCase.getTestStepAt(ix);
    201 				ActionSupport.insertActions(ActionListBuilder.buildActions( testStep ), testListPopup, 0);
    202 			}
    203 		}
    204
    205 		public void popupMenuWillBecomeInvisible(PopupMenuEvent e)
    206 		{
    207 		}
    208
    209 		public void popupMenuCanceled(PopupMenuEvent e)
    210 		{
    211 		}
    212 	}
    213
    214 	private final class StepListMouseListener extends MouseAdapter
    215 	{
    216 		public void mouseClicked(MouseEvent e)
    217 		{
    218 			if (e.getClickCount() < 2)
    219 			{
    220 				return;
    221 			}
    222
    223 			ModelItem modelItem = (ModelItem) testStepList.getSelectedValue();
    224 			if (modelItem == null)
    225 				return;
    226
    227 			Action defaultAction = ActionListBuilder.buildActions( modelItem ).getDefaultAction();
    228 			if( defaultAction != null )
    229 				defaultAction.actionPerformed( new ActionEvent( TestStepList.this, 0, null ));
    230 		}
    231 	}
    232
    233 	/***
    234 	 * Renderer which sets icon and wider border for teststeps
    235 	 *
    236 	 * @author Ole.Matzura
    237 	 */
    238
    239 	private final static class TestStepCellRenderer extends JLabel implements ListCellRenderer
    240 	{
    241 		public TestStepCellRenderer()
    242 		{
    243 			setOpaque(true);
    244 			setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
    245 		}
    246
    247 		public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
    248 				boolean cellHasFocus)
    249 		{
    250 			WsdlTestStep testStep = (WsdlTestStep) value;
    251
    252 			setText(testStep.getLabel());
    253 			setIcon(testStep.getIcon());
    254
    255 			if (isSelected)
    256 			{
    257 				setBackground(list.getSelectionBackground());
    258 				setForeground(list.getSelectionForeground());
    259 			}
    260 			else
    261 			{
    262 				setBackground(list.getBackground());
    263 				setForeground(list.getForeground());
    264 			}
    265
    266 			setEnabled(list.isEnabled() && !testStep.isDisabled());
    267
    268 			String toolTipText = list.getToolTipText();
    269 			if( toolTipText == null )
    270 				setToolTipText( testStep.getDescription() );
    271 			else
    272 				setToolTipText( toolTipText.length() == 0 ? null : toolTipText );
    273
    274 			return this;
    275 		}
    276 	}
    277
    278 	private class TestStepListModel extends AbstractListModel implements PropertyChangeListener
    279 	{
    280 		private TestStepListTestSuiteListener testStepListTestSuiteListener = new TestStepListTestSuiteListener();
    281
    282 		public TestStepListModel()
    283 		{
    284 			for (int c = 0; c < getSize(); c++)
    285 				testCase.getTestStepAt(c).addPropertyChangeListener(this);
    286
    287 			testCase.getTestSuite().addTestSuiteListener(testStepListTestSuiteListener);
    288 		}
    289
    290 		public int getSize()
    291 		{
    292 			return testCase.getTestStepCount();
    293 		}
    294
    295 		public Object getElementAt(int index)
    296 		{
    297 			return testCase.getTestStepAt(index);
    298 		}
    299
    300 		public void propertyChange(PropertyChangeEvent arg0)
    301 		{
    302 			int ix = testCase.getIndexOfTestStep((TestStep) arg0.getSource());
    303 			if (ix == -1)
    304 				return;
    305
    306 			fireContentsChanged(this, ix, ix);
    307 		}
    308
    309 		public void release()
    310 		{
    311 			testCase.getTestSuite().removeTestSuiteListener(testStepListTestSuiteListener);
    312
    313 			for (int c = 0; c < getSize(); c++)
    314 				testCase.getTestStepAt(c).removePropertyChangeListener(this);
    315 		}
    316
    317 		private class TestStepListTestSuiteListener extends TestSuiteListenerAdapter
    318 		{
    319 			public void testStepAdded(TestStep testStep, int ix)
    320 			{
    321 				if( testStep.getTestCase() == testCase )
    322 				{
    323 					testStep.addPropertyChangeListener(TestStepListModel.this);
    324 					fireIntervalAdded(TestStepListModel.this, ix, ix);
    325 				}
    326 			}
    327
    328 			public void testStepRemoved(TestStep testStep, int ix)
    329 			{
    330 				if( testStep.getTestCase() == testCase )
    331 				{
    332 					testStep.removePropertyChangeListener(TestStepListModel.this);
    333 					fireIntervalRemoved(TestStepListModel.this, ix, ix);
    334 				}
    335 			}
    336
    337 			@Override
    338 			public void testStepMoved( TestStep testStep, int fromIndex, int offset )
    339 			{
    340 				if( testStep.getTestCase() == testCase )
    341 				{
    342 					fireContentsChanged( TestStepListModel.this, fromIndex, fromIndex+offset);
    343 					int selectedIndex = testStepList.getSelectedIndex();
    344 					if( selectedIndex == fromIndex )
    345 					{
    346 						testStepList.setSelectedIndex( fromIndex+offset );
    347 					}
    348 					else if( selectedIndex < fromIndex && selectedIndex >= fromIndex+offset )
    349 					{
    350 						testStepList.setSelectedIndex( selectedIndex+1 );
    351 					}
    352 					else if( selectedIndex > fromIndex && selectedIndex <= fromIndex+offset )
    353 					{
    354 						testStepList.setSelectedIndex( selectedIndex-1 );
    355 					}
    356 				}
    357 			}
    358 		}
    359 	}
    360
    361 	public class InsertTestStepAction extends AbstractAction
    362 	{
    363 		private final WsdlTestStepFactory factory;
    364
    365 		public InsertTestStepAction(WsdlTestStepFactory factory)
    366 		{
    367 			super(factory.getTestStepName());
    368 			putValue( Action.SHORT_DESCRIPTION, factory.getTestStepDescription());
    369 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( factory.getTestStepIconPath() ));
    370 			this.factory = factory;
    371 		}
    372
    373 		public void actionPerformed(ActionEvent e)
    374 		{
    375 			String name = UISupport.prompt( "Specify name for new step", "Insert Step", factory.getTestStepName());
    376 			if( name != null )
    377 			{
    378 				TestStepConfig newTestStepConfig = factory.createNewTestStep(testCase, name);
    379 				if( newTestStepConfig != null )
    380 				{
    381 					WsdlTestStep testStep = testCase.addTestStep(newTestStepConfig);
    382 					UISupport.selectAndShow( testStep );
    383 				}
    384 			}
    385 		}
    386 	}
    387
    388 	public void setSelectedIndex(int i)
    389 	{
    390 		testStepList.setSelectedIndex(i);
    391 	}
    392
    393 	public void setSelectedValue(TestStep testStep, boolean b)
    394 	{
    395 		testStepList.setSelectedValue(testStep, true);
    396 	}
    397
    398 	public void release()
    399 	{
    400 		testStepListModel.release();
    401 	}
    402
    403 	private static class TestStepJList extends JList implements Autoscroll
    404 	{
    405 		private AutoscrollSupport autoscrollSupport;
    406
    407 		public TestStepJList( TestStepListModel testStepListModel )
    408 		{
    409 			super( testStepListModel );
    410
    411 			autoscrollSupport = new AutoscrollSupport( this, new Insets(10, 10, 10, 10) );
    412 		}
    413
    414 		public void autoscroll( Point cursorLoc )
    415 		{
    416 			autoscrollSupport.autoscroll( cursorLoc );
    417 		}
    418
    419 		public Insets getAutoscrollInsets()
    420 		{
    421 			 return autoscrollSupport.getAutoscrollInsets();
    422 		}
    423 	}
    424 }