Package org.apache.jmeter.visualizers.gui

Source Code of org.apache.jmeter.visualizers.gui.AbstractVisualizer

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.apache.jmeter.visualizers.gui;

import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Collection;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPopupMenu;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.apache.jmeter.gui.AbstractJMeterGuiComponent;
import org.apache.jmeter.gui.GuiPackage;
import org.apache.jmeter.gui.SavePropertyDialog;
import org.apache.jmeter.gui.UnsharedComponent;
import org.apache.jmeter.gui.util.FilePanel;
import org.apache.jmeter.gui.util.MenuFactory;
import org.apache.jmeter.reporters.AbstractListenerElement;
import org.apache.jmeter.reporters.ResultCollector;
import org.apache.jmeter.samplers.Clearable;
import org.apache.jmeter.samplers.SampleSaveConfiguration;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jmeter.visualizers.Visualizer;
import org.apache.jorphan.gui.ComponentUtil;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;

/**
* This is the base class for JMeter GUI components which can display test
* results in some way. It provides the following conveniences to developers:
* <ul>
* <li>Implements the
* {@link org.apache.jmeter.gui.JMeterGUIComponent JMeterGUIComponent} interface
* that allows your Gui visualizer to "plug-in" to the JMeter GUI environment.
* Provides implementations for the following methods:
* <ul>
* <li>{@link org.apache.jmeter.gui.JMeterGUIComponent#configure(TestElement) configure(TestElement)}.
* Any additional parameters of your Visualizer need to be handled by you.</li>
* <li>{@link org.apache.jmeter.gui.JMeterGUIComponent#createTestElement() createTestElement()}.
* For most purposes, the default
* {@link org.apache.jmeter.reporters.ResultCollector ResultCollector} created
* by this method is sufficient.</li>
* <li>{@link org.apache.jmeter.gui.JMeterGUIComponent#getMenuCategories getMenuCategories()}.
* To control where in the GUI your visualizer can be added.</li>
* <li>{@link org.apache.jmeter.gui.JMeterGUIComponent#modifyTestElement(TestElement) modifyTestElement(TestElement)}.
* Again, additional parameters you require have to be handled by you.</li>
* <li>{@link org.apache.jmeter.gui.JMeterGUIComponent#createPopupMenu() createPopupMenu()}.</li>
* </ul>
* </li>
* <li>Provides convenience methods to help you make a JMeter-compatible GUI:
* <ul>
* <li>{@link #makeTitlePanel()}. Returns a panel that includes the name of
* the component, and a FilePanel that allows users to control what file samples
* are logged to.</li>
* <li>{@link #getModel()} and {@link #setModel(ResultCollector)} methods for
* setting and getting the model class that handles the receiving and logging of
* sample results.</li>
* </ul>
* </li>
* </ul>
* For most developers, making a new visualizer is primarly for the purpose of
* either calculating new statistics on the sample results that other
* visualizers don't calculate, or displaying the results visually in a new and
* interesting way. Making a new visualizer for either of these purposes is easy -
* just extend this class and implement the
* {@link org.apache.jmeter.visualizers.Visualizer#add add(SampleResult)}
* method and display the results as you see fit. This AbstractVisualizer and
* the default
* {@link org.apache.jmeter.reporters.ResultCollector ResultCollector} handle
* logging and registering to receive SampleEvents for you - all you need to do
* is include the JPanel created by makeTitlePanel somewhere in your gui to
* allow users set the log file.
* <p>
* If you are doing more than that, you may need to extend
* {@link org.apache.jmeter.reporters.ResultCollector ResultCollector} as well
* and modify the {@link #configure(TestElement)},
* {@link #modifyTestElement(TestElement)}, and {@link #createTestElement()}
* methods to create and modify your alternate ResultCollector. For an example
* of this, see the
* {@link org.apache.jmeter.visualizers.MailerVisualizer MailerVisualizer}.
* <p>
*
*/
public abstract class AbstractVisualizer
    extends AbstractJMeterGuiComponent
    implements Visualizer, ChangeListener, UnsharedComponent, Clearable
    {
  /** Logging. */
  private static final Logger log = LoggingManager.getLoggerForClass();

  /** A panel allowing results to be saved. */
  private FilePanel filePanel;

  /** A checkbox choosing whether or not only errors should be logged. */
  private JCheckBox errorLogging;
 
  /* A checkbox choosing whether or not only successes should be logged. */
  private JCheckBox successOnlyLogging;

  private JButton saveConfigButton;

  protected ResultCollector collector = new ResultCollector();

  protected boolean isStats = false;

  public AbstractVisualizer() {
    super();

    // errorLogging and successOnlyLogging are mutually exclusive
    errorLogging = new JCheckBox(JMeterUtils.getResString("log_errors_only")); // $NON-NLS-1$
    errorLogging.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e) {
        if (errorLogging.isSelected()) successOnlyLogging.setSelected(false);
      }     
    });
    successOnlyLogging = new JCheckBox(JMeterUtils.getResString("log_success_only")); // $NON-NLS-1$
    successOnlyLogging.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e) {
        if (successOnlyLogging.isSelected()) errorLogging.setSelected(false);
      }     
    });
    saveConfigButton = new JButton(JMeterUtils.getResString("config_save_settings")); // $NON-NLS-1$
    saveConfigButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        SavePropertyDialog d = new SavePropertyDialog(
                        GuiPackage.getInstance().getMainFrame(),
                        JMeterUtils.getResString("sample_result_save_configuration"), // $NON-NLS-1$
                        true, collector.getSaveConfig());
        d.pack();
        ComponentUtil.centerComponentInComponent(GuiPackage.getInstance().getMainFrame(), d);
        d.setVisible(true);
      }
    });

    filePanel = new FilePanel(JMeterUtils.getResString("file_visualizer_output_file"), ".jtl"); // $NON-NLS-1$ $NON-NLS-2$
    filePanel.addChangeListener(this);
    filePanel.add(new JLabel(JMeterUtils.getResString("log_only"))); // $NON-NLS-1$
    filePanel.add(errorLogging);
    filePanel.add(successOnlyLogging);
    filePanel.add(saveConfigButton);

  }

  public boolean isStats() {
    return isStats;
  }

  /**
   * Gets the checkbox which selects whether or not only errors should be
   * logged. Subclasses don't normally need to worry about this checkbox,
   * because it is automatically added to the GUI in {@link #makeTitlePanel()},
   * and the behavior is handled in this base class.
   *
   * @return the error logging checkbox
   */
  protected JCheckBox getErrorLoggingCheckbox() {
    return errorLogging;
  }

  /**
   * Provides access to the ResultCollector model class for extending
   * implementations. Using this method and setModel(ResultCollector) is only
   * necessary if your visualizer requires a differently behaving
   * ResultCollector. Using these methods will allow maximum reuse of the
   * methods provided by AbstractVisualizer in this event.
   */
  protected ResultCollector getModel() {
    return collector;
  }

  /**
   * Gets the file panel which allows the user to save results to a file.
   * Subclasses don't normally need to worry about this panel, because it is
   * automatically added to the GUI in {@link #makeTitlePanel()}, and the
   * behavior is handled in this base class.
   *
   * @return the file panel allowing users to save results
   */
  protected Component getFilePanel() {
    return filePanel;
  }

  /**
   * Sets the filename which results will be saved to. This will set the
   * filename in the FilePanel. Subclasses don't normally need to call this
   * method, because configuration of the FilePanel is handled in this base
   * class.
   *
   * @param filename
   *            the new filename
   *
   * @see #getFilePanel()
   */
  public void setFile(String filename) {
    // TODO: Does this method need to be public? It isn't currently
    // called outside of this class.
    filePanel.setFilename(filename);
  }

  /**
   * Gets the filename which has been entered in the FilePanel. Subclasses
   * don't normally need to call this method, because configuration of the
   * FilePanel is handled in this base class.
   *
   * @return the current filename
   *
   * @see #getFilePanel()
   */
  public String getFile() {
    // TODO: Does this method need to be public? It isn't currently
    // called outside of this class.
    return filePanel.getFilename();
  }

  /**
   * When a user right-clicks on the component in the test tree, or selects
   * the edit menu when the component is selected, the component will be asked
   * to return a JPopupMenu that provides all the options available to the
   * user from this component.
   * <p>
   * This implementation returns menu items appropriate for most visualizer
   * components.
   *
   * @return a JPopupMenu appropriate for the component.
   */
  public JPopupMenu createPopupMenu() {
    return MenuFactory.getDefaultVisualizerMenu();
  }

  /**
   * Invoked when the target of the listener has changed its state. This
   * implementation assumes that the target is the FilePanel, and will update
   * the result collector for the new filename.
   *
   * @param e
   *            the event that has occurred
   */
  public void stateChanged(ChangeEvent e) {
    log.debug("getting new collector");
    collector = (ResultCollector) createTestElement();
        collector.loadExistingFile();
  }

  /**
   * This is the list of menu categories this gui component will be available
   * under. This implementation returns
   * {@link org.apache.jmeter.gui.util.MenuFactory#LISTENERS}, which is
   * appropriate for most visualizer components.
   *
   * @return a Collection of Strings, where each element is one of the
   *         constants defined in MenuFactory
   */
  public Collection getMenuCategories() {
    return Arrays.asList(new String[] { MenuFactory.LISTENERS });
  }

  /* Implements JMeterGUIComponent.createTestElement() */
  public TestElement createTestElement() {
    if (collector == null) {
      collector = new ResultCollector();
    }
    modifyTestElement(collector);
    return (TestElement) collector.clone();
  }

  /* Implements JMeterGUIComponent.modifyTestElement(TestElement) */
  public void modifyTestElement(TestElement c) {
    configureTestElement((AbstractListenerElement) c);
    if (c instanceof ResultCollector) {
      ResultCollector rc = (ResultCollector) c;
      rc.setErrorLogging(errorLogging.isSelected());
      rc.setSuccessOnlyLogging(successOnlyLogging.isSelected());
      rc.setFilename(getFile());
      collector = rc;
    }
  }

  /* Overrides AbstractJMeterGuiComponent.configure(TestElement) */
  public void configure(TestElement el) {
    super.configure(el);
    setFile(el.getPropertyAsString(ResultCollector.FILENAME));
    ResultCollector rc = (ResultCollector) el;
    errorLogging.setSelected(rc.isErrorLogging());
    successOnlyLogging.setSelected(rc.isSuccessOnlyLogging());
    if (collector == null) {
      collector = new ResultCollector();
    }
    collector.setSaveConfig((SampleSaveConfiguration) rc.getSaveConfig().clone());
  }

  /**
   * This provides a convenience for extenders when they implement the
   * {@link org.apache.jmeter.gui.JMeterGUIComponent#createTestElement()}
   * method. This method will set the name, gui class, and test class for the
   * created Test Element. It should be called by every extending class when
   * creating Test Elements, as that will best assure consistent behavior.
   *
   * @param mc
   *            the TestElement being created.
   */
  protected void configureTestElement(AbstractListenerElement mc) {
    // TODO: Should the method signature of this method be changed to
    // match the super-implementation (using a TestElement parameter
    // instead of AbstractListenerElement)? This would require an
    // instanceof check before adding the listener (below), but would
    // also make the behavior a bit more obvious for sub-classes -- the
    // Java rules dealing with this situation aren't always intuitive,
    // and a subclass may think it is calling this version of the method
    // when it is really calling the superclass version instead.
    super.configureTestElement(mc);
    mc.setListener(this);
  }

  /**
   * Create a standard title section for JMeter components. This includes the
   * title for the component and the Name Panel allowing the user to change
   * the name for the component. The AbstractVisualizer also adds the
   * FilePanel allowing the user to save the results, and the error logging
   * checkbox, allowing the user to choose whether or not only errors should
   * be logged.
   * <p>
   * This method is typically added to the top of the component at the
   * beginning of the component's init method.
   *
   * @return a panel containing the component title, name panel, file panel,
   *         and error logging checkbox
   */
  protected Container makeTitlePanel() {
    Container panel = super.makeTitlePanel();
    // Note: the file panel already includes the error logging checkbox,
    // so we don't have to add it explicitly.
    panel.add(getFilePanel());
    return panel;
  }

  /**
   * Provides extending classes the opportunity to set the ResultCollector
   * model for the Visualizer. This is useful to allow maximum reuse of the
   * methods from AbstractVisualizer.
   *
   * @param collector
   */
  protected void setModel(ResultCollector collector) {
    this.collector = collector;
  }

  public void clearGui(){
    super.clearGui();
    filePanel.clearGui();
  }
}
TOP

Related Classes of org.apache.jmeter.visualizers.gui.AbstractVisualizer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.