org.jactr.entry.Main.java Source code

Java tutorial

Introduction

Here is the source code for org.jactr.entry.Main.java

Source

/**
 * Copyright (C) 2001-3, Anthony Harrison anh23@pitt.edu This library is free
 * software; you can redistribute it and/or modify it under the terms of the GNU
 * Lesser General Public License as published by the Free Software Foundation;
 * either version 2.1 of the License, or (at your option) any later version.
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details. You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

package org.jactr.entry;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.locks.ReadWriteLock;

import org.antlr.runtime.tree.CommonTree;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jactr.core.concurrent.ExecutorServices;
import org.jactr.core.logging.Logger;
import org.jactr.core.logging.impl.DefaultModelLogger;
import org.jactr.core.model.IModel;
import org.jactr.core.runtime.ACTRRuntime;
import org.jactr.core.runtime.controller.DefaultController;
import org.jactr.core.runtime.controller.IController;
import org.jactr.io.IOUtilities;
import org.jactr.io.antlr3.compiler.CompilationWarning;
import org.jactr.io.antlr3.misc.CommonTreeException;
import org.jactr.io.environment.EnvironmentParser;

/**
 * jACT-R start up application Usage: jactr --compile modelFile.jactr execution:
 * jactr --environment environment.env jactr --run modelFile.compiled jactr
 * --run modelFile.compiled --onStart class --onStop class jactr --log exit
 * codes: -3 unknown -2 compilation error -1 configuration error 0 success
 * 
 * @author harrison
 * @created July 19, 2001
 */
public class Main {

    static private final Log LOGGER = LogFactory.getLog(Main.class);

    /**
     * @param cmd
     */
    public Main() {
    }

    /**
     * create the deafault environment for a run.. possibly setting up the
     * onStart/Stop
     * 
     * @return
     */
    public ACTRRuntime configureRuntime(ACTRRuntime runtime, CommandLine cmd) {

        // now we try to attach the onStart onStop
        if (cmd.hasOption('s')) {
            String className = cmd.getOptionValue('s');
            try {
                Class runnableClass = getClass().getClassLoader().loadClass(className);
                Runnable runner = (Runnable) runnableClass.newInstance();
                runtime.setOnStart(runner);
            } catch (Exception e) {
                LOGGER.error("Could not load the onStart class " + className, e);
                System.err.println("Could not load the onStart class " + className);
                e.printStackTrace(System.err);
                System.exit(-1);
            }
        }

        if (cmd.hasOption('p')) {
            String className = cmd.getOptionValue('p');
            try {
                Class runnableClass = getClass().getClassLoader().loadClass(className);
                Runnable runner = (Runnable) runnableClass.newInstance();
                runtime.setOnStop(runner);
            } catch (Exception e) {
                LOGGER.error("Could not load the onStop class " + className, e);
                System.err.println("Could not load the onStop class " + className);
                e.printStackTrace(System.err);
                System.exit(-1);
            }
        }

        return runtime;
    }

    /**
     * set up the logging for the models
     * 
     * @param cmd
     * @return
     */
    public ACTRRuntime configureLogging(ACTRRuntime runtime, CommandLine cmd) {
        if (cmd.hasOption('l'))
            for (IModel model : runtime.getModels()) {
                /*
                 * route all the named logs to System.out
                 */
                DefaultModelLogger dml = new DefaultModelLogger();
                // and attach to the available models
                model.install(dml);

                String[] logs = cmd.getOptionValues('l');
                for (String logName : logs) {
                    Logger.Stream.valueOf(logName);
                    dml.setParameter(logName, "out");
                }

            }
        return runtime;
    }

    public void waitForRuntime(ACTRRuntime runtime) {
        IController controller = runtime.getController();
        try {
            controller.complete().get();
        } catch (InterruptedException ie) {
            LOGGER.error(ie);
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            LOGGER.error("Main.waitForRuntime threw ExecutionException : ", e);
        }
    }

    public void run(ACTRRuntime runtime) {

        IController controller = runtime.getController();
        if (controller == null) {
            controller = new DefaultController();
            runtime.setController(controller);
        }

        try {
            controller.start().get();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            LOGGER.error("Main.run threw InterruptedException : ", e);
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            LOGGER.error("Main.run threw ExecutionException : ", e);
        }
    }

    public void cleanUp(ACTRRuntime runtime) {

        if (runtime.getConnector().isRunning())
            try {
                runtime.getConnector().stop();
            } catch (Exception e) {
                LOGGER.error("Failed to shutdown connector ", e);
            }

        /*
         * detach the current controller before we exit
         */
        runtime.setController(null);

        /*
         * and clean up
         */
        ArrayList<IModel> toDispose = new ArrayList<IModel>();
        for (IModel model : new ArrayList<IModel>(runtime.getModels())) {
            runtime.removeModel(model);
            toDispose.add(model);
        }

        /*
         * will kill the background threads..
         */
        ExecutorServices.shutdown(0);

        /*
         * and dispose. Why not dispose with the remove? listeners may still be
         * active even after the runtime has stopped. We dispose after the service
         * has been shutdown, making sure that all work has been completed
         */
        for (IModel model : toDispose) {
            ReadWriteLock lock = model.getLock();
            lock.writeLock().lock();

            try {
                model.dispose();
            } catch (Exception e) {
                LOGGER.error(String.format("Failed to dispose of %s cleanly. ", model), e);
            } finally {
                lock.writeLock().unlock();
            }
        }
    }

