jboutcher    02/03/15 05:11:28

  Added:       src/org/apache/jmeter/visualizers RunningSample.java
                        StatVisualizer.java StatVisualizerModel.java
  Log:
  initial checkin - bugzilla 5127
  
  Revision  Changes    Path
  1.1                  
jakarta-jmeter/src/org/apache/jmeter/visualizers/RunningSample.java
  
  Index: RunningSample.java
  ===================================================================
  /*
   * ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   * if any, must include the following acknowledgment:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowledgment may appear in the software itself,
   * if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   * "Apache JMeter" must not be used to endorse or promote products
   * derived from this software without prior written permission. For
   * written permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   * "Apache JMeter", nor may "Apache" appear in their name, without
   * prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.jmeter.visualizers;
  
  // java
  import java.text.DecimalFormat;
  
  
  /**
   * Title:        RunningSample.java
   * Description:  Aggegate sample data container
   *
   * Class which is used to store aggregate sample data.
   * Just instantiate a new instance of this class, and then call addSample() a few 
times,
   * and pull the stats out with whatever methods you prefer.
   *
   * Copyright:    Copyright (c) 2001
   * Company:      Apache Foundation
   * @author James Boutcher
   * @version 1.0
   */
  public class RunningSample {
  
      private long counter;
      private long runningSum;
      private long max, min;
      private long errorCount;
      private long firstTime;
  
      /**
       * use this constructor.
       */
      public RunningSample() {
          counter = 0L;
          runningSum = 0L;
          max = Long.MIN_VALUE;
          min = Long.MAX_VALUE;
          errorCount = 0L;
          firstTime = 0L;
      }
  
      /**
       * Returns a String that shows the rate the samples are being taken.
       * Examples:
       *      "34.2/sec"
       *      "0.1/sec"
       *      "43.0/hour"
       *      "15.9/min"
       * @return a String representation of the rate the samples are being taken at.
       */
      public String getRateString() {
          long howLongRunning = System.currentTimeMillis() - firstTime;
  
          if (howLongRunning == 0) return ("N/A");
          double samplesPerSecond = ((double) counter / ((double) howLongRunning / 
1000.0));
  //        System.out.println("Running for " + howLongRunning + " seconds - " + 
samplesPerSecond + " samples per second.");
          String perString = "/sec";
          if (samplesPerSecond < 1.0) {
              samplesPerSecond *= 60;
              perString = "/min";
          }
          if (samplesPerSecond < 1.0) {
              samplesPerSecond *= 60;
              perString = "/hour";
          }
          // i guess now, samplesPerSECOND really might NOT be that. :-)
  
          /** @todo probably should turn this DecimalFormat (and the one used below a 
few methods) into static member
           variables, so the decimal formatter isn't instantiated in each call to this 
method.. */
          DecimalFormat myDF = new DecimalFormat("#.0");
          String rval = myDF.format(samplesPerSecond) + perString;
          return (rval);
      }
  
  
      /**
       * Records a sample.
       * @arg aTimeInMillis Time in milliseconds that this sample took to process
       * @arg aSuccessFlag Flag for if this sample was successful or not
       */
      public synchronized void addSample(long aTimeInMillis, boolean aSuccessFlag) {
          counter++;
          if (firstTime == 0L) {
              // this is our first sample, set the start time to current system time..
              firstTime = System.currentTimeMillis();
          }
          runningSum += aTimeInMillis;
          if (aTimeInMillis > max) max = aTimeInMillis;
          if (aTimeInMillis < min) min = aTimeInMillis;
          if (!aSuccessFlag) errorCount++;
      }
  
      /**
       * Returns the time in milliseconds of the quickest sample.
       * @return the time in milliseconds of the quickest sample.
       */
      public long getMin() {
          long rval = 0;
          if (min != Long.MIN_VALUE) rval = min;
          return (rval);
      }
  
      /**
       * Returns the time in milliseconds of the slowest sample.
       * @return the time in milliseconds of the slowest sample.
       */
      public long getMax() {
          long rval = 0;
          if (max != Long.MAX_VALUE) rval = max;
          return (rval);
      }
  
      /**
       * Returns the average time in milliseconds that samples ran in.
       * @return the average time in milliseconds that samples ran in.
       */
      public long getAverage() {
          if (counter == 0) return (0);
          return (runningSum / counter);
      }
  
      /**
       * Returns the number of samples that have been recorded by this instance of the 
RunningSample class.
       * @return the number of samples that have been recorded by this instance of the 
RunningSample class.
       */
      public long getNumSamples() {
          return (counter);
      }
  
      /**
       * Returns the raw double value of the percentage of samples with errors that 
were recorded.
       * (Between 0.0 and 1.0)
       * If you want a nicer return format, see getErrorPercentageString()
       *
       * @return the raw double value of the percentage of samples with errors that 
were recorded.
       */
      public double getErrorPercentage() {
          double rval = 0.0;
          if (counter == 0) return (rval);
          rval = (double) errorCount / (double) counter;
          return (rval);
      }
  
  
      /**
       * Returns a String which represents the percentage of sample errors that have 
occurred.
       * "0.00%" through "100.00%"
       * @return a String which represents the percentage of sample errors that have 
occurred.
       */
      public String getErrorPercentageString() {
          double myErrorPercentage = this.getErrorPercentage();
          DecimalFormat myDF = new DecimalFormat("#0.00%");
          return (myDF.format(myErrorPercentage));
      }
  
      /**
       * For debugging purposes, mainly.
       */
      public String toString() {
          StringBuffer mySB = new StringBuffer();
          mySB.append("Samples: " + this.getNumSamples() + "  ");
          mySB.append("Avg: " + this.getAverage() + "  ");
          mySB.append("Min: " + this.getMin() + "  ");
          mySB.append("Max: " + this.getMax() + "  ");
          mySB.append("Error Rate: " + this.getErrorPercentageString() + "  ");
          mySB.append("Sample Rate: " + this.getRateString());
          return (mySB.toString());
      }
  
  } // class RunningSample
  
  
  
  1.1                  
