View Javadoc

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