languageTools.Analyzer.java Source code

Java tutorial

Introduction

Here is the source code for languageTools.Analyzer.java

Source

/**
 * The GOAL Grammar Tools. Copyright (C) 2014 Koen Hindriks.
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program 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 General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */

package languageTools;

import goalhub.krTools.KRFactory;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import krTools.errors.exceptions.KRInitFailedException;
import languageTools.analyzer.Validator;
import languageTools.analyzer.agent.AgentValidator;
import languageTools.analyzer.mas.MASValidator;
import languageTools.analyzer.module.ModuleValidator;
import languageTools.analyzer.test.TestValidator;
import languageTools.utils.Extension;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;

/**
 * <pre>
 * {@code
 * Usage: languageTools.Analyzer [options] [[file|directory]]
 *  -mas            Analyze MAS files
 *  -goal            Analyze GOAL agent files
 *  -module            Analyze module files
 *  -r,--recursive      Recursively search directories
 * }
 * </pre>
 */
public class Analyzer {

    private static final String OPTION_LEXER = "lexer";
    private static final String OPTION_PROGRAM = "program";

    private static final String OPTION_MAS = "mas";
    private static final String OPTION_GOAL = "goal";
    private static final String OPTION_MOD2G = "module";

    private static final String OPTION_RECURSIVE = "recursive";
    private static final String OPTION_RECURSIVE_SHORT = "r";

    private static final String OPTION_HELP = "help";
    private static final String OPTION_HELP_SHORT = "h";

    private static final String OPTION_LICENSE = "license";

    private static final Options options = createOptions();

    // Print token output generated by lexer?
    private static boolean lexer = false;
    // Print program generated by parser?
    private static boolean program = false;
    // Analyze MAS files?
    private static boolean masFile;
    // Analyze agent files?
    private static boolean agentFile;
    // Analyze module files?
    private static boolean moduleFile;
    // Recursively search directories?
    private static boolean recursive;

    /**
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) {

        // Get start time.
        long startTime = System.nanoTime();

        // Parse command line options
        File file;
        try {
            file = parseOptions(args);
        } catch (ParseException e) {
            System.out.println(e.getMessage());
            showHelp();
            return;
        }

        // Get all files that should be analyzed
        List<File> files = new ArrayList<File>();
        if (file.isDirectory()) {
            // Search directory for indicated file types
            files = searchDirectory(file);
            System.out.println("Found " + files.size() + " file(s).\n");
        } else {
            files.add(file);
        }

        // Process files found
        for (File filefound : files) {
            System.out.println("Processing file: " + filefound.getPath() + ".\n");
            Validator<?, ?, ?, ?> validator = null;
            switch (Extension.getFileExtension(filefound)) {
            case GOAL:
                validator = new AgentValidator(filefound.getPath());
                // TODO we need to set a KR interface; use default (only one)
                // right now. Best we can do now
                // is to ask user to set it.
                try {
                    ((AgentValidator) validator).setKRInterface(KRFactory.getDefaultInterface());
                } catch (KRInitFailedException e) {
                    // TODO: use logger.
                    System.out.println(e.getMessage());
                }
                break;
            case MOD2G:
                validator = new ModuleValidator(filefound.getPath());
                // TODO we need to set a KR interface; use default (only one)
                // right now. Best we can do now
                // is to ask user to set it.
                try {
                    ((ModuleValidator) validator).setKRInterface(KRFactory.getDefaultInterface());
                } catch (KRInitFailedException e) {
                    // TODO: use logger.
                    System.out.println(e.getMessage());
                }
                break;
            case MAS2G:
                validator = new MASValidator(filefound.getPath());
                break;
            case TEST2G:
                validator = new TestValidator(filefound.getPath());
                break;
            default:
                // TODO: use logger.
                System.out.println("Expected file with extension 'goal', 'mas2g', 'mod2g', or 'test2g'");
                continue;
            }

            // Validate program file
            validator.validate();

            // Print lexer tokens
            if (lexer) {
                validator.printLexerTokens();
            }

            // Print constructed program
            if (program) {
                System.out.println("\n\n" + validator.getProgram().toString(" ", " "));
            }

            // Print report with warnings, and parsing and validation messages
            System.out.println(validator.report());
        }

        // Get elapsed time.
        long elapsedTime = (System.nanoTime() - startTime) / 1000000;
        System.out.println("Took " + elapsedTime + " milliseconds to analyze " + files.size() + " file(s).");
    }

    /**
     * Collects relevant files in a directory.
     *
     * @param directory
     *            The directory to be searched.
     * @param recursive
     *            Indicates whether directory should be searched recursively,
     *            i.e., whether directories inside directories should also be
     *            searched.
     * @return List of retrieved files.
     */
    private static List<File> searchDirectory(File directory) {
        List<File> files = new ArrayList<File>();

        for (File file : directory.listFiles()) {
            if (file.isFile()) {
                if (isMASFile(file) && masFile) {
                    files.add(file);
                }
                if (isAgentFile(file) && agentFile) {
                    files.add(file);
                }
                if (isModuleFile(file) && moduleFile) {
                    files.add(file);
                }
            }
            if (file.isDirectory() && recursive) {
                files.addAll(searchDirectory(file));
            }
        }

        return files;
    }