    public ACTRRuntime createRuntime(URL environmentConfigFile) throws Exception {
        EnvironmentParser parser = new EnvironmentParser();
        parser.parse(environmentConfigFile);
        return ACTRRuntime.getRuntime();
    }

    public ACTRRuntime createRuntime(CommandLine cmd) throws Exception {
        ACTRRuntime runtime = null;
        if (cmd.hasOption('e')) {
            String envFile = cmd.getOptionValue('e');
            File fp = new File(envFile);
            runtime = createRuntime(fp.toURL());
        }

        return runtime;
    }

    /**
     * compile the models
     * 
     * @param cmd
     */
    public void compile(CommandLine cmd) {
        boolean error = false;
        if (cmd.hasOption('c')) {
            String[] sourceModelFiles = cmd.getOptionValues('c');
            for (String source : sourceModelFiles) {
                ArrayList<Exception> warnings = new ArrayList<Exception>();
                ArrayList<Exception> errors = new ArrayList<Exception>();
                CommonTree md = null;

                try {
                    URL url = new File(source).toURL();
                    md = IOUtilities.loadModelFile(url, warnings, errors);
                    // compile
                    error = !IOUtilities.compileModelDescriptor(md, warnings, errors);

                    dumpExceptions(source, warnings);
                    dumpExceptions(source, errors);
                } catch (Exception e) {
                    LOGGER.error("Could not load " + source, e);
                    System.err.println("Could not load " + source);
                    e.printStackTrace(System.err);
                    error = true;
                }
            }
        }

        if (error)
            System.exit(-2);
    }

    protected void dumpExceptions(String sourceFile, Collection<Exception> exceptions) {
        for (Exception e : exceptions) {
            StringBuilder builder = new StringBuilder();
            builder.append("(");
            builder.append(sourceFile);

            if (e instanceof CommonTreeException) {
                CommonTreeException ae = (CommonTreeException) e;
                CommonTree node = ae.getStartNode();
                builder.append(":");
                builder.append(node.getLine());
                builder.append(",");
                builder.append(node.getCharPositionInLine());
                builder.append(") ");

                if (ae instanceof CompilationWarning)
                    builder.append(" Warning : ");
                else
                    builder.append(" Error : ");
            } else
                builder.append(") Error : ");

            builder.append(e.getMessage());
            System.err.println(builder.toString());
        }
    }

    public ACTRRuntime loadModels(ACTRRuntime runtime, CommandLine cmd) {
        boolean error = false;
        if (cmd.hasOption('r')) {
            String[] compiledModelFiles = cmd.getOptionValues('r');
            for (String modelFile : compiledModelFiles)
                try {
                    URL url = new File(modelFile).toURL();
                    Collection<Exception> warnings = new ArrayList<Exception>();
                    Collection<Exception> errors = new ArrayList<Exception>();

                    CommonTree md = IOUtilities.loadModelFile(url, warnings, errors);
                    // compile
                    IOUtilities.compileModelDescriptor(md, warnings, errors);

                    // construct
                    IModel model = IOUtilities.constructModel(md, warnings, errors);

                    if (warnings.size() != 0) {
                        System.err.println(modelFile + " has warnings");
                        dumpExceptions(modelFile, warnings);
                    }

                    if (errors.size() == 0)
                        runtime.addModel(model);
                    else {
                        System.err.println(modelFile + " has errors");
                        dumpExceptions(modelFile, errors);
                    }
                } catch (Exception e) {
                    LOGGER.error("Could not load model from " + modelFile, e);
                    System.err.println("Could not load model from " + modelFile);
                    e.printStackTrace(System.err);
                    error = true;
                }
        }

        if (error)
            System.exit(-3);

        return runtime;
    }

    /**
     * The main program for the jactr class
     * 
     * @param argv
     *          The command line arguments
     * @since
     */
    public static void main(String[] argv) {
        try {
            Options options = new Options();
            options.addOption(OptionBuilder.create("h"));

            options.addOption(OptionBuilder.create('c'));

            options.addOption(OptionBuilder.create('e'));

            options.addOption(OptionBuilder.create('r'));

            options.addOption(OptionBuilder.create('s'));
            options.addOption(OptionBuilder.create('p'));

            options.addOption(OptionBuilder.create('l'));

            CommandLineParser parser = new PosixParser();

            CommandLine cmd = parser.parse(options, argv);
            Main env = new Main();

            /*
             * compile
             */
            if (cmd.hasOption('c'))
                env.compile(cmd);
            else if (cmd.hasOption('e') || cmd.hasOption('r')) {
                ExecutorServices.initialize();

                ACTRRuntime runtime = env.configureLogging(
                        env.loadModels(env.configureRuntime(env.createRuntime(cmd), cmd), cmd), cmd);

                if (cmd.hasOption('r'))
                    env.run(runtime);

                env.waitForRuntime(runtime);

                env.cleanUp(runtime);
            } else {
                HelpFormatter formatter = new HelpFormatter();
                formatter.printHelp("jactr", options);
                System.exit(0);
            }
        } catch (Exception e) {
            LOGGER.error("Main exception ", e);
            e.printStackTrace();
            System.exit(-3);
        }
        System.exit(0);
    }

}