View Javadoc

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