diff options
author | Matthew Davis | 2011-03-08 18:37:24 +0000 |
---|---|---|
committer | Matthew Davis | 2011-03-08 18:37:24 +0000 |
commit | 2df9af2913973ae674d2bd735287db68867c831e (patch) | |
tree | 321cfa95a4fccb14515b56ea0a9236e040cab11d | |
parent | de8f43efceb063713b7b4af82088709b2c569c9e (diff) | |
download | org.eclipse.stem-2df9af2913973ae674d2bd735287db68867c831e.tar.gz org.eclipse.stem-2df9af2913973ae674d2bd735287db68867c831e.tar.xz org.eclipse.stem-2df9af2913973ae674d2bd735287db68867c831e.zip |
Adding headless launch option
git-svn-id: http://dev.eclipse.org/svnroot/technology/org.eclipse.stem/trunk@1514 92a21009-5b66-0410-b83a-dc787c41c6e9
6 files changed, 424 insertions, 16 deletions
diff --git a/org.eclipse.stem.ui/src/org/eclipse/stem/core/common/presentation/CoreEditorAdvisor.java b/org.eclipse.stem.ui/src/org/eclipse/stem/core/common/presentation/CoreEditorAdvisor.java index 619c62e55..dac9a413a 100644 --- a/org.eclipse.stem.ui/src/org/eclipse/stem/core/common/presentation/CoreEditorAdvisor.java +++ b/org.eclipse.stem.ui/src/org/eclipse/stem/core/common/presentation/CoreEditorAdvisor.java @@ -36,12 +36,12 @@ import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.stem.core.launcher.LauncherFactory; import org.eclipse.stem.ui.Activator; import org.eclipse.stem.ui.perspectives.Simulation; import org.eclipse.stem.ui.preferences.STEMPreferencePage; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IFolderLayout; @@ -52,7 +52,6 @@ import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; -import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; import org.eclipse.ui.actions.ContributionItemFactory; @@ -400,20 +399,7 @@ public final class CoreEditorAdvisor extends WorkbenchAdvisor { * @generated */ public Object start(IApplicationContext context) throws Exception { - WorkbenchAdvisor workbenchAdvisor = new CoreEditorAdvisor(); - Display display = PlatformUI.createDisplay(); - try { - int returnCode = PlatformUI.createAndRunWorkbench(display, workbenchAdvisor); - if (returnCode == PlatformUI.RETURN_RESTART) { - return IApplication.EXIT_RESTART; - } - else { - return IApplication.EXIT_OK; - } - } - finally { - display.dispose(); - } + return LauncherFactory.getLauncher(context).launch(); } /** diff --git a/org.eclipse.stem.ui/src/org/eclipse/stem/core/launcher/CommandArgumentParser.java b/org.eclipse.stem.ui/src/org/eclipse/stem/core/launcher/CommandArgumentParser.java new file mode 100644 index 000000000..1c821fc26 --- /dev/null +++ b/org.eclipse.stem.ui/src/org/eclipse/stem/core/launcher/CommandArgumentParser.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.stem.core.launcher; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Simple class to read and parse command line options + * passed to the Eclipse / STEM runtime. Parses out + * arguments beginning with "-" into keys and space-separated + * values following the key as a list of values. + * + */ +public class CommandArgumentParser +{ + public static final String NO_COMMAND_KEY = "NONE"; + + /** + * Parses an array of command-line arguments into key/value + * groupings of command keys (starting with '-') and the values that + * follow the keys. + * + * @param args Array of command line arguments + * @return Parsed map of key/value commands + */ + public static Map<String,List<String>> parse(String[] args) + { + Map<String,List<String>> params = new HashMap<String,List<String>>(); + + if (args != null && args.length > 0) { + String currentParam = null; + List<String> currentParamValues = null; + + for (String arg : args) { + if (arg.charAt(0) == '-') { + currentParam = arg.substring(1); + currentParamValues = new ArrayList<String>(); + params.put(currentParam, currentParamValues); + + } else { + if (currentParam == null) { + currentParam = NO_COMMAND_KEY; + currentParamValues = new ArrayList<String>(); + params.put(currentParam, currentParamValues); + } + + currentParamValues.add(arg); + } + } + } + + return Collections.unmodifiableMap(params); + } + +} diff --git a/org.eclipse.stem.ui/src/org/eclipse/stem/core/launcher/HeadlessLauncher.java b/org.eclipse.stem.ui/src/org/eclipse/stem/core/launcher/HeadlessLauncher.java new file mode 100644 index 000000000..062cf8b72 --- /dev/null +++ b/org.eclipse.stem.ui/src/org/eclipse/stem/core/launcher/HeadlessLauncher.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.stem.core.launcher; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.equinox.app.IApplication; +import org.eclipse.equinox.app.IApplicationContext; +import org.eclipse.stem.jobs.headless.HeadlessSimulationRunner; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Synchronizer; +import org.osgi.framework.Bundle; + +/** + * Launcher that starts STEM in a non-GUI "headless" mode. The purpose + * of this class is to enable command line execution of specific + * STEM operations, such as running individual simulations and experiments. + * + */ +public class HeadlessLauncher extends Launcher +{ + private static final String DISTRIBUTED_CONTROLLER_PLUGIN_NAME = "org.eclipse.stem.graphsynchronizer"; + + /** + * STEM Launcher for headless mode. + * @param ctx Eclipse Application Context + * @param args Command line arguments + */ + public HeadlessLauncher(IApplicationContext ctx, Map<String,List<String>> args) + { + super(ctx,args); + } + + /** + * Checks for the presence of the -distributed command line option + * and enables distributed STEM by issue a transient start to the + * implementing OSGi bundle. + */ + protected void checkDistributed() + { + if (args.containsKey("distributed")) { + try { + System.out.println("Enabling STEM distributed mode."); + Bundle distBundle = Platform.getBundle(DISTRIBUTED_CONTROLLER_PLUGIN_NAME); + if (distBundle != null) { + distBundle.start(Bundle.START_TRANSIENT); + } else { + System.err.println("Distributed STEM plugin not found. Distributed mode not enabled."); + } + } catch (Exception e) { + System.err.println("Error launching distributed STEM plugin. Will continue in standalone."); + e.printStackTrace(System.err); + } + } + } + + /** + * Sets the correct System streams based on command line options + */ + protected void setStreams() + { + if (args.containsKey("quiet")) { + System.setOut(new PrintStream(new NullOutputStream())); + } + } + + /* (non-Javadoc) + * @see org.eclipse.stem.core.launcher.Launcher#launch() + */ + public Object launch() + { + // Create the display on the main thread (OS X workaround) + Display display = Display.getDefault(); + // Override the display synchronizer to prevent deadlocks (sync) + // and missed executions (async) in headless mode + display.setSynchronizer(new HeadlessDisplaySynchronizer(display)); + // Drop the splash screen + context.applicationRunning(); + + setStreams(); + + try { + // Check for and enable distributed mode if requested + checkDistributed(); + + // Collect scenarios to simulate and run + HeadlessSimulationRunner runner = new HeadlessSimulationRunner(); + runner.run(args); + + return IApplication.EXIT_OK; + } finally { + display.dispose(); + } + } + + /** + * SWT Display synchronizer to fix issues with using Display.syncExec + * and Display.asyncExec when no UI is present. Highly non-kosher. + * + */ + private class HeadlessDisplaySynchronizer extends Synchronizer + { + public HeadlessDisplaySynchronizer(Display d) + { + super(d); + } + + /* (non-Javadoc) + * @see org.eclipse.swt.widgets.Synchronizer#asyncExec(java.lang.Runnable) + */ + protected void asyncExec(final Runnable runnable) + { + // For asynchronous execution, schedule and run + // an asynchronous job to execute the runnable instance. + if (runnable != null) { + new Job(runnable.toString()) { + @SuppressWarnings("unused") + protected IStatus run(IProgressMonitor monitor) { + runnable.run(); + return Status.OK_STATUS; + } + }.schedule(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.swt.widgets.Synchronizer#syncExec(java.lang.Runnable) + */ + protected void syncExec(final Runnable runnable) + { + // For synchronous execution, just call the + // runnable instance directly. Should block + // on execution to complete. + if (runnable != null) { + runnable.run(); + } + } + + } + + /** + * Null output stream for ignoring all output + */ + @SuppressWarnings("unused") + private class NullOutputStream extends OutputStream + { + NullOutputStream() {} + public void close() {} + public void flush() {} + public void write( byte[] b, int off, int len) {} + public void write(byte[] b) {} + public void write(int b) {} + } +} diff --git a/org.eclipse.stem.ui/src/org/eclipse/stem/core/launcher/Launcher.java b/org.eclipse.stem.ui/src/org/eclipse/stem/core/launcher/Launcher.java new file mode 100644 index 000000000..34d468a67 --- /dev/null +++ b/org.eclipse.stem.ui/src/org/eclipse/stem/core/launcher/Launcher.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.stem.core.launcher; + +import java.util.List; +import java.util.Map; + +import org.eclipse.equinox.app.IApplicationContext; + +/** + * Abstract class representing a STEM application launcher + * Implementing classes should populate the abstract + * launch() method for invocation. + * + */ +public abstract class Launcher +{ + /** + * Eclipse Application Context + */ + protected IApplicationContext context; + + /** + * Parsed command line arguments + */ + protected Map<String,List<String>> args; + + /** + * Launcher super constructor. Sets the application context and command + * line arguments for all implementations. + * + * @param context Eclipse Application Context (passed to IApplication#start()) + * @param args Parsed command line arguments + */ + public Launcher(IApplicationContext context, Map<String,List<String>> args) + { + this.context = context; + this.args = args; + } + + /** + * @return The Eclipse application context + */ + protected IApplicationContext getContext() + { + return context; + } + + /** + * @return The parsed command line arguments + */ + protected Map<String,List<String>> getCommandArguments() + { + return args; + } + + /** + * Launches the STEM application. Implementations should + * use this method to prepare, launch, and manage the lifecycle + * of the STEM application based on the conditions of the launcher + * implementation. + * + * The return from this method represents the intended return from + * {@link IApplication#start(IApplicationContext)}, an integer from the set of [{@link IApplication#EXIT_OK}, + * {@link IApplication#EXIT_RELAUNCH}, {@link IApplication#EXIT_RESTART}]. + * + * @return See return from IApplication#start(IApplicationContext) + */ + public abstract Object launch(); +} diff --git a/org.eclipse.stem.ui/src/org/eclipse/stem/core/launcher/LauncherFactory.java b/org.eclipse.stem.ui/src/org/eclipse/stem/core/launcher/LauncherFactory.java new file mode 100644 index 000000000..01612ec37 --- /dev/null +++ b/org.eclipse.stem.ui/src/org/eclipse/stem/core/launcher/LauncherFactory.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.stem.core.launcher; + +import java.util.List; +import java.util.Map; + +import org.eclipse.equinox.app.IApplicationContext; + +/** + * Factory class to determine and return the correct + * STEM launcher implementation based on the application + * context and command line parameters. + */ +public class LauncherFactory +{ + /** + * Parses command line arguments and returns the requested + * STEM launcher based on the arguments passed. + * + * Currently only supports the workbench and the headless launchers. + * + * @param context Eclipse Application Context + * @return Launcher to use for launching the STEM application + */ + public static Launcher getLauncher(IApplicationContext context) + { + // Parse the command line arugments + String[] args = (String[])context.getArguments().get("application.args"); + Map<String,List<String>> commandArgs = CommandArgumentParser.parse(args); + + Launcher launcher = null; + if (commandArgs.containsKey("headless")) { + launcher = new HeadlessLauncher(context, commandArgs); + } else { + launcher = new WorkbenchLauncher(context, commandArgs); + } + + return launcher; + } +} diff --git a/org.eclipse.stem.ui/src/org/eclipse/stem/core/launcher/WorkbenchLauncher.java b/org.eclipse.stem.ui/src/org/eclipse/stem/core/launcher/WorkbenchLauncher.java new file mode 100644 index 000000000..4d8f10cef --- /dev/null +++ b/org.eclipse.stem.ui/src/org/eclipse/stem/core/launcher/WorkbenchLauncher.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.stem.core.launcher; + +import java.util.List; +import java.util.Map; + +import org.eclipse.equinox.app.IApplication; +import org.eclipse.equinox.app.IApplicationContext; +import org.eclipse.stem.core.common.presentation.CoreEditorAdvisor; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.application.WorkbenchAdvisor; + +/** + * Standard STEM Workbench launcher. This launches the full + * STEM user interface and workbench, including RCP application. + * + */ +public class WorkbenchLauncher extends Launcher +{ + /** + * @param ctx Eclipse Application Context + * @param args Command arguments + */ + public WorkbenchLauncher(IApplicationContext ctx, Map<String,List<String>> args) + { + super(ctx,args); + } + + /* (non-Javadoc) + * @see org.eclipse.stem.core.launcher.Launcher#launch() + */ + public Object launch() + { + WorkbenchAdvisor workbenchAdvisor = new CoreEditorAdvisor(); + Display display = PlatformUI.createDisplay(); + try { + int returnCode = PlatformUI.createAndRunWorkbench(display, workbenchAdvisor); + if (returnCode == PlatformUI.RETURN_RESTART) { + return IApplication.EXIT_RESTART; + } + + return IApplication.EXIT_OK; + } finally { + display.dispose(); + } + } +} |