001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
013: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
014: * License for the specific language governing permissions and limitations
015: * under the License.
016: *
017: */
018:
019: package org.apache.jmeter.visualizers;
020:
021: import java.awt.BorderLayout;
022: import java.awt.Dimension;
023: import java.util.Collections;
024: import java.util.HashMap;
025: import java.util.Map;
026:
027: import javax.swing.BoxLayout;
028: import javax.swing.JPanel;
029: import javax.swing.JScrollPane;
030: import javax.swing.JTable;
031: import javax.swing.border.Border;
032: import javax.swing.border.EmptyBorder;
033: import javax.swing.table.TableCellRenderer;
034:
035: import org.apache.jmeter.samplers.Clearable;
036: import org.apache.jmeter.samplers.SampleResult;
037: import org.apache.jmeter.util.Calculator;
038: import org.apache.jmeter.util.JMeterUtils;
039: import org.apache.jmeter.visualizers.gui.AbstractVisualizer;
040: import org.apache.jorphan.gui.NumberRenderer;
041: import org.apache.jorphan.gui.ObjectTableModel;
042: import org.apache.jorphan.gui.RateRenderer;
043: import org.apache.jorphan.gui.RendererUtils;
044: import org.apache.jorphan.reflect.Functor;
045:
046: /**
047: * Simpler (lower memory) version of Aggregate Report (StatVisualizer).
048: * Excludes the Median and 90% columns, which are expensive in memory terms
049: */
050: public class SummaryReport extends AbstractVisualizer implements
051: Clearable {
052: private final String[] COLUMNS = {
053: JMeterUtils.getResString("sampler_label"), //$NON-NLS-1$
054: JMeterUtils.getResString("aggregate_report_count"), //$NON-NLS-1$
055: JMeterUtils.getResString("average"), //$NON-NLS-1$
056: JMeterUtils.getResString("aggregate_report_min"), //$NON-NLS-1$
057: JMeterUtils.getResString("aggregate_report_max"), //$NON-NLS-1$
058: JMeterUtils.getResString("aggregate_report_stddev"), //$NON-NLS-1$
059: JMeterUtils.getResString("aggregate_report_error%"), //$NON-NLS-1$
060: JMeterUtils.getResString("aggregate_report_rate"), //$NON-NLS-1$
061: JMeterUtils.getResString("aggregate_report_bandwidth"), //$NON-NLS-1$
062: JMeterUtils.getResString("average_bytes"), //$NON-NLS-1$
063: };
064:
065: private final String TOTAL_ROW_LABEL = JMeterUtils
066: .getResString("aggregate_report_total_label"); //$NON-NLS-1$
067:
068: protected JTable myJTable;
069:
070: protected JScrollPane myScrollPane;
071:
072: transient private ObjectTableModel model;
073:
074: Map tableRows = Collections.synchronizedMap(new HashMap());
075:
076: // Column renderers
077: private static final TableCellRenderer[] RENDERERS = new TableCellRenderer[] {
078: null, // Label
079: null, // count
080: null, // Mean
081: null, // Min
082: null, // Max
083: new NumberRenderer("#0.00"), // Std Dev.
084: new NumberRenderer("#0.00%"), // Error %age
085: new RateRenderer("#.0"), // Throughpur
086: new NumberRenderer("#0.00"), // kB/sec
087: new NumberRenderer("#.0"), // avg. pageSize
088: };
089:
090: public SummaryReport() {
091: super ();
092: model = new ObjectTableModel(COLUMNS, Calculator.class,// All rows have this class
093: new Functor[] { new Functor("getLabel"), //$NON-NLS-1$
094: new Functor("getCount"), //$NON-NLS-1$
095: new Functor("getMeanAsNumber"), //$NON-NLS-1$
096: new Functor("getMin"), //$NON-NLS-1$
097: new Functor("getMax"), //$NON-NLS-1$
098: new Functor("getStandardDeviation"), //$NON-NLS-1$
099: new Functor("getErrorPercentage"), //$NON-NLS-1$
100: new Functor("getRate"), //$NON-NLS-1$
101: new Functor("getKBPerSecond"), //$NON-NLS-1$
102: new Functor("getAvgPageBytes"), //$NON-NLS-1$
103: }, new Functor[] { null, null, null, null, null, null,
104: null, null, null, null }, new Class[] {
105: String.class, Long.class, Long.class,
106: Long.class, Long.class, String.class,
107: String.class, String.class, String.class,
108: String.class });
109: clearData();
110: init();
111: }
112:
113: public static boolean testFunctors() {
114: SummaryReport instance = new SummaryReport();
115: return instance.model.checkFunctors(null, instance.getClass());
116: }
117:
118: public String getLabelResource() {
119: return "summary_report"; //$NON-NLS-1$
120: }
121:
122: public void add(SampleResult res) {
123: Calculator row = null;
124: synchronized (tableRows) {
125: row = (Calculator) tableRows.get(res.getSampleLabel());
126: if (row == null) {
127: row = new Calculator(res.getSampleLabel());
128: tableRows.put(row.getLabel(), row);
129: model.insertRow(row, model.getRowCount() - 1);
130: }
131: }
132: row.addSample(res);
133: Calculator tot = ((Calculator) tableRows.get(TOTAL_ROW_LABEL));
134: tot.addSample(res);
135: model.fireTableDataChanged();
136: }
137:
138: /**
139: * Clears this visualizer and its model, and forces a repaint of the table.
140: */
141: public void clearData() {
142: model.clearData();
143: tableRows.clear();
144: tableRows.put(TOTAL_ROW_LABEL, new Calculator(TOTAL_ROW_LABEL));
145: model.addRow(tableRows.get(TOTAL_ROW_LABEL));
146: }
147:
148: /**
149: * Main visualizer setup.
150: */
151: private void init() {
152: this .setLayout(new BorderLayout());
153:
154: // MAIN PANEL
155: JPanel mainPanel = new JPanel();
156: Border margin = new EmptyBorder(10, 10, 5, 10);
157:
158: mainPanel.setBorder(margin);
159: mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
160:
161: mainPanel.add(makeTitlePanel());
162:
163: myJTable = new JTable(model);
164: myJTable.setPreferredScrollableViewportSize(new Dimension(500,
165: 70));
166: RendererUtils.applyRenderers(myJTable, RENDERERS);
167: myScrollPane = new JScrollPane(myJTable);
168: this.add(mainPanel, BorderLayout.NORTH);
169: this.add(myScrollPane, BorderLayout.CENTER);
170: }
171: }
|