jakarta-jmeter/src/org/apache/jmeter/visualizers/StatVisualizer.java
  
  Index: StatVisualizer.java
  ===================================================================
  /*
   * ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   * if any, must include the following acknowledgment:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowledgment may appear in the software itself,
   * if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   * "Apache JMeter" must not be used to endorse or promote products
   * derived from this software without prior written permission. For
   * written permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   * "Apache JMeter", nor may "Apache" appear in their name, without
   * prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
   package org.apache.jmeter.visualizers;
  
  // apache
  import org.apache.jmeter.gui.ModelSupported;
  import org.apache.jmeter.gui.NamePanel;
  import org.apache.jmeter.gui.VerticalLayout;
  
  // java
  import javax.swing.*;
  import javax.swing.border.Border;
  import javax.swing.border.EmptyBorder;
  import javax.swing.event.TableModelEvent;
  import javax.swing.table.AbstractTableModel;
  import javax.swing.table.TableModel;
  import java.awt.*;
  import java.awt.event.MouseAdapter;
  import java.awt.event.MouseEvent;
  import java.util.Arrays;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.Vector;
  
  
  
  
  /**
   * Title:        StatVisualizer.java
   * Description:  Aggregrate Table-Based Reporting Visualizer for JMeter
   *
   * Props to the people who've done the other visualizers ahead of me (Stefano 
Mazzocchi), who I borrowed code from
   * to start me off (and much code may still exist).. Thank you!
   *
   * Copyright:    Copyright (c) 2001
   * Company:      Apache Foundation
   * @author James Boutcher
   * @version 1.0
   */
  public class StatVisualizer extends JComponent implements Scrollable, 
