Package org.aspectj.ajde

Source Code of org.aspectj.ajde.Ajde$RunProperties

/* *******************************************************************
* Copyright (c) 1999-2001 Xerox Corporation,
*               2002 Palo Alto Research Center, Incorporated (PARC).
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
* Contributors:
*     Xerox/PARC     initial implementation
*     Helen Hawkins  Converted to new interface (bug 148190)
*******************************************************************/

package org.aspectj.ajde;

import java.awt.Frame;
import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import javax.swing.JOptionPane;

import org.aspectj.ajde.core.AjCompiler;
import org.aspectj.ajde.core.IBuildProgressMonitor;
import org.aspectj.ajde.core.ICompilerConfiguration;
import org.aspectj.ajde.internal.BuildConfigListener;
import org.aspectj.ajde.internal.BuildConfigManager;
import org.aspectj.ajde.internal.LstBuildConfigManager;
import org.aspectj.ajde.ui.FileStructureView;
import org.aspectj.ajde.ui.StructureSearchManager;
import org.aspectj.ajde.ui.StructureViewManager;
import org.aspectj.ajde.ui.swing.BrowserViewManager;
import org.aspectj.ajde.ui.swing.OptionsFrame;
import org.aspectj.ajde.ui.swing.StructureViewPanel;
import org.aspectj.ajde.ui.swing.SwingTreeViewNodeFactory;
import org.aspectj.ajde.ui.swing.TreeViewBuildConfigEditor;
import org.aspectj.asm.AsmManager;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.Message;
import org.aspectj.util.LangUtil;
import org.aspectj.util.Reflection;

/**
* Singleton class used to initialize the Ajde ui as well as the properties required to run the compiler. Users must call
* "Ajde.init(...)" before doing anything else. There are getter methods for the various properties that are set in the
* initialization.
*
* This also defines the factory for getting new AjCompiler instances.
*
* @author Mik Kersten
* @author Andy Clement
*/
public class Ajde {

  protected static final Ajde INSTANCE = new Ajde();
  private BrowserViewManager viewManager = null;

  private IdeUIAdapter ideUIAdapter = null;
  private TreeViewBuildConfigEditor buildConfigEditor = null;
  private IconRegistry iconRegistry;
  private IRuntimeProperties runtimeProperties;
  private boolean initialized = false;
  private AsmManager asm;
  private OptionsFrame optionsFrame = null;
  private Frame rootFrame = null;
  private StructureViewPanel fileStructurePanel = null;

  private EditorAdapter editorAdapter;
  private StructureViewManager structureViewManager;
  private StructureSearchManager structureSearchManager;
  private final BuildConfigManager configurationManager;

  // all to do with building....
  private ICompilerConfiguration compilerConfig;
  private IUIBuildMessageHandler uiBuildMsgHandler;
  private IBuildProgressMonitor buildProgressMonitor;
  private AjCompiler compiler;

  public AsmManager getModel() {
    return asm;
  }

  /**
   * This class can only be constructured by itself (as a singleton) or by sub-classes.
   */
  protected Ajde() {
    configurationManager = new LstBuildConfigManager();
  }