    /**
     * Checks whether file is a MAS file.
     *
     * @param file
     *            The file to check.
     * @return {@code true} if extension of the file is {@link Extension#MAS}.
     */
    public static boolean isMASFile(File file) {
        return Extension.getFileExtension(file) == Extension.MAS2G;
    }

    /**
     * Checks whether file is an agent file.
     *
     * @param file
     *            The file to check.
     * @return {@code true} if extension of the file is {@link Extension#GOAL}.
     */
    public static boolean isAgentFile(File file) {
        return Extension.getFileExtension(file) == Extension.GOAL;
    }

    /**
     * Checks whether file is a module file.
     *
     * @param file
     *            The file to check.
     * @return {@code true} if extension of the file is {@link Extension#MOD2G}.
     */
    public static boolean isModuleFile(File file) {
        return Extension.getFileExtension(file) == Extension.MOD2G;
    }

    /**
     * Checks whether file is a test file.
     *
     * @param file
     *            The file to check.
     * @return {@code true} if extension of the file is {@link Extension#TEST}.
     */
    public static boolean isTestFile(File file) {
        return Extension.getFileExtension(file) == Extension.TEST2G;
    }

    // -------------------------------------------------------------
    // Command line options
    // -------------------------------------------------------------

    /**
     * Creates the command line options.
     *
     * @return The command line options.
     */
    private static Options createOptions() {
        Options options = new Options();

        OptionBuilder.withDescription("Output tokens generated by lexer");
        options.addOption(OptionBuilder.create(OPTION_LEXER));

        OptionBuilder.withDescription("Program generated by parser");
        options.addOption(OptionBuilder.create(OPTION_PROGRAM));

        OptionBuilder.withDescription("Analyze MAS files");
        options.addOption(OptionBuilder.create(OPTION_MAS));

        OptionBuilder.withDescription("Analyze GOAL agent files");
        options.addOption(OptionBuilder.create(OPTION_GOAL));

        OptionBuilder.withDescription("Analyze module files");
        options.addOption(OptionBuilder.create(OPTION_MOD2G));

        OptionBuilder.withDescription("Recursively search directories for files");
        OptionBuilder.withLongOpt(OPTION_RECURSIVE);
        options.addOption(OptionBuilder.create(OPTION_RECURSIVE_SHORT));

        options.addOption(new Option(OPTION_HELP_SHORT, OPTION_HELP, false, "Displays this help"));

        OptionBuilder.withDescription("Shows the license");
        OptionBuilder.withLongOpt(OPTION_LICENSE);
        options.addOption(OptionBuilder.create());

        return options;
    }

    private static File parseOptions(String[] args) throws ParseException {
        CommandLineParser parser = new PosixParser();
        CommandLine cmd = parser.parse(options, args);

        lexer = cmd.hasOption(OPTION_LEXER);
        program = cmd.hasOption(OPTION_PROGRAM);
        masFile = cmd.hasOption(OPTION_MAS);
        agentFile = cmd.hasOption(OPTION_GOAL);
        moduleFile = cmd.hasOption(OPTION_MOD2G);
        recursive = cmd.hasOption(OPTION_RECURSIVE);

        /*
         * Handle general options.
         */
        if (cmd.hasOption(OPTION_HELP)) {
            throw new ParseException("The GOAL Grammar Tools. Copyright (C) 2014 GPLv3");
        }

        if (cmd.hasOption(OPTION_LICENSE)) {
            showLicense();
            throw new ParseException("");
        }

        // Process remaining arguments
        if (cmd.getArgs().length == 0) {
            throw new ParseException("Missing file or directory");
        }
        if (cmd.getArgs().length > 1) {
            throw new ParseException("Expected single file or directory name but got: " + cmd.getArgs());
        }

        // Check existence of file
        File file = new File(cmd.getArgs()[0]);
        if (!file.exists()) {
            throw new ParseException("Could not find " + file);
        }
        return file;
    }

    /**
     * Prints help message with command line options.
     */
    private static void showHelp() {
        HelpFormatter formatter = new HelpFormatter();
        formatter.printHelp(Analyzer.class.getCanonicalName() + " [options] [[file|directory]]", options);
    }

    /**
     * Print the license; required by GPL v3.
     */
    private static void showLicense() {
        System.out.println("The GOAL Grammar Tools. Copyright (C) 2014 Koen Hindriks.\n\n"
                + "This program is free software: you can redistribute it and/or modify\n"
                + "it under the terms of the GNU General Public License as published by\n"
                + "the Free Software Foundation, either version 3 of the License, or\n"
                + "(at your option) any later version.\n\n"
                + "This program is distributed in the hope that it will be useful,\n"
                + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
                + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
                + "GNU General Public License for more details.\n\n"
                + "You should have received a copy of the GNU General Public License\n"
                + "along with this program.  If not, see <http://www.gnu.org/licenses/>.\n");
    }

}