Package qat.gui

Source Code of qat.gui.QAT

package qat.gui;

/**
*
* @author webhiker
* @version 2.3, 17 June 1999
*/

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.net.InetAddress;
import java.net.URL;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.BevelBorder;
import javax.swing.event.ChangeListener;

import qat.common.Common;
import qat.common.ProtocolConstants;
import qat.common.Resources;
import qat.common.SwingUtils;
import qat.common.Utils;
import qat.components.Gauge;
import qat.components.StatusWindow;
import qat.parser.ParserInterface;

//import Agent;

/**
* This class is the main object of the GUI for the test harness. All other gui objects are used by
* or contained in this object.
*
* @author webhiker
* @version %W %E
*/
public class QAT extends JFrame implements QATInterface, ActionListener, WindowListener {
  /**
   *
   */
  private static final long serialVersionUID = 9148287993064840709L;
  public  KeywordComponent keywordComponent;
  private JLabel statusLabel, parserLabel;
  private String serializedTreeName;
  private Properties projectProperties;
  private Cursor waitCursor=null, defaultCursor=null;
  private Gauge statusGauge;
  private TestTree testTree;
  private ParserOutputViewer parserOutputViewer; 
  private TestDetailViewer testDetailViewer; 
  private TestRunner testRunner;
  private TimerRunner timerRunner;
  private JToolBar toolbar;
  private JMenuBar menuBar;
  private JMenu consoleMenu, pluginMenu;
  private Hashtable<String, PluginInterface> pluginList;
  private HttpQATHandler httpQATHandler;
  private String projectFileName;
  // instanceSuffix is used to to allow each new instance of QAT to use
  // it's own property settings
  private String instanceSuffix;
  private static ArrayList<QAT> instanceList;
  private static Properties sessionProperties;
  private JSplitPane leftrightSplit, topbottomSplit;

  // the internal frame components
  RuntimeComponent runtimeComponent;

  static {
    setSessionProperties(new Properties());
    instanceList = new ArrayList<QAT>();
  }

  /*
   * This constructs a new Qat instance.
   * Passing visible as false indicates we are starting a commandline
   * version, and no GUI components will be set tot visible.
   */
  public QAT(boolean visible) {
    super();   
    // this section ensure we can run multiple instance of the QAT
    // harness in the same JVM
    instanceList.add(this);
    if (instanceList.size()==1) {
      instanceSuffix = "";
    }
    else {
      instanceSuffix = Integer.toString(instanceList.size());
    }

    SplashScreen splash = new SplashScreen(this, new ImageIcon(Resources.getImageResource("splashImage")),Resources.getString("pleaseWait"));
    if (visible)
      splash.showSplash();
    pluginList = new Hashtable<String, PluginInterface>();
    splash.setText(Resources.getString("pleaseWait"),10);
    setTitle(Resources.getString("pleaseWait"));
    setIconImage(new ImageIcon(Resources.getImageResource("sunLogo")).getImage());
    testRunner = new TestRunner(this);
    timerRunner = new TimerRunner(this,testRunner);
    getContentPane().setLayout(new BorderLayout());
    splash.setText(Resources.getString("splashText1"),17);
    addMenuBar();
    splash.setText(Resources.getString("splashText2"),24);
    addToolBar();
    splash.setText(Resources.getString("splashText3"),31);
    addCenterPanel(splash);
    splash.setText(Resources.getString("splashText9"),73);
    addStatusBar();
    splash.setText(Resources.getString("splashText10"),80);
    pack();
    splash.setText(Resources.getString("splashText11"),87);
    loadSession();

    setTitle(Resources.getString("title")+" "+Common.VERSION+" "+projectFileName);
    addWindowListener(this);

    validate();
    splash.setText(Resources.getString("pleaseWait"),94);
    leftrightSplit.setDividerLocation(0.25);
    setVisible(visible);
    splash.setText(Resources.getString("pleaseWait"),98);

    splash.setText(Resources.getString("splashText12"),100);
    String httpPortNumber = getProperty(Common.HTTP_PORT_KEY,
        Common.HTTP_PORT_DEFAULT);
    httpQATHandler = new HttpQATHandler(httpPortNumber, this);
    httpQATHandler.start();

    splash.hideSplash();
    splash.dispose();     
  }

  /**
   * This is the normal constructor for launching the QAT gui.
   */
  public QAT() {
    this(true);
  }

  private void saveFrameState(JFrame f, String key) {
    // charge Properties with frame size & position
    setSessionProperty(key+"Height",Integer.toString(f.getSize().height));
    setSessionProperty(key+"Width",Integer.toString(f.getSize().width));
    setSessionProperty(key+"X",Integer.toString((int)f.getLocation().getX()));
    setSessionProperty(key+"Y",Integer.toString((int)f.getLocation().getY()));
  }

  private JFrame loadFrameState(JFrame f, String key) {
    if (getSessionProperty(key+"X","")=="") {
      f.pack();
      f.setSize(640,480);
    }
    else {
      // adjust screen position
      Point location;
      location = new Point(new Integer(getSessionProperty(key+"X")).intValue(),
          new Integer(getSessionProperty(key+"Y")).intValue());
      f.setLocation(location);
      Dimension d;
      d = new Dimension(new Integer(getSessionProperty(key+"Width")).intValue(),
          new Integer(getSessionProperty(key+"Height")).intValue());
      f.setSize(d);
    }
    return f;
  }

  /**
   * Retrieve info about last session from the specified file name.
   */
  private void loadSession(String fileName) {
    try {
      FileInputStream in = new FileInputStream(new File(fileName));
      Utils.touch(fileName);
      getSessionProperties().load(in);
      in.close();
      // adjust screen position and size to last saved settings
      loadFrameState((JFrame)this,"Screen");
      // load plugins if any are configured
    }
    catch (Exception e) {
      showError("Problem loading session.properties :"+e.getMessage(),
          Resources.getString("error"),
          JOptionPane.ERROR_MESSAGE);
    }
    try {
      // load default project
      loadProject(getSessionProperty(Common.PROJECT_PROPERTYNAME_KEY, Common.getHarnessBaseDirectory()+
          File.separator+
          Utils.ensureSuffix(Common.DEFAULT_PROJECTNAME,Common.PROJECT_FILE_SUFFIX)));
    }
    catch (Exception e) {
      showError("Problem loading project :"+e.getMessage(),
          Resources.getString("error"),
          JOptionPane.ERROR_MESSAGE);
    }
  }

  /**
   * Retrieve info about last session.
   */
  private void loadSession() {
    String fileName = Common.getHarnessBaseDirectory()+File.separator+Common.SESSION_FILE_NAME;
    loadSession(fileName);
  }

  /**
   * Saves info about last project in use, screen size etc.
   */
  private void saveSession() {
    try {
      // charge session Properties with current screen size & position
      saveFrameState(this,"Screen");     
      String fileName = Common.getHarnessBaseDirectory()+File.separator+Common.SESSION_FILE_NAME;
      Utils.touch(fileName);
      FileOutputStream in = new FileOutputStream(new File(fileName));
      getSessionProperties().store(in,Common.SESSION_FILE_NAME);
      in.flush();
      in.close();
    }
    catch (Exception e) {
      showError("Problem saving session.properties :"+e.getMessage(),
          Resources.getString("error"),
          JOptionPane.ERROR_MESSAGE);
    }
  }

  /**
   * Prompt the user for a new properties file to load.
   */
  private void loadProject() {
    JFileChooser projectFile = new JFileChooser(projectFileName);
    projectFile.setFileHidingEnabled(false);
    projectFile.setDialogTitle(Resources.getString("selectProject"));
    ExtensionFileFilter filter = new ExtensionFileFilter(Common.PROJECT_FILE_SUFFIX,"Project files");
    projectFile.addChoosableFileFilter(filter);
    projectFile.setFileFilter(filter);
    try {
      if (projectFile.showOpenDialog(this)==JFileChooser.APPROVE_OPTION) {
        loadProject(projectFile.getSelectedFile().getCanonicalPath());
      }
    }
    catch (java.io.IOException e) {
      showError(Resources.getString("unexpectedError")+e.getMessage(),
          Resources.getString("error"),
          JOptionPane.ERROR_MESSAGE);
    }
  }