  /**
   * Initializes the ajde ui and sets up the compiler
   */
  public void init(ICompilerConfiguration compilerConfig, IUIBuildMessageHandler uiBuildMessageHandler,
      IBuildProgressMonitor monitor, EditorAdapter editorAdapter, IdeUIAdapter ideUIAdapter, IconRegistry iconRegistry,
      Frame rootFrame, IRuntimeProperties runtimeProperties, boolean useFileView) {
    try {

      INSTANCE.compilerConfig = compilerConfig;
      INSTANCE.uiBuildMsgHandler = uiBuildMessageHandler;
      INSTANCE.buildProgressMonitor = monitor;
      INSTANCE.asm = AsmManager.createNewStructureModel(Collections.EMPTY_MAP);

      INSTANCE.iconRegistry = iconRegistry;
      INSTANCE.ideUIAdapter = ideUIAdapter;
      INSTANCE.buildConfigEditor = new TreeViewBuildConfigEditor();
      INSTANCE.rootFrame = rootFrame;
      INSTANCE.runtimeProperties = runtimeProperties;

      INSTANCE.configurationManager.addListener(INSTANCE.STRUCTURE_UPDATE_CONFIG_LISTENER);
      INSTANCE.ideUIAdapter = ideUIAdapter;
      INSTANCE.editorAdapter = editorAdapter;
      INSTANCE.structureSearchManager = new StructureSearchManager();
      INSTANCE.structureViewManager = new StructureViewManager(new SwingTreeViewNodeFactory(iconRegistry));

      if (useFileView) {
        FileStructureView structureView = structureViewManager.createViewForSourceFile(editorAdapter.getCurrFile(),
            structureViewManager.getDefaultViewProperties());
        structureViewManager.setDefaultFileView(structureView);
        fileStructurePanel = new StructureViewPanel(structureView);
      }

      viewManager = new BrowserViewManager();
      optionsFrame = new OptionsFrame(iconRegistry);

      initialized = true;
    } catch (Throwable t) {
      Message error = new Message("AJDE UI failed to initialize", IMessage.ABORT, t, null);
      uiBuildMsgHandler.handleMessage(error);
    }
  }

  public void showOptionsFrame() {
    int x = (rootFrame.getWidth() / 2) + rootFrame.getX() - optionsFrame.getWidth() / 2;
    int y = (rootFrame.getHeight() / 2) + rootFrame.getY() - optionsFrame.getHeight() / 2;
    optionsFrame.setLocation(x, y);
    optionsFrame.setVisible(true);
  }

  /**
   * @return true if init(..) has been run, false otherwise
   */
  public boolean isInitialized() {
    return initialized;
  }

  private final BuildConfigListener STRUCTURE_UPDATE_CONFIG_LISTENER = new BuildConfigListener() {
    public void currConfigChanged(String configFilePath) {
      if (configFilePath != null) {
        Ajde.getDefault().asm.readStructureModel(configFilePath);
      }
    }

    public void configsListUpdated(List configsList) {
    }
  };

  /**
   * Utility to run the project main class from the project properties in the same VM using a class loader populated with the
   * classpath and output path or jar. Errors are logged to the ErrorHandler.
   *
   * @param project the ProjectPropertiesAdapter specifying the main class, classpath, and executable arguments.
   * @return Thread running with process, or null if unable to start
   */
  public Thread runInSameVM() {
    final RunProperties props = new RunProperties(compilerConfig, runtimeProperties, uiBuildMsgHandler, rootFrame);
    if (!props.valid) {
      return null; // error already handled
    }
    Runnable runner = new Runnable() {
      public void run() {
        try {
          Reflection.runMainInSameVM(props.classpath, props.mainClass, props.args);
        } catch (Throwable e) {
          Message msg = new Message("Error running " + props.mainClass, IMessage.ERROR, e, null);
          uiBuildMsgHandler.handleMessage(msg);
        }
      }
    };
    Thread result = new Thread(runner, props.mainClass);
    result.start();
    return result;
  }

