1
2
3
4
5
6
7
8
9
10
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.event.ActionEvent;
18 import java.awt.event.ItemEvent;
19 import java.awt.event.ItemListener;
20 import java.awt.event.MouseAdapter;
21 import java.awt.event.MouseEvent;
22 import java.text.SimpleDateFormat;
23 import java.util.ArrayList;
24 import java.util.Date;
25 import java.util.List;
26
27 import javax.swing.AbstractAction;
28 import javax.swing.Action;
29 import javax.swing.BorderFactory;
30 import javax.swing.Icon;
31 import javax.swing.ImageIcon;
32 import javax.swing.JButton;
33 import javax.swing.JComboBox;
34 import javax.swing.JComponent;
35 import javax.swing.JLabel;
36 import javax.swing.JPanel;
37 import javax.swing.JPopupMenu;
38 import javax.swing.JScrollPane;
39 import javax.swing.JTable;
40 import javax.swing.event.ListDataEvent;
41 import javax.swing.event.ListDataListener;
42 import javax.swing.event.TableModelEvent;
43 import javax.swing.event.TableModelListener;
44 import javax.swing.table.AbstractTableModel;
45 import javax.swing.table.DefaultTableCellRenderer;
46 import javax.swing.table.TableColumnModel;
47
48 import org.jdesktop.swingx.JXTable;
49 import org.jdesktop.swingx.decorator.Filter;
50 import org.jdesktop.swingx.decorator.FilterPipeline;
51 import org.jdesktop.swingx.decorator.PatternFilter;
52 import org.jdesktop.swingx.decorator.SortOrder;
53
54 import com.eviware.soapui.impl.wsdl.loadtest.LoadTestAssertion;
55 import com.eviware.soapui.impl.wsdl.loadtest.data.actions.ExportLoadTestLogAction;
56 import com.eviware.soapui.impl.wsdl.loadtest.log.LoadTestLog;
57 import com.eviware.soapui.impl.wsdl.loadtest.log.LoadTestLogEntry;
58 import com.eviware.soapui.model.testsuite.TestStep;
59 import com.eviware.soapui.support.UISupport;
60 import com.eviware.soapui.support.action.swing.ActionList;
61 import com.eviware.soapui.support.action.swing.ActionSupport;
62 import com.eviware.soapui.support.components.JXToolBar;
63 import com.jgoodies.forms.builder.ButtonBarBuilder;
64
65 /***
66 * Compound component for showing a LoadTestLog
67 *
68 * @author Ole.Matzura
69 */
70
71 public class JLoadTestLogTable extends JPanel
72 {
73 private final LoadTestLog loadTestLog;
74 private JXTable logTable;
75 private PatternFilter stepFilter;
76 private PatternFilter typeFilter;
77 private JComboBox typesFilterComboBox;
78 private JComboBox stepsFilterComboBox;
79 private JButton clearErrorsButton;
80 private JLabel rowCountLabel;
81 @SuppressWarnings( "unused" )
82 private JPopupMenu popup;
83 private LoadTestLogTableModel logTableModel;
84 private JButton exportButton;
85 private LogTableModelListener logTableModelListener;
86
87 public JLoadTestLogTable( LoadTestLog log )
88 {
89 super( new BorderLayout() );
90
91 loadTestLog = log;
92
93 logTableModel = new LoadTestLogTableModel();
94 logTable = new JXTable( logTableModel );
95 logTable.setHorizontalScrollEnabled( true );
96 logTable.setColumnControlVisible( true );
97 logTable.addMouseListener( new LoadTestLogTableMouseListener() );
98
99 TableColumnModel columnModel = logTable.getColumnModel();
100 columnModel.getColumn( 0 ).setMaxWidth( 5 );
101 columnModel.getColumn( 0 ).setCellRenderer( new IconTableCellRenderer() );
102
103 columnModel.getColumn( 1 ).setPreferredWidth( 120 );
104 columnModel.getColumn( 1 ).setCellRenderer( new TimestampTableCellRenderer() );
105
106 columnModel.getColumn( 2 ).setPreferredWidth( 110 );
107 columnModel.getColumn( 3 ).setPreferredWidth( 110 );
108 columnModel.getColumn( 4 ).setPreferredWidth( 250 );
109
110 typeFilter = new PatternFilter( ".*", 0, 2 );
111 typeFilter.setAcceptNull( true );
112 stepFilter = new PatternFilter( ".*", 0, 3 );
113 stepFilter.setAcceptNull( true );
114
115 Filter[] filters = new Filter[] { typeFilter,
116 stepFilter
117 };
118
119 FilterPipeline pipeline = new FilterPipeline( filters );
120 logTable.setFilters( pipeline );
121
122 JScrollPane scrollPane = new JScrollPane( logTable );
123 add( scrollPane, BorderLayout.CENTER );
124 add( buildToolbar(), BorderLayout.NORTH );
125 add( buildStatus(), BorderLayout.SOUTH );
126
127 logTableModelListener = new LogTableModelListener();
128 logTable.getModel().addTableModelListener( logTableModelListener );
129
130 logTable.setSortOrder( 1, SortOrder.ASCENDING );
131 }
132
133 public void addNotify()
134 {
135 super.addNotify();
136 if( logTableModelListener != null )
137 logTableModel.addTableModelListener( logTableModelListener );
138
139 loadTestLog.addListDataListener( logTableModel );
140 }
141
142 public void removeNotify()
143 {
144 super.removeNotify();
145 logTableModel.removeTableModelListener( logTableModelListener );
146 loadTestLog.removeListDataListener( logTableModel );
147 }
148
149 private JComponent buildStatus()
150 {
151 ButtonBarBuilder builder = new ButtonBarBuilder();
152 rowCountLabel = new JLabel( "0 entries" );
153 builder.addFixed( rowCountLabel );
154 builder.addGlue();
155 builder.setBorder( BorderFactory.createEmptyBorder( 3, 3, 3, 3 ) );
156 return builder.getPanel();
157 }
158
159 protected void updateRowCountLabel()
160 {
161 int c = logTableModel.getRowCount();
162 rowCountLabel.setText( c == 1 ? "1 entry" : c + " entries" );
163 }
164
165 private JComponent buildToolbar()
166 {
167 JXToolBar toolbar = UISupport.createToolbar();
168
169 clearErrorsButton = UISupport.createToolbarButton( new ClearErrorsAction() );
170 exportButton = UISupport.createToolbarButton( new ExportLoadTestLogAction( loadTestLog, logTable ) );
171
172 toolbar.add( clearErrorsButton );
173 toolbar.add( exportButton );
174 toolbar.addGlue();
175
176 List<Object> steps = new ArrayList<Object>();
177 steps.add( "- All -" );
178 steps.add( "Message" );
179 for( LoadTestAssertion assertion : loadTestLog.getLoadTest().getAssertionList() )
180 {
181 steps.add( assertion.getName() );
182 }
183
184 toolbar.add( new JLabel( "Show Types:" ) );
185 toolbar.addSeparator();
186 typesFilterComboBox = new JComboBox( steps.toArray() );
187 typesFilterComboBox.addItemListener( new ItemListener()
188 {
189
190 public void itemStateChanged( ItemEvent e )
191 {
192 int ix = typesFilterComboBox.getSelectedIndex();
193 if( ix == -1 )
194 return;
195
196 typeFilter.setAcceptNull( ix == 0 );
197
198 if( ix == 0 )
199 typeFilter.setPattern( ".*", 0 );
200 else
201 typeFilter.setPattern( typesFilterComboBox.getSelectedItem().toString(), 0 );
202
203 updateRowCountLabel();
204 }
205 } );
206
207 toolbar.add( typesFilterComboBox );
208 toolbar.addSeparator();
209
210 List<Object> types = new ArrayList<Object>();
211 types.add( "- All -" );
212 for( TestStep testStep : loadTestLog.getLoadTest().getTestCase().getTestStepList() )
213 {
214 types.add( testStep.getName() );
215 }
216
217 toolbar.addFixed( new JLabel( "Show Steps:" ) );
218 toolbar.addSeparator();
219 stepsFilterComboBox = new JComboBox( types.toArray() );
220 stepsFilterComboBox.addItemListener( new ItemListener()
221 {
222
223 public void itemStateChanged( ItemEvent e )
224 {
225 int ix = stepsFilterComboBox.getSelectedIndex();
226 if( ix == -1 )
227 return;
228
229 stepFilter.setAcceptNull( ix == 0 );
230
231 if( ix == 0 )
232 stepFilter.setPattern( ".*", 0 );
233 else
234 stepFilter.setPattern( stepsFilterComboBox.getSelectedItem().toString(), 0 );
235
236 updateRowCountLabel();
237 }
238 } );
239
240 toolbar.addFixed( stepsFilterComboBox );
241
242
243 return toolbar;
244 }
245
246 private final class LogTableModelListener implements TableModelListener
247 {
248 public void tableChanged( TableModelEvent e )
249 {
250 updateRowCountLabel();
251 }
252 }
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275 private class LoadTestLogTableModel extends AbstractTableModel implements ListDataListener
276 {
277 public LoadTestLogTableModel()
278 {
279 }
280
281 public int getRowCount()
282 {
283 return loadTestLog.getSize();
284 }
285
286 public int getColumnCount()
287 {
288 return 5;
289 }
290
291 public Class<?> getColumnClass( int columnIndex )
292 {
293 switch( columnIndex )
294 {
295 case 0 :
296 return ImageIcon.class;
297 case 1 :
298 return Date.class;
299 default :
300 return String.class;
301 }
302 }
303
304 public String getColumnName( int column )
305 {
306 switch( column )
307 {
308 case 0 :
309 return " ";
310 case 1 :
311 return "time";
312 case 2 :
313 return "type";
314 case 3 :
315 return "step";
316 case 4 :
317 return "message";
318 }
319
320 return null;
321 }
322
323 public Object getValueAt( int rowIndex, int columnIndex )
324 {
325 if( rowIndex == -1 )
326 return null;
327
328 LoadTestLogEntry entry = ( LoadTestLogEntry )loadTestLog.getElementAt( rowIndex );
329
330 switch( columnIndex )
331 {
332 case 0 :
333 return entry.getIcon();
334 case 1 :
335 return entry.getTimeStamp();
336 case 2 :
337 return entry.getType();
338 case 3 :
339 return entry.getTargetStepName();
340 case 4 :
341 return entry.getMessage();
342 }
343
344 return null;
345 }
346
347 public void intervalAdded( ListDataEvent e )
348 {
349 fireTableRowsInserted( e.getIndex0(), e.getIndex1() );
350 }
351
352 public void intervalRemoved( ListDataEvent e )
353 {
354 fireTableRowsDeleted( e.getIndex0(), e.getIndex1() );
355 }
356
357 public void contentsChanged( ListDataEvent e )
358 {
359 fireTableDataChanged();
360 }
361 }
362
363 private static final class IconTableCellRenderer extends DefaultTableCellRenderer
364 {
365 public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus,
366 int row, int column )
367 {
368 if( value != null )
369 setIcon( ( Icon )value );
370
371 if( isSelected )
372 {
373 setBackground( table.getSelectionBackground() );
374 setForeground( table.getSelectionForeground() );
375 }
376 else
377 {
378 setBackground( table.getBackground() );
379 setForeground( table.getForeground() );
380 }
381
382 return this;
383 }
384 }
385
386 private static final class TimestampTableCellRenderer extends DefaultTableCellRenderer
387 {
388 private SimpleDateFormat sdf;
389
390 private TimestampTableCellRenderer()
391 {
392 sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss:SSS" );
393 }
394
395 public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus,
396 int row, int column )
397 {
398 if( value != null )
399 setText( sdf.format( new Date( ( Long )value ) ) );
400
401 if( isSelected )
402 {
403 setBackground( table.getSelectionBackground() );
404 setForeground( table.getSelectionForeground() );
405 }
406 else
407 {
408 setBackground( table.getBackground() );
409 setForeground( table.getForeground() );
410 }
411
412 return this;
413 }
414 }
415
416 public class ClearErrorsAction extends AbstractAction
417 {
418 public ClearErrorsAction()
419 {
420 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/clear_errors.gif" ) );
421 putValue( Action.SHORT_DESCRIPTION, "Removes all errors from the LoadTest log" );
422 }
423
424 public void actionPerformed( ActionEvent e )
425 {
426 loadTestLog.clearErrors();
427 }
428 }
429
430 private final class LoadTestLogTableMouseListener extends MouseAdapter
431 {
432 public void mouseClicked( MouseEvent e )
433 {
434 if( e.getClickCount() > 1 )
435 {
436 int selectedRow = logTable.getSelectedRow();
437 if( selectedRow < 0 )
438 return;
439
440 int row = logTable.convertRowIndexToModel( selectedRow );
441 if( row < 0 )
442 return;
443
444 LoadTestLogEntry entry = ( LoadTestLogEntry )loadTestLog.getElementAt( row );
445 ActionList actions = entry.getActions();
446 if( actions != null )
447 actions.performDefaultAction( new ActionEvent( logTable, 0, null ) );
448 }
449 }
450
451 public void mousePressed( MouseEvent e )
452 {
453 if( e.isPopupTrigger() )
454 {
455 showPopup( e );
456 }
457 }
458
459 public void mouseReleased( MouseEvent e )
460 {
461 if( e.isPopupTrigger() )
462 {
463 showPopup( e );
464 }
465 }
466 }
467
468 public void showPopup( MouseEvent e )
469 {
470 int selectedRow = logTable.rowAtPoint( e.getPoint() );
471 if( selectedRow == -1 )
472 return;
473
474 if( logTable.getSelectedRow() != selectedRow )
475 {
476 logTable.getSelectionModel().setSelectionInterval( selectedRow, selectedRow );
477 }
478
479 int row = logTable.convertRowIndexToModel( selectedRow );
480 if( row < 0 )
481 return;
482
483 LoadTestLogEntry entry = ( LoadTestLogEntry )loadTestLog.getElementAt( row );
484 ActionList actions = entry.getActions();
485
486 if( actions == null || actions.getActionCount() == 0 )
487 return;
488
489 JPopupMenu popup = ActionSupport.buildPopup( actions );
490 popup.setInvoker( logTable );
491
492 popup.setLocation( ( int )( logTable.getLocationOnScreen().getX() + e.getPoint().getX() ), ( int )( logTable
493 .getLocationOnScreen().getY() + e.getPoint().getY() ) );
494 popup.setVisible( true );
495 }
496 }