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[] {
116 typeFilter,
117 stepFilter
118 };
119
120 FilterPipeline pipeline = new FilterPipeline(filters);
121 logTable.setFilters( pipeline );
122
123 JScrollPane scrollPane = new JScrollPane(logTable);
124 add( scrollPane, BorderLayout.CENTER );
125 add( buildToolbar(), BorderLayout.NORTH );
126 add( buildStatus(), BorderLayout.SOUTH );
127
128 logTableModelListener = new LogTableModelListener();
129 logTable.getModel().addTableModelListener( logTableModelListener );
130
131 logTable.setSortOrder( 1, SortOrder.ASCENDING );
132 }
133
134 public void addNotify()
135 {
136 super.addNotify();
137 if( logTableModelListener != null )
138 logTableModel.addTableModelListener( logTableModelListener );
139
140 loadTestLog.addListDataListener( logTableModel );
141 }
142
143 public void removeNotify()
144 {
145 super.removeNotify();
146 logTableModel.removeTableModelListener( logTableModelListener );
147 loadTestLog.removeListDataListener( logTableModel );
148 }
149
150 private JComponent buildStatus()
151 {
152 ButtonBarBuilder builder = new ButtonBarBuilder();
153 rowCountLabel = new JLabel( "0 entries" );
154 builder.addFixed( rowCountLabel );
155 builder.addGlue();
156 builder.setBorder( BorderFactory.createEmptyBorder( 3, 3, 3, 3 ));
157 return builder.getPanel();
158 }
159
160 protected void updateRowCountLabel()
161 {
162 int c = logTableModel.getRowCount();
163 rowCountLabel.setText( c == 1 ? "1 entry" : c + " entries" );
164 }
165
166 private JComponent buildToolbar()
167 {
168 JXToolBar toolbar = UISupport.createToolbar();
169
170 clearErrorsButton = UISupport.createToolbarButton( new ClearErrorsAction() );
171 exportButton = UISupport.createToolbarButton( new ExportLoadTestLogAction( loadTestLog, logTable ) );
172
173 toolbar.add( clearErrorsButton );
174 toolbar.add( exportButton );
175 toolbar.addGlue();
176
177 List<Object> steps = new ArrayList<Object>();
178 steps.add( "- All -" );
179 steps.add( "Message" );
180 for( LoadTestAssertion assertion : loadTestLog.getLoadTest().getAssertionList() )
181 {
182 steps.add( assertion.getName() );
183 }
184
185 toolbar.add( new JLabel( "Show Types:"));
186 toolbar.addSeparator();
187 typesFilterComboBox = new JComboBox( steps.toArray() );
188 typesFilterComboBox.addItemListener( new ItemListener() {
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 toolbar.add( typesFilterComboBox );
207 toolbar.addSeparator();
208
209 List<Object> types = new ArrayList<Object>();
210 types.add( "- All -" );
211 for( TestStep testStep : loadTestLog.getLoadTest().getTestCase().getTestStepList() )
212 {
213 types.add( testStep.getName() );
214 }
215
216 toolbar.addFixed( new JLabel( "Show Steps:"));
217 toolbar.addSeparator();
218 stepsFilterComboBox = new JComboBox( types.toArray() );
219 stepsFilterComboBox.addItemListener( new ItemListener() {
220
221 public void itemStateChanged(ItemEvent e)
222 {
223 int ix = stepsFilterComboBox.getSelectedIndex();
224 if( ix == -1 )
225 return;
226
227 stepFilter.setAcceptNull( ix == 0 );
228
229 if( ix == 0 )
230 stepFilter.setPattern( ".*", 0 );
231 else
232 stepFilter.setPattern( stepsFilterComboBox.getSelectedItem().toString(), 0 );
233
234 updateRowCountLabel();
235 }} );
236
237 toolbar.addFixed( stepsFilterComboBox );
238
239
240 return toolbar;
241 }
242
243 private final class LogTableModelListener implements TableModelListener
244 {
245 public void tableChanged(TableModelEvent e)
246 {
247 updateRowCountLabel();
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
286 private class LoadTestLogTableModel extends AbstractTableModel implements ListDataListener
287 {
288 public LoadTestLogTableModel()
289 {
290 }
291
292 public int getRowCount()
293 {
294 return loadTestLog.getSize();
295 }
296
297 public int getColumnCount()
298 {
299 return 5;
300 }
301
302 public Class<?> getColumnClass(int columnIndex)
303 {
304 switch( columnIndex )
305 {
306 case 0 : return ImageIcon.class;
307 case 1 : return Date.class;
308 default : return String.class;
309 }
310 }
311
312 public String getColumnName(int column)
313 {
314 switch( column )
315 {
316 case 0 : return " ";
317 case 1 : return "time";
318 case 2 : return "type";
319 case 3 : return "step";
320 case 4 : return "message";
321 }
322
323 return null;
324 }
325
326 public Object getValueAt(int rowIndex, int columnIndex)
327 {
328 if( rowIndex == -1 )
329 return null;
330
331 LoadTestLogEntry entry = (LoadTestLogEntry) loadTestLog.getElementAt( rowIndex );
332
333 switch( columnIndex )
334 {
335 case 0 : return entry.getIcon();
336 case 1 : return entry.getTimeStamp();
337 case 2 : return entry.getType();
338 case 3 : return entry.getTargetStepName();
339 case 4 : return entry.getMessage();
340 }
341
342 return null;
343 }
344
345 public void intervalAdded(ListDataEvent e)
346 {
347 fireTableRowsInserted( e.getIndex0(), e.getIndex1() );
348 }
349
350 public void intervalRemoved(ListDataEvent e)
351 {
352 fireTableRowsDeleted( e.getIndex0(), e.getIndex1() );
353 }
354
355 public void contentsChanged(ListDataEvent e)
356 {
357 fireTableDataChanged();
358 }}
359
360 private static final class IconTableCellRenderer extends DefaultTableCellRenderer
361 {
362 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
363 {
364 if( value != null )
365 setIcon( (Icon) value );
366
367 if (isSelected)
368 {
369 setBackground(table.getSelectionBackground());
370 setForeground(table.getSelectionForeground());
371 }
372 else
373 {
374 setBackground(table.getBackground());
375 setForeground(table.getForeground());
376 }
377
378 return this;
379 }
380 }
381
382 private static final class TimestampTableCellRenderer extends DefaultTableCellRenderer
383 {
384 private SimpleDateFormat sdf;
385
386 private TimestampTableCellRenderer()
387 {
388 sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
389 }
390
391 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
392 {
393 if( value != null )
394 setText( sdf.format( new Date( (Long)value )));
395
396 if (isSelected)
397 {
398 setBackground(table.getSelectionBackground());
399 setForeground(table.getSelectionForeground());
400 }
401 else
402 {
403 setBackground(table.getBackground());
404 setForeground(table.getForeground());
405 }
406
407 return this;
408 }
409 }
410
411 public class ClearErrorsAction extends AbstractAction
412 {
413 public ClearErrorsAction()
414 {
415 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/clear_errors.gif"));
416 putValue( Action.SHORT_DESCRIPTION, "Removes all errors from the LoadTest log" );
417 }
418
419 public void actionPerformed(ActionEvent e)
420 {
421 loadTestLog.clearErrors();
422 }
423 }
424
425 private final class LoadTestLogTableMouseListener extends MouseAdapter
426 {
427 public void mouseClicked(MouseEvent e)
428 {
429 if( e.getClickCount() > 1 )
430 {
431 int selectedRow = logTable.getSelectedRow();
432 if( selectedRow < 0 )
433 return;
434
435 int row = logTable.convertRowIndexToModel( selectedRow );
436 if( row < 0 )
437 return;
438
439 LoadTestLogEntry entry = (LoadTestLogEntry) loadTestLog.getElementAt( row );
440 ActionList actions = entry.getActions();
441 if( actions != null )
442 actions.performDefaultAction( new ActionEvent( logTable, 0, null ));
443 }
444 }
445
446 public void mousePressed(MouseEvent e)
447 {
448 if( e.isPopupTrigger() )
449 {
450 showPopup( e );
451 }
452 }
453
454 public void mouseReleased(MouseEvent e)
455 {
456 if( e.isPopupTrigger() )
457 {
458 showPopup( e );
459 }
460 }
461 }
462
463 public void showPopup(MouseEvent e)
464 {
465 int selectedRow = logTable.rowAtPoint( e.getPoint() );
466 if( selectedRow == -1 )
467 return;
468
469 if( logTable.getSelectedRow() != selectedRow )
470 {
471 logTable.getSelectionModel().setSelectionInterval( selectedRow, selectedRow );
472 }
473
474 int row = logTable.convertRowIndexToModel( selectedRow );
475 if( row < 0 )
476 return;
477
478 LoadTestLogEntry entry = (LoadTestLogEntry) loadTestLog.getElementAt( row );
479 ActionList actions = entry.getActions();
480
481 if( actions == null || actions.getActionCount() == 0 )
482 return;
483
484 JPopupMenu popup = ActionSupport.buildPopup( actions );
485 popup.setInvoker( logTable );
486
487 popup.setLocation( (int)(logTable.getLocationOnScreen().getX() + e.getPoint().getX()),
488 (int)(logTable.getLocationOnScreen().getY() + e.getPoint().getY()));
489 popup.setVisible( true );
490 }
491 }