  /**
   * Utility to run the project main class from the project properties in a new VM. Errors are logged to the ErrorHandler.
   *
   * @return LangUtil.ProcessController running with process, or null if unable to start
   */
  public LangUtil.ProcessController runInNewVM() {
    final RunProperties props = new RunProperties(compilerConfig, runtimeProperties, uiBuildMsgHandler, rootFrame);
    if (!props.valid) {
      return null; // error already handled
    }
    // setup to run asynchronously, pipe streams through, and report errors
    final StringBuffer command = new StringBuffer();
    LangUtil.ProcessController controller = new LangUtil.ProcessController() {
      public void doCompleting(Throwable thrown, int result) {
        LangUtil.ProcessController.Thrown any = getThrown();
        if (!any.thrown && (null == thrown) && (0 == result)) {
          return; // no errors
        }
        // handle errors
        String context = props.mainClass + " command \"" + command + "\"";
        if (null != thrown) {
          String m = "Exception running " + context;
          uiBuildMsgHandler.handleMessage(new Message(m, IMessage.ERROR, thrown, null));
        } else if (0 != result) {
          String m = "Result of running " + context;
          uiBuildMsgHandler.handleMessage(new Message(m, IMessage.ERROR, null, null));
        }
        if (null != any.fromInPipe) {
          String m = "Error processing input pipe for " + context;
          uiBuildMsgHandler.handleMessage(new Message(m, IMessage.ERROR, thrown, null));
        }
        if (null != any.fromOutPipe) {
          String m = "Error processing output pipe for " + context;
          uiBuildMsgHandler.handleMessage(new Message(m, IMessage.ERROR, thrown, null));
        }
        if (null != any.fromErrPipe) {
          String m = "Error processing error pipe for " + context;
          uiBuildMsgHandler.handleMessage(new Message(m, IMessage.ERROR, thrown, null));
        }
      }
    };

    controller = LangUtil.makeProcess(controller, props.classpath, props.mainClass, props.args);

    command.append(Arrays.asList(controller.getCommand()).toString());

    // now run the process
    controller.start();
    return controller;
  }

  /** struct class to interpret project properties */
  private static class RunProperties {
    final String mainClass;
    final String classpath;
    final String[] args;
    final boolean valid;
    private final Frame rootFrame;

    RunProperties(ICompilerConfiguration compilerConfig, IRuntimeProperties runtimeProperties, IUIBuildMessageHandler handler,
        Frame rootFrame) {
      // XXX really run arbitrary handler in constructor? hmm.
      LangUtil.throwIaxIfNull(runtimeProperties, "runtime properties");
      LangUtil.throwIaxIfNull(compilerConfig, "compiler configuration");
      LangUtil.throwIaxIfNull(handler, "handler");
      LangUtil.throwIaxIfNull(rootFrame, "rootFrame");
      String mainClass = null;
      String classpath = null;
      String[] args = null;
      boolean valid = false;
      this.rootFrame = rootFrame;

      mainClass = runtimeProperties.getClassToExecute();
      if (LangUtil.isEmpty(mainClass)) {
        showWarningMessage("No main class specified");
      } else {
        StringBuffer sb = new StringBuffer();
        List outputDirs = compilerConfig.getOutputLocationManager().getAllOutputLocations();
        for (Iterator iterator = outputDirs.iterator(); iterator.hasNext();) {
          File dir = (File) iterator.next();
          sb.append(dir.getAbsolutePath() + File.pathSeparator);
        }
        classpath = LangUtil.makeClasspath(null, compilerConfig.getClasspath(), sb.toString(), compilerConfig.getOutJar());
        if (LangUtil.isEmpty(classpath)) {
          showWarningMessage("No classpath specified");
        } else {
          args = LangUtil.split(runtimeProperties.getExecutionArgs());
          valid = true;
        }
      }
      this.mainClass = mainClass;
      this.classpath = classpath;
      this.args = args;
      this.valid = valid;
    }

    private void showWarningMessage(String message) {
      JOptionPane.showMessageDialog(rootFrame, message, "Warning", JOptionPane.WARNING_MESSAGE);
    }

  }

  /**
   * Set the build off in the same thread
   *
   * @param configFile
   * @param buildFresh - true if want to do a full build, false otherwise
   */
  public void runBuildInSameThread(String configFile, boolean buildFresh) {
    AjCompiler c = getCompilerForConfigFile(configFile);
    if (c == null)
      return;
    if (buildFresh) {
      c.buildFresh();
    } else {
      c.build();
    }
  }

  /**
   * Set the build off in a different thread. Would need to set the build off in a different thread if using a swing application
   * to display the build progress.
   *
   * @param configFile
   * @param buildFresh - true if want to do a full build, false otherwise
   */
  public void runBuildInDifferentThread(String configFile, boolean buildFresh) {
    AjCompiler c = getCompilerForConfigFile(configFile);
    if (c == null)
      return;
    CompilerThread compilerThread = new CompilerThread(c, buildFresh);
    compilerThread.start();
  }

