You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jmeter-dev@jakarta.apache.org by wo...@apache.org on 2005/08/13 01:58:48 UTC

cvs commit: jakarta-jmeter/src/reports/org/apache/jmeter/report/writers/gui AbstractReportWriterGui.java

woolfel     2005/08/12 16:58:48

  Added:       src/reports/org/apache/jmeter JMeterReport.java
               src/reports/org/apache/jmeter/control/gui ReportGui.java
               src/reports/org/apache/jmeter/testelement ReportPlan.java
               src/reports/org/apache/jmeter/gui/tree ReportTreeModel.java
                        ReportTreeNode.java
               src/reports/org/apache/jmeter/report/writers/gui
                        AbstractReportWriterGui.java
  Log:
  adding the classes I have so far for the report component
  peter
  
  Revision  Changes    Path
  1.1                  jakarta-jmeter/src/reports/org/apache/jmeter/JMeterReport.java
  
  Index: JMeterReport.java
  ===================================================================
  /*
   * Copyright 2005 The Apache Software Foundation.
   *
   * Licensed 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;
  
  import java.awt.event.ActionEvent;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileNotFoundException;
  import java.io.IOException;
  import java.util.Enumeration;
  import java.util.List;
  import java.util.Properties;
  
  import org.apache.commons.cli.avalon.CLArgsParser;
  import org.apache.commons.cli.avalon.CLOption;
  import org.apache.commons.cli.avalon.CLOptionDescriptor;
  import org.apache.commons.cli.avalon.CLUtil;
  import org.apache.jmeter.config.gui.AbstractConfigGui;
  import org.apache.jmeter.control.gui.AbstractControllerGui;
  import org.apache.jmeter.control.gui.ReportGui;
  import org.apache.jmeter.control.gui.TestPlanGui;
  import org.apache.jmeter.control.gui.WorkBenchGui;
  import org.apache.jmeter.gui.GuiPackage;
  import org.apache.jmeter.gui.action.ActionRouter;
  import org.apache.jmeter.gui.action.CheckDirty;
  import org.apache.jmeter.gui.action.Load;
  import org.apache.jmeter.gui.tree.JMeterTreeListener;
  import org.apache.jmeter.gui.tree.JMeterTreeModel;
  import org.apache.jmeter.plugin.JMeterPlugin;
  import org.apache.jmeter.plugin.PluginManager;
  import org.apache.jmeter.samplers.gui.AbstractSamplerGui;
  import org.apache.jmeter.save.SaveService;
  import org.apache.jmeter.threads.gui.ThreadGroupGui;
  import org.apache.jmeter.timers.gui.AbstractTimerGui;
  import org.apache.jmeter.report.writers.gui.AbstractReportWriterGui;
  import org.apache.jmeter.util.JMeterUtils;
  import org.apache.jmeter.visualizers.gui.AbstractVisualizer;
  import org.apache.jorphan.collections.HashTree;
  import org.apache.jorphan.gui.ComponentUtil;
  import org.apache.jorphan.logging.LoggingManager;
  import org.apache.jorphan.util.JOrphanUtils;
  import org.apache.log.Logger;
  
  /**
   * @author pete
   *
   * JMeterReport is the main class for the reporting component. For now,
   * the plan is to make the reporting component a separate GUI, which 
   * can run in GUI or console mode. The purpose of the GUI is to design
   * reports, which can then be run. One of the primary goals of the
   * reporting component is to make it so the reports can be run in an
   * automated process.
   * The report GUI is different than the main JMeter GUI in several ways.
   * <ul>
   *   <li> the gui is not multi-threaded</li>
   *   <li> the gui uses different components</li>
   *   <li> the gui is focused on designing reports from the jtl logs
   * generated during a test run</li>
   * </ul>
   * The class follows the same design as JMeter.java. This should keep
   * things consistent and make it easier to maintain.
   */
  public class JMeterReport implements JMeterPlugin {
  
      transient private static Logger log = LoggingManager.getLoggerForClass();
  
      private static final int PROPFILE_OPT = 'p';
  
      private static final int PROPFILE2_OPT = 'q'; // Bug 33920 - additional
                                                      // prop files
  
      private static final int TESTFILE_OPT = 't';
  
      private static final int LOGFILE_OPT = 'l';
  
      private static final int NONGUI_OPT = 'n';
  
      private static final int HELP_OPT = 'h';
  
      private static final int VERSION_OPT = 'v';
  
      private static final int SERVER_OPT = 's';
  
      private static final int PROXY_HOST = 'H';
  
      private static final int PROXY_PORT = 'P';
  
      private static final int PROXY_USERNAME = 'u';
  
      private static final int PROXY_PASSWORD = 'a';
  
      private static final int JMETER_PROPERTY = 'J';
  
      private static final int SYSTEM_PROPERTY = 'D';
  
      private static final int LOGLEVEL = 'L';
  
      private static final int REMOTE_OPT = 'r';
  
      private static final int JMETER_HOME_OPT = 'd';
  
      private JMeterReport parent;
  
      private static final CLOptionDescriptor[] options = new CLOptionDescriptor[] {
              new CLOptionDescriptor("help", CLOptionDescriptor.ARGUMENT_DISALLOWED, HELP_OPT,
                      "print usage information and exit"),
              new CLOptionDescriptor("version", CLOptionDescriptor.ARGUMENT_DISALLOWED, VERSION_OPT,
                      "print the version information and exit"),
              new CLOptionDescriptor("propfile", CLOptionDescriptor.ARGUMENT_REQUIRED, PROPFILE_OPT,
                      "the jmeter property file to use"),
              new CLOptionDescriptor("addprop", CLOptionDescriptor.ARGUMENT_REQUIRED
                      | CLOptionDescriptor.DUPLICATES_ALLOWED, // Bug 33920 -
                                                                  // allow
                                                                  // multiple
                                                                  // props
                      PROPFILE2_OPT, "additional property file(s)"),
              new CLOptionDescriptor("testfile", CLOptionDescriptor.ARGUMENT_REQUIRED, TESTFILE_OPT,
                      "the jmeter test(.jmx) file to run"),
              new CLOptionDescriptor("logfile", CLOptionDescriptor.ARGUMENT_REQUIRED, LOGFILE_OPT,
                      "the file to log samples to"),
              new CLOptionDescriptor("nongui", CLOptionDescriptor.ARGUMENT_DISALLOWED, NONGUI_OPT,
                      "run JMeter in nongui mode"),
              new CLOptionDescriptor("server", CLOptionDescriptor.ARGUMENT_DISALLOWED, SERVER_OPT,
                      "run the JMeter server"),
              new CLOptionDescriptor("proxyHost", CLOptionDescriptor.ARGUMENT_REQUIRED, PROXY_HOST,
                      "Set a proxy server for JMeter to use"),
              new CLOptionDescriptor("proxyPort", CLOptionDescriptor.ARGUMENT_REQUIRED, PROXY_PORT,
                      "Set proxy server port for JMeter to use"),
              new CLOptionDescriptor("username", CLOptionDescriptor.ARGUMENT_REQUIRED, PROXY_USERNAME,
                      "Set username for proxy server that JMeter is to use"),
              new CLOptionDescriptor("password", CLOptionDescriptor.ARGUMENT_REQUIRED, PROXY_PASSWORD,
                      "Set password for proxy server that JMeter is to use"),
              new CLOptionDescriptor("jmeterproperty", CLOptionDescriptor.DUPLICATES_ALLOWED
                      | CLOptionDescriptor.ARGUMENTS_REQUIRED_2, JMETER_PROPERTY, "Define additional JMeter properties"),
              new CLOptionDescriptor("systemproperty", CLOptionDescriptor.DUPLICATES_ALLOWED
                      | CLOptionDescriptor.ARGUMENTS_REQUIRED_2, SYSTEM_PROPERTY, "Define additional JMeter properties"),
              new CLOptionDescriptor("loglevel", CLOptionDescriptor.DUPLICATES_ALLOWED
                      | CLOptionDescriptor.ARGUMENTS_REQUIRED_2, LOGLEVEL,
                      "Define loglevel: [category=]level e.g. jorphan=INFO or " + "jmeter.util=DEBUG"),
              new CLOptionDescriptor("runremote", CLOptionDescriptor.ARGUMENT_DISALLOWED, REMOTE_OPT,
                      "Start remote servers from non-gui mode"),
              new CLOptionDescriptor("homedir", CLOptionDescriptor.ARGUMENT_REQUIRED, JMETER_HOME_OPT,
                      "the jmeter home directory to use"), };
      
      /**
  	 * 
  	 */
  	public JMeterReport() {
  		super();
  	}
  
      /**
       * The default icons for the report GUI.
       */
      private static final String[][] DEFAULT_ICONS = {
              { TestPlanGui.class.getName(), "org/apache/jmeter/images/beaker.gif" },
              { AbstractTimerGui.class.getName(), "org/apache/jmeter/images/timer.gif" },
              { ThreadGroupGui.class.getName(), "org/apache/jmeter/images/thread.gif" },
              { AbstractVisualizer.class.getName(), "org/apache/jmeter/images/meter.png" },
              { AbstractConfigGui.class.getName(), "org/apache/jmeter/images/testtubes.png" },
              { AbstractControllerGui.class.getName(), "org/apache/jmeter/images/knob.gif" },
              { WorkBenchGui.class.getName(), "org/apache/jmeter/images/clipboard.gif" },
              { AbstractSamplerGui.class.getName(), "org/apache/jmeter/images/pipet.png" },
              { AbstractReportWriterGui.class.getName(), "org/apache/jmeter/images/new/pencil.png" },
              { ReportGui.class.getName(), "org/apache/jmeter/images/new/book.png" }
      };
      
  	/* (non-Javadoc)
  	 * @see org.apache.jmeter.plugin.JMeterPlugin#getIconMappings()
  	 */
  	public String[][] getIconMappings() {
          String iconProp = JMeterUtils.getPropDefault("jmeter.icons", "org/apache/jmeter/images/icon.properties");
          Properties p = JMeterUtils.loadProperties(iconProp);
          if (p == null) {
              log.info(iconProp + " not found - using default icon set");
              return DEFAULT_ICONS;
          }
          log.info("Loaded icon properties from " + iconProp);
          String[][] iconlist = new String[p.size()][3];
          Enumeration pe = p.keys();
          int i = 0;
          while (pe.hasMoreElements()) {
              String key = (String) pe.nextElement();
              String icons[] = JOrphanUtils.split(p.getProperty(key), " ");
              iconlist[i][0] = key;
              iconlist[i][1] = icons[0];
              if (icons.length > 1)
                  iconlist[i][2] = icons[1];
              i++;
          }
          return iconlist;
  	}
  
  	/* (non-Javadoc)
  	 * @see org.apache.jmeter.plugin.JMeterPlugin#getResourceBundles()
  	 */
  	public String[][] getResourceBundles() {
          return new String[0][];
  	}
  
      public void startNonGui(CLOption testFile, CLOption logFile){
          System.setProperty("JMeter.NonGui", "true");
          JMeterReport driver = new JMeterReport();
          driver.parent = this;
          PluginManager.install(this, false);
      }
      
      public void startGui(CLOption testFile) {
          PluginManager.install(this, true);
          JMeterTreeModel treeModel = new JMeterTreeModel();
          JMeterTreeListener treeLis = new JMeterTreeListener(treeModel);
          treeLis.setActionHandler(ActionRouter.getInstance());
          // NOTUSED: GuiPackage guiPack =
          GuiPackage.getInstance(treeLis, treeModel);
          org.apache.jmeter.gui.ReportMainFrame main = new org.apache.jmeter.gui.ReportMainFrame(ActionRouter.getInstance(),
                  treeModel, treeLis);
          main.setTitle("Apache JMeter Report");
          main.setIconImage(JMeterUtils.getImage("jmeter.jpg").getImage());
          ComponentUtil.centerComponentInWindow(main, 80);
          main.show();
          ActionRouter.getInstance().actionPerformed(new ActionEvent(main, 1, CheckDirty.ADD_ALL));
          if (testFile != null) {
              try {
                  File f = new File(testFile.getArgument());
                  log.info("Loading file: " + f);
                  FileInputStream reader = new FileInputStream(f);
                  HashTree tree = SaveService.loadTree(reader);
  
                  GuiPackage.getInstance().setTestPlanFile(f.getAbsolutePath());
  
                  new Load().insertLoadedTree(1, tree);
              } catch (Exception e) {
                  log.error("Failure loading test file", e);
                  JMeterUtils.reportErrorToUser(e.toString());
              }
          }
          
      }
  
      /**
       * 
       * @param args
       */
      public void start(String[] args) {
          CLArgsParser parser = new CLArgsParser(args, options);
          if (null != parser.getErrorString()) {
              System.err.println("Error: " + parser.getErrorString());
              System.out.println("Usage");
              System.out.println(CLUtil.describeOptions(options).toString());
              return;
          }
          try {
              initializeProperties(parser);
              log.info("Version " + JMeterUtils.getJMeterVersion());
              log.info("java.version=" + System.getProperty("java.version"));
              log.info(JMeterUtils.getJMeterCopyright());
              if (parser.getArgumentById(VERSION_OPT) != null) {
                  System.out.println(JMeterUtils.getJMeterCopyright());
                  System.out.println("Version " + JMeterUtils.getJMeterVersion());
              } else if (parser.getArgumentById(HELP_OPT) != null) {
                  System.out.println(JMeterUtils.getResourceFileAsText("org/apache/jmeter/help.txt"));
              } else if (parser.getArgumentById(NONGUI_OPT) == null) {
                  startGui(parser.getArgumentById(TESTFILE_OPT));
              } else {
                  startNonGui(parser.getArgumentById(TESTFILE_OPT), parser.getArgumentById(LOGFILE_OPT));
              }
          } catch (Exception e) {
              e.printStackTrace();
              System.out.println("An error occurred: " + e.getMessage());
              System.exit(-1);
          }
      }
      
      private void initializeProperties(CLArgsParser parser) {
          if (parser.getArgumentById(PROPFILE_OPT) != null) {
              JMeterUtils.getProperties(parser.getArgumentById(PROPFILE_OPT).getArgument());
          } else {
              JMeterUtils.getProperties(NewDriver.getJMeterDir() + File.separator + "bin" + File.separator
                      + "jmeter.properties");
          }
  
          // Bug 33845 - allow direct override of Home dir
          if (parser.getArgumentById(JMETER_HOME_OPT) == null) {
              JMeterUtils.setJMeterHome(NewDriver.getJMeterDir());
          } else {
              JMeterUtils.setJMeterHome(parser.getArgumentById(JMETER_HOME_OPT).getArgument());
          }
  
          // Process command line property definitions (can occur multiple times)
  
          Properties jmeterProps = JMeterUtils.getJMeterProperties();
          List clOptions = parser.getArguments();
          int size = clOptions.size();
  
          for (int i = 0; i < size; i++) {
              CLOption option = (CLOption) clOptions.get(i);
              String name = option.getArgument(0);
              String value = option.getArgument(1);
  
              switch (option.getDescriptor().getId()) {
              case PROPFILE2_OPT: // Bug 33920 - allow multiple props
                  File f = new File(name);
                  try {
                      jmeterProps.load(new FileInputStream(f));
                  } catch (FileNotFoundException e) {
                      log.warn("Can't find additional property file: " + name, e);
                  } catch (IOException e) {
                      log.warn("Error loading additional property file: " + name, e);
                  }
                  break;
              case SYSTEM_PROPERTY:
                  if (value.length() > 0) { // Set it
                      log.info("Setting System property: " + name + "=" + value);
                      System.getProperties().setProperty(name, value);
                  } else { // Reset it
                      log.warn("Removing System property: " + name);
                      System.getProperties().remove(name);
                  }
                  break;
              case JMETER_PROPERTY:
                  if (value.length() > 0) { // Set it
                      log.info("Setting JMeter property: " + name + "=" + value);
                      jmeterProps.setProperty(name, value);
                  } else { // Reset it
                      log.warn("Removing JMeter property: " + name);
                      jmeterProps.remove(name);
                  }
                  break;
              case LOGLEVEL:
                  if (value.length() > 0) { // Set category
                      log.info("LogLevel: " + name + "=" + value);
                      LoggingManager.setPriority(value, name);
                  } else { // Set root level
                      log.warn("LogLevel: " + name);
                      LoggingManager.setPriority(name);
                  }
                  break;
              }
          }
  
      }
      
  }
  
  
  1.1                  jakarta-jmeter/src/reports/org/apache/jmeter/control/gui/ReportGui.java
  
  Index: ReportGui.java
  ===================================================================
  // $Header: /home/cvs/jakarta-jmeter/src/reports/org/apache/jmeter/control/gui/ReportGui.java,v 1.1 2005/08/12 23:58:48 woolfel Exp $
  /*
   * Copyright 2001-2004 The Apache Software Foundation.
   *
   * Licensed 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.control.gui;
  
  import java.awt.BorderLayout;
  import java.awt.Container;
  import java.util.Collection;
  
  import javax.swing.JCheckBox;
  import javax.swing.JLabel;
  import javax.swing.JMenu;
  import javax.swing.JPanel;
  import javax.swing.JPopupMenu;
  import javax.swing.JTextArea;
  
  import org.apache.jmeter.config.Arguments;
  import org.apache.jmeter.config.gui.ArgumentsPanel;
  import org.apache.jmeter.gui.AbstractJMeterGuiComponent;
  import org.apache.jmeter.gui.util.MenuFactory;
  import org.apache.jmeter.gui.util.VerticalPanel;
  import org.apache.jmeter.testelement.AbstractTestElement;
  import org.apache.jmeter.testelement.TestElement;
  import org.apache.jmeter.testelement.ReportPlan;
  import org.apache.jmeter.threads.gui.ThreadGroupGui;
  import org.apache.jmeter.util.JMeterUtils;
  
  /**
   * JMeter GUI component representing the test plan which will be executed when
   * the test is run.
   * 
   * @version $Revision: 1.1 $ Last Updated: $Date: 2005/08/12 23:58:48 $
   */
  public class ReportGui extends AbstractJMeterGuiComponent {
  
  	private JCheckBox serializedMode;
  
  	/** A panel allowing the user to define variables. */
  	private ArgumentsPanel argsPanel;
  
  	/** A panel to contain comments on the test plan. */
  	private JTextArea commentPanel;
  
  	/**
  	 * Create a new TestPlanGui.
  	 */
  	public ReportGui() {
  		init();
  	}
  
  	/**
  	 * 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>
  	 * The TestPlan will return a popup menu allowing you to add ThreadGroups,
  	 * Listeners, Configuration Elements, Assertions, PreProcessors,
  	 * PostProcessors, and Timers.
  	 * 
  	 * @return a JPopupMenu appropriate for the component.
  	 */
  	public JPopupMenu createPopupMenu() {
  		JPopupMenu pop = new JPopupMenu();
  		JMenu addMenu = new JMenu(JMeterUtils.getResString("Add"));
  		addMenu.add(MenuFactory.makeMenuItem(new ThreadGroupGui().getStaticLabel(), ThreadGroupGui.class.getName(),
  				"Add"));
  		addMenu.add(MenuFactory.makeMenu(MenuFactory.LISTENERS, "Add"));
  		addMenu.add(MenuFactory.makeMenu(MenuFactory.CONFIG_ELEMENTS, "Add"));
  		pop.add(addMenu);
  		MenuFactory.addFileMenu(pop);
  		return pop;
  	}
  
  	/* Implements JMeterGUIComponent.createTestElement() */
  	public TestElement createTestElement() {
  		ReportPlan tp = new ReportPlan();
  		modifyTestElement(tp);
  		return tp;
  	}
  
  	/* Implements JMeterGUIComponent.modifyTestElement(TestElement) */
  	public void modifyTestElement(TestElement plan) {
  		super.configureTestElement(plan);
  		if (plan instanceof ReportPlan) {
  			ReportPlan tp = (ReportPlan) plan;
  			tp.setSerialized(serializedMode.isSelected());
  			tp.setUserDefinedVariables((Arguments) argsPanel.createTestElement());
  			tp.setProperty(ReportPlan.COMMENTS, commentPanel.getText());
  		}
  	}
  
  	public String getLabelResource() {
  		return "test_plan";
  	}
  
  	/**
  	 * This is the list of menu categories this gui component will be available
  	 * under. This implementation returns null, since the TestPlan appears at
  	 * the top level of the tree and cannot be added elsewhere.
  	 * 
  	 * @return a Collection of Strings, where each element is one of the
  	 *         constants defined in MenuFactory
  	 */
  	public Collection getMenuCategories() {
  		return null;
  	}
  
  	/**
  	 * A newly created component can be initialized with the contents of a Test
  	 * Element object by calling this method. The component is responsible for
  	 * querying the Test Element object for the relevant information to display
  	 * in its GUI.
  	 * 
  	 * @param el
  	 *            the TestElement to configure
  	 */
  	public void configure(TestElement el) {
  		super.configure(el);
  
  		serializedMode.setSelected(((AbstractTestElement) el).getPropertyAsBoolean(ReportPlan.SERIALIZE_THREADGROUPS));
  
  		if (el.getProperty(ReportPlan.USER_DEFINED_VARIABLES) != null) {
  			argsPanel.configure((Arguments) el.getProperty(ReportPlan.USER_DEFINED_VARIABLES).getObjectValue());
  		}
  		commentPanel.setText(el.getPropertyAsString(ReportPlan.COMMENTS));
  	}
  
  	/**
  	 * Create a panel allowing the user to define variables for the test.
  	 * 
  	 * @return a panel for user-defined variables
  	 */
  	private JPanel createVariablePanel() {
  		argsPanel = new ArgumentsPanel(JMeterUtils.getResString("user_defined_variables"));
  
  		return argsPanel;
  	}
  
  	private Container createCommentPanel() {
  		Container panel = makeTitlePanel();
  		commentPanel = new JTextArea();
  		JLabel label = new JLabel(JMeterUtils.getResString("testplan_comments"));
  		label.setLabelFor(commentPanel);
  		panel.add(label);
  		panel.add(commentPanel);
  		return panel;
  	}
  
  	/**
  	 * Initialize the components and layout of this component.
  	 */
  	private void init() {
  		setLayout(new BorderLayout(10, 10));
  		setBorder(makeBorder());
  
  		add(createCommentPanel(), BorderLayout.NORTH);
  
  		add(createVariablePanel(), BorderLayout.CENTER);
  
  		VerticalPanel southPanel = new VerticalPanel();
  		serializedMode = new JCheckBox(JMeterUtils.getResString("testplan.serialized"));
  		southPanel.add(serializedMode);
  		JTextArea explain = new JTextArea(JMeterUtils.getResString("functional_mode_explanation"));
  		explain.setEditable(false);
  		explain.setBackground(this.getBackground());
  		southPanel.add(explain);
  
  		add(southPanel, BorderLayout.SOUTH);
  	}
  }
  
  
  
  1.1                  jakarta-jmeter/src/reports/org/apache/jmeter/testelement/ReportPlan.java
  
  Index: ReportPlan.java
  ===================================================================
  /*
   * Copyright 2005 The Apache Software Foundation.
   *
   * Licensed 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.testelement;
  
  import java.io.IOException;
  import java.io.Serializable;
  import java.util.Collection;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Map;
  
  import org.apache.jmeter.config.Arguments;
  import org.apache.jmeter.config.ConfigElement;
  import org.apache.jmeter.engine.event.LoopIterationEvent;
  import org.apache.jmeter.services.FileServer;
  import org.apache.jmeter.testelement.property.BooleanProperty;
  import org.apache.jmeter.testelement.property.CollectionProperty;
  import org.apache.jmeter.testelement.property.StringProperty;
  import org.apache.jmeter.testelement.property.TestElementProperty;
  import org.apache.jmeter.threads.ThreadGroup;
  import org.apache.jmeter.util.JMeterUtils;
  import org.apache.jorphan.logging.LoggingManager;
  import org.apache.log.Logger;
  
  /**
   * @author Peter Lin created 8/11
   * @version $Revision: 1.1 $ Last updated: $Date: 2005/08/12 23:58:48 $
   */
  public class ReportPlan extends AbstractTestElement implements Serializable, TestListener {
  	private static Logger log = LoggingManager.getLoggerForClass();
  
  	public final static String THREAD_GROUPS = "ReportPlan.thread_groups";
  
  	public final static String FUNCTIONAL_MODE = "ReportPlan.functional_mode";
  
  	public final static String USER_DEFINED_VARIABLES = "ReportPlan.user_defined_variables";
  
  	public final static String SERIALIZE_THREADGROUPS = "ReportPlan.serialize_threadgroups";
  
  	public final static String COMMENTS = "ReportPlan.comments";
  
  	public final static String BASEDIR = "basedir";
  
  	private transient List threadGroups = new LinkedList();
  
  	private transient List configs = new LinkedList();
  
  	private static List itemsCanAdd = new LinkedList();
  
  	private static ReportPlan plan;
  
  	// There's only 1 test plan, so can cache the mode here
  	private static boolean functionalMode = false;
  
  	static {
  		// WARNING! This String value must be identical to the String value
  		// returned in org.apache.jmeter.threads.ThreadGroup.getClassLabel()
  		// method. If it's not you will not be able to add a Thread Group
  		// element to a Test Plan.
  		itemsCanAdd.add(JMeterUtils.getResString("threadgroup"));
  	}
  
  	public ReportPlan() {
  		// this("Test Plan");
  		// setFunctionalMode(false);
  		// setSerialized(false);
  	}
  
  	public ReportPlan(String name) {
  		setName(name);
  		// setFunctionalMode(false);
  		// setSerialized(false);
  		setProperty(new CollectionProperty(THREAD_GROUPS, threadGroups));
  	}
  
  	/**
  	 * Fetches the functional mode property
  	 * 
  	 * @return functional mode
  	 */
  	public boolean isFunctionalMode() {
  		return getPropertyAsBoolean(FUNCTIONAL_MODE);
  	}
  
  	public void setUserDefinedVariables(Arguments vars) {
  		setProperty(new TestElementProperty(USER_DEFINED_VARIABLES, vars));
  	}
  
  	public String getBasedir() {
  		return getPropertyAsString(BASEDIR);
  	}
  
  	public void setBasedir(String b) {
  		setProperty(BASEDIR, b);
  	}
  
  	public Map getUserDefinedVariables() {
  		Arguments args = getVariables();
  		return args.getArgumentsAsMap();
  	}
  
  	private Arguments getVariables() {
  		Arguments args = (Arguments) getProperty(USER_DEFINED_VARIABLES).getObjectValue();
  		if (args == null) {
  			args = new Arguments();
  			setUserDefinedVariables(args);
  		}
  		return args;
  	}
  
  	public void setFunctionalMode(boolean funcMode) {
  		setProperty(new BooleanProperty(FUNCTIONAL_MODE, funcMode));
  		functionalMode = funcMode;
  	}
  
  	/**
  	 * Gets the static copy of the functional mode
  	 * 
  	 * @return mode
  	 */
  	public static boolean getFunctionalMode() {
  		return functionalMode;
  	}
  
  	public void setSerialized(boolean serializeTGs) {
  		setProperty(new BooleanProperty(SERIALIZE_THREADGROUPS, serializeTGs));
  	}
  
  	/**
  	 * Fetch the serialize threadgroups property
  	 * 
  	 * @return serialized setting
  	 */
  	public boolean isSerialized() {
  		return getPropertyAsBoolean(SERIALIZE_THREADGROUPS);
  	}
  
  	public void addParameter(String name, String value) {
  		getVariables().addArgument(name, value);
  	}
  
  	public static ReportPlan createTestPlan(String name) {
  		if (plan == null) {
  			if (name == null) {
  				plan = new ReportPlan();
  			} else {
  				plan = new ReportPlan(name);
  			}
  			plan.setProperty(new StringProperty(TestElement.GUI_CLASS, "org.apache.jmeter.control.gui.TestPlanGui"));
  		}
  		return plan;
  	}
  
  	public void addTestElement(TestElement tg) {
  		super.addTestElement(tg);
  		if (tg instanceof ThreadGroup && !isRunningVersion()) {
  			addThreadGroup((ThreadGroup) tg);
  		}
  	}
  
  	public void addJMeterComponent(TestElement child) {
  		if (child instanceof ThreadGroup) {
  			addThreadGroup((ThreadGroup) child);
  		}
  	}
  
  	/**
  	 * Gets the ThreadGroups attribute of the TestPlan object.
  	 * 
  	 * @return the ThreadGroups value
  	 */
  	public Collection getThreadGroups() {
  		return threadGroups;
  	}
  
  	/**
  	 * Adds a feature to the ConfigElement attribute of the TestPlan object.
  	 * 
  	 * @param c
  	 *            the feature to be added to the ConfigElement attribute
  	 */
  	public void addConfigElement(ConfigElement c) {
  		configs.add(c);
  	}
  
  	/**
  	 * Adds a feature to the ThreadGroup attribute of the TestPlan object.
  	 * 
  	 * @param group
  	 *            the feature to be added to the ThreadGroup attribute
  	 */
  	public void addThreadGroup(ThreadGroup group) {
  		threadGroups.add(group);
  	}
  
  	/*
  	 * (non-Javadoc)
  	 * 
  	 * @see org.apache.jmeter.testelement.TestListener#testEnded()
  	 */
  	public void testEnded() {
  		try {
  			FileServer.getFileServer().closeFiles();
  		} catch (IOException e) {
  			log.error("Problem closing files at end of test", e);
  		}
  	}
  
  	/*
  	 * (non-Javadoc)
  	 * 
  	 * @see org.apache.jmeter.testelement.TestListener#testEnded(java.lang.String)
  	 */
  	public void testEnded(String host) {
  		testEnded();
  
  	}
  
  	/*
  	 * (non-Javadoc)
  	 * 
  	 * @see org.apache.jmeter.testelement.TestListener#testIterationStart(org.apache.jmeter.engine.event.LoopIterationEvent)
  	 */
  	public void testIterationStart(LoopIterationEvent event) {
  	}
  
  	/*
  	 * (non-Javadoc)
  	 * 
  	 * @see org.apache.jmeter.testelement.TestListener#testStarted()
  	 */
  	public void testStarted() {
  		if (getBasedir() != null && getBasedir().length() > 0) {
  			try {
  				FileServer.getFileServer().setBasedir(FileServer.getFileServer().getBaseDir() + getBasedir());
  			} catch (IOException e) {
  				log.error("Failed to set file server base dir with " + getBasedir(), e);
  			}
  		}
  	}
  
  	/*
  	 * (non-Javadoc)
  	 * 
  	 * @see org.apache.jmeter.testelement.TestListener#testStarted(java.lang.String)
  	 */
  	public void testStarted(String host) {
  		testStarted();
  	}
  }
  
  
  
  1.1                  jakarta-jmeter/src/reports/org/apache/jmeter/gui/tree/ReportTreeModel.java
  
  Index: ReportTreeModel.java
  ===================================================================
  // $Header: /home/cvs/jakarta-jmeter/src/reports/org/apache/jmeter/gui/tree/ReportTreeModel.java,v 1.1 2005/08/12 23:58:48 woolfel Exp $
  /*
   * Copyright 2001-2005 The Apache Software Foundation.
   *
   * Licensed 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.gui.tree;
  
  import java.util.Enumeration;
  import java.util.Iterator;
  import java.util.LinkedList;
  import java.util.List;
  
  import javax.swing.tree.DefaultTreeModel;
  
  import org.apache.jmeter.config.gui.AbstractConfigGui;
  import org.apache.jmeter.control.gui.TestPlanGui;
  import org.apache.jmeter.control.gui.ReportGui;
  import org.apache.jmeter.exceptions.IllegalUserActionException;
  import org.apache.jmeter.gui.GuiPackage;
  import org.apache.jmeter.gui.JMeterGUIComponent;
  import org.apache.jmeter.testelement.TestElement;
  import org.apache.jmeter.testelement.ReportPlan;
  import org.apache.jmeter.testelement.WorkBench;
  import org.apache.jmeter.testelement.property.NullProperty;
  import org.apache.jmeter.util.NameUpdater;
  import org.apache.jorphan.collections.HashTree;
  import org.apache.jorphan.collections.ListedHashTree;
  
  /**
   * 
   * author Michael Stover
   * 
   * @version $Revision: 1.1 $
   */
  public class ReportTreeModel extends DefaultTreeModel {
  
  	public ReportTreeModel() {
  		super(new ReportTreeNode(new ReportGui().createTestElement(), null));
  		initTree();
  	}
  
  	/**
  	 * Returns a list of tree nodes that hold objects of the given class type.
  	 * If none are found, an empty list is returned.
  	 */
  	public List getNodesOfType(Class type) {
  		List nodeList = new LinkedList();
  		traverseAndFind(type, (ReportTreeNode) this.getRoot(), nodeList);
  		return nodeList;
  	}
  
  	/**
  	 * Get the node for a given TestElement object.
  	 */
  	public ReportTreeNode getNodeOf(TestElement userObject) {
  		return traverseAndFind(userObject, (ReportTreeNode) getRoot());
  	}
  
  	/**
  	 * Adds the sub tree at the given node. Returns a boolean indicating whether
  	 * the added sub tree was a full test plan.
  	 */
  	public HashTree addSubTree(HashTree subTree, ReportTreeNode current) throws IllegalUserActionException {
  		Iterator iter = subTree.list().iterator();
  		while (iter.hasNext()) {
  			TestElement item = (TestElement) iter.next();
  			if (item instanceof ReportPlan) {
  				current = (ReportTreeNode) ((ReportTreeNode) getRoot()).getChildAt(0);
  				((TestElement) current.getUserObject()).addTestElement(item);
  				((ReportPlan) current.getUserObject()).setName(item.getPropertyAsString(TestElement.NAME));
  				((ReportPlan) current.getUserObject()).setFunctionalMode(item
  						.getPropertyAsBoolean(ReportPlan.FUNCTIONAL_MODE));
  				((ReportPlan) current.getUserObject()).setSerialized(item
  						.getPropertyAsBoolean(ReportPlan.SERIALIZE_THREADGROUPS));
  				addSubTree(subTree.getTree(item), current);
  			} else {
  				addSubTree(subTree.getTree(item), addComponent(item, current));
  			}
  		}
  		return getCurrentSubTree(current);
  	}
  
  	public ReportTreeNode addComponent(TestElement component, ReportTreeNode node) throws IllegalUserActionException {
  		if (node.getUserObject() instanceof AbstractConfigGui) {
  			throw new IllegalUserActionException("This node cannot hold sub-elements");
  		}
  		component.setProperty(TestElement.GUI_CLASS, NameUpdater.getCurrentName(component
  				.getPropertyAsString(TestElement.GUI_CLASS)));
  		GuiPackage.getInstance().updateCurrentNode();
  		JMeterGUIComponent guicomp = GuiPackage.getInstance().getGui(component);
  		guicomp.configure(component);
  		guicomp.modifyTestElement(component);
  		GuiPackage.getInstance().getCurrentGui(); // put the gui object back
  													// to the way it was.
  		ReportTreeNode newNode = new ReportTreeNode(component, this);
  
  		// This check the state of the TestElement and if returns false it
  		// disable the loaded node
  		try {
  			if (component.getProperty(TestElement.ENABLED) instanceof NullProperty
  					|| component.getPropertyAsBoolean(TestElement.ENABLED)) {
  				newNode.setEnabled(true);
  			} else {
  				newNode.setEnabled(false);
  			}
  		} catch (Exception e) {
  			newNode.setEnabled(true);
  		}
  
  		this.insertNodeInto(newNode, node, node.getChildCount());
  		return newNode;
  	}
  
  	public void removeNodeFromParent(JMeterTreeNode node) {
  		if (!(node.getUserObject() instanceof ReportPlan) && !(node.getUserObject() instanceof WorkBench)) {
  			super.removeNodeFromParent(node);
  		}
  	}
  
  	private void traverseAndFind(Class type, ReportTreeNode node, List nodeList) {
  		if (type.isInstance(node.getUserObject())) {
  			nodeList.add(node);
  		}
  		Enumeration enumNode = node.children();
  		while (enumNode.hasMoreElements()) {
  			ReportTreeNode child = (ReportTreeNode) enumNode.nextElement();
  			traverseAndFind(type, child, nodeList);
  		}
  	}
  
  	private ReportTreeNode traverseAndFind(TestElement userObject, ReportTreeNode node) {
  		if (userObject == node.getUserObject()) {
  			return node;
  		}
  		Enumeration enumNode = node.children();
  		while (enumNode.hasMoreElements()) {
  			ReportTreeNode child = (ReportTreeNode) enumNode.nextElement();
  			ReportTreeNode result = traverseAndFind(userObject, child);
  			if (result != null)
  				return result;
  		}
  		return null;
  	}
  
  	public HashTree getCurrentSubTree(ReportTreeNode node) {
  		ListedHashTree hashTree = new ListedHashTree(node);
  		Enumeration enumNode = node.children();
  		while (enumNode.hasMoreElements()) {
  			ReportTreeNode child = (ReportTreeNode) enumNode.nextElement();
  			hashTree.add(node, getCurrentSubTree(child));
  		}
  		return hashTree;
  	}
  
  	public HashTree getTestPlan() {
  		return getCurrentSubTree((ReportTreeNode) ((ReportTreeNode) this.getRoot()).getChildAt(0));
  	}
  
  	public void clearTestPlan() {
  		super.removeNodeFromParent((ReportTreeNode) getChild(getRoot(), 0));
  		initTree();
  	}
  
  	private void initTree() {
  		TestElement tp = new TestPlanGui().createTestElement();
  		TestElement wb = new ReportGui().createTestElement();
  		this.insertNodeInto(new ReportTreeNode(tp, this), (ReportTreeNode) getRoot(), 0);
  		try {
  			super.removeNodeFromParent((ReportTreeNode) getChild(getRoot(), 1));
  		} catch (RuntimeException e) {
  		}
  		this.insertNodeInto(new ReportTreeNode(wb, this), (ReportTreeNode) getRoot(), 1);
  	}
  }
  
  
  
  1.1                  jakarta-jmeter/src/reports/org/apache/jmeter/gui/tree/ReportTreeNode.java
  
  Index: ReportTreeNode.java
  ===================================================================
  // $Header: /home/cvs/jakarta-jmeter/src/reports/org/apache/jmeter/gui/tree/ReportTreeNode.java,v 1.1 2005/08/12 23:58:48 woolfel Exp $
  /*
   * Copyright 2002-2004 The Apache Software Foundation.
   *
   * Licensed 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.gui.tree;
  
  import java.awt.Image;
  import java.beans.BeanInfo;
  import java.beans.IntrospectionException;
  import java.beans.Introspector;
  import java.util.Collection;
  
  import javax.swing.ImageIcon;
  import javax.swing.JPopupMenu;
  import javax.swing.tree.DefaultMutableTreeNode;
  
  import org.apache.jmeter.gui.GUIFactory;
  import org.apache.jmeter.gui.GuiPackage;
  import org.apache.jmeter.testbeans.TestBean;
  import org.apache.jmeter.testelement.AbstractTestElement;
  import org.apache.jmeter.testelement.TestElement;
  import org.apache.jmeter.testelement.property.BooleanProperty;
  import org.apache.jmeter.testelement.property.StringProperty;
  import org.apache.jorphan.logging.LoggingManager;
  import org.apache.log.Logger;
  
  /**
   * @author Michael Stover
   * @version $Revision: 1.1 $
   */
  public class ReportTreeNode extends DefaultMutableTreeNode {
  	transient private static Logger log = LoggingManager.getLoggerForClass();
  
  	private ReportTreeModel treeModel;
  
  	// boolean enabled = true;
  
  	public ReportTreeNode() {// Allow serializable test to work
  		// TODO: is the serializable test necessary now that JMeterTreeNode is
  		// no longer a GUI component?
  		this(null, null);
  	}
  
  	public ReportTreeNode(TestElement userObj, ReportTreeModel treeModel) {
  		super(userObj);
  		this.treeModel = treeModel;
  	}
  
  	public boolean isEnabled() {
  		return ((AbstractTestElement) getTestElement()).getPropertyAsBoolean(TestElement.ENABLED);
  	}
  
  	public void setEnabled(boolean enabled) {
  		getTestElement().setProperty(new BooleanProperty(TestElement.ENABLED, enabled));
  		treeModel.nodeChanged(this);
  	}
  
  	public ImageIcon getIcon() {
  		return getIcon(true);
  	}
  
  	public ImageIcon getIcon(boolean enabled) {
  		try {
  			if (getTestElement() instanceof TestBean) {
  				try {
  					Image img = Introspector.getBeanInfo(getTestElement().getClass())
  							.getIcon(BeanInfo.ICON_COLOR_16x16);
  					// If icon has not been defined, then use GUI_CLASS property
  					if (img == null) {//
  						Object clazz = Introspector.getBeanInfo(getTestElement().getClass()).getBeanDescriptor()
  								.getValue(TestElement.GUI_CLASS);
  						if (clazz == null) {
  							log.error("Can't obtain GUI class for " + getTestElement().getClass().getName());
  							return null;
  						}
  						return GUIFactory.getIcon(Class.forName((String) clazz), enabled);
  					}
  					return new ImageIcon(img);
  				} catch (IntrospectionException e1) {
  					log.error("Can't obtain icon", e1);
  					throw new org.apache.jorphan.util.JMeterError(e1);
  				}
  			} else {
  				return GUIFactory.getIcon(Class.forName(getTestElement().getPropertyAsString(TestElement.GUI_CLASS)),
  						enabled);
  			}
  		} catch (ClassNotFoundException e) {
  			log.warn("Can't get icon for class " + getTestElement(), e);
  			return null;
  		}
  	}
  
  	public Collection getMenuCategories() {
  		try {
  			return GuiPackage.getInstance().getGui(getTestElement()).getMenuCategories();
  		} catch (Exception e) {
  			log.error("Can't get popup menu for gui", e);
  			return null;
  		}
  	}
  
  	public JPopupMenu createPopupMenu() {
  		try {
  			return GuiPackage.getInstance().getGui(getTestElement()).createPopupMenu();
  		} catch (Exception e) {
  			log.error("Can't get popup menu for gui", e);
  			return null;
  		}
  	}
  
  	public TestElement getTestElement() {
  		return (TestElement) getUserObject();
  	}
  
  	public String getStaticLabel() {
  		return GuiPackage.getInstance().getGui((TestElement) getUserObject()).getStaticLabel();
  	}
  
  	public String getDocAnchor() {
  		return GuiPackage.getInstance().getGui((TestElement) getUserObject()).getDocAnchor();
  	}
  
  	public void setName(String name) {
  		((TestElement) getUserObject()).setProperty(new StringProperty(TestElement.NAME, name));
  	}
  
  	public String getName() {
  		return ((TestElement) getUserObject()).getPropertyAsString(TestElement.NAME);
  	}
  
  	public void nameChanged() {
  		treeModel.nodeChanged(this);
  	}
  }
  
  
  
  1.1                  jakarta-jmeter/src/reports/org/apache/jmeter/report/writers/gui/AbstractReportWriterGui.java
  
  Index: AbstractReportWriterGui.java
  ===================================================================
  // $Header: /home/cvs/jakarta-jmeter/src/reports/org/apache/jmeter/report/writers/gui/AbstractReportWriterGui.java,v 1.1 2005/08/12 23:58:48 woolfel Exp $
  /*
   * Copyright 2003-2004 The Apache Software Foundation.
   *
   * Licensed 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.report.writers.gui;
  
  import java.util.Arrays;
  import java.util.Collection;
  
  import javax.swing.JPopupMenu;
  
  import org.apache.jmeter.gui.AbstractJMeterGuiComponent;
  import org.apache.jmeter.gui.util.MenuFactory;
  
  /**
   * This is the base class for JMeter GUI components which manage timers.
   * 
   * @author Michael Stover
   * @version $Revision: 1.1 $
   */
  public abstract class AbstractReportWriterGui extends AbstractJMeterGuiComponent {
  	/**
  	 * 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 timer
  	 * components.
  	 * 
  	 * @return a JPopupMenu appropriate for the component.
  	 */
  	public JPopupMenu createPopupMenu() {
  		return MenuFactory.getDefaultTimerMenu();
  	}
  
  	/**
  	 * This is the list of menu categories this gui component will be available
  	 * under. This implementation returns
  	 * {@link org.apache.jmeter.gui.util.MenuFactory#TIMERS}, which is
  	 * appropriate for most timer 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.TIMERS });
  	}
  }
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: jmeter-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jmeter-dev-help@jakarta.apache.org