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.addMouseListener( new LoadTestLogTableMouseListener() );
97
98 TableColumnModel columnModel = logTable.getColumnModel();
99 columnModel.getColumn( 0 ).setMaxWidth( 5 );
100 columnModel.getColumn( 0 ).setCellRenderer( new IconTableCellRenderer() );
101
102 columnModel.getColumn( 1 ).setPreferredWidth( 120 );
103 columnModel.getColumn( 1 ).setCellRenderer( new TimestampTableCellRenderer() );
104
105 columnModel.getColumn( 2 ).setPreferredWidth( 110 );
106 columnModel.getColumn( 3 ).setPreferredWidth( 110 );
107 columnModel.getColumn( 4 ).setPreferredWidth( 250 );
108
109 typeFilter = new PatternFilter(".*", 0, 2);
110 typeFilter.setAcceptNull( true );
111 stepFilter = new PatternFilter(".*", 0, 3);
112 stepFilter.setAcceptNull( true );
113
114 Filter[] filters = new Filter[] {
115 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 public void itemStateChanged(ItemEvent e)
190 {
191 int ix = typesFilterComboBox.getSelectedIndex();
192 if( ix == -1 )
193 return;
194
195 typeFilter.setAcceptNull( ix == 0 );
196
197 if( ix == 0 )
198 typeFilter.setPattern( ".*", 0 );
199 else
200 typeFilter.setPattern( typesFilterComboBox.getSelectedItem().toString(), 0 );
201
202 updateRowCountLabel();
203 }} );
204
205 toolbar.add( typesFilterComboBox );
206 toolbar.addSeparator();
207
208 List<Object> types = new ArrayList<Object>();
209 types.add( "- All -" );
210 for( TestStep testStep : loadTestLog.getLoadTest().getTestCase().getTestStepList() )
211 {
212 types.add( testStep.getName() );
213 }
214
215 toolbar.addFixed( new JLabel( "Show Steps:"));
216 toolbar.addSeparator();
217 stepsFilterComboBox = new JComboBox( types.toArray() );
218 stepsFilterComboBox.addItemListener( new ItemListener() {
219
220 public void itemStateChanged(ItemEvent e)
221 {
222 int ix = stepsFilterComboBox.getSelectedIndex();
223 if( ix == -1 )
224 return;
225
226 stepFilter.setAcceptNull( ix == 0 );
227
228 if( ix == 0 )
229 stepFilter.setPattern( ".*", 0 );
230 else
231 stepFilter.setPattern( stepsFilterComboBox.getSelectedItem().toString(), 0 );
232
233 updateRowCountLabel();
234 }} );
235
236 toolbar.addFixed( stepsFilterComboBox );
237
238
239 return toolbar;
240 }
241
242 private final class LogTableModelListener implements TableModelListener
243 {
244 public void tableChanged(TableModelEvent e)
245 {
246 updateRowCountLabel();
247 }
248 }
249
250
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
276
277
278
279
280
281
282
283
284
285 private class LoadTestLogTableModel extends AbstractTableModel implements ListDataListener
286 {
287 public LoadTestLogTableModel()
288 {
289 }
290
291 public int getRowCount()
292 {
293 return loadTestLog.getSize();
294 }
295
296 public int getColumnCount()
297 {
298 return 5;
299 }
300
301 public Class<?> getColumnClass(int columnIndex)
302 {
303 switch( columnIndex )
304 {
305 case 0 : return ImageIcon.class;
306 case 1 : return Date.class;
307 default : return String.class;
308 }
309 }
310
311 public String getColumnName(int column)
312 {
313 switch( column )
314 {
315 case 0 : return " ";
316 case 1 : return "time";
317 case 2 : return "type";
318 case 3 : return "step";
319 case 4 : return "message";
320 }
321
322 return null;
323 }
324
325 public Object getValueAt(int rowIndex, int columnIndex)
326 {
327 if( rowIndex == -1 )
328 return null;
329
330 LoadTestLogEntry entry = (LoadTestLogEntry) loadTestLog.getElementAt( rowIndex );
331
332 switch( columnIndex )
333 {
334 case 0 : return entry.getIcon();
335 case 1 : return entry.getTimeStamp();
336 case 2 : return entry.getType();
337 case 3 : return entry.getTargetStepName();
338 case 4 : return entry.getMessage();
339 }
340
341 return null;
342 }
343
344 public void intervalAdded(ListDataEvent e)
345 {
346 fireTableRowsInserted( e.getIndex0(), e.getIndex1() );
347 }
348
349 public void intervalRemoved(ListDataEvent e)
350 {
351 fireTableRowsDeleted( e.getIndex0(), e.getIndex1() );
352 }
353
354 public void contentsChanged(ListDataEvent e)
355 {
356 fireTableDataChanged();
357 }}
358
359 private static final class IconTableCellRenderer extends DefaultTableCellRenderer
360 {
361 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
362 {
363 if( value != null )
364 setIcon( (Icon) value );
365
366 if (isSelected)
367 {
368 setBackground(table.getSelectionBackground());
369 setForeground(table.getSelectionForeground());
370 }
371 else
372 {
373 setBackground(table.getBackground());
374 setForeground(table.getForeground());
375 }
376
377 return this;
378 }
379 }
380
381 private static final class TimestampTableCellRenderer extends DefaultTableCellRenderer
382 {
383 private SimpleDateFormat sdf;
384
385 private TimestampTableCellRenderer()
386 {
387 sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
388 }
389
390 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
391 {
392 if( value != null )
393 setText( sdf.format( new Date( (Long)value )));
394
395 if (isSelected)
396 {
397 setBackground(table.getSelectionBackground());
398 setForeground(table.getSelectionForeground());
399 }
400 else
401 {
402 setBackground(table.getBackground());
403 setForeground(table.getForeground());
404 }
405
406 return this;
407 }
408 }
409
410 public class ClearErrorsAction extends AbstractAction
411 {
412 public ClearErrorsAction()
413 {
414 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/clear_errors.gif"));
415 putValue( Action.SHORT_DESCRIPTION, "Removes all errors from the LoadTest log" );
416 }
417
418 public void actionPerformed(ActionEvent e)
419 {
420 loadTestLog.clearErrors();
421 }
422 }
423
424 private final class LoadTestLogTableMouseListener extends MouseAdapter
425 {
426 public void mouseClicked(MouseEvent e)
427 {
428 if( e.getClickCount() > 1 )
429 {
430 int selectedRow = logTable.getSelectedRow();
431 if( selectedRow < 0 )
432 return;
433
434 int row = logTable.convertRowIndexToModel( selectedRow );
435 if( row < 0 )
436 return;
437
438 LoadTestLogEntry entry = (LoadTestLogEntry) loadTestLog.getElementAt( row );
439 ActionList actions = entry.getActions();
440 if( actions != null )
441 actions.performDefaultAction( new ActionEvent( logTable, 0, null ));
442 }
443 }
444
445 public void mousePressed(MouseEvent e)
446 {
447 if( e.isPopupTrigger() )
448 {
449 showPopup( e );
450 }
451 }
452
453 public void mouseReleased(MouseEvent e)
454 {
455 if( e.isPopupTrigger() )
456 {
457 showPopup( e );
458 }
459 }
460 }
461
462 public void showPopup(MouseEvent e)
463 {
464 int selectedRow = logTable.rowAtPoint( e.getPoint() );
465 if( selectedRow == -1 )
466 return;
467
468 if( logTable.getSelectedRow() != selectedRow )
469 {
470 logTable.getSelectionModel().setSelectionInterval( selectedRow, selectedRow );
471 }
472
473 int row = logTable.convertRowIndexToModel( selectedRow );
474 if( row < 0 )
475 return;
476
477 LoadTestLogEntry entry = (LoadTestLogEntry) loadTestLog.getElementAt( row );
478 ActionList actions = entry.getActions();
479
480 if( actions == null || actions.getActionCount() == 0 )
481 return;
482
483 JPopupMenu popup = ActionSupport.buildPopup( actions );
484 popup.setInvoker( logTable );
485
486 popup.setLocation( (int)(logTable.getLocationOnScreen().getX() + e.getPoint().getX()),
487 (int)(logTable.getLocationOnScreen().getY() + e.getPoint().getY()));
488 popup.setVisible( true );
489 }
490 }