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 			if( testStep.isDisabled() )
    253 				setText(testStep.getName() + " (disabled)");
    254 			else
    255 				setText(testStep.getName());
    256
    257 			setIcon(testStep.getIcon());
    258
    259 			if (isSelected)
    260 			{
    261 				setBackground(list.getSelectionBackground());
    262 				setForeground(list.getSelectionForeground());
    263 			}
    264 			else
    265 			{
    266 				setBackground(list.getBackground());
    267 				setForeground(list.getForeground());
    268 			}
    269
    270 			setEnabled(list.isEnabled() && !testStep.isDisabled());
    271
    272 			String toolTipText = list.getToolTipText();
    273 			if( toolTipText == null )
    274 				setToolTipText( testStep.getDescription() );
    275 			else
    276 				setToolTipText( toolTipText.length() == 0 ? null : toolTipText );
    277
    278 			return this;
    279 		}
    280 	}
    281
    282 	private class TestStepListModel extends AbstractListModel implements PropertyChangeListener
    283 	{
    284 		private TestStepListTestSuiteListener testStepListTestSuiteListener = new TestStepListTestSuiteListener();
    285
    286 		public TestStepListModel()
    287 		{
    288 			for (int c = 0; c < getSize(); c++)
    289 				testCase.getTestStepAt(c).addPropertyChangeListener(this);
    290
    291 			testCase.getTestSuite().addTestSuiteListener(testStepListTestSuiteListener);
    292 		}
    293
    294 		public int getSize()
    295 		{
    296 			return testCase.getTestStepCount();
    297 		}
    298
    299 		public Object getElementAt(int index)
    300 		{
    301 			return testCase.getTestStepAt(index);
    302 		}
    303
    304 		public void propertyChange(PropertyChangeEvent arg0)
    305 		{
    306 			int ix = testCase.getIndexOfTestStep((TestStep) arg0.getSource());
    307 			if (ix == -1)
    308 				return;
    309
    310 			fireContentsChanged(this, ix, ix);
    311 		}
    312
    313 		public void release()
    314 		{
    315 			testCase.getTestSuite().removeTestSuiteListener(testStepListTestSuiteListener);
    316
    317 			for (int c = 0; c < getSize(); c++)
    318 				testCase.getTestStepAt(c).removePropertyChangeListener(this);
    319 		}
    320
    321 		private class TestStepListTestSuiteListener extends TestSuiteListenerAdapter
    322 		{
    323 			public void testStepAdded(TestStep testStep, int ix)
    324 			{
    325 				if( testStep.getTestCase() == testCase )
    326 				{
    327 					testStep.addPropertyChangeListener(TestStepListModel.this);
    328 					fireIntervalAdded(TestStepListModel.this, ix, ix);
    329 				}
    330 			}
    331
    332 			public void testStepRemoved(TestStep testStep, int ix)
    333 			{
    334 				if( testStep.getTestCase() == testCase )
    335 				{
    336 					testStep.removePropertyChangeListener(TestStepListModel.this);
    337 					fireIntervalRemoved(TestStepListModel.this, ix, ix);
    338 				}
    339 			}
    340
    341 			@Override
    342 			public void testStepMoved( TestStep testStep, int fromIndex, int offset )
    343 			{
    344 				if( testStep.getTestCase() == testCase )
    345 				{
    346 					fireContentsChanged( TestStepListModel.this, fromIndex, fromIndex+offset);
    347 					int selectedIndex = testStepList.getSelectedIndex();
    348 					if( selectedIndex == fromIndex )
    349 					{
    350 						testStepList.setSelectedIndex( fromIndex+offset );
    351 					}
    352 					else if( selectedIndex < fromIndex && selectedIndex >= fromIndex+offset )
    353 					{
    354 						testStepList.setSelectedIndex( selectedIndex+1 );
    355 					}
    356 					else if( selectedIndex > fromIndex && selectedIndex <= fromIndex+offset )
    357 					{
    358 						testStepList.setSelectedIndex( selectedIndex-1 );
    359 					}
    360 				}
    361 			}
    362 		}
    363 	}
    364
    365 	public class InsertTestStepAction extends AbstractAction
    366 	{
    367 		private final WsdlTestStepFactory factory;
    368
    369 		public InsertTestStepAction(WsdlTestStepFactory factory)
    370 		{
    371 			super(factory.getTestStepName());
    372 			putValue( Action.SHORT_DESCRIPTION, factory.getTestStepDescription());
    373 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( factory.getTestStepIconPath() ));
    374 			this.factory = factory;
    375 		}
    376
    377 		public void actionPerformed(ActionEvent e)
    378 		{
    379 			String name = UISupport.prompt( "Specify name for new step", "Insert Step", factory.getTestStepName());
    380 			if( name != null )
    381 			{
    382 				TestStepConfig newTestStepConfig = factory.createNewTestStep(testCase, name);
    383 				if( newTestStepConfig != null )
    384 				{
    385 					WsdlTestStep testStep = testCase.addTestStep(newTestStepConfig);
    386 					UISupport.selectAndShow( testStep );
    387 				}
    388 			}
    389 		}
    390 	}
    391
    392 	public void setSelectedIndex(int i)
    393 	{
    394 		testStepList.setSelectedIndex(i);
    395 	}
    396
    397 	public void setSelectedValue(TestStep testStep, boolean b)
    398 	{
    399 		testStepList.setSelectedValue(testStep, true);
    400 	}
    401
    402 	public void release()
    403 	{
    404 		testStepListModel.release();
    405 	}
    406
    407 	private static class TestStepJList extends JList implements Autoscroll
    408 	{
    409 		private AutoscrollSupport autoscrollSupport;
    410
    411 		public TestStepJList( TestStepListModel testStepListModel )
    412 		{
    413 			super( testStepListModel );
    414
    415 			autoscrollSupport = new AutoscrollSupport( this, new Insets(10, 10, 10, 10) );
    416 		}
    417
    418 		public void autoscroll( Point cursorLoc )
    419 		{
    420 			autoscrollSupport.autoscroll( cursorLoc );
    421 		}
    422
    423 		public Insets getAutoscrollInsets()
    424 		{
    425 			 return autoscrollSupport.getAutoscrollInsets();
    426 		}
    427 	}
    428 }