ModelSupported, GenericGraphListener
  {
  
  //    protected NamePanel namePanel;
  //    protected GraphAccum graph;
  
  //    protected JPanel legendPanel;
      protected JTable myJTable;
      protected JScrollPane myScrollPane;
  
  //    private boolean data = true;
  //    private boolean average = true;
  //    private boolean deviation = true;
  
      private StatVisualizerModel model;
      private StatTableModel myStatTableModel;
  
      private static int width = 2000;
      private long sleepTill = 0;
  
  
      /**
       *  Constructor for the Graph object
       */
      public StatVisualizer() {
          super();
          this.setPreferredSize(new Dimension(width, 800));
      }
  
  
      /**
       * YAC (Yet another constructor) - this one ties it to the model.
       */
      public StatVisualizer(StatVisualizerModel model) {
          this();
          setModel(model);
      }
  
      /**
       * Ties this visualizer to the model.
       */
      public void setModel(Object model) {
          this.model = (StatVisualizerModel)model;
          this.model.addModelListener(this);
          init();
      }
  
      /**
       * Clears this visualizer, it model, and forces a repaint of the table
       */
      public void clear()
      {
          myStatTableModel.clear();
          myJTable.tableChanged(new TableModelEvent(myStatTableModel));
      }
  
      /**
       *  Gets the PreferredScrollableViewportSize attribute of this Visualizer
       *
       *@return    The PreferredScrollableViewportSize value
       */
      public Dimension getPreferredScrollableViewportSize()
      {
          return this.getPreferredSize();
      }
  
      /**
       *  Gets the ScrollableUnitIncrement attribute of the Visualizer
       *
       *@param  visibleRect  Description of Parameter
       *@param  orientation  Description of Parameter
       *@param  direction    Description of Parameter
       *@return              The ScrollableUnitIncrement value
       */
      public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, 
int direction)
      {
          // yanked this from some other visualizer - along with most of the core GUI 
stuff. not my bag.
          return 5;
      }
  
      /**
       *  Gets the ScrollableBlockIncrement attribute of the Visualizer
       *
       *@param  visibleRect  Description of Parameter
       *@param  orientation  Description of Parameter
       *@param  direction    Description of Parameter
       *@return              The ScrollableBlockIncrement value
       */
      public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, 