  static class CompilerThread extends Thread {

    private final AjCompiler compiler;
    private final boolean buildFresh;

    public CompilerThread(AjCompiler compiler, boolean buildFresh) {
      this.compiler = compiler;
      this.buildFresh = buildFresh;
    }

    public void run() {
      if (buildFresh) {
        compiler.buildFresh();
      } else {
        compiler.build();
      }
    }
  }

  // ---------- getter methods for the ui --------------

  /**
   * @return the singleton instance
   */
  public static Ajde getDefault() {
    return INSTANCE;
  }

  /**
   * @return the BrowserViewManager
   */
  public BrowserViewManager getViewManager() {
    return viewManager;
  }

  /**
   * @return the main frame
   */
  public Frame getRootFrame() {
    return rootFrame;
  }

  /**
   * @return the parent frame for the options panel
   */
  public OptionsFrame getOptionsFrame() {
    return optionsFrame;
  }

  /**
   * @return the IdeUIAdapter
   */
  public IdeUIAdapter getIdeUIAdapter() {
    return ideUIAdapter;
  }

  /**
   * @return the EditorAdapter
   */
  public EditorAdapter getEditorAdapter() {
    return editorAdapter;
  }

  /**
   * @return the TreeViewBuildConfigEditor
   */
  public TreeViewBuildConfigEditor getBuildConfigEditor() {
    return buildConfigEditor;
  }

  /**
   * @return the StructureViewPanel
   */
  public StructureViewPanel getFileStructurePanel() {
    return fileStructurePanel;
  }

  /**
   * @return the IconRegistry
   */
  public IconRegistry getIconRegistry() {
    return iconRegistry;
  }

  /**
   * @return the StructureViewManager
   */
  public StructureViewManager getStructureViewManager() {
    return structureViewManager;
  }

  /**
   * @return the StructureSearchManager
   */
  public StructureSearchManager getStructureSearchManager() {
    return structureSearchManager;
  }

  /**
   * @return the BuildConfigManager
   */
  public BuildConfigManager getBuildConfigManager() {
    return configurationManager;
  }

  // -------------- getter methods for the compiler -------------

  /**
   * @return the ICompilerConfiguration
   */
  public ICompilerConfiguration getCompilerConfig() {
    return compilerConfig;
  }

  /**
   * @return the IUIBuildMessageHandler
   */
  public IUIBuildMessageHandler getMessageHandler() {
    return uiBuildMsgHandler;
  }

  /**
   * @return the IBuildProgressMonitor
   */
  public IBuildProgressMonitor getBuildProgressMonitor() {
    return buildProgressMonitor;
  }

  /**
   * If the provided configFile is the same as the id for the last compiler then returns that, otherwise clears the state for the
   * saved compiler and creates a new one for the provided configFile
   *
   * @param configFile
   * @return the AjCompiler with the id of the given configFile
   */
  public AjCompiler getCompilerForConfigFile(String configFile) {
    if (configFile == null) {
      return null;
    }
    if ((compiler == null || !compiler.getId().equals(configFile))) {
      if (compiler != null) {
        // have to remove the incremental state of the previous
        // compiler - this will remove it from the
        // IncrementalStateManager's
        // list
        compiler.clearLastState();
      }
      getMessageHandler().reset();
      compiler = new AjCompiler(configFile, getCompilerConfig(), getBuildProgressMonitor(), getMessageHandler());
    }
    return compiler;
  }

  public AsmManager getModelForConfigFile(String configFile) {
    return compiler.getModel();
    // if ((compiler == null || !compiler.getId().equals(configFile))) {
    // if (compiler != null) {
    // // have to remove the incremental state of the previous
    // // compiler - this will remove it from the
    // // IncrementalStateManager's
    // // list
    // compiler.clearLastState();
    // }
    // getMessageHandler().reset();
    // compiler = new AjCompiler(configFile, getCompilerConfig(), getBuildProgressMonitor(), getMessageHandler());
    // }

  }
}
TOP

Related Classes of org.aspectj.ajde.Ajde$RunProperties

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.