View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2009 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 JTestStepList 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 JTestStepList( 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.MULTIPLE_INTERVAL_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.isSelectedIndex( index )
153 						&& testStepList.getCellBounds( index, index ).contains( location ) )
154 				{
155 					testStepList.addSelectionInterval( index, index );
156 					ix = index;
157 				}
158 				else if( index != -1 && testStepList.isSelectedIndex( index )
159 						&& testStepList.getCellBounds( index, index ).contains( location ) )
160 				{
161 					ix = index;
162 				}
163 			}
164 
165 			if( ix >= 0 )
166 			{
167 				int[] indices = testStepList.getSelectedIndices();
168 				if( indices.length == 1 )
169 				{
170 					TestStep testStep = ( TestStep )testCase.getTestStepAt( ix );
171 					ActionSupport.addActions( ActionListBuilder.buildActions( testStep ), testListPopup );
172 				}
173 				else
174 				{
175 					ModelItem[] modelItems = new ModelItem[indices.length];
176 					for( int c = 0; c < indices.length; c++ )
177 						modelItems[c] = testCase.getTestStepAt( indices[c] ).getModelItem();
178 
179 					ActionSupport.addActions( ActionListBuilder.buildMultiActions( modelItems ), testListPopup );
180 				}
181 			}
182 			else
183 			{
184 				testStepList.clearSelection();
185 				testListPopup.add( appendStepMenu );
186 			}
187 		}
188 
189 		public void popupMenuWillBecomeInvisible( PopupMenuEvent e )
190 		{
191 		}
192 
193 		public void popupMenuCanceled( PopupMenuEvent e )
194 		{
195 		}
196 	}
197 
198 	// private final class StepListMouseListener extends MouseAdapter
199 	// {
200 	// public void mouseClicked(MouseEvent e)
201 	// {
202 	// if (e.getClickCount() < 2)
203 	// {
204 	// return;
205 	// }
206 	//			
207 	// ModelItem modelItem = (ModelItem) testStepList.getSelectedValue();
208 	// if (modelItem == null)
209 	// return;
210 	//
211 	// Action defaultAction = ActionListBuilder.buildActions( modelItem
212 	// ).getDefaultAction();
213 	// if( defaultAction != null )
214 	// defaultAction.actionPerformed( new ActionEvent( TestStepList.this, 0, null
215 	// ));
216 	// }
217 	// }
218 
219 	/***
220 	 * Renderer which sets icon and wider border for teststeps
221 	 * 
222 	 * @author Ole.Matzura
223 	 */
224 
225 	private final static class TestStepCellRenderer extends JLabel implements ListCellRenderer
226 	{
227 		public TestStepCellRenderer()
228 		{
229 			setOpaque( true );
230 			setBorder( BorderFactory.createEmptyBorder( 3, 3, 3, 3 ) );
231 		}
232 
233 		public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected,
234 				boolean cellHasFocus )
235 		{
236 			WsdlTestStep testStep = ( WsdlTestStep )value;
237 
238 			setText( testStep.getLabel() );
239 			setIcon( testStep.getIcon() );
240 
241 			if( isSelected )
242 			{
243 				setBackground( list.getSelectionBackground() );
244 				setForeground( list.getSelectionForeground() );
245 			}
246 			else
247 			{
248 				setBackground( list.getBackground() );
249 				setForeground( list.getForeground() );
250 			}
251 
252 			setEnabled( list.isEnabled() && !testStep.isDisabled() );
253 
254 			String toolTipText = list.getToolTipText();
255 			if( toolTipText == null )
256 				setToolTipText( testStep.getDescription() );
257 			else
258 				setToolTipText( toolTipText.length() == 0 ? null : toolTipText );
259 
260 			return this;
261 		}
262 	}
263 
264 	private class TestStepListModel extends AbstractListModel implements PropertyChangeListener
265 	{
266 		private TestStepListTestSuiteListener testStepListTestSuiteListener = new TestStepListTestSuiteListener();
267 
268 		public TestStepListModel()
269 		{
270 			for( int c = 0; c < getSize(); c++ )
271 				testCase.getTestStepAt( c ).addPropertyChangeListener( this );
272 
273 			testCase.getTestSuite().addTestSuiteListener( testStepListTestSuiteListener );
274 		}
275 
276 		public int getSize()
277 		{
278 			return testCase.getTestStepCount();
279 		}
280 
281 		public Object getElementAt( int index )
282 		{
283 			return testCase.getTestStepAt( index );
284 		}
285 
286 		public void propertyChange( PropertyChangeEvent arg0 )
287 		{
288 			int ix = testCase.getIndexOfTestStep( ( TestStep )arg0.getSource() );
289 			if( ix == -1 )
290 				return;
291 
292 			fireContentsChanged( this, ix, ix );
293 		}
294 
295 		public void release()
296 		{
297 			testCase.getTestSuite().removeTestSuiteListener( testStepListTestSuiteListener );
298 
299 			for( int c = 0; c < getSize(); c++ )
300 				testCase.getTestStepAt( c ).removePropertyChangeListener( this );
301 		}
302 
303 		private class TestStepListTestSuiteListener extends TestSuiteListenerAdapter
304 		{
305 			public void testStepAdded( TestStep testStep, int ix )
306 			{
307 				if( testStep.getTestCase() == testCase )
308 				{
309 					testStep.addPropertyChangeListener( TestStepListModel.this );
310 					fireIntervalAdded( TestStepListModel.this, ix, ix );
311 				}
312 			}
313 
314 			public void testStepRemoved( TestStep testStep, int ix )
315 			{
316 				if( testStep.getTestCase() == testCase )
317 				{
318 					testStep.removePropertyChangeListener( TestStepListModel.this );
319 					fireIntervalRemoved( TestStepListModel.this, ix, ix );
320 				}
321 			}
322 
323 			@Override
324 			public void testStepMoved( TestStep testStep, int fromIndex, int offset )
325 			{
326 				if( testStep.getTestCase() == testCase )
327 				{
328 					fireContentsChanged( TestStepListModel.this, fromIndex, fromIndex + offset );
329 					int selectedIndex = testStepList.getSelectedIndex();
330 					if( selectedIndex == fromIndex )
331 					{
332 						testStepList.setSelectedIndex( fromIndex + offset );
333 					}
334 					else if( selectedIndex < fromIndex && selectedIndex >= fromIndex + offset )
335 					{
336 						testStepList.setSelectedIndex( selectedIndex + 1 );
337 					}
338 					else if( selectedIndex > fromIndex && selectedIndex <= fromIndex + offset )
339 					{
340 						testStepList.setSelectedIndex( selectedIndex - 1 );
341 					}
342 				}
343 			}
344 		}
345 	}
346 
347 	public class InsertTestStepAction extends AbstractAction
348 	{
349 		private final WsdlTestStepFactory factory;
350 
351 		public InsertTestStepAction( WsdlTestStepFactory factory )
352 		{
353 			super( factory.getTestStepName() );
354 			putValue( Action.SHORT_DESCRIPTION, factory.getTestStepDescription() );
355 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( factory.getTestStepIconPath() ) );
356 			this.factory = factory;
357 		}
358 
359 		public void actionPerformed( ActionEvent e )
360 		{
361 			String name = UISupport.prompt( "Specify name for new step", "Insert Step", factory.getTestStepName() );
362 			if( name != null )
363 			{
364 				TestStepConfig newTestStepConfig = factory.createNewTestStep( testCase, name );
365 				if( newTestStepConfig != null )
366 				{
367 					WsdlTestStep testStep = testCase.addTestStep( newTestStepConfig );
368 					UISupport.selectAndShow( testStep );
369 				}
370 			}
371 		}
372 	}
373 
374 	public void setSelectedIndex( int i )
375 	{
376 		testStepList.setSelectedIndex( i );
377 	}
378 
379 	public void setSelectedValue( TestStep testStep, boolean b )
380 	{
381 		try
382 		{
383 			testStepList.setSelectedValue( testStep, true );
384 		}
385 		catch( RuntimeException e )
386 		{
387 			e.printStackTrace();
388 		}
389 	}
390 
391 	public void release()
392 	{
393 		testStepListModel.release();
394 	}
395 
396 	private static class TestStepJList extends JList implements Autoscroll
397 	{
398 		private AutoscrollSupport autoscrollSupport;
399 
400 		public TestStepJList( TestStepListModel testStepListModel )
401 		{
402 			super( testStepListModel );
403 
404 			autoscrollSupport = new AutoscrollSupport( this, new Insets( 10, 10, 10, 10 ) );
405 		}
406 
407 		public void autoscroll( Point cursorLoc )
408 		{
409 			autoscrollSupport.autoscroll( cursorLoc );
410 		}
411 
412 		public Insets getAutoscrollInsets()
413 		{
414 			return autoscrollSupport.getAutoscrollInsets();
415 		}
416 	}
417 }