int direction)
      {
          return (int)(visibleRect.width*.9);
      }
  
      /**
       *  Gets the ScrollableTracksViewportWidth attribute of the Visualizer
       *
       *@return    The ScrollableTracksViewportWidth value
       */
      public boolean getScrollableTracksViewportWidth()
      {
          return false;
      }
  
      /**
       *  Gets the ScrollableTracksViewportHeight attribute of the Visualizer
       *
       *@return    The ScrollableTracksViewportHeight value
       */
      public boolean getScrollableTracksViewportHeight()
      {
          return true;
      }
  
  
      /**
       * Main visualizer setup..
       */
      private void init()
        {
  
                this.setLayout(new BorderLayout());
  
                // MAIN PANEL
                JPanel mainPanel = new JPanel();
                Border margin = new EmptyBorder(10, 10, 5, 10);
                mainPanel.setBorder(margin);
                mainPanel.setLayout(new VerticalLayout(5, VerticalLayout.LEFT));
  
                // TITLE
                JLabel panelTitleLabel = new JLabel("Aggregate Report");
                Font curFont = panelTitleLabel.getFont();
                int curFontSize = curFont.getSize();
                curFontSize += 4;
                panelTitleLabel.setFont(new Font(curFont.getFontName(), 
curFont.getStyle(), curFontSize));
                mainPanel.add(panelTitleLabel);
  
          myStatTableModel = new StatTableModel();
  //        SortFilterModel mySortedModel = new SortFilterModel(myStatTableModel);
  
          myJTable = new JTable(myStatTableModel);
          myJTable.setPreferredScrollableViewportSize(
                    new Dimension(500, 70));
  
          myScrollPane = new JScrollPane(myJTable);
  
                this.add(mainPanel, BorderLayout.NORTH);
                this.add(myScrollPane, BorderLayout.CENTER);
        }
  
  
      /**
       * Called by the model when the model has changed, and probably called by the 
GUI when componets are resized, I'm guessing.
       */
      public void updateGui()
      {
          if(updateChart(myJTable,model.getURLStats())) {
              myJTable.tableChanged(new TableModelEvent(myStatTableModel));
          }
      }
  
  
      /**
       * Main method to update the chart with data contained in the passed-in-map.
       * No matter how quickly you repeatedly call this method, the table will only be 
updated at most
       * once per second.
       *
       * @return A flag whether or not the graph was updated at all
       */
      public boolean updateChart(JTable aTable, Map dataset) {
  
          // some logic here so that if we're getting calls to update the chart 
5000x/sec, we only do it once a second.
          // it's too busy otherwise.
          if(System.currentTimeMillis() < sleepTill) {
              // Sleeping.. won't update yet
              return false;
          } else {
              sleepTill = System.currentTimeMillis() + 1000L;
          }
  
          // go through the dataset and plop values in the table
          Iterator e = dataset.keySet().iterator();
          int ridx=-1;
          while(e.hasNext()) {
               ridx++;
               String thisKey = (String)e.next();
               RunningSample rs = (RunningSample)dataset.get(thisKey);
  
               aTable.setValueAt((String)thisKey,ridx,0);
               aTable.setValueAt(new Long(rs.getNumSamples()),ridx,1);
               aTable.setValueAt(new Long(rs.getAverage()),ridx,2);
               aTable.setValueAt(new Long(rs.getMin()),ridx,3);
               aTable.setValueAt(new Long(rs.getMax()),ridx,4);
               aTable.setValueAt(rs.getErrorPercentageString(),ridx,5);
               aTable.setValueAt(rs.getRateString(),ridx,6);
               if(rs.getErrorPercentage() > .5) {
                  // have some fun with cell renderers later, change this text to red 
or something.
                  // here is where the logic would be.
               }
  
          } // while
  
          // we ended up updating the data in the table, so we'll return true so our 
caller can force a repaint
          // of components
          return(true);
      }
  
        } // class StatVisualizer
  
  
      /**
       * Pulled this mainly out of a Core Java book to implement a sorted table - 
haven't implemented this yet,
       * it needs some non-trivial work done to it to support our dynamically-sizing 
TableModel for this visualizer.
       */
      class SortFilterModel extends AbstractTableModel {
  
          private TableModel model;
          private int sortColumn;
          private Row[] rows;
  
          public SortFilterModel(TableModel m) {
              model  = m;
              rows = new Row[model.getRowCount()];
              for (int i=0; i<rows.length; i++) {
                  rows[i] = new Row();
                  rows[i].index=i;
              }
          }
  
          public void sort(int c) {
              sortColumn = c;
              Arrays.sort(rows);
              fireTableDataChanged();
          }
  
          public Object getValueAt(int r, int c) {
              return model.getValueAt(rows[r].index, c);
          }
  
          public boolean isCellEditable(int r, int c) {
              return model.isCellEditable(rows[r].index, c);
          }
  
          public void setValueAt(Object aValue, int r, int c) {
              model.setValueAt(aValue,rows[r].index, c);
          }
  
          public int getRowCount() {
              return model.getRowCount();
          }
  
          public int getColumnCount() {
              return model.getColumnCount();
          }
  
          public String getColumnName(int c) {
              return model.getColumnName(c);
          }
  
          public Class getColumnClass(int c) {
              return model.getColumnClass(c);
          }
  
          public void addMouseListener(final JTable table) {
              table.getTableHeader().addMouseListener(new MouseAdapter() {
                  public void mouseClicked(MouseEvent event) {
                      if(event.getClickCount() < 2) return;
  
                      int tableColumn = table.columnAtPoint(event.getPoint());
  
                      int modelColumn = table.convertColumnIndexToModel(tableColumn);
                      sort(modelColumn);
                  }
              });
          }
  
  
          private class Row implements Comparable {
              public int index;
  
              public int compareTo(Object other) {
  
                  Row otherRow = (Row)other;
                  Object a = model.getValueAt(index,sortColumn);
                  Object b = model.getValueAt(otherRow.index, sortColumn);
                  if(a instanceof Comparable)
                      return ((Comparable)a).compareTo(b);
                  else
                      return index-otherRow.index;
              }
          }
  
      } // class SortFilterModel
  
  
  
      /**
       * Class which implements the model for our main table in this visualizer.
       */
      class StatTableModel extends AbstractTableModel {
          final String[] columnNames = {"URL",
                                           "Count",
                                           "Average",
                                           "Min",
                                           "Max",
                                           "Error%",
                                           "Rate"};
          Vector data;
  
          public StatTableModel() {
              super();
              data = new Vector();
          }
  
          public void clear() {
              data.clear();
          }
  
             public int getColumnCount() {
                 return columnNames.length;
             }
  
             public int getRowCount() {
                 return data.size();
             }
  
             public String getColumnName(int col) {
                 return columnNames[col];
             }
  
             public Object getValueAt(int row, int col) {
                //When created, rows are null, need to check that
                if((((Object[])data.get(row))[col]) != null) {
                    return (((Object[])(data.get(row)))[col]);
                } else {
                    return (" ");
                }
             }
  
  
             public Class getColumnClass(int c) {
                 return getValueAt(0, c).getClass();
             }
  
  
  
             public void setValueAt(Object value, int row, int col) {
                 Object[] temp;
                 //Extends the size of the vector as needed (can be used for append)
                 if (row>=data.size()) {
                     data.setSize(row+1);
                 }
                 //Check if the line is not empty
                 if ((Object[])(data.get(row))==null) {
                     temp = new Object[this.getColumnCount()];
                 } else {
                     temp = (Object[])(data.get(row));
                 }
                 temp[col]=value;
                 //Columns are stored as an array
                 data.set(row,temp);
            }
  
  
            public void insertRowAt(int row) {
                 data.insertElementAt(new Object[this.getColumnCount()],row);
            }
  
  
  
         } // class StatTableModel
  
  
  
  1.1                  
