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.loadtest;
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.MouseAdapter;
20  import java.awt.event.MouseEvent;
21  import java.beans.PropertyChangeEvent;
22  import java.beans.PropertyChangeListener;
23  
24  import javax.swing.AbstractAction;
25  import javax.swing.Action;
26  import javax.swing.Icon;
27  import javax.swing.ImageIcon;
28  import javax.swing.JButton;
29  import javax.swing.JComponent;
30  import javax.swing.JPanel;
31  import javax.swing.JPopupMenu;
32  import javax.swing.JScrollPane;
33  import javax.swing.JTable;
34  import javax.swing.ListSelectionModel;
35  import javax.swing.event.ListSelectionEvent;
36  import javax.swing.event.ListSelectionListener;
37  import javax.swing.table.AbstractTableModel;
38  import javax.swing.table.DefaultTableCellRenderer;
39  import javax.swing.table.TableColumnModel;
40  
41  import org.jdesktop.swingx.JXTable;
42  
43  import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
44  import com.eviware.soapui.impl.wsdl.loadtest.LoadTestAssertion;
45  import com.eviware.soapui.impl.wsdl.loadtest.LoadTestListener;
46  import com.eviware.soapui.impl.wsdl.loadtest.WsdlLoadTest;
47  import com.eviware.soapui.impl.wsdl.loadtest.assertions.LoadTestAssertionRegistry;
48  import com.eviware.soapui.impl.wsdl.support.Configurable;
49  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
50  import com.eviware.soapui.support.UISupport;
51  import com.eviware.soapui.support.components.JXToolBar;
52  
53  /***
54   * Table showing configured assertions for a WsdlLoadTest
55   * 
56   * @todo add popup menu
57   * 
58   * @author Ole.Matzura
59   */
60  
61  public class JLoadTestAssertionsTable extends JPanel
62  {
63  	private JXTable table;
64  	private final WsdlLoadTest loadTest;
65  	private ConfigureAssertionAction configureAssertionAction;
66  	private RemoveAssertionAction removeAssertionAction;
67  	private AddLoadTestAssertionAction addLoadTestAssertionAction;
68  	private LoadTestAssertionsTableModel tableModel;
69  	private JPopupMenu assertionPopup;
70  	private InternalLoadTestListener internalLoadTestListener = new InternalLoadTestListener();
71  
72  	public JLoadTestAssertionsTable( WsdlLoadTest wsdlLoadTest )
73  	{
74  		super( new BorderLayout() );
75  		this.loadTest = wsdlLoadTest;
76  
77  		loadTest.addLoadTestListener( internalLoadTestListener );
78  
79  		tableModel = new LoadTestAssertionsTableModel();
80  		table = new JXTable( tableModel );
81  		table.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
82  
83  		TableColumnModel columnModel = table.getColumnModel();
84  		columnModel.getColumn( 0 ).setMaxWidth( 16 );
85  		columnModel.getColumn( 0 ).setCellRenderer( new IconTableCellRenderer() );
86  		columnModel.getColumn( 1 ).setPreferredWidth( 100 );
87  		columnModel.getColumn( 2 ).setPreferredWidth( 100 );
88  		columnModel.getColumn( 3 ).setPreferredWidth( 200 );
89  
90  		JScrollPane scrollPane = new JScrollPane( table );
91  		add( scrollPane, BorderLayout.CENTER );
92  
93  		table.addMouseListener( new MouseAdapter()
94  		{
95  
96  			public void mouseClicked( MouseEvent e )
97  			{
98  				if( e.getClickCount() < 2 )
99  					return;
100 
101 				int ix = table.getSelectedRow();
102 				if( ix == -1 )
103 					return;
104 				ix = table.convertRowIndexToModel( ix );
105 
106 				Object obj = loadTest.getAssertionAt( ix );
107 				if( obj instanceof Configurable )
108 				{
109 					( ( Configurable )obj ).configure();
110 				}
111 				else
112 					Toolkit.getDefaultToolkit().beep();
113 			}
114 		} );
115 
116 		add( buildToolbar(), BorderLayout.NORTH );
117 
118 		table.getSelectionModel().addListSelectionListener( new ListSelectionListener()
119 		{
120 
121 			public void valueChanged( ListSelectionEvent e )
122 			{
123 				int ix = table.getSelectedRow();
124 
125 				configureAssertionAction.setEnabled( ix >= 0 );
126 				removeAssertionAction.setEnabled( ix >= 0 );
127 
128 				if( ix == -1 )
129 					return;
130 
131 				ix = table.convertRowIndexToModel( ix );
132 				configureAssertionAction.setEnabled( loadTest.getAssertionAt( ix ) instanceof Configurable );
133 			}
134 		} );
135 
136 		assertionPopup = new JPopupMenu();
137 		assertionPopup.add( configureAssertionAction );
138 		assertionPopup.addSeparator();
139 		assertionPopup.add( addLoadTestAssertionAction );
140 		assertionPopup.add( removeAssertionAction );
141 
142 		setComponentPopupMenu( assertionPopup );
143 
144 		scrollPane.setInheritsPopupMenu( true );
145 		table.setComponentPopupMenu( assertionPopup );
146 	}
147 
148 	public void release()
149 	{
150 		tableModel.release();
151 		loadTest.removeLoadTestListener( internalLoadTestListener );
152 	}
153 
154 	private JComponent buildToolbar()
155 	{
156 		configureAssertionAction = new ConfigureAssertionAction();
157 		removeAssertionAction = new RemoveAssertionAction();
158 		addLoadTestAssertionAction = new AddLoadTestAssertionAction();
159 
160 		JXToolBar toolbar = UISupport.createSmallToolbar();
161 
162 		JButton button = UISupport.createToolbarButton( addLoadTestAssertionAction );
163 		toolbar.addFixed( button );
164 		button = UISupport.createToolbarButton( removeAssertionAction );
165 		toolbar.addFixed( button );
166 		button = UISupport.createToolbarButton( configureAssertionAction );
167 		toolbar.addFixed( button );
168 		toolbar.addGlue();
169 		toolbar.add( new ShowOnlineHelpAction( HelpUrls.LOADTEST_ASSERTIONS_URL ) );
170 
171 		return toolbar;
172 	}
173 
174 	private class LoadTestAssertionsTableModel extends AbstractTableModel implements PropertyChangeListener
175 	{
176 		public LoadTestAssertionsTableModel()
177 		{
178 			for( int c = 0; c < loadTest.getAssertionCount(); c++ )
179 			{
180 				loadTest.getAssertionAt( c ).addPropertyChangeListener( LoadTestAssertion.CONFIGURATION_PROPERTY, this );
181 			}
182 		}
183 
184 		public void release()
185 		{
186 			for( int c = 0; c < loadTest.getAssertionCount(); c++ )
187 			{
188 				loadTest.getAssertionAt( c ).removePropertyChangeListener( LoadTestAssertion.CONFIGURATION_PROPERTY, this );
189 			}
190 		}
191 
192 		public int getRowCount()
193 		{
194 			return loadTest.getAssertionCount();
195 		}
196 
197 		public int getColumnCount()
198 		{
199 			return 4;
200 		}
201 
202 		public Class<?> getColumnClass( int columnIndex )
203 		{
204 			switch( columnIndex )
205 			{
206 			case 0 :
207 				return ImageIcon.class;
208 			default :
209 				return String.class;
210 			}
211 		}
212 
213 		public String getColumnName( int column )
214 		{
215 			switch( column )
216 			{
217 			case 0 :
218 				return " ";
219 			case 1 :
220 				return "Name";
221 			case 2 :
222 				return "Step";
223 			case 3 :
224 				return "Details";
225 			}
226 
227 			return null;
228 		}
229 
230 		public Object getValueAt( int rowIndex, int columnIndex )
231 		{
232 			LoadTestAssertion assertion = loadTest.getAssertionAt( rowIndex );
233 
234 			switch( columnIndex )
235 			{
236 			case 0 :
237 				return assertion.getIcon();
238 			case 1 :
239 				return assertion.getName();
240 			case 2 :
241 				return assertion.getTargetStep();
242 			case 3 :
243 				return assertion.getDescription();
244 			}
245 
246 			return null;
247 		}
248 
249 		public void assertionRemoved( LoadTestAssertion assertion )
250 		{
251 			assertion.removePropertyChangeListener( LoadTestAssertion.CONFIGURATION_PROPERTY, this );
252 			fireTableDataChanged();
253 		}
254 
255 		public void assertionAdded( LoadTestAssertion assertion )
256 		{
257 			assertion.addPropertyChangeListener( LoadTestAssertion.CONFIGURATION_PROPERTY, this );
258 			fireTableRowsInserted( getRowCount() - 1, getRowCount() - 1 );
259 		}
260 
261 		public void propertyChange( PropertyChangeEvent evt )
262 		{
263 			fireTableDataChanged();
264 		}
265 	}
266 
267 	private static final class IconTableCellRenderer extends DefaultTableCellRenderer
268 	{
269 		public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus,
270 				int row, int column )
271 		{
272 			if( value != null )
273 				setIcon( ( Icon )value );
274 
275 			if( isSelected )
276 			{
277 				setBackground( table.getSelectionBackground() );
278 				setForeground( table.getSelectionForeground() );
279 			}
280 			else
281 			{
282 				setBackground( table.getBackground() );
283 				setForeground( table.getForeground() );
284 			}
285 
286 			return this;
287 		}
288 	}
289 
290 	public class AddLoadTestAssertionAction extends AbstractAction
291 	{
292 		public AddLoadTestAssertionAction()
293 		{
294 			super( "Add Assertion" );
295 			putValue( Action.SHORT_DESCRIPTION, "Adds an assertion to this LoadTest" );
296 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/addAssertion.gif" ) );
297 		}
298 
299 		public void actionPerformed( ActionEvent e )
300 		{
301 			String[] types = LoadTestAssertionRegistry.getAvailableAssertions();
302 			String type = ( String )UISupport.prompt( "Select assertion type to add", "Add Assertion", types );
303 			if( type != null )
304 			{
305 				loadTest.addAssertion( type, LoadTestAssertion.ANY_TEST_STEP, true );
306 			}
307 		}
308 	}
309 
310 	public class ConfigureAssertionAction extends AbstractAction
311 	{
312 		ConfigureAssertionAction()
313 		{
314 			super( "Configure" );
315 			putValue( Action.SHORT_DESCRIPTION, "Configures the selection assertion" );
316 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/options.gif" ) );
317 			setEnabled( false );
318 		}
319 
320 		public void actionPerformed( ActionEvent e )
321 		{
322 			int ix = table.getSelectedRow();
323 			if( ix == -1 )
324 				return;
325 			ix = table.convertRowIndexToModel( ix );
326 
327 			Object obj = loadTest.getAssertionAt( ix );
328 			if( obj instanceof Configurable )
329 			{
330 				( ( Configurable )obj ).configure();
331 				tableModel.fireTableRowsUpdated( ix, ix );
332 			}
333 			else
334 				Toolkit.getDefaultToolkit().beep();
335 		}
336 	}
337 
338 	public class RemoveAssertionAction extends AbstractAction
339 	{
340 		public RemoveAssertionAction()
341 		{
342 			super( "Remove Assertion" );
343 			putValue( Action.SHORT_DESCRIPTION, "Removes the selected assertion from this LoadTest" );
344 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/remove_assertion.gif" ) );
345 			setEnabled( false );
346 		}
347 
348 		public void actionPerformed( ActionEvent e )
349 		{
350 			int ix = table.getSelectedRow();
351 			if( ix == -1 )
352 				return;
353 			ix = table.convertRowIndexToModel( ix );
354 
355 			LoadTestAssertion assertion = loadTest.getAssertionAt( ix );
356 			if( UISupport.confirm( "Remove assertion [" + assertion.getName() + "]", "Remove Assertion" ) )
357 			{
358 				loadTest.removeAssertion( assertion );
359 			}
360 		}
361 	}
362 
363 	public class InternalLoadTestListener implements LoadTestListener
364 	{
365 		public void assertionAdded( LoadTestAssertion assertion )
366 		{
367 			tableModel.assertionAdded( assertion );
368 			table.getSelectionModel().setSelectionInterval( tableModel.getRowCount() - 1, tableModel.getRowCount() - 1 );
369 		}
370 
371 		public void assertionRemoved( LoadTestAssertion assertion )
372 		{
373 			tableModel.assertionRemoved( assertion );
374 		}
375 	}
376 }