  /**
   * Loads the project named in fileName.
   */
  public void loadProject(String fileName) throws IOException {
    setProjectProperties(new Properties());
    projectFileName = fileName;
    File f = new File(projectFileName);
    if (f.exists()) {
      BufferedInputStream in;
      getProjectProperties().load(in = new BufferedInputStream(new FileInputStream(f)));

      in.close();
      keywordComponent.loadKeyWordHistFromProperties(projectProperties);

      // check if we need to load a new look and feel
      // for this project session
      try {
        String defaultLF = UIManager.getLookAndFeel().getClass().getName();
        if (!getProperty(Common.LOOK_AND_FEEL_KEY,
            defaultLF).equals(defaultLF)) {
          try {
            UIManager.setLookAndFeel(getProperty(Common.LOOK_AND_FEEL_KEY,
                defaultLF));
            SwingUtilities.updateComponentTreeUI(this);
          }
          catch (Throwable t) {
            JOptionPane.showMessageDialog(this,
                t.toString(),
                Resources.getString("error"),
                JOptionPane.ERROR_MESSAGE);
          }
        }
      }
      catch (Exception ex) {
        ex.printStackTrace();
      }
    }
    // load previous tree
    serializedTreeName = Utils.ensureSuffix(projectFileName,Common.SERIALIZED_TREE_EXTENSION);
    loadTree(serializedTreeName);

    // push the current projectProperties onto the (possibly) new testTree
    testTree.setParentQAT(this);
  }

  /**
   * This method creates a new, blank project using the name default.prj.
   */
  private void newProject() {
    clearProjectProperties();
    clearSessionProperties();
    setSessionProperty(Common.PROJECT_PROPERTYNAME_KEY,
        Common.getHarnessBaseDirectory()+
        File.separator+
        Utils.ensureSuffix(Common.DEFAULT_PROJECTNAME,Common.PROJECT_FILE_SUFFIX));
    projectFileName = getSessionProperty(Common.PROJECT_PROPERTYNAME_KEY);

    // clear existing tree
    testTree.removeAllNodes();


    // push the current projectProperties onto the (possibly) new testTree
    testTree.setParentQAT(this);
    projectPropertiesChanged();
  }

  private void loadTree(String fileName) {
    try {
      serializedTreeName = fileName;
      File f = new File (serializedTreeName);
      if (f.exists()) {
        BufferedInputStream in = new BufferedInputStream((new FileInputStream(f)));
        // now read the data
        ObjectInputStream serializedObject = new ObjectInputStream(in);                     
        testTree.loadTests(serializedObject);
        keywordComponent.loadTestsKeywords();
        projectPropertiesChanged();
        testTreeChanged();
      }
      else {
        showError(Resources.getString("missingProjectSerFile")+serializedTreeName,
            Resources.getString("error"),
            JOptionPane.ERROR_MESSAGE);
      }
    }
    catch (InvalidClassException ex) {
      showError(Resources.getString("notCompatible"),
          Resources.getString("error"),
          JOptionPane.ERROR_MESSAGE);
      projectPropertiesChanged();
      parseTests();
    }
    catch (StreamCorruptedException x) {
      showError(Resources.getString("corruptedFile"),
          Resources.getString("error"),
          JOptionPane.ERROR_MESSAGE);
      projectPropertiesChanged();
      parseTests();
    }
    catch (Exception e) {
      showError("Sorry, due to new packaging you need to reparse the tests again..",
          Resources.getString("error"),
          JOptionPane.ERROR_MESSAGE);
    }
    finally {
      testTree.repaint();
    }
  }

  private void saveProjectAs() {   
    JFileChooser projectFile = new JFileChooser(projectFileName);
    projectFile.setFileHidingEnabled(false);
    projectFile.setDialogTitle(Resources.getString("selectProjectName"));
    projectFile.setDialogType(JFileChooser.SAVE_DIALOG);
    ExtensionFileFilter filter = new ExtensionFileFilter(Common.PROJECT_FILE_SUFFIX,"Project files");
    projectFile.addChoosableFileFilter(filter);
    projectFile.setFileFilter(filter);
    try {
      if (projectFile.showSaveDialog(this)==JFileChooser.APPROVE_OPTION) {       
        String oldProjectDir = Common.getProjectResultsDirectory(projectFileName);
        projectFileName = Utils.ensureSuffix(projectFile.getSelectedFile().getCanonicalPath(),Common.PROJECT_FILE_SUFFIX);
        saveProject(projectFileName,false);
        // now we need to copy the results if they exist
        StatusWindow waitWindow = new StatusWindow(this,Resources.getString("pleaseWait"),"");
        try {
          SwingUtils.copy(oldProjectDir,Common.getProjectResultsDirectory(projectFileName),waitWindow);
        }
        catch (Exception e) {
          // don't report errors - shouldn't be usefull here
        }
        finally {
          waitWindow.setVisible(false);
        }                   
      }
    }
    catch (java.io.IOException e) {
      showError(Resources.getString("unexpectedError")+e.getMessage(),
          Resources.getString("error"),
          JOptionPane.ERROR_MESSAGE)
    }
    finally {
      projectPropertiesChanged();
    }
  }

  /**
   * This method saves the current projectdisplaying GUI status windows
   * during the save process.
   */
  public void saveProject() {
    saveSession();
    saveProject(projectFileName,false);
  }

  /**
   * This method saves the current project without displaying any GUI status windows
   * during the save process.
   */
  public void saveProject(boolean quiet) {
    saveProject(projectFileName, quiet);
  }

  public void saveProject(String fileName, boolean quiet) {
    StatusWindow waitWindow;
    if (!quiet)
      waitWindow = new StatusWindow(this,
          Resources.getString("pleaseWait"),
          Resources.getString("savingProject")+" :"+fileName);
    else
      waitWindow = null;
    projectFileName = fileName;

    try {
      if (!quiet) waitWindow.setMessage(Resources.getString("projectProperties"));
      // create the file & parent dirs if they don't exist
      Utils.touch(projectFileName);
      // charge with the keyword history properties
      keywordComponent.saveKeyWordHistToProperties(projectProperties);
      // store version information for this properties file
      setProperty(Common.PROPERTIES_VERSION,Common.CURRENT_PROPERTIES_VERSION);

      // save the project.properties file
      BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(projectFileName));
      getProjectProperties().store(out,Common.SERIALIZED_NODE_HEADERV11);
      out.flush();
      out.close();
      // save the tree structure
      if (!quiet) waitWindow.setMessage(Resources.getString("savingTree"));
      saveTree(serializedTreeName);
    }
    catch (Exception e) {
      showError("3:"+Resources.getString("unexpectedError")+e.toString(),
          Resources.getString("error"),
          JOptionPane.ERROR_MESSAGE);
    }
    finally {
      if (!quiet)
        waitWindow.setVisible(false);
      projectPropertiesChanged();
      testTreeChanged();
    }
  }

  private void saveTree(String fileName) {
    try {
      serializedTreeName = fileName;
      Utils.touch(serializedTreeName);
      BufferedOutputStream out_ser = new BufferedOutputStream((new FileOutputStream(fileName)));
      // now write the data
      ObjectOutputStream serializedObject = new ObjectOutputStream(out_ser);
      testTree.saveTests(serializedObject);
      out_ser.flush();
      out_ser.close();
    }
    catch (Exception e) {
      showError("4:"+Resources.getString("unexpectedError")+e.toString(),
          Resources.getString("error"),
          JOptionPane.ERROR_MESSAGE);
   
  }

  /**
   * This method will copy a project.prj and project.ser files, as well as the corresponding results,
   * if they exist.
   * Note : Projects may not be imported/exported across different file systems, due to the fact that
   * the file nodes are file-system specific, and each root of the test tree
   * neccesarily includes/excludes drive-specifier information, depending on the OS.
   */
  private void importProject() {
    JFileChooser projectFile = new JFileChooser(projectFileName);
    projectFile.setFileHidingEnabled(false);
    projectFile.setDialogTitle(Resources.getString("selectProjectName"));
    projectFile.setDialogType(JFileChooser.SAVE_DIALOG);
    projectFile.setApproveButtonText(Resources.getString("importProject"));
    ExtensionFileFilter filter = new ExtensionFileFilter(Common.PROJECT_FILE_SUFFIX,"Project files");
    projectFile.addChoosableFileFilter(filter);
    projectFile.setFileFilter(filter);
    if (projectFile.showSaveDialog(this)==JFileChooser.APPROVE_OPTION) {
      StatusWindow waitWindow = new StatusWindow(this,Resources.getString("pleaseWait"),"");
      try {
        String importProjectName = Utils.removeSuffix(Utils.extractFileName(projectFile.getSelectedFile().getCanonicalPath()));
        String importProjectPath = Utils.extractPath(projectFile.getSelectedFile().getCanonicalPath());
        String importResultsDirectory = importProjectPath+File.separator+Common.RESULTS_DIR_NAME+File.separator+importProjectName;
        String src, dest;
        waitWindow.setMessage("Project file");
        // copy the prj file to our .qat directory
        src=projectFile.getSelectedFile().getCanonicalPath();
        dest=Common.getHarnessBaseDirectory();
        //System.out.println("Copying :"+src+" to :"+dest);
        SwingUtils.copy(src,dest,waitWindow);

        waitWindow.setMessage("Serialiased file");
        // copy the ser file to out .qat directory
        src = Utils.ensureSuffix(projectFile.getSelectedFile().getCanonicalPath(),Common.SERIALIZED_TREE_EXTENSION);
        dest = Common.getHarnessBaseDirectory();
        //System.out.println("Copying :"+src+" to :"+dest);
        SwingUtils.copy(src,dest,waitWindow);

        // copy the results directory to out .qat/harness/results directory
        try {
          waitWindow.setMessage("Results");
          src = importResultsDirectory;
          dest = Common.getHarnessBaseDirectory()+File.separator+Common.RESULTS_DIR_NAME+File.separator+importProjectName;
          //System.out.println("Copying :"+src+" to :"+dest);
          SwingUtils.copy(src,dest,waitWindow);
        }
        catch (IOException e) {
          // don't report, it only means no results directory was found to be copied.
        }

        // load this project
        loadProject(Common.getHarnessBaseDirectory()+File.separator+Utils.ensureSuffix(importProjectName,Common.PROJECT_FILE_SUFFIX));
      }
      catch (Exception e) {
        e.printStackTrace();
      }
      finally {
        waitWindow.setVisible(false);
      }
      projectPropertiesChanged();
    }
  }

  private void exportProject() {
    JFileChooser projectFile = new JFileChooser(projectFileName);
    projectFile.setSelectedFile(new File(getSessionProperty(Common.PROJECT_PROPERTYNAME_KEY,
        Common.getHarnessBaseDirectory()+
        File.separator+
        Utils.ensureSuffix(Common.DEFAULT_PROJECTNAME,Common.PROJECT_FILE_SUFFIX))));
    projectFile.setFileHidingEnabled(false);
    projectFile.setDialogTitle(Resources.getString("selectExportName"));
    projectFile.setDialogType(JFileChooser.SAVE_DIALOG);
    projectFile.setApproveButtonText(Resources.getString("exportProject"));
    ExtensionFileFilter filter = new ExtensionFileFilter(Common.PROJECT_FILE_SUFFIX,"Project files");
    projectFile.addChoosableFileFilter(filter);
    projectFile.setFileFilter(filter);
    if (projectFile.showSaveDialog(this)==JFileChooser.APPROVE_OPTION) {
      // do some sanity checking on what the user selected
      try {
        // check if source==dest, if so exit with error
        if (projectFile.getSelectedFile().getCanonicalPath().equals(getSessionProperty(Common.PROJECT_PROPERTYNAME_KEY,
            Common.getHarnessBaseDirectory()+
            File.separator+
            Utils.ensureSuffix(Common.DEFAULT_PROJECTNAME,Common.PROJECT_FILE_SUFFIX)))) {
          showError(Resources.getString("exportErrorSameDest"),
              Resources.getString("error"),
              JOptionPane.ERROR_MESSAGE);
          return;
        }
        // check if dest already exists
        if ((new File(projectFile.getSelectedFile().getCanonicalPath())).exists()) {
          if (JOptionPane.YES_OPTION!=JOptionPane.showConfirmDialog(this,
              Resources.getString("exportDestExists"))) {
            return;
          }
        }
      }
      catch (IOException e) {
        showError(e.toString(),
            Resources.getString("error"),
            JOptionPane.ERROR_MESSAGE);
      }
      // now copy it
      StatusWindow waitWindow = new StatusWindow(this,Resources.getString("pleaseWait"),"");
      try {
        String exportProjectName = Utils.removeSuffix(Utils.extractFileName(projectFile.getSelectedFile().getCanonicalPath()));
        String exportProjectPath = Utils.extractPath(projectFile.getSelectedFile().getCanonicalPath());
        String exportResultsDirectory = exportProjectPath+File.separator+Common.RESULTS_DIR_NAME+File.separator+exportProjectName;
        String src, dest;

        // copy the prj file to our .qat directory
        src=Common.getHarnessBaseDirectory()+File.separator+Utils.ensureSuffix(Common.getProjectName(projectFileName),Common.PROJECT_FILE_SUFFIX);
        dest=exportProjectPath+File.separator+Utils.ensureSuffix(exportProjectName,Common.PROJECT_FILE_SUFFIX);
        //System.out.println("Copying :"+src+" to :"+dest);
        SwingUtils.copy(src,dest,waitWindow);

        // copy the ser file to out .qat directory
        src=Common.getHarnessBaseDirectory()+File.separator+Utils.ensureSuffix(Common.getProjectName(projectFileName),Common.SERIALIZED_TREE_EXTENSION);
        dest=exportProjectPath+File.separator+Utils.ensureSuffix(exportProjectName,Common.SERIALIZED_TREE_EXTENSION);
        //System.out.println("Copying :"+src+" to :"+dest);
        SwingUtils.copy(src,dest,waitWindow);

        // copy the results directory to out .qat/harness/results directory
        try {
          src = Common.getProjectResultsDirectory(projectFileName);
          dest=exportResultsDirectory;
          Utils.checkSubDirsExist(dest);
          //System.out.println("Copying :"+src+" to :"+dest);
          SwingUtils.copy(src,dest,waitWindow);
        }
        catch (IOException e) {
          // don't report, it only means no results directory was found to be copied.
        }

      }
      catch (Exception e) {
        e.printStackTrace();
      }
      finally {
        waitWindow.setVisible(false);
      }
    }
  }

  public TestTree getTestTree() {
    return testTree;
  }

  public void firePropertiesChanged(Properties properties) {
    projectProperties = properties;
    projectPropertiesChanged();
  }

  private void projectPropertiesChanged() {
    testTree.setDefaultProperties(projectProperties);
    setTitle(Resources.getString("title")+" "+Utils.extractFileName(projectFileName));
    serializedTreeName = Utils.ensureSuffix(projectFileName,Common.SERIALIZED_TREE_EXTENSION);
    setSessionProperty(Common.PROJECT_PROPERTYNAME_KEY,projectFileName);
    updateStatus(Resources.getString("done")+" ("+Utils.extractFileName(projectFileName)+")");     

    // check if we need to restart the http server on another port
    if (httpQATHandler!=null) {
      if (!getProperty(Common.HTTP_PORT_KEY,Common.HTTP_PORT_DEFAULT).equals(httpQATHandler.getPort())) {
        httpQATHandler.stopServer();
        httpQATHandler = new HttpQATHandler(getProperty(Common.HTTP_PORT_KEY,
            Common.HTTP_PORT_DEFAULT),this);
        httpQATHandler.start();
      }
    }
    updateConsoleMenu();
    updatePluginMenu();
  }

  /**
   * Update the plugin menu to reflect the user defined
   * plugin classes we have installed.
   */
  @SuppressWarnings("static-access")
  private void updatePluginMenu() {
    try {
      pluginMenu.removeAll();
      if (getProperty(Common.PLUGIN_CLASSES,new String()).length()>0) {
        StringTokenizer tokens = new StringTokenizer(getProperty(Common.PLUGIN_CLASSES));
        String className;
        PluginInterface plugin;
        JMenuItem item;
        while (tokens.hasMoreTokens()) {
          try {
            className = tokens.nextToken();
            plugin = (PluginInterface)((QAT.class.forName(className)).newInstance());
            pluginList.put(plugin.getPluginName(),plugin);
            item = new JMenuItem(plugin.getPluginName());
            item.addActionListener(this);
            pluginMenu.add(item);
          }
          catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
      else {
        pluginMenu.add(new JMenuItem(Resources.getString("pluginMenuEmpty")));
      }
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   *  Set the agent console menu to reflect new list of agents.
   */
  private void updateConsoleMenu() {
    int agentCount = Integer.parseInt(getProperty(Common.AGENT_COUNT,"0"));
    int currAgent;
    JMenuItem item;
    consoleMenu.removeAll();
    for (int i = 0; i < agentCount;i++) {
      currAgent = i+1;
      consoleMenu.add(item = new JMenuItem("Agent "+currAgent+" ("+
          getProperty(Common.host+currAgent+Common.hostNamePattern)+" "+
          getProperty(Common.host+currAgent+Common.hostPortPattern)+")"));
      item.addActionListener(this);
    }
  }

  private void testTreeChanged() {
    testTree.setParentQAT(this);
  }

  private void addMenuBar() {
    // ---------- set up the system menu ------------
    menuBar = new JMenuBar();
    JMenu menu;
    JMenuItem item;
    // ------------------add the file menu-------------------
    menu = new JMenu(Resources.getString("file"));
    // create new blank project
    menu.add(item = new JMenuItem(Resources.getString("newProject"),
        new ImageIcon(Resources.getImageResource("newProjectImage"))));   
    item.addActionListener(this);
    // load project
    menu.add(item = new JMenuItem(Resources.getString("loadProject"),
        new ImageIcon(Resources.getImageResource("loadProjectImage"))));
    item.addActionListener(this);
    // save project
    menu.add(item = new JMenuItem(Resources.getString("saveProject"),
        new ImageIcon(Resources.getImageResource("saveProjectImage"))));
    item.addActionListener(this);
    // save project as
    menu.add(item = new JMenuItem(Resources.getString("saveProjectAs"),
        new ImageIcon(Resources.getImageResource("saveProjectAsImage"))));
    item.addActionListener(this);

    menu.addSeparator();
    // import/export project
    menu.add(item = new JMenuItem(Resources.getString("importProject"),
        new ImageIcon(Resources.getImageResource("importImage"))));
    item.addActionListener(this);
    menu.add(item = new JMenuItem(Resources.getString("exportProject"),
        new ImageIcon(Resources.getImageResource("exportImage"))));
    item.addActionListener(this);
    menu.addSeparator();
    // launch new QAT instance
    menu.add(item = new JMenuItem(Resources.getString("launchQatInstance")));
    item.addActionListener(this);
    // close this QAT instance
    menu.add(item = new JMenuItem(Resources.getString("closeQatInstance")));
    item.addActionListener(this);
    menu.addSeparator();

    // run selected tests
    menu.add(item = new JMenuItem(Resources.getString("runSelectedTests"),
        new ImageIcon(Resources.getImageResource("runSelectedImage"))));   
    item.addActionListener(this);
    // stop current run
    menu.add(item = new JMenuItem(Resources.getString("stopCurrentRun"),
        new ImageIcon(Resources.getImageResource("stopRunImage"))));
    item.addActionListener(this)
    menu.addSeparator();
    // reparse tests from current working directory
    menu.add(item = new JMenuItem(Resources.getString("reparseTests"),
        new ImageIcon(Resources.getImageResource("parseAllImage"))));
    item.addActionListener(this);
    // reparse selected tests
    menu.add(item = new JMenuItem(Resources.getString("parseSelected"),
        new ImageIcon(Resources.getImageResource("parseSelectedImage"))));
    item.addActionListener(this);
    menu.addSeparator();
    // exit
    menu.add(item = new JMenuItem(Resources.getString("exit"),
        new ImageIcon(Resources.getImageResource("exitImage"))));
    item.addActionListener(this);
    menuBar.add(menu);
    // ------------------add the edit menu-------------------
    menu = new JMenu(Resources.getString("edit"));
    // select all tests
    menu.add(item = new JMenuItem(Resources.getString("selectAll"),
        new ImageIcon(Resources.getImageResource("selectAllImage"))));
    item.addActionListener(this);
    menu.addSeparator();
    menu.add(item = new JMenuItem(Resources.getString("projectSettings"),
        new ImageIcon(Resources.getImageResource("projectSettingsImage"))));
    item.addActionListener(this);
    menuBar.add(menu);

    // ------------------add the agents menu-------------------
    menu = new JMenu(Resources.getString("agents"));
    consoleMenu = new JMenu(Resources.getString("connect"));
    consoleMenu.add(item = new JMenuItem(Resources.getString("connectAgentEmpty"),
        new ImageIcon(Resources.getImageResource("connectImage"))));
    menu.add(consoleMenu);   

    menu.add(item = new JMenuItem(Resources.getString("agentSettings"),
        new ImageIcon(Resources.getImageResource("agentSettingsImage"))));
    item.addActionListener(this);
    menuBar.add(menu);

    // ------------------add the plugin menu-------------------
    pluginMenu = new JMenu(Resources.getString("plugin"));
    pluginMenu.add(item = new JMenuItem(Resources.getString("pluginMenuEmpty"),
        new ImageIcon(Resources.getImageResource("pluginImage"))));
    menuBar.add(pluginMenu);

    // ------------------add the report menu-------------------
    menu = new JMenu(Resources.getString("report"));
    // compare test results
    menu.add(item = new JMenuItem(Resources.getString("compareResults"),
        new ImageIcon(Resources.getImageResource("compareImage"))));
    item.addActionListener(this);
    menu.addSeparator();
    // print all tests
    menu.add(item = new JMenuItem(Resources.getString("printAll"),
        new ImageIcon(Resources.getImageResource("printImage"))));
    item.addActionListener(this);
    // print all tests (sort by status)
    menu.add(item = new JMenuItem(Resources.getString("printAllSorted"),
        item.getIcon()));
    item.addActionListener(this);
    // print all tests (non-passed only)
    menu.add(item = new JMenuItem(Resources.getString("printAllNonPassed"),
        item.getIcon()));
    item.addActionListener(this);
    // print as text file
    menu.add(item = new JMenuItem(Resources.getString("printAsTextFile"),
        item.getIcon()));
    item.addActionListener(this);
    // print as XML file
    menu.add(item = new JMenuItem(Resources.getString("printAsXmlFile"),
        item.getIcon()));
    item.addActionListener(this);
    menu.addSeparator();
    // generate Html report
    menu.add(item = new JMenuItem(Resources.getString("generateHtmlReport"),
        new ImageIcon(Resources.getImageResource("htmlImage"))));
    item.addActionListener(this);
    menuBar.add(menu);
    // ------------------add the help menu-------------------
    menu = new JMenu(Resources.getString("help"));
    menu.add(item = new JMenuItem(Resources.getString("about"),
        new ImageIcon(Resources.getImageResource("aboutImage"))));
    item.addActionListener(this);
    menuBar.add(menu);
    setJMenuBar(menuBar);
  }

  /**
   * Create the toolbar.  By default this reads the
   * resource file for the definition of the toolbar.
   */
  private void addToolBar() {
    Container frame = getContentPane();
    toolbar = new JToolBar();
    String[] toolKeys = {"loadProject", "saveProject", "-", "-",
        "runSelected", "parseSelected","stopRun","-", "-",
        "timerRun", "-", "-",              
        "expandAll",
        "collapseTree",
    "expandTree"};
    for (int i = 0; i < toolKeys.length; i++) {
      if (toolKeys[i].equals("-")) {
        toolbar.add(Box.createHorizontalStrut(5));
      }
      else {
        toolbar.add(createToolbarButton(toolKeys[i]));
      }
    }
    toolbar.add(Box.createHorizontalGlue());
    frame.add(toolbar,BorderLayout.NORTH);
  }

  private JButton createToolbarButton(String key) {
    URL url = Resources.getImageResource(key + "Image");
    JButton b = new JButton(new ImageIcon(url)) {
      private static final long serialVersionUID = -7195796451856780112L;
      public float getAlignmentY() { return 0.5f; }
    };
    b.setRequestFocusEnabled(false);
    b.setMargin(new Insets(1,1,1,1));

    b.setToolTipText(Resources.getString(key + "ToolTip"));

    b.addActionListener(this);
    return b;
  }

  private void addStatusBar() {
    //  add the status bar here.
    JPanel statusBar = new JPanel(new GridLayout(1,3));
    statusLabel = new JLabel("",SwingConstants.CENTER);
    statusLabel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
    statusBar.add(statusLabel);
    parserLabel = new JLabel("",SwingConstants.CENTER);
    parserLabel.setForeground(Color.black);
    parserLabel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
    statusBar.add(parserLabel);
    JPanel p2 = new JPanel(new GridLayout(1,1));
    statusGauge = new Gauge();
    statusGauge.setForeground(Color.green, Color.red, Color.blue, new Color(99,99,156), Color.orange);
    p2.add(statusGauge);
    p2.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
    statusBar.add(p2);
    runtimeComponent.setStatus(Resources.getString("ready"),0,0,0,0,0,0);
    getContentPane().add(statusBar,BorderLayout.SOUTH);
  }

  private void addCenterPanel(SplashScreen splash) {
    // create the TestTree
    splash.setText(Resources.getString("splashText4"),38);
    testTree = new TestTree();

    // create the runtime panel
    splash.setText(Resources.getString("splashText5"),45);
    runtimeComponent = new RuntimeComponent(this);       

    // create the keyword component
    splash.setText(Resources.getString("splashText6"),52);
    keywordComponent = new KeywordComponent(testTree);

    // create the ParserOutputViewer
    splash.setText(Resources.getString("splashText7"),59);
    parserOutputViewer = new ParserOutputViewer(this);
    testTree.addTreeSelectionListener(parserOutputViewer);
    testTree.addChangeListener(parserOutputViewer);

    // create the test detail viewer
    splash.setText(Resources.getString("splashText8"),66);
    testDetailViewer = new TestDetailViewer(this);
    testTree.addTreeSelectionListener(testDetailViewer);
    testTree.addChangeListener(testDetailViewer);

    JTabbedPane runtimeTab = new JTabbedPane();
    runtimeTab.add("Parser Output",parserOutputViewer);
    runtimeTab.add("Runtime",runtimeComponent);
    runtimeTab.add("Keywords",keywordComponent);

    leftrightSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true,testTree,testDetailViewer);
    leftrightSplit.setDividerSize(5);

    topbottomSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT,true,leftrightSplit,runtimeTab);
    getContentPane().add(topbottomSplit,BorderLayout.CENTER);         
    try {
      topbottomSplit.setResizeWeight(1)
    }
    catch (Throwable ex) {
      // this method does not exist in jdk1.2.2
      System.out.println("Warning "+ex.toString());
    }
  }

  /**
   * Set the status bar to display the message specified in msg.
   * @param msg - the message to display.
   */
  public void setStatus(String msg) {
    statusLabel.setText(msg);
    statusLabel.repaint();
    runtimeComponent.updateMemoryStatus();
    runtimeComponent.updateRunProgress(testRunner.getRunTotal(),
        testRunner.getRunProgress(),
        testRunner.getElapsedTime(),
        testRunner.getRemainingTime());
  }

  public Object[] calculateStatus() {
    return calculateStatus(testTree.getAllTests());
  }

  public Object[] calculateStatus(List<TestSpecification> tests) {
    int passed=0, failed=0, unresolved=0, notrun=0, pending=0;
    statusGauge.setMax(tests.size());
    for (int i = 0; i < tests.size(); i++) {
      switch (((TestSpecification)tests.get(i)).getStatus()) {
      case ProtocolConstants.PASSED : passed++;
      break;
      case ProtocolConstants.FAILED : failed++;
      break;
      case ProtocolConstants.UNRESOLVED : unresolved++;
      break;
      case ProtocolConstants.NOTRUN : notrun++;
      break;       
      case ProtocolConstants.PENDING : pending++;
      break;
      }
    }
    Object objArray[] = new Object[5];
    objArray[0] = new Integer(passed);
    objArray[1] = new Integer(failed);
    objArray[2] = new Integer(unresolved);
    objArray[3] = new Integer(notrun);
    objArray[4] = new Integer(pending);
    return objArray;
  }   

  /**
   * This form automatically calculates all the values required to display the entire test
   * tree results.
   */

  public void updateStatus(String msg) {
    updateStatus(msg,0);   
  }

  public void updateStatus(String msg, double runCount) {
    updateStatus(msg,testTree.getAllTests(),runCount);   
  }

  public void updateStatus(String msg, List<TestSpecification> tests) {
    updateStatus(msg,tests,0);
  }

  public void updateStatus(String msg, List<TestSpecification> tests, double runCount) {
    Object objArray[] = calculateStatus(tests);
    runtimeComponent.setStatus(msg,
        ((Integer)objArray[0]).doubleValue(), // passed
        ((Integer)objArray[1]).doubleValue(), // failed
        ((Integer)objArray[2]).doubleValue(), // unresolved
        ((Integer)objArray[3]).doubleValue(), // notrun
        ((Integer)objArray[4]).doubleValue(), // pending
        runCount); // running
  }

  private void loadTests() {
    setWaitCursor();
    JFileChooser testDir = new JFileChooser(testTree.getProjectRoot());
    testDir.setFileHidingEnabled(false);
    testDir.setDialogTitle(Resources.getString("selectTestDir"));
    testDir.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

    try {
      if (testDir.showOpenDialog(this)==JFileChooser.APPROVE_OPTION) {
        StatusWindow waitWindow = new StatusWindow(this,
            Resources.getString("pleaseWait"),
            Resources.getString("loadingProject"));
        testTree.loadNewTestDir(testDir.getSelectedFile().getCanonicalPath(),
            waitWindow);
        waitWindow.setVisible(false);
      }
    }
    catch (java.io.IOException e) {
      showError(Resources.getString("unexpectedError")+e.getMessage(),
          Resources.getString("error"),
          JOptionPane.ERROR_MESSAGE);
    }
    // update the keyword list
    keywordComponent.loadTestsKeywords();
    setDefaultCursor();
    // reload the properties
    projectPropertiesChanged();
    testTreeChanged();
  }

  public void parseTests() {
    parseTests(true);
  }

  public void parseTests(boolean visible) {
    StatusWindow waitWindow = new StatusWindow(this,
        Resources.getString("pleaseWait"),
        Resources.getString("reloadingProject"),
        visible);
    setWaitCursor();
    // remove previous trace & stderr/stdout files
    waitWindow.setMessage(getProperty(Common.PROJECTPATH_KEY, Resources.getString("clearResults")));
    try {
      SwingUtils.delete(Common.getProjectResultsDirectory(projectFileName),waitWindow);
    }
    catch (IOException e) {
      //e.printStackTrace();
      // not too important - we can ignore this error
      // because maybe it doesn't exist yet
    }

    // load the new tests of the disk
    waitWindow.setMessage(getProperty(Common.PROJECTPATH_KEY, testTree.getProjectRoot()));
    testTree.loadNewTestDir(getProperty(Common.PROJECTPATH_KEY, testTree.getProjectRoot()),
        waitWindow);

    // update the keyword list
    keywordComponent.loadTestsKeywords();
    setDefaultCursor();
    waitWindow.setVisible(false);
    projectPropertiesChanged();
    testTreeChanged();
    updateStatus(Resources.getString("finishedParsing"));
  }

  /**
   * This will relook at the disk only from this directory onwards, instead of re-parsing the entire
   * tree off disk.
   */
  public void reloadDirectory(TestTreeNode testNode) {
    StatusWindow waitWindow = new StatusWindow(this,
        Resources.getString("pleaseWait"),
        Resources.getString("reloadDirectory"));
    testTree.parseTestsFrom(testNode,waitWindow);
    waitWindow.setVisible(false);
    updateStatus(Resources.getString("finishedParsing"));
 

  public void parseTest(TestTreeNode testNode, ParserInterface parser) {
    updateStatus(testNode.toString());
    testTree.parseTestNode(testNode,parser);
    testTree.nodeChanged(testNode);
  }

  public void parseSelectedTests() {
    // make sure we cannot start another run while this one is running
    if ((!testRunner.isRunning())&&
        (!timerRunner.isRunning())) {
      testRunner = new TestRunner(this);
      testRunner.setEvaluationMode(true);
      List<TestSpecification> selectedTests = testTree.getSelectedTests();
      if (selectedTests.size()>0) {
        // make sure we have at least one agent defined
        int agentCount = Integer.parseInt(getProperty(Common.AGENT_COUNT,"0"));
        if (agentCount>0) {
          // check if we need to clear their status first
          if (new Boolean(getProperty(Common.RESET_STATUS,"false")).booleanValue())
            testTree.resetSelectedTestStatus();
          testRunner.setRunList(selectedTests);
          testRunner.setProjectRoot(testTree.getProjectRoot());
          testRunner.start();
          statusGauge.setMax(selectedTests.size());
        }
        else {
          showError(Resources.getString("noAgentsDefined"),
              Resources.getString("error"),
              JOptionPane.ERROR_MESSAGE);
        }
      }
      else {
        showError(Resources.getString("noTestsSelected"),
            Resources.getString("error"),
            JOptionPane.ERROR_MESSAGE);
      }
    }
    else {
      showError(Resources.getString("runInProgress"),
          Resources.getString("error"),
          JOptionPane.ERROR_MESSAGE);
    }   
  }

  /**
   * This forces a repaint of the QAT gui - used in TestTree
   * when changing the status window.
   */
  public void update() {
    toolbar.repaint();
    menuBar.repaint();
  }

  private void editProject() {
    new EditProject(this,projectProperties,Utils.extractFileName(projectFileName));   
  }

  public void editProjectCallback(EditProject editProject) {
    projectProperties = editProject.getProperties();
    projectPropertiesChanged();
    keywordComponent.loadKeyWordHistFromProperties(projectProperties);
    if (editProject.needToReloadTests()) {
      StatusWindow waitWindow = new StatusWindow(this,
          Resources.getString("pleaseWait"),
          Resources.getString("reloadingProject"));
      testTree.loadNewTestDir(getProperty(Common.PROJECTPATH_KEY, Common.getHarnessBaseDirectory()),
          waitWindow);
      setProperty(Common.PROJECTPATH_KEY,testTree.getProjectRoot());
      waitWindow.setVisible(false);
    }     
  }

  private void editAgentSettings() {
    new AgentInfo(this,Resources.getString("agentSettings"),projectProperties);   
  }

  public void editAgentSettingsCallback(AgentInfo editAgents) {
    editAgents.updateProperties(projectProperties);
    projectPropertiesChanged();
  }

  public boolean isTestRunning() {
    return ((testRunner.isRunning())||
        (timerRunner.isRunning()));
  }

  public void stopTestRun() {
    // make sure we cannot start another run while this one is running
    if (testRunner.isRunning()) {
      testRunner.interrupt();
      updateStatus(Resources.getString("interrupted"));
      return;
    }
    if (timerRunner.isRunning()) {
      timerRunner.interrupt();
      updateStatus(Resources.getString("interrupted"));
      return;
    }
    showError(Resources.getString("noRunInProgress"),
        Resources.getString("error"),
        JOptionPane.ERROR_MESSAGE);
  }

  /**
   * Selects all the tests in the tree.
   */
  public void selectAll() {
    testTree.selectAll();
  }

  public void generateHtmlReport() {
    JFileChooser dirChooser = new JFileChooser(projectFileName);
    dirChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    dirChooser.setDialogTitle(Resources.getString("selectHtmlRootDir"));
    dirChooser.setApproveButtonText("Generate");
    if (dirChooser.showOpenDialog(this)==JFileChooser.APPROVE_OPTION) {
      StatusWindow status= new StatusWindow(this,Resources.getString("generating"),Resources.getString("pleaseWait"));
      try {
        generateHtmlReport(dirChooser.getSelectedFile().getCanonicalPath(),status);
      }
      catch (Exception ex) {
        showError(Resources.getString("unexpectedError")+ex.getMessage(),
            Resources.getString("error"),
            JOptionPane.ERROR_MESSAGE)
      }
      finally {
        status.setVisible(false);
      }
    }
  }

  public void generateHtmlReport(String directoryRoot, StatusWindow status) throws Exception {
    new HttpReport(this,"http://"+InetAddress.getLocalHost().getHostName()+":"+
        getProperty(Common.HTTP_PORT_KEY,
            Common.HTTP_PORT_DEFAULT),
            directoryRoot,
            status);
  }

//  private boolean match(String keys[], String key) {
//    for (int i = 0; i < keys.length; i++)
//      if (keys[i].indexOf(key)>=0)
//        return true;
//    return false;
//  }

  private void timerRun() {
    // make sure we cannot start another run while this one is running
    if (timerRunner.isRunning()==false) {
      List<TestSpecification> selectedTests = testTree.getSelectedTests();
      if (selectedTests.size()>0) {
        if (timerRunner.promptForDate()) {
          timerRunner.setRunList(selectedTests);
          timerRunner.start();
        }
        else {
          timerRunner.interrupt();
        }
      }
      else {
        showError(Resources.getString("noTestsSelected"),
            Resources.getString("error"),
            JOptionPane.ERROR_MESSAGE);
      }
    }
    else {
      showError(Resources.getString("runInProgress"),
          Resources.getString("error"),
          JOptionPane.ERROR_MESSAGE);
    }
  }

//  private void timerStop() {
//    if (timerRunner!=null) {
//      timerRunner.interrupt();
//    }
//  }

  /**
   * This method runs all tests with status PASSED, returning false if none were run for
   * some reason (such as none exist etc).
   * Used by the Http interface.
   */
  public boolean runPassedTests() {
    return runTestsWithStatus(ProtocolConstants.PASSED);
  }

  /**
   * This method runs all tests with status FAILED, returning false if none were run for
   * some reason (such as none exist etc).
   * Used by the Http interface.
   */
  public boolean runFailedTests() {
    return runTestsWithStatus(ProtocolConstants.FAILED);
  }

  /**
   * This method runs all tests with status UNRESOLVED, returning false if none were run for
   * some reason (such as none exist etc).
   * Used by the Http interface.
   */
  public boolean runUnresolvedTests() {
    return runTestsWithStatus(ProtocolConstants.UNRESOLVED);
  }

  /**
   * This method runs all tests with status NOTRUN, returning false if none were run for
   * some reason (such as none exist etc).
   * Used by the Http interface.
   */
  public boolean runNotRunTests() {
    return runTestsWithStatus(ProtocolConstants.NOTRUN);
  }

  /**
   * This method runs all tests with matching status, returning false if none were run for
   * some reason (such as none exist etc).
   * Used by the Http interface.
   */
  public boolean runTestsWithStatus(int status) {
    testTree.unSelectAll();
    testTree.selectAllWithStatus(status);
    if (testTree.getSelectedTests().size()==0)
      return false;
    else
      runSelectedTests();
    return true;
  }

  public void runSelectedTests() {
    runSelectedTests(false);
  }

  public void runSelectedTests(boolean quiet) {
    // make sure we cannot start another run while this one is running
    if ((!testRunner.isRunning())&&
        (!timerRunner.isRunning())) {
      testRunner = new TestRunner(this);
      List<TestSpecification> selectedTests = testTree.getSelectedTests();
      if (selectedTests.size()>0) {
        // make sure we have at least one agent defined
        int agentCount = Integer.parseInt(getProperty(Common.AGENT_COUNT,"0"));
        if (agentCount>0) {
          // check if we need to clear their status first
          if (new Boolean(getProperty(Common.RESET_STATUS,"false")).booleanValue())
            testTree.resetSelectedTestStatus();
          testRunner.setRunList(selectedTests);
          testRunner.setProjectRoot(testTree.getProjectRoot());
          testRunner.start();
          statusGauge.setMax(selectedTests.size());
        }
        else {
          showError(Resources.getString("noAgentsDefined"),
              Resources.getString("error"),
              JOptionPane.ERROR_MESSAGE);
        }
      }
      else {
        showError(Resources.getString("noTestsSelected"),
            Resources.getString("error"),
            JOptionPane.ERROR_MESSAGE);
      }
    }
    else {
      showError(Resources.getString("runInProgress"),
          Resources.getString("error"),
          JOptionPane.ERROR_MESSAGE);
    }
  }

  public TestSpecification getSelectedTest() {
    List<TestSpecification> selectedTests = testTree.getSelectedTests();
    return (TestSpecification)selectedTests.get(0);
  }

  /**
   * This allows a single test to be run.
   * It is normally called by the Run method of NodeMenu when you
   * right-click a test.
   */
  public void runSingleTest(TestSpecification test) {
    // make sure we cannot start another run while this one is running
    if ((!testRunner.isRunning())&&
        (!timerRunner.isRunning())) {
      testRunner = new TestRunner(this);
      ArrayList<TestSpecification> v = new ArrayList<TestSpecification>(1);
      v.add(test);
      testRunner.setRunList(v);
      testRunner.setProjectRoot(testTree.getProjectRoot());
      testRunner.start();
    }
    else {
      showError(Resources.getString("runInProgress"),
          Resources.getString("error"),
          JOptionPane.ERROR_MESSAGE);
    }
  }

  /**
   * This method is called by the testRunner once the test result is known, and allows the test
   * node to be repainted with the proper result.
   */
  public void updateTest(TestSpecification test, boolean evaluating) {
    testTree.setTest(test);
    // only autosave during test run, not during evaluation parse
    if (!evaluating) {
      // now save the tree if autosave is enabled and the test is not RUNNING
      if ((getProperty(Common.AUTOSAVE_PROJECT,"false").equals("true"))&&
          (test.getStatus()!=ProtocolConstants.RUNNING)) {
        saveProject(true);
      }
    }
  }

  /**
   * This method saves this instances session and project properties, and if
   * no run/parse is in progress, will close the window.
   * If it is the last visible Qat instance, the JVM will
   * be halted as well.
   */
  public void closeQatInstance(boolean quiet) {
    // make sure we cannot exit while running tests
    if ((!testRunner.isRunning())&&
        (!timerRunner.isRunning())) {
      saveProject(quiet);
      instanceList.remove(this);
      setVisible(false);
      dispose();
      if (instanceList.size()==0)
        System.exit(0);
    }
    else {
      showError(Resources.getString("runInProgress"),
          Resources.getString("error"),
          JOptionPane.ERROR_MESSAGE);
    }
  }

  private void exit() {
    Object instanceListArray[] = instanceList.toArray();
    if (instanceListArray.length>1) {
      if (JOptionPane.showConfirmDialog(this,
          Resources.getString("closeAllQatInstances"),
          Resources.getString("warning"),
          JOptionPane.YES_NO_OPTION,
          JOptionPane.WARNING_MESSAGE)==JOptionPane.OK_OPTION) {
        for (int i = 0; i< instanceListArray.length; i++) {
          ((QAT)instanceListArray[i]).closeQatInstance(false);
        }
      }
    }
    else {
      ((QAT)instanceListArray[0]).closeQatInstance(false);
    }
  }

  private void compareResults() {
    new CompareResults(this,
        Utils.ensureSuffix(projectFileName,Common.SERIALIZED_TREE_EXTENSION),
        Utils.ensureSuffix(projectFileName,Common.SERIALIZED_TREE_EXTENSION));
  }

  private void launchQatInstance() {
    new QAT();
  }

  private void printTestTree(int printType) {   
    PrintManager p = new PrintManager("Print job title",this);
    if (p.startPrint()) {
      StatusWindow waitWindow = new StatusWindow(this,Resources.getString("pleaseWait"),"Printing in progress");
      ReportObject report = new ReportObject(testTree);
      report.printTree(p,projectFileName,printType);
      p.endPrint();
      waitWindow.setVisible(false);
    }
  }

  private void setWaitCursor() {
    if (waitCursor==null)
      waitCursor=new Cursor(Cursor.WAIT_CURSOR);
    setCursor(waitCursor);
  }

  private void setDefaultCursor() {
    if (defaultCursor==null)
      defaultCursor=new Cursor(Cursor.DEFAULT_CURSOR);
    setCursor(defaultCursor);   
  }

  public Properties getProjectProperties() {
    return projectProperties;
  }

  public void setProjectProperties(Properties p) {
    projectProperties = p;
  }

  public void clearProjectProperties() {
    projectProperties.clear();
  }

  /**
   * This allows other classes access to the project property values.
   */
  public String getProperty(String key, String defaultValue) {
    return projectProperties.getProperty(key,defaultValue);
  }

  /**
   * This allows other classes access to the project property values.
   */
  public String getProperty(String key) {
    return projectProperties.getProperty(key);
  }

  /**
   * This allows other classes access to the project property values.
   */
  public void setProperty(String key, String defaultValue) {
    projectProperties.setProperty(key,defaultValue);
  }

  /**
   * This allows other classes access to the project property values.
   */
  public Properties getProperties() {
    return projectProperties;
  }

  /**
   * This allows us to retrieve properties for this
   * session and this Qat instance.
   */
  private Properties getSessionProperties() {
    return sessionProperties;
  }

  /**
   * This allows us to set properties for this
   * session and this Qat instance.
   */
  private static void setSessionProperties(Properties newSessionProperties) {
    sessionProperties = newSessionProperties;
  }

  /**
   * This allows us to retrieve properties for this
   * session and this Qat instance.
   */
  private String getSessionProperty(String key, String defaultValue) {
    return sessionProperties.getProperty(key+instanceSuffix,
        defaultValue);
  }

  /**
   * This allows us to retrieve properties for this
   * session and this Qat instance.
   */
  private String getSessionProperty(String key) {
    return sessionProperties.getProperty(key+instanceSuffix);
  }

  /**
   * This allows us to set properties for this
   * session and this Qat instance.
   */
  private void setSessionProperty(String key, String value) {
    sessionProperties.setProperty(key+instanceSuffix,
        value);
  }

  /**
   * This allows us to clear properties for this
   * session and this Qat instance.
   */
  private void clearSessionProperties() {
    sessionProperties.clear();
  }

  /**
   * This allows other classes to update the parser output window.
   */
  public void setParserView(TestSpecification test) {
    parserOutputViewer.setObjectView(test);
    testDetailViewer.setObjectView(test);
  }

  public void setStatusGauge(double passed, double failed, double unresolved, double pending, double notrun) {
    statusGauge.setValue(passed,
        failed,
        unresolved,
        pending,
        notrun);
  }

  public void setStatusGaugeMax(int max) {
    statusGauge.setMax(max);
  }

  public void addChangeListener(ChangeListener listener) {
    getTestTree().addChangeListener(listener);
  }

  public void removeChangeListener(ChangeListener listener) {
    getTestTree().removeChangeListener(listener);
  }

  private void activatePlugin(String description) {
    PluginInterface plugin = ((PluginInterface)pluginList.get(description));
    plugin.activatePlugin(this);
  }

  //  public void removeChangeListener(ChangeListener listener) {
  //    getTestTree().removeChangeListener(listener);
  //  }

  /**
   * Used to fulfil the QATInterface requirement to allow
   * plugins to create modal dialogs based on the same
   * Swing worker thread etc.
   */
  public JFrame getOwnerHandle() {
    return this;
  }

  /**
   * Returns a handle to the label which displays the current QASH command being
   * parsed. Used by ParserInterface.
   */
  public JLabel getParserStatusLabel() {
    return parserLabel;
  }

  /**
   * This method returns the directory into which all parser trace files are put,
   * and all traces retrieved from the agent by the parser.
   */
  public String getProjectResultsDirectory() {
    return Common.getProjectResultsDirectory(projectFileName);
  }

  /* ----------- THESE ARE THE EVENT HANDLING ROUTINES ------------*/
  public void actionPerformed(ActionEvent e) {
    if (e.getSource() instanceof JMenuItem) {
      // exit
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("exit"))) {
        exit();
      }
      // stop test run
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("stopCurrentRun"))) {
        stopTestRun();
        return;
      }
      // run selected tests
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("runSelectedTests"))) {
        runSelectedTests();
        return;
      }
      // compare test results
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("compareResults"))) {
        compareResults();
        return;
      }
      // printall tests sorted
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("printAll"))) {
        printTestTree(0);
        return;
      }
      // printall  tests
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("printAllSorted"))) {
        printTestTree(1);
        return;
      }
      // printall nonpassed tests
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("printAllNonPassed"))) {
        printTestTree(2);
        return;
      }
      // print to text file
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("printAsTextFile"))) {
        JFileChooser textFileDialog = new JFileChooser(projectFileName);
        textFileDialog.setDialogTitle(Resources.getString("printAsTextFile"));
        textFileDialog.setApproveButtonText("Print");
        ExtensionFileFilter filter = new ExtensionFileFilter("txt","Text file");
        textFileDialog.addChoosableFileFilter(filter);
        textFileDialog.setFileFilter(filter);
        try {
          if (textFileDialog.showOpenDialog(this)==JFileChooser.APPROVE_OPTION) {
            ReportObject report = new ReportObject(testTree);
            report.printAsTextFile(textFileDialog.getSelectedFile().getCanonicalPath(),projectFileName);
          }
        }
        catch (java.io.IOException ex) {
          showError(Resources.getString("unexpectedError")+ex.getMessage(),
              Resources.getString("error"),
              JOptionPane.ERROR_MESSAGE)
        }
        return;
      }
      //  print to text file
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("printAsXmlFile"))) {
        JFileChooser textFileDialog = new JFileChooser(projectFileName);
        textFileDialog.setDialogTitle(Resources.getString("printAsXmlFile"));
        textFileDialog.setApproveButtonText("Print");
        ExtensionFileFilter filter = new ExtensionFileFilter("xml","XML file");
        textFileDialog.addChoosableFileFilter(filter);
        textFileDialog.setFileFilter(filter);
        try {
          if (textFileDialog.showOpenDialog(this)==JFileChooser.APPROVE_OPTION) {
            XmlReport report = new XmlReport(testTree);
            report.printAsXmlFile(textFileDialog.getSelectedFile().getCanonicalPath(),projectFileName);
          }
        }
        catch (java.io.IOException ex) {
          showError(Resources.getString("unexpectedError")+ex.getMessage(),
              Resources.getString("error"),
              JOptionPane.ERROR_MESSAGE)
        }
        return;
      }
      // generate Html report
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("generateHtmlReport"))) {
        generateHtmlReport();       
        return;
      }
      // select all tests
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("selectAll"))) {
        selectAll();
        return;
      }
      // load tests from directory
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("selectTestDir"))) {     
        loadTests();
        return;     
      }
      // reparse tests in current test directory
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("reparseTests"))) {
        parseTests();
        return;     
     
      // reparse selected tests
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("parseSelected"))) {
        parseSelectedTests();
        return;     
     
      // import project
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("importProject"))) {
        importProject();
        return;
      }
      // export project
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("exportProject"))) {
        exportProject();
        return;
      }
      // new Qat instance
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("launchQatInstance"))) {
        launchQatInstance();
        return;
      }
      // close Qat instance
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("closeQatInstance"))) {
        closeQatInstance(false);
        return;
      }
      // new project
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("newProject"))) {
        newProject();
        return;
      }
      // load project
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("loadProject"))) {
        loadProject();
        return;
      }
      // save project
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("saveProject"))) {
        saveProject();
        return;
      }
      // save project as
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("saveProjectAs"))) {
        saveProjectAs();
        return;
      }
      // edit project
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("projectSettings"))) {
        editProject();
        return;
      }
      // edit editAgent Settings
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("agentSettings"))) {
        editAgentSettings();
        return;
      }
      // connect to agent console
      if (((JMenuItem)e.getSource()).getText().startsWith("Agent ")) {
        String s = ((JMenuItem)e.getSource()).getText();
        String agentIndex = s.substring(s.indexOf(' ')+1,s.indexOf(' ')+2);
        s = s.substring(s.indexOf('(')+1,s.lastIndexOf(')'));
        String agentName = s.substring(0,s.indexOf(' '));
        String agentPort = s.substring(s.indexOf(' ')+1,s.length());
        AgentConsole agentConsole  = new AgentConsole(agentIndex,
            agentName,
            Integer.parseInt(agentPort),
            Integer.parseInt(getProperty(Common.CONSOLE_DEBUG_LEVEL,
                Common.CONSOLE_DEBUG_LEVEL_VALUE)),
                Integer.parseInt(getProperty(Common.CONSOLE_BUFFER_SIZE,
                    Common.CONSOLE_BUFFER_SIZE_VALUE)));
        Thread x = new Thread(agentConsole);
        x.start();
        return;
      }

      // about dialog
      if (((JMenuItem)e.getSource()).getText().equals(Resources.getString("about"))) {   
        new AboutDialog(this);
        return;
      }

      // could be a plugin launch
      if (pluginList.get(((JMenuItem)e.getSource()).getText())!=null) {
        activatePlugin(((JMenuItem)e.getSource()).getText());
        return;
      }     
    }
    if (e.getSource() instanceof JButton) {
      // load project (toolbar button)
      if (((JButton)e.getSource()).getToolTipText().equals(Resources.getString("loadProjectToolTip"))) { 
        loadProject();
        return;
      }
      // run selected tests (toolbar button)
      if (((JButton)e.getSource()).getToolTipText().equals(Resources.getString("runSelectedToolTip"))) { 
        runSelectedTests();
        return;
      }
      // parse selected tests (toolbar button)
      if (((JButton)e.getSource()).getToolTipText().equals(Resources.getString("parseSelectedToolTip"))) { 
        parseSelectedTests();
        return;
      }
      // stop run (toolbar button)
      if (((JButton)e.getSource()).getToolTipText().equals(Resources.getString("stopRunToolTip"))) { 
        stopTestRun();
        return;
      }
      // timer run (toolbar button)
      if (((JButton)e.getSource()).getToolTipText().equals(Resources.getString("timerRunToolTip"))) { 
        timerRun();
        return;
      }
      // save project (toolbar button)
      if (((JButton)e.getSource()).getToolTipText().equals(Resources.getString("saveProjectToolTip"))) { 
        saveProject();
        return;
      }
      // expand test tree level (toolbar button)
      if (((JButton)e.getSource()).getToolTipText().equals(Resources.getString("expandTreeToolTip"))) { 
        testTree.expandLevel();
        return;
      }
      // expand entire tree (toolbar button)
      if (((JButton)e.getSource()).getToolTipText().equals(Resources.getString("expandAllToolTip"))) { 
        testTree.expandAll();
        return;
      }
      // collapse test tree level (toolbar button)
      if (((JButton)e.getSource()).getToolTipText().equals(Resources.getString("collapseTreeToolTip"))) { 
        testTree.collapseLevel();
        return;
      }
      showError("Unhandled button :"+((JButton)e.getSource()).getText(),
          Resources.getString("error"),
          JOptionPane.ERROR_MESSAGE);
    }
  }

  public void windowClosed(WindowEvent e) {
  }

  public void windowIconified(WindowEvent e) {
  }

  public void windowDeiconified(WindowEvent e) {
  }

  public void windowActivated(WindowEvent e) {
  }

  public void windowDeactivated(WindowEvent e) {
  }

  public void windowClosing(WindowEvent e) {
    closeQatInstance(false);
  }

  public void windowOpened(WindowEvent e) {
  }

  private void showError(String message, String title, int type) {
    if (isVisible()) {
      JOptionPane.showMessageDialog(this,
          message,
          title,
          type);
    }
    else {
      System.out.println(title+":"+message);
    }
  }
}
TOP

Related Classes of qat.gui.QAT

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.