jakarta-jmeter/src/org/apache/jmeter/visualizers/StatVisualizerModel.java
  
  Index: StatVisualizerModel.java
  ===================================================================
  /*
   * ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   * if any, must include the following acknowledgment:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowledgment may appear in the software itself,
   * if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   * "Apache JMeter" must not be used to endorse or promote products
   * derived from this software without prior written permission. For
   * written permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   * "Apache JMeter", nor may "Apache" appear in their name, without
   * prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.jmeter.visualizers;
  
  
  // apache
  import org.apache.jmeter.gui.JMeterComponentModel;
  import org.apache.jmeter.gui.ModelSupported;
  import org.apache.jmeter.samplers.Clearable;
  import org.apache.jmeter.samplers.SampleEvent;
  import org.apache.jmeter.samplers.SampleListener;
  import org.apache.jmeter.save.Saveable;
  
  // java
  import java.util.*;
  
  
  
  /**
   * Title:        StatVisualizerModel.java
   * Description:  Aggregrate Table-Based Reporting Model for JMeter
   *
   * Props to the people who've done the other visualizers ahead of me (Stefano 
Mazzocchi), who I borrowed code from
   * to start me off (and much code may still exist).. Thank you!
   *
   * Copyright:    Copyright (c) 2001
   * Company:      Apache Foundation
   * @author James Boutcher
   * @version 1.0
   */
  public class StatVisualizerModel implements JMeterComponentModel, SampleListener, 
Saveable, Clearable {
  
      private final static String VISUALIZER_NAME = "Aggregate Report";
  
      private String name;
      private List listeners;
      private Map responseCodeMap;
      private Map labelMap;
  
  
      /**
       * Default Constuctor
       */
      public StatVisualizerModel() {
          listeners = new LinkedList();
          responseCodeMap = Collections.synchronizedMap(new HashMap(10));
          labelMap = Collections.synchronizedMap(new HashMap(10));
      }
  
      /**
       * ??
       */
      public void addJMeterComponent(JMeterComponentModel child) {
  //        System.out.println("StatVisualizerModel.addJMeterComponent() called.");
      }
  
  
      /**
       * Returns the Map containing a list of HTTP/FTP Response Codes and their 
corresponding counts.
       */
      public Map getResponseCodeMap() {
          return (responseCodeMap);
      }
  
  
      /**
       * This gets called a lot, but I don't know what it's used for.
       */
      public void uncompile() {
  //       System.out.println("StatVisualizerModel.uncompile() called.");
      }
  
  
      /**
       * Returns the Map containing the Samples we've collected and their 
corresponding RunningSample instance.
       */
      public Map getURLStats() {
          return (labelMap);
      }
  
  
      /**
       * ??
       */
      public Class getTagHandlerClass() {
          return org.apache.jmeter.save.handlers.JMeterComponentHandler.class;
      }
  
  
      /**
       * Called when the model changes - then we call out to all registered listeners 
and tell them to update themselves.
       */
      protected void fireDataChanged() {
          Iterator iter = listeners.iterator();
          while (iter.hasNext()) {
              Object myObj = iter.next();
              if (!(myObj instanceof ModelSupported)) continue;
              ((ModelSupported) myObj).updateGui();
          }
      }
  
      protected void clearAllListeners() {
          Iterator i = listeners.iterator();
  //        System.out.println("clearAllListeners called - size of List=" + 
listeners.size());
          while (i.hasNext()) {
              Object myObj = i.next();
              if (!(myObj instanceof GenericGraphListener)) continue;
              ((GenericGraphListener) myObj).clear();
          }
      }
  
  
      /**
       * Registers a listener (a visualizer, graph, etc) to this model. This will 
allow the model to fire GUI updates
       * to anyone when data changes, etc.
       */
      public void addModelListener(java.awt.Component modelListener) {
          listeners.add(modelListener);
      }
  
  
      /**
       *  Sets the Name attribute of the StatVisualizerModel object
       *
       *@param  name  The new Name value
       */
      public void setName(String name) {
          this.name = name;
      }
  
  
      /**
       *  Gets the GuiClass attribute of the StatVisualizerModel object
       *
       *@return    The GuiClass value
       */
      public Class getGuiClass() {
          return StatVisualizer.class;
      }
  
  
      /**
       *  Gets the Name attribute of the StatVisualizerModel object
       *
       *@return    The Name value
       */
      public String getName() {
          return name;
      }
  
  
      /**
       *  Gets the AddList attribute of the StatVisualizerModel object
       *
       *@return    The AddList value
       */
      public Collection getAddList() {
          // nothing below me!
          return null;
      }
  
  
      /**
       *  Gets the ClassLabel attribute of the StatVisualizerModel object
       *
       *@return    The ClassLabel value
       */
      public String getClassLabel() {
          return VISUALIZER_NAME;
      }
  
  
      public void sampleOccurred(SampleEvent e) {
  
  // [[ uncomment the following lines to see massive details on stdout about each 
sample that comes in ]]
  //       System.out.println("Sample occurred");
  //       String something[] = e.getResult().getNames();
  //       for(int i=0; i<something.length; i++) {
  //           System.out.print(something[i] + " = " + 
e.getResult().getValue(something[i]) + ", ---   ");
  //       }
  //       System.out.println("");
  
          boolean wasSuccessful = false;
          if (e.getResult().getValue("sampler.SUCCESS") != null) {
              wasSuccessful = ((Boolean) 
e.getResult().getValue("sampler.SUCCESS")).booleanValue();
          }
  
          addNewSample(e.getResult().getTime(), (String) 
e.getResult().getValue("sampler.LABEL"), wasSuccessful, (String) 
e.getResult().getValue("sampler.RESPONSE_CODE"));
  
          this.fireDataChanged();
  
      }
  
  
      /**
       * ???
       */
      public void sampleStarted(SampleEvent e) {
  //        System.out.println("StatVisualizerModel.sampleStarted() called.");
      }
  
  
      /**
       * Reset everything we can in the model.
       */
      public void clear() {
  //        System.out.println("StatVisualizerModel.clear() called");
  
          // clear the data structures
          responseCodeMap.clear();
          labelMap.clear();
  
          // and tell all our listeners to update themselves.
          clearAllListeners();
  
          this.fireDataChanged();
      }
  
  
      private void addNewSample(long sample, String aLabel, boolean isSuccess, String 
responseCode) {
  
          if (responseCodeMap.containsKey(responseCode)) {
              long tempLong = ((Long) responseCodeMap.get(responseCode)).longValue();
              tempLong++;
              responseCodeMap.put(responseCode, new Long(tempLong));
          } else {
              responseCodeMap.put(responseCode, new Long(1));
          }
  
          RunningSample myRS;
          if (labelMap.containsKey(aLabel)) {
              myRS = (RunningSample) labelMap.get(aLabel);
          } else {
              // put a new one there..
              myRS = new RunningSample();
              labelMap.put(aLabel, myRS);
          }
          myRS.addSample(sample, isSuccess);
  
  
      }
  
  
      /**
       * Odd, this isn't called when I click on Run/Stop. It would be nice if it did. 
:-)
       */
      public void sampleStopped(SampleEvent e) {
  //       System.out.println("StatVisualizerModel.sampleStopped() called.");
      }
  
  
  }
  
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to