package org.jactr.launching; import java.net.URI; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.GnuParser; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.equinox.app.IApplication; import org.eclipse.equinox.app.IApplicationContext; import org.jactr.core.concurrent.ExecutorServices; import org.jactr.core.runtime.ACTRRuntime; import org.jactr.core.runtime.event.ACTRRuntimeAdapter; import org.jactr.core.runtime.event.ACTRRuntimeEvent; import org.jactr.core.runtime.event.IACTRRuntimeListener; import org.jactr.entry.Main; import org.jactr.entry.iterative.IterativeMain; import org.osgi.framework.Bundle; /** * This class controls all aspects of the application's execution */ public class Application implements IApplication { /** * Logger definition */ static private final transient Log LOGGER = LogFactory .getLog(Application.class); /** * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext) */ public Object start(IApplicationContext context) throws Exception { String[] arguments = (String[]) context.getArguments().get( IApplicationContext.APPLICATION_ARGS); Options options = new Options(); /* * this option is supposed to be consumed by the launcher, but it is passing * it along for some unknown reason */ // options.addOption(new Option("2","launcher.secondThread", false, "MAC // Only : force launcher to use second thread")); options.addOption(new Option("e", "environment", true, "Load the contents of the environment config file")); options.addOption(new Option("r", "run", true, "Run the configured environment")); options.addOption(new Option("i", "iterative", true, "Run the iterative environment")); options.addOption(new Option("p","permissions", true, "modify permissions")); addIrrelevantOptions(options); CommandLineParser parser = new GnuParser(); CommandLine cmd = parser.parse(options, arguments, false); String environmentFile = ""; boolean shouldRun = false; boolean isIterative = false; if(cmd.hasOption('p')) Activator.getDefault().modifyPermissions(cmd.getOptionValue('p')); if (cmd.hasOption('e')) environmentFile = cmd.getOptionValue('e'); if (cmd.hasOption('r')) { shouldRun = true; environmentFile = cmd.getOptionValue('r'); } if (cmd.hasOption('i')) { isIterative = true; environmentFile = cmd.getOptionValue('i'); } if (LOGGER.isDebugEnabled()) LOGGER.debug("Loading " + environmentFile + " run:" + shouldRun); URL url = getClass().getClassLoader().getResource(environmentFile); try { if (url == null) url = URI.create(environmentFile).toURL(); context.applicationRunning(); if (isIterative) runIterative(url); else runNormal(url, shouldRun); } catch (Exception e) { String msg = "Unable to execute runtime from " + environmentFile; LOGGER.error(msg, e); Activator.getDefault().getLog().log( new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, msg, e)); return -1; } return IApplication.EXIT_OK; } /** * this adds the irrelevant options that for whatever buggy reason eclipse * does not consume * * @param options */ private void addIrrelevantOptions(Options options) { for (String opt : new String[] { "consoleLog", "showlocation" }) options.addOption(new Option(opt, false, "unconsumed eclipse option")); for (String opt : new String[] { "keyring" }) options.addOption(new Option(opt, true, "unconsumed eclipse option")); } /** * run using the iterative entry point * * @param url * @throws Exception */ protected void runIterative(URL url) throws Exception { IterativeMain main = new IterativeMain(); main.run(url); } /** * run using the standard entry point * * @param url * @param shouldRun */ protected void runNormal(URL url, boolean shouldRun) throws Exception { Main jactrEntryPoint = new Main(); ACTRRuntime runtime = jactrEntryPoint.createRuntime(url); if (shouldRun) { if (LOGGER.isDebugEnabled()) LOGGER.debug("Starting"); jactrEntryPoint.run(runtime); } else waitForStart(runtime); if (LOGGER.isDebugEnabled()) LOGGER.debug("Waiting for completion"); jactrEntryPoint.waitForRuntime(runtime); if (LOGGER.isDebugEnabled()) LOGGER.debug("Cleaning up"); jactrEntryPoint.cleanUp(runtime); } private void waitForStart(ACTRRuntime runtime) throws Exception { final Lock lock = new ReentrantLock(); final Condition condition = lock.newCondition(); IACTRRuntimeListener listener = new ACTRRuntimeAdapter(){ public void runtimeStarted(ACTRRuntimeEvent event) { try { lock.lock(); condition.signalAll(); } finally { lock.unlock(); } } }; runtime.addListener(listener, ExecutorServices.INLINE_EXECUTOR); /* * wait to start */ try { lock.lock(); while(!runtime.getController().isRunning()) condition.await(); } finally { lock.unlock(); } runtime.removeListener(listener); } /** * @see org.eclipse.equinox.app.IApplication#stop() */ public void stop() { // TODO implement Application.stop if (LOGGER.isWarnEnabled()) LOGGER.warn("Application.stop is not implemented"); } @SuppressWarnings("unchecked") static public void main(String[] argv) { final Map args = new HashMap(); args.put(IApplicationContext.APPLICATION_ARGS, argv); IApplicationContext context = new IApplicationContext() { public void applicationRunning() { } public Map getArguments() { return args; } public String getBrandingApplication() { return null; } public Bundle getBrandingBundle() { return null; } public String getBrandingDescription() { return null; } public String getBrandingId() { return null; } public String getBrandingName() { return null; } public String getBrandingProperty(String key) { return null; } public void setResult(Object result, IApplication application) { // TODO Auto-generated method stub } }; Application app = new Application(); try { app.start(context); } catch (Exception e) { LOGGER.error("Application.main threw Exception : ", e); System.exit(-1); } System.exit(0); } }