]> source.dussan.org Git - aspectj.git/commitdiff
support both same- and other-vm runs using new using new LangUtil API's for running...
authorwisberg <wisberg>
Mon, 5 May 2003 07:33:17 +0000 (07:33 +0000)
committerwisberg <wisberg>
Mon, 5 May 2003 07:33:17 +0000 (07:33 +0000)
ajde/src/org/aspectj/ajde/Ajde.java

index bc9893dea75bf2737fed09df105ac8232d017e60..b1a473d7e57658e96cd671df43f567fee737dc0f 100644 (file)
 
 package org.aspectj.ajde;
 
-import java.io.File;
-import java.io.PrintStream;
-import java.util.List;
-
 import org.aspectj.ajde.internal.AspectJBuildManager;
 import org.aspectj.ajde.internal.LstBuildConfigManager;
 import org.aspectj.ajde.ui.EditorManager;
@@ -30,6 +26,10 @@ import org.aspectj.bridge.Version;
 import org.aspectj.util.LangUtil;
 import org.aspectj.util.Reflection;
 
+import java.io.PrintStream;
+import java.util.Arrays;
+import java.util.List;
+
 /**
  * Singleton class responsible for AJDE initialization, and the main point of access to
  * Ajde functionality. 
@@ -41,33 +41,7 @@ public class Ajde {
        private static final Ajde INSTANCE = new Ajde();
        private static final String NOT_INITIALIZED_MESSAGE = "Ajde is not initialized.";
        private static boolean isInitialized = false;
-
-    /**
-     * Utility to run the project main class in the same VM
-     * using a class loader populated with the classpath
-     * and output path or jar.
-     * @param project the ProjectPropertiesAdapter specifying the
-     * main class, classpath, and executable arguments.
-     */
-    public static void runInSameVM(ProjectPropertiesAdapter project) {
-        String mainClass = "<none>";
-        try {            
-            mainClass = project.getClassToExecute();
-            if (LangUtil.isEmpty(mainClass)) {
-                Ajde.getDefault().getErrorHandler().handleWarning("No main class specified");
-            }
-            String classpath = project.getOutputPath();
-            if (LangUtil.isEmpty(classpath)) {
-                classpath = project.getOutJar();
-            }
-            classpath += File.pathSeparator + project.getClasspath();
-            String[] args = LangUtil.split(project.getExecutionArgs());
-            Reflection.runMainInSameVM(classpath, mainClass, args);
-        } catch(Throwable e) {
-            Ajde.getDefault().getErrorHandler().handleError("Error running " + mainClass, e);
-        }
-    }  
-
+    
        private BuildManager buildManager;
        private EditorManager editorManager;
        private StructureViewManager structureViewManager;
@@ -206,6 +180,101 @@ public class Ajde {
                }       
        }
 
+    /**
+     * 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(getProjectProperties(), getErrorHandler());
+        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) {
+                    Ajde.getDefault().getErrorHandler().handleError("Error running " + props.mainClass, e);
+                }
+            }
+        };
+        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(getProjectProperties(), getErrorHandler());
+        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() {
+                protected 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;
+                        getErrorHandler().handleError(m, thrown);
+                    } else if (0 != result) {
+                        String m = "Result of running " + context;
+                        getErrorHandler().handleError(m + ": " + result);
+                    }
+                    if (null != any.fromInPipe) {
+                        String m = "Error processing input pipe for " + context;
+                        getErrorHandler().handleError(m, any.fromInPipe);
+                    }
+                    if (null != any.fromOutPipe) {
+                        String m = "Error processing output pipe for " + context;
+                        getErrorHandler().handleError(m, any.fromOutPipe);
+                    }
+                    if (null != any.fromErrPipe) {
+                        String m = "Error processing error pipe for " + context;
+                        getErrorHandler().handleError(m, any.fromErrPipe);
+                    }
+                }
+            };
+            
+        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;
+    }
+
        private final BuildConfigListener STRUCTURE_UPDATE_CONFIG_LISTENER = new BuildConfigListener() {
                public void currConfigChanged(String configFilePath) {
                        if (configFilePath != null) Ajde.getDefault().getStructureModelManager().readStructureModel(configFilePath);
@@ -247,6 +316,45 @@ public class Ajde {
                this.errorHandler = errorHandler;
        }
 
+    /** struct class to interpret project properties */
+    private static class RunProperties {
+        final String mainClass;
+        final String classpath;
+        final String[] args;
+        final boolean valid;
+        RunProperties(
+            ProjectPropertiesAdapter project, 
+            ErrorHandler handler) {
+            // XXX really run arbitrary handler in constructor? hmm.
+            LangUtil.throwIaxIfNull(project, "project");
+            LangUtil.throwIaxIfNull(handler, "handler");
+            String mainClass = null;
+            String classpath = null;            
+            String[] args = null;
+            boolean valid = false;
+            
+            mainClass = project.getClassToExecute();
+            if (LangUtil.isEmpty(mainClass)) {
+                handler.handleWarning("No main class specified");
+            } else {
+                classpath = LangUtil.makeClasspath(
+                    project.getBootClasspath(),
+                    project.getClasspath(),
+                    project.getOutputPath(),
+                    project.getOutJar());
+                if (LangUtil.isEmpty(classpath)) {
+                    handler.handleWarning("No classpath specified");
+                } else {
+                    args = LangUtil.split(project.getExecutionArgs());
+                    valid = true;
+                }
+            }
+            this.mainClass = mainClass;
+            this.classpath = classpath;
+            this.args = args;
+            this.valid = valid;
+        }
+    }
 }