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