diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/arara/source/src/main/java/com/github/cereda/arara/model/Parser.java |
Initial commit
Diffstat (limited to 'support/arara/source/src/main/java/com/github/cereda/arara/model/Parser.java')
-rw-r--r-- | support/arara/source/src/main/java/com/github/cereda/arara/model/Parser.java | 410 |
1 files changed, 410 insertions, 0 deletions
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/Parser.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/Parser.java new file mode 100644 index 0000000000..723e24e76e --- /dev/null +++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/Parser.java @@ -0,0 +1,410 @@ +/** + * Arara, the cool TeX automation tool + * Copyright (c) 2012 -- 2018, Paulo Roberto Massa Cereda + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the project's author nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY + * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.github.cereda.arara.model; + +import com.github.cereda.arara.controller.ConfigurationController; +import com.github.cereda.arara.controller.LanguageController; +import com.github.cereda.arara.controller.LoggingController; +import com.github.cereda.arara.utils.CommonUtils; +import com.github.cereda.arara.utils.DisplayUtils; +import java.util.Locale; +import java.util.Map; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; + +/** + * Implements the command line parser. + * @author Paulo Roberto Massa Cereda + * @version 4.0 + * @since 4.0 + */ +public class Parser { + + // command line arguments to be + // processed by this parser + private final String[] arguments; + + // command line options, it will + // group each option available + // in arara + private Options options; + + // each option available in + // arara + private Option version; + private Option help; + private Option log; + private Option verbose; + private Option silent; + private Option dryrun; + private Option timeout; + private Option language; + private Option loops; + private Option preamble; + private Option onlyheader; + + public Parser() { + this.arguments = null; + } + + // the application messages obtained from the + // language controller + private static final LanguageController messages = + LanguageController.getInstance(); + + /** + * Constructor. + * @param arguments Array of strings representing the command line + * arguments. + */ + public Parser(String[] arguments) { + this.arguments = arguments; + } + + /** + * Parses the command line arguments. + * @return A boolean value indicating if the parsing should allow the + * application to look for directives in the provided main file. + * @throws AraraException Something wrong happened, to be caught in the + * higher levels. + */ + public boolean parse() throws AraraException { + + // create new instances of the + // command line options, including + // the ones that require arguments + version = new Option("V", "version", false, ""); + help = new Option("h", "help", false, ""); + log = new Option("l", "log", false, ""); + verbose = new Option("v", "verbose", false, ""); + silent = new Option("s", "silent", false, ""); + dryrun = new Option("n", "dry-run", false, ""); + timeout = new Option("t", "timeout", true, ""); + timeout.setArgName("number"); + language = new Option("L", "language", true, ""); + language.setArgName("code"); + loops = new Option("m", "max-loops", true, ""); + loops.setArgName("number"); + preamble = new Option("p", "preamble", true, ""); + preamble.setArgName("name"); + onlyheader = new Option("H", "header", false, ""); + + // add all options to the options + // group, so they are recognized + // by the command line parser + options = new Options(); + options.addOption(version); + options.addOption(help); + options.addOption(log); + options.addOption(verbose); + options.addOption(silent); + options.addOption(dryrun); + options.addOption(timeout); + options.addOption(language); + options.addOption(loops); + options.addOption(preamble); + options.addOption(onlyheader); + + // update all descriptions based + // on the localized messages + updateDescriptions(); + + // a new default command line + // parser is created and the + // arguments are parsed + CommandLineParser parser = new DefaultParser(); + + try { + + CommandLine line = parser.parse(options, arguments); + + String reference; + if (line.hasOption("language")) { + ConfigurationController.getInstance(). + put("execution.language", + new Language(line.getOptionValue("language")) + ); + Locale locale = ((Language) ConfigurationController. + getInstance().get("execution.language")).getLocale(); + messages.setLocale(locale); + updateDescriptions(); + } + + if (line.hasOption("help")) { + printVersion(); + printUsage(); + return false; + } + + if (line.hasOption("version")) { + printVersion(); + printNotes(); + return false; + } + + if (line.getArgs().length != 1) { + printVersion(); + printUsage(); + return false; + } else { + reference = line.getArgs()[0]; + } + + if (line.hasOption("timeout")) { + try { + long value = Long.parseLong(line.getOptionValue("timeout")); + if (value <= 0) { + throw new AraraException( + messages.getMessage( + Messages.ERROR_PARSER_TIMEOUT_INVALID_RANGE + ) + ); + } else { + ConfigurationController.getInstance(). + put("execution.timeout", true); + ConfigurationController.getInstance(). + put("execution.timeout.value", value); + } + } catch (NumberFormatException nfexception) { + throw new AraraException( + messages.getMessage( + Messages.ERROR_PARSER_TIMEOUT_NAN + ) + ); + } + } + + if (line.hasOption("max-loops")) { + try { + long value = Long.parseLong( + line.getOptionValue("max-loops") + ); + if (value <= 0) { + throw new AraraException( + messages.getMessage( + Messages.ERROR_PARSER_LOOPS_INVALID_RANGE + ) + ); + } else { + ConfigurationController.getInstance(). + put("execution.loops", value); + } + } catch (NumberFormatException nfexception) { + throw new AraraException( + messages.getMessage( + Messages.ERROR_PARSER_LOOPS_NAN + ) + ); + } + } + + if (line.hasOption("verbose")) { + ConfigurationController.getInstance(). + put("execution.verbose", true); + } + + if (line.hasOption("silent")) { + ConfigurationController.getInstance(). + put("execution.verbose", false); + } + + if (line.hasOption("dry-run")) { + ConfigurationController.getInstance(). + put("execution.dryrun", true); + ConfigurationController.getInstance(). + put("execution.errors.halt", false); + } + + if (line.hasOption("log")) { + ConfigurationController.getInstance(). + put("execution.logging", true); + } + + if (line.hasOption("preamble")) { + @SuppressWarnings("unchecked") + Map<String, String> preambles = (Map<String, String>) + ConfigurationController.getInstance(). + get("execution.preambles"); + if (preambles.containsKey(line.getOptionValue("preamble"))) { + ConfigurationController.getInstance(). + put("execution.preamble.active", true); + ConfigurationController.getInstance(). + put("execution.preamble.content", + preambles.get(line.getOptionValue("preamble")) + ); + } + else { + throw new AraraException( + messages.getMessage( + Messages.ERROR_PARSER_INVALID_PREAMBLE, + line.getOptionValue("preamble") + ) + ); + } + } + + if (line.hasOption("header")) { + ConfigurationController.getInstance(). + put("execution.header", true); + } + + CommonUtils.discoverFile(reference); + LoggingController.enableLogging((Boolean) ConfigurationController. + getInstance().get("execution.logging")); + ConfigurationController.getInstance().put("display.time", true); + + return true; + + } catch (ParseException pexception) { + printVersion(); + printUsage(); + return false; + } + } + + /** + * Prints the application usage. + */ + private void printUsage() { + HelpFormatter formatter = new HelpFormatter(); + StringBuilder builder = new StringBuilder(); + builder.append("arara [file [--dry-run] [--log] "); + builder.append("[--verbose | --silent] [--timeout N] "); + builder.append("[--max-loops N] [--language L] "); + builder.append("[ --preamble P ] [--header] | --help | --version]"); + formatter.printHelp(builder.toString(), options); + } + + /** + * Prints the application version. + */ + private void printVersion() { + String year = (String) ConfigurationController.getInstance(). + get("application.copyright.year"); + String number = (String) ConfigurationController.getInstance(). + get("application.version"); + String revision = (String) ConfigurationController.getInstance(). + get("application.revision"); + StringBuilder builder = new StringBuilder(); + builder.append("arara "); + builder.append(number); + builder.append(" (revision "); + builder.append(revision); + builder.append(")"); + builder.append("\n"); + builder.append("Copyright (c) ").append(year).append(", "); + builder.append("Paulo Roberto Massa Cereda"); + builder.append("\n"); + builder.append(messages.getMessage( + Messages.INFO_PARSER_ALL_RIGHTS_RESERVED) + ); + builder.append("\n"); + System.out.println(builder.toString()); + } + + /** + * Print the application notes. + */ + private void printNotes() { + DisplayUtils.wrapText(messages.getMessage(Messages.INFO_PARSER_NOTES)); + } + + /** + * Updates all the descriptions in order to make them reflect the current + * language setting. + */ + private void updateDescriptions() { + version.setDescription( + messages.getMessage( + Messages.INFO_PARSER_VERSION_DESCRIPTION + ) + ); + help.setDescription( + messages.getMessage( + Messages.INFO_PARSER_HELP_DESCRIPTION + ) + ); + log.setDescription( + messages.getMessage( + Messages.INFO_PARSER_LOG_DESCRIPTION + ) + ); + verbose.setDescription( + messages.getMessage( + Messages.INFO_PARSER_VERBOSE_MODE_DESCRIPTION + ) + ); + silent.setDescription( + messages.getMessage( + Messages.INFO_PARSER_SILENT_MODE_DESCRIPTION + ) + ); + dryrun.setDescription( + messages.getMessage( + Messages.INFO_PARSER_DRYRUN_MODE_DESCRIPTION + ) + ); + timeout.setDescription( + messages.getMessage( + Messages.INFO_PARSER_TIMEOUT_DESCRIPTION + ) + ); + language.setDescription( + messages.getMessage( + Messages.INFO_PARSER_LANGUAGE_DESCRIPTION + ) + ); + loops.setDescription( + messages.getMessage( + Messages.INFO_PARSER_LOOPS_DESCRIPTION + ) + ); + preamble.setDescription( + messages.getMessage( + Messages.INFO_PARSER_PREAMBLE_DESCRIPTION + ) + ); + onlyheader.setDescription( + messages.getMessage( + Messages.INFO_PARSER_ONLY_HEADER + ) + ); + } + +} |