summaryrefslogtreecommitdiff
path: root/support/arara/source/src/main/java/com/github/cereda/arara/model
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/arara/source/src/main/java/com/github/cereda/arara/model
Initial commit
Diffstat (limited to 'support/arara/source/src/main/java/com/github/cereda/arara/model')
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/AraraException.java88
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/Argument.java125
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/Command.java122
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/Conditional.java139
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/Configuration.java246
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/Database.java80
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/Directive.java146
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/Evaluator.java158
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/Extractor.java88
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/FileType.java170
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/FileTypeResource.java84
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/Interpreter.java458
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/Language.java148
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/Messages.java170
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/Pair.java92
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/Parser.java410
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/Resource.java291
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/Rule.java155
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/RuleCommand.java103
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/Session.java122
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/StopWatch.java84
-rw-r--r--support/arara/source/src/main/java/com/github/cereda/arara/model/Trigger.java135
22 files changed, 3614 insertions, 0 deletions
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/AraraException.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/AraraException.java
new file mode 100644
index 0000000000..f2a340fd01
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/AraraException.java
@@ -0,0 +1,88 @@
+/**
+ * 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;
+
+/**
+ * Implements the specific exception model for arara.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class AraraException extends Exception {
+
+ // the underlying exception,
+ // used to hold more details
+ // on what really happened
+ private Exception exception;
+
+ /**
+ * Constructor. Takes the exception message.
+ * @param message The exception message.
+ */
+ public AraraException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructor. Takes the exception message and the underlying exception.
+ * @param message The exception message.
+ * @param exception The underlying exception object.
+ */
+ public AraraException(String message, Exception exception) {
+ super(message);
+ this.exception = exception;
+ }
+
+ /**
+ * Gets the underlying exception.
+ * @return The underlying message.
+ */
+ public Exception getException() {
+ return exception;
+ }
+
+ /**
+ * Checks if there is an underlying exception defined in the current object.
+ * @return A boolean value indicating if the current object has an
+ * underlying exception.
+ */
+ public boolean hasException() {
+ if (exception != null) {
+ return (exception.getMessage() != null);
+ } else {
+ return false;
+ }
+ }
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/Argument.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/Argument.java
new file mode 100644
index 0000000000..0b15baf9d7
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/Argument.java
@@ -0,0 +1,125 @@
+/**
+ * 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.utils.CommonUtils;
+
+/**
+ * The rule argument model.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class Argument {
+
+ // the argument identifier
+ private String identifier;
+
+ // a boolean indicating if the
+ // current argument is required
+ private boolean required;
+
+ // the flag to hold the argument
+ // value manipulation
+ private String flag;
+
+ // the argument fallback if it is
+ // not defined in the directive
+ private String fallback;
+
+ /**
+ * Gets the identifier.
+ * @return The identifier.
+ */
+ public String getIdentifier() {
+ return CommonUtils.removeKeyword(identifier);
+ }
+
+ /**
+ * Sets the identifier.
+ * @param identifier The identifier.
+ */
+ public void setIdentifier(String identifier) {
+ this.identifier = identifier;
+ }
+
+ /**
+ * Checks if the argument is required.
+ * @return A boolean value indicating if the argument is required.
+ */
+ public boolean isRequired() {
+ return required;
+ }
+
+ /**
+ * Sets the argument requirement.
+ * @param required A boolean value.
+ */
+ public void setRequired(boolean required) {
+ this.required = required;
+ }
+
+ /**
+ * Gets the argument flag.
+ * @return The flag.
+ */
+ public String getFlag() {
+ return CommonUtils.removeKeyword(flag);
+ }
+
+ /**
+ * Sets the argument flag.
+ * @param flag The argument flag.
+ */
+ public void setFlag(String flag) {
+ this.flag = flag;
+ }
+
+ /**
+ * Gets the argument fallback.
+ * @return The argument fallback.
+ */
+ public String getDefault() {
+ return CommonUtils.removeKeyword(fallback);
+ }
+
+ /**
+ * Sets the argument fallback.
+ * @param fallback The argument fallback.
+ */
+ public void setDefault(String fallback) {
+ this.fallback = fallback;
+ }
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/Command.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/Command.java
new file mode 100644
index 0000000000..3058389832
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/Command.java
@@ -0,0 +1,122 @@
+/**
+ * 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.utils.CommonUtils;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Implements a command model, containing a list of strings.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class Command {
+
+ // a list of elements which are components
+ // of a command and represented as strings
+ private final List<String> elements;
+
+ // an optional file acting as a reference
+ // for the default working directory
+ private File workingDirectory;
+
+ /**
+ * Constructor.
+ * @param values An array of objects.
+ */
+ public Command(Object... values) {
+ elements = new ArrayList<String>();
+ List result = CommonUtils.flatten(Arrays.asList(values));
+ for (Object value : result) {
+ String element = String.valueOf(value);
+ if (!CommonUtils.checkEmptyString(element)) {
+ elements.add(element);
+ }
+ }
+ }
+
+ /**
+ * Constructor.
+ * @param elements A list of strings.
+ */
+ public Command(List<String> elements) {
+ this.elements = elements;
+ }
+
+ /**
+ * Gets the list of strings representing each element of a command.
+ * @return A list of strings.
+ */
+ public List<String> getElements() {
+ return elements;
+ }
+
+ /**
+ * Sets the working directory.
+ * @param workingDirectory A file representing the working directory.
+ */
+ public void setWorkingDirectory(File workingDirectory) {
+ this.workingDirectory = workingDirectory;
+ }
+
+ /**
+ * Gets the working directory, if any.
+ * @return A file representing the working directory.
+ */
+ public File getWorkingDirectory() {
+ return workingDirectory;
+ }
+
+ /**
+ * Checks if a working directory was defined.
+ * @return A logic value indicating if a working directory was defined.
+ */
+ public boolean hasWorkingDirectory() {
+ return workingDirectory != null;
+ }
+
+ /**
+ * Provides a textual representation of the current command.
+ * @return A string representing the current command.
+ */
+ @Override
+ public String toString() {
+ return CommonUtils.getCollectionElements(elements, "[ ", " ]", ", ");
+ }
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/Conditional.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/Conditional.java
new file mode 100644
index 0000000000..4c830f0a1b
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/Conditional.java
@@ -0,0 +1,139 @@
+/**
+ * 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;
+
+/**
+ * The conditional class, it represents the type of conditional available
+ * for a directive and its corresponding expression to be evaluated.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class Conditional {
+
+ // these are all types of conditionals arara
+ // is able to recognize; personally, I believe
+ // they are more than sufficient to cover the
+ // majority of test cases
+ public enum ConditionalType {
+
+ // evaluated beforehand, directive is interpreted
+ // if and only if the result is true
+ IF,
+
+ // there is no evaluation, directive is interpreted,
+ // no extra effort is needed
+ NONE,
+
+ // evaluated beforehand, directive is interpreted
+ // if and only if the result is false
+ UNLESS,
+
+ // directive is interpreted the first time, then the
+ // evaluation is done; while the result is false,
+ // the directive is interpreted again and again
+ UNTIL,
+
+ // evaluated beforehand, directive is interpreted if
+ // and oly if the result is true, and the process is
+ // repeated while the result still holds true
+ WHILE
+ }
+
+ // the conditional type, specified above; the
+ // default fallback, as seen in the constructor,
+ // is set to NONE, that is, no conditional at all
+ private ConditionalType type;
+
+ // the expression to be evaluated according to its
+ // type; the default fallback, as seen in the
+ // constructor, is set to an empty string
+ private String condition;
+
+ /**
+ * Constructor.
+ */
+ public Conditional() {
+ type = ConditionalType.NONE;
+ condition = "";
+ }
+
+ /**
+ * Gets the conditional type.
+ * @return The conditional type.
+ */
+ public ConditionalType getType() {
+ return type;
+ }
+
+ /**
+ * Sets the conditional type.
+ * @param type The conditional type.
+ */
+ public void setType(ConditionalType type) {
+ this.type = type;
+ }
+
+ /**
+ * Gets the condition, that is, the expression to be evaluated.
+ * @return A string representing the condition.
+ */
+ public String getCondition() {
+ return condition;
+ }
+
+ /**
+ * Sets the condition, that is, the expression to be evaluated.
+ * @param condition A string representing the condition.
+ */
+ public void setCondition(String condition) {
+ this.condition = condition;
+ }
+
+ /**
+ * Provides a textual representation of the conditional object.
+ * @return A string representation of this object.
+ */
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("{ ").append(type);
+ if (type != ConditionalType.NONE) {
+ builder.append(", expression: ").append(condition.trim());
+ }
+ builder.append(" }");
+ return builder.toString();
+ }
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/Configuration.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/Configuration.java
new file mode 100644
index 0000000000..0c2c294958
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/Configuration.java
@@ -0,0 +1,246 @@
+/**
+ * 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.utils.CommonUtils;
+import com.github.cereda.arara.utils.ConfigurationUtils;
+import java.io.File;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Implements the configuration model, which holds the default settings and can
+ * load the configuration file.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class Configuration {
+
+ // the application messages obtained from the
+ // language controller
+ private static final LanguageController messages =
+ LanguageController.getInstance();
+
+ /**
+ * Loads the application configuration.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static void load() throws AraraException {
+
+ // initialize both file type and language models,
+ // since we can track errors from there instead
+ // of relying on a check on this level
+ FileType.init();
+ Language.init();
+
+ // reset everything
+ reset();
+
+ // get the configuration file, if any
+ File file = ConfigurationUtils.getConfigFile();
+ if (file != null) {
+
+ // set the configuration file name for
+ // logging purposes
+ ConfigurationController.getInstance().
+ put("execution.configuration.name",
+ CommonUtils.getCanonicalPath(file)
+ );
+
+ // then validate it and update the
+ // configuration accordingly
+ Resource resource = ConfigurationUtils.validateConfiguration(file);
+ update(resource);
+ }
+
+ // just to be sure, update the
+ // current locale in order to
+ // display localized messages
+ Locale locale = ((Language) ConfigurationController.
+ getInstance().get("execution.language")).getLocale();
+ LanguageController.getInstance().setLocale(locale);
+ }
+
+ /**
+ * Resets the configuration to initial settings.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ private static void reset() throws AraraException {
+
+ // put everything in a map to be
+ // later assigned to the configuration
+ // controller, which holds the settings
+ Map<String, Object> mapping = new HashMap<String, Object>();
+
+ mapping.put("execution.loops", 10L);
+ mapping.put("directives.charset", Charset.forName("UTF-8"));
+ mapping.put("execution.errors.halt", true);
+ mapping.put("execution.timeout", false);
+ mapping.put("execution.timeout.value", 0L);
+ mapping.put("execution.timeout.unit", TimeUnit.MILLISECONDS);
+ mapping.put("application.version", "4.0");
+ mapping.put("application.revision", "1");
+ mapping.put("directives.linebreak.pattern", "^\\s*-->\\s(.*)$");
+
+ String directive = "^\\s*(\\w+)\\s*(:\\s*(\\{.*\\})\\s*)?";
+ String pattern = "(\\s+(if|while|until|unless)\\s+(\\S.*))?$";
+
+ mapping.put("directives.pattern", directive.concat(pattern));
+ mapping.put("application.pattern", "arara:\\s");
+ mapping.put("application.width", 65);
+ mapping.put("execution.database.name", "arara");
+ mapping.put("execution.log.name", "arara");
+ mapping.put("execution.verbose", false);
+
+ mapping.put("trigger.halt", false);
+ mapping.put("execution.language", new Language("en"));
+ mapping.put("execution.logging", false);
+ mapping.put("execution.dryrun", false);
+ mapping.put("execution.status", 0);
+ mapping.put("application.copyright.year", "2012-2018");
+ mapping.put("execution.filetypes", ConfigurationUtils.
+ getDefaultFileTypes());
+ mapping.put("execution.rule.paths",
+ Arrays.asList(
+ CommonUtils.buildPath(
+ ConfigurationUtils.getApplicationPath(),
+ "rules"
+ )
+ )
+ );
+
+ mapping.put("execution.preambles", new HashMap<String, String>());
+ mapping.put("execution.preamble.active", false);
+ mapping.put("execution.configuration.name", "[none]");
+ mapping.put("execution.header", false);
+ mapping.put("ui.lookandfeel", "none");
+
+ // get the configuration controller and
+ // set every map key to it
+ ConfigurationController controller =
+ ConfigurationController.getInstance();
+ for (String key : mapping.keySet()) {
+ controller.put(key, mapping.get(key));
+ }
+ }
+
+ /**
+ * Update the configuration based on the provided map.
+ * @param data Map containing the new configuration settings.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ private static void update(Resource resource) throws AraraException {
+
+ ConfigurationController controller =
+ ConfigurationController.getInstance();
+
+ if (resource.getPaths() != null) {
+ List<String> paths = resource.getPaths();
+ paths = ConfigurationUtils.normalizePaths(paths);
+ controller.put("execution.rule.paths", paths);
+ }
+
+ if (resource.getFiletypes() != null) {
+ List<FileTypeResource> resources = resource.getFiletypes();
+ List<FileType> filetypes = new ArrayList<FileType>();
+ for (FileTypeResource type : resources) {
+ if (type.getPattern() != null) {
+ filetypes.add(
+ new FileType(type.getExtension(), type.getPattern())
+ );
+ } else {
+ filetypes.add(new FileType(type.getExtension()));
+ }
+ }
+ filetypes = ConfigurationUtils.normalizeFileTypes(filetypes);
+ controller.put("execution.filetypes", filetypes);
+ }
+
+ controller.put("execution.verbose", resource.isVerbose());
+ controller.put("execution.logging", resource.isLogging());
+ controller.put("execution.header", resource.isHeader());
+
+ if (resource.getDbname() != null) {
+ controller.put("execution.database.name",
+ ConfigurationUtils.cleanFileName(resource.getDbname()));
+ }
+
+ if (resource.getLogname() != null) {
+ controller.put("execution.log.name",
+ ConfigurationUtils.cleanFileName(resource.getLogname()));
+ }
+
+ if (resource.getLanguage() != null) {
+ controller.put("execution.language",
+ new Language(resource.getLanguage()));
+ }
+
+ long loops = resource.getLoops();
+ if (loops > 0) {
+ controller.put("execution.loops", loops);
+ } else {
+ if (loops < 0) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_CONFIGURATION_LOOPS_INVALID_RANGE
+ )
+ );
+ }
+ }
+
+ if (resource.getPreambles() != null) {
+ controller.put("execution.preambles",
+ resource.getPreambles());
+ }
+
+ if (resource.getLaf() != null) {
+ controller.put("ui.lookandfeel",
+ resource.getLaf());
+ }
+
+ }
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/Database.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/Database.java
new file mode 100644
index 0000000000..66d360fdc0
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/Database.java
@@ -0,0 +1,80 @@
+/**
+ * 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 java.util.HashMap;
+import org.simpleframework.xml.ElementMap;
+import org.simpleframework.xml.Root;
+
+/**
+ * The XML database model, which keeps track on file changes. I am using the
+ * Simple framework to marshall and unmarshall objects and XML files.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+@Root(name = "status")
+public class Database {
+
+ // the whole database is implemented as a map, where
+ // the key is the absolute canonical file and the value
+ // is its corresponding CRC32 hash; the XML map is done
+ // inline, so it does not clutter the output a lot
+ @ElementMap(entry = "hash", key = "file", attribute = true, inline = true)
+ private HashMap<String, String> map;
+
+ /**
+ * Constructor. It creates a new map.
+ */
+ public Database() {
+ map = new HashMap<String, String>();
+ }
+
+ /**
+ * Gets the map.
+ * @return The map.
+ */
+ public HashMap<String, String> getMap() {
+ return map;
+ }
+
+ /**
+ * Sets the map.
+ * @param map The map.
+ */
+ public void setMap(HashMap<String, String> map) {
+ this.map = map;
+ }
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/Directive.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/Directive.java
new file mode 100644
index 0000000000..e311477125
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/Directive.java
@@ -0,0 +1,146 @@
+/**
+ * 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 java.util.List;
+import java.util.Map;
+
+/**
+ * Implements the directive model.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class Directive {
+
+ // the directive identifier, it is resolved
+ // to the rule identifier later on
+ private String identifier;
+
+ // a map containing the parameters; they
+ // are validated later on in order to
+ // ensure they are valid
+ private Map<String, Object> parameters;
+
+ // a conditional containing the type and
+ // the expression to be evaluated later on
+ private Conditional conditional;
+
+ // a list contained all line numbers from
+ // the main file which built the current
+ // directive
+ private List<Integer> lineNumbers;
+
+ /**
+ * Gets the directive identifier.
+ * @return A string representing the directive identifier.
+ */
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ /**
+ * Sets the directive identifier.
+ * @param identifier A string representing the directive identifier.
+ */
+ public void setIdentifier(String identifier) {
+ this.identifier = identifier;
+ }
+
+ /**
+ * Gets the directive parameters.
+ * @return A map containing the directive parameters.
+ */
+ public Map<String, Object> getParameters() {
+ return parameters;
+ }
+
+ /**
+ * Sets the directive parameters.
+ * @param parameters A map containing the directive parameters.
+ */
+ public void setParameters(Map<String, Object> parameters) {
+ this.parameters = parameters;
+ }
+
+ /**
+ * Gets the conditional object from the current directive.
+ * @return The conditional object from the current directive.
+ */
+ public Conditional getConditional() {
+ return conditional;
+ }
+
+ /**
+ * Sets the conditional object from the current directive.
+ * @param conditional The conditional object from the current directive.
+ */
+ public void setConditional(Conditional conditional) {
+ this.conditional = conditional;
+ }
+
+ /**
+ * Gets the list containing all line numbers from the current directive.
+ * @return A list containing all line numbers from the current directive.
+ */
+ public List<Integer> getLineNumbers() {
+ return lineNumbers;
+ }
+
+ /**
+ * Sets the list containing all line numbers from the current directive.
+ * @param lineNumbers A list containing all line numbers from the current
+ * directive.
+ */
+ public void setLineNumbers(List<Integer> lineNumbers) {
+ this.lineNumbers = lineNumbers;
+ }
+
+ /**
+ * Provides a textual representation of the current directive.
+ * @return A string containing a textual representation of the current
+ * directive.
+ */
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("Directive: { ");
+ builder.append("identifier: ").append(identifier).append(", ");
+ builder.append("parameters: ").append(parameters).append(", ");
+ builder.append("conditional: ").append(conditional).append(", ");
+ builder.append("lines: ").append(lineNumbers).append(" }");
+ return builder.toString();
+ }
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/Evaluator.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/Evaluator.java
new file mode 100644
index 0000000000..41f8d09943
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/Evaluator.java
@@ -0,0 +1,158 @@
+/**
+ * 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.utils.CommonUtils;
+import com.github.cereda.arara.utils.Methods;
+import java.util.HashMap;
+import java.util.Map;
+import org.mvel2.templates.TemplateRuntime;
+
+/**
+ * Implements the evaluator model, on which a conditional can be analyzed and
+ * processed.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class Evaluator {
+
+ // this attribute holds the maximum number of
+ // loops arara will accept; it's like
+ // reaching infinity
+ private final long loops;
+
+ // the counter for the current execution, it
+ // helps us keep track of the number of times
+ // this evaluation has happened, and also to
+ // prevent potential infinite loops
+ private long counter;
+
+ // a flag that indicates the
+ // evaluation to halt regardless
+ // of the the result
+ private boolean halt;
+
+ // the application messages obtained from the
+ // language controller
+ private static final LanguageController messages =
+ LanguageController.getInstance();
+
+ /**
+ * Constructor. It gets the application maximum number of loops and reset
+ * all counters.
+ */
+ public Evaluator() {
+ loops = (Long) ConfigurationController.getInstance().
+ get("execution.loops");
+ counter = 0;
+ halt = false;
+ }
+
+ /**
+ * Evaluate the provided conditional.
+ * @param conditional The conditional object.
+ * @return A boolean value indicating if the conditional holds.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public boolean evaluate(Conditional conditional) throws AraraException {
+
+ // when in dry-run mode, arara
+ // always ignore conditional evaluations
+ if (((Boolean) ConfigurationController.
+ getInstance().get("execution.dryrun")) == true) {
+ return false;
+ }
+
+ switch (conditional.getType()) {
+ case NONE:
+ return false;
+ case IF:
+ case UNLESS:
+ if (!halt) {
+ halt = true;
+ } else {
+ return false;
+ }
+ break;
+ }
+
+ // check counters and see if the execution
+ // has reached our concept of infinity,
+ // thus breaking the cycles
+ counter++;
+ if (((conditional.getType() == Conditional.ConditionalType.WHILE) &&
+ (counter > loops)) ||
+ ((conditional.getType() == Conditional.ConditionalType.UNTIL) &&
+ (counter >= loops))) {
+ return false;
+ } else {
+
+ Map<String, Object> context = new HashMap<String, Object>();
+ Methods.addConditionalMethods(context);
+
+ try {
+ Object result = TemplateRuntime.eval("@{ ".concat(
+ conditional.getCondition()).concat(" }"), context);
+ if (!CommonUtils.checkClass(Boolean.class, result)) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_EVALUATE_NOT_BOOLEAN_VALUE
+ )
+ );
+ } else {
+ boolean value = (Boolean) result;
+ switch (conditional.getType()) {
+ case UNLESS:
+ case UNTIL:
+ value = !value;
+ break;
+ }
+ return value;
+ }
+ } catch (RuntimeException exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_EVALUATE_COMPILATION_FAILED
+ ),
+ exception
+ );
+ }
+ }
+ }
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/Extractor.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/Extractor.java
new file mode 100644
index 0000000000..84edef1eb0
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/Extractor.java
@@ -0,0 +1,88 @@
+/**
+ * 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.utils.CommonUtils;
+import com.github.cereda.arara.utils.DirectiveUtils;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.List;
+import org.apache.commons.io.FileUtils;
+
+/**
+ * It extracts directives from the provided main file.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class Extractor {
+
+ // the application messages obtained from the
+ // language controller
+ private static final LanguageController messages =
+ LanguageController.getInstance();
+
+ /**
+ * Extracts a list of directives from the provided main file, obtained from
+ * the configuration controller.
+ * @return A list of directives.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public List<Directive> extract() throws AraraException {
+
+ File file = (File) ConfigurationController.
+ getInstance().get("execution.reference");
+ Charset charset = (Charset) ConfigurationController.
+ getInstance().get("directives.charset");
+
+ try {
+ List<String> content = CommonUtils.getPreambleContent();
+ List<String> lines = FileUtils.readLines(file, charset.name());
+ content.addAll(lines);
+ return DirectiveUtils.extractDirectives(content);
+ } catch (IOException ioexception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_EXTRACTOR_IO_ERROR
+ ),
+ ioexception
+ );
+ }
+ }
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/FileType.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/FileType.java
new file mode 100644
index 0000000000..b9f2a01e03
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/FileType.java
@@ -0,0 +1,170 @@
+/**
+ * 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.LanguageController;
+import com.github.cereda.arara.utils.CommonUtils;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+/**
+ * Implements the file type model.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class FileType {
+
+ // string representing the
+ // file extension
+ private String extension;
+
+ // string representing the
+ // file pattern to be used
+ // as directive lookup
+ private String pattern;
+
+ // the application messages obtained from the
+ // language controller
+ private static final LanguageController messages =
+ LanguageController.getInstance();
+
+ // a map containing all file
+ // types that arara accepts
+ private static final Map<String, String> types =
+ new HashMap<String, String>();
+
+ /**
+ * Initializes the file type class by setting the default file types and
+ * their corresponding patterns.
+ */
+ public static void init() {
+ types.put("tex", "^\\s*%\\s+");
+ types.put("dtx", "^\\s*%\\s+");
+ types.put("ltx", "^\\s*%\\s+");
+ types.put("drv", "^\\s*%\\s+");
+ types.put("ins", "^\\s*%\\s+");
+ }
+
+ /**
+ * Constructor. It takes both file extension and pattern lookup.
+ * @param extension The file extension.
+ * @param pattern The file pattern.
+ */
+ public FileType(String extension, String pattern) {
+ this.extension = extension;
+ this.pattern = pattern;
+ }
+
+ /**
+ * Constructor. It takes the extension, but it might raise an exception if
+ * the extension is unknown. This constructor is used when you just want
+ * to reorganize the file lookup priority without the need of changing the
+ * default extensions.
+ * @param extension The file extension.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public FileType(String extension) throws AraraException {
+ if (types.containsKey(extension)) {
+ this.extension = extension;
+ this.pattern = types.get(extension);
+ } else {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_FILETYPE_UNKNOWN_EXTENSION,
+ extension,
+ CommonUtils.getFileTypesList()
+ )
+ );
+ }
+ }
+
+ /**
+ * Implements the file type hash code. Note that only the file extension is
+ * considered.
+ * @return An integer representing the file type hash code.
+ */
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(extension).toHashCode();
+ }
+
+ /**
+ * Implements the file type equals method, checking if one file type is
+ * equal to another. Note that only the file extension is considered.
+ * @param object The object to be analyzed.
+ * @return A boolean value indicating if those two objects are equal.
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (object == null) {
+ return false;
+ }
+ if (getClass() != object.getClass()) {
+ return false;
+ }
+ final FileType reference = (FileType) object;
+ return new EqualsBuilder().append(extension, reference.extension).isEquals();
+ }
+
+ /**
+ * Gets the file type extension.
+ * @return String representing the file type extension.
+ */
+ public String getExtension() {
+ return extension;
+ }
+
+ /**
+ * Gets the file type pattern.
+ * @return String representing the file type pattern.
+ */
+ public String getPattern() {
+ return pattern;
+ }
+
+ /**
+ * Provides a textual representation of the current file type object.
+ * @return A string containing a textual representation of the current file
+ * type object.
+ */
+ @Override
+ public String toString() {
+ return ".".concat(extension);
+ }
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/FileTypeResource.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/FileTypeResource.java
new file mode 100644
index 0000000000..2934035858
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/FileTypeResource.java
@@ -0,0 +1,84 @@
+/**
+ * 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.utils.CommonUtils;
+
+/**
+ * Implements the file type resource model.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class FileTypeResource {
+
+ // the file extension
+ private String extension;
+
+ // the file pattern
+ private String pattern;
+
+ /**
+ * Gets the extension.
+ * @return The extension.
+ */
+ public String getExtension() {
+ return CommonUtils.removeKeyword(extension);
+ }
+
+ /**
+ * Sets the extension.
+ * @param extension The extension.
+ */
+ public void setExtension(String extension) {
+ this.extension = extension;
+ }
+
+ /**
+ * Gets the pattern.
+ * @return The pattern.
+ */
+ public String getPattern() {
+ return CommonUtils.removeKeyword(pattern);
+ }
+
+ /**
+ * Sets the pattern.
+ * @param pattern The pattern.
+ */
+ public void setPattern(String pattern) {
+ this.pattern = pattern;
+ }
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/Interpreter.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/Interpreter.java
new file mode 100644
index 0000000000..7c8f6e3928
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/Interpreter.java
@@ -0,0 +1,458 @@
+/**
+ * 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.utils.CommonUtils;
+import com.github.cereda.arara.utils.DisplayUtils;
+import com.github.cereda.arara.utils.InterpreterUtils;
+import com.github.cereda.arara.utils.Methods;
+import com.github.cereda.arara.utils.RuleUtils;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.mvel2.templates.TemplateRuntime;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Interprets the list of directives.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class Interpreter {
+
+ // the application messages obtained from the
+ // language controller
+ private static final LanguageController messages =
+ LanguageController.getInstance();
+
+ // the class logger obtained from
+ // the logger factory
+ private static final Logger logger =
+ LoggerFactory.getLogger(Interpreter.class);
+
+ // list of directives to be
+ // interpreted in here
+ private List<Directive> directives;
+
+ /**
+ * Sets the list of directives.
+ * @param directives The list of directives.
+ */
+ public void setDirectives(List<Directive> directives) {
+ this.directives = directives;
+ }
+
+ /**
+ * Executes each directive, throwing an exception if something bad has
+ * happened.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public void execute() throws AraraException {
+
+ for (Directive directive : directives) {
+
+ logger.info(
+ messages.getMessage(
+ Messages.LOG_INFO_INTERPRET_RULE,
+ directive.getIdentifier()
+ )
+ );
+
+ ConfigurationController.getInstance().
+ put("execution.file",
+ directive.getParameters().get("reference")
+ );
+ File file = getRule(directive);
+
+ logger.info(
+ messages.getMessage(
+ Messages.LOG_INFO_RULE_LOCATION,
+ file.getParent()
+ )
+ );
+
+ ConfigurationController.getInstance().
+ put("execution.info.rule.id", directive.getIdentifier());
+ ConfigurationController.getInstance().
+ put("execution.info.rule.path", file.getParent());
+ ConfigurationController.getInstance().
+ put("execution.directive.lines",
+ directive.getLineNumbers()
+ );
+ ConfigurationController.getInstance().
+ put("execution.directive.reference",
+ directive.getParameters().get("reference")
+ );
+
+ Rule rule = parseRule(file, directive);
+ Map<String, Object> parameters = parseArguments(rule, directive);
+ Methods.addRuleMethods(parameters);
+
+ String name = rule.getName();
+ List<String> authors = rule.getAuthors() == null ?
+ new ArrayList<String>() : rule.getAuthors();
+ ConfigurationController.getInstance().
+ put("execution.rule.arguments",
+ InterpreterUtils.getRuleArguments(rule)
+ );
+
+ Evaluator evaluator = new Evaluator();
+
+ boolean available = true;
+ if (InterpreterUtils.
+ runPriorEvaluation(directive.getConditional())) {
+ available = evaluator.evaluate(directive.getConditional());
+ }
+
+ if (available) {
+
+ do {
+
+ List<RuleCommand> commands = rule.getCommands();
+ for (RuleCommand command : commands) {
+ String closure = command.getCommand();
+ Object result = null;
+ try {
+ result = TemplateRuntime.eval(closure, parameters);
+ } catch (RuntimeException exception) {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().concat(
+ messages.getMessage(
+ Messages.ERROR_INTERPRETER_COMMAND_RUNTIME_ERROR
+ )
+ ),
+ exception
+ );
+ }
+
+ List<Object> execution = new ArrayList<Object>();
+ if (CommonUtils.checkClass(List.class, result)) {
+ execution = CommonUtils.flatten((List<?>) result);
+ } else {
+ execution.add(result);
+ }
+
+ for (Object current : execution) {
+
+ if (current == null) {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().concat(
+ messages.getMessage(
+ Messages.ERROR_INTERPRETER_NULL_COMMAND
+ )
+ )
+ );
+ } else {
+
+ if (!CommonUtils.checkEmptyString(
+ String.valueOf(current))) {
+
+ DisplayUtils.printEntry(name,
+ command.getName() == null ?
+ messages.getMessage(
+ Messages.INFO_LABEL_UNNAMED_TASK
+ )
+ : command.getName()
+ );
+ boolean success = true;
+
+ if (CommonUtils.checkClass(
+ Trigger.class, current)) {
+ if (((Boolean) ConfigurationController.
+ getInstance().
+ get("execution.dryrun")) == false) {
+ if (((Boolean) ConfigurationController.
+ getInstance().
+ get("execution.verbose")) == true) {
+ DisplayUtils.wrapText(
+ messages.getMessage(
+ Messages.INFO_INTERPRETER_VERBOSE_MODE_TRIGGER_MODE
+ )
+ );
+ }
+ } else {
+ DisplayUtils.printAuthors(authors);
+ DisplayUtils.wrapText(
+ messages.getMessage(
+ Messages.INFO_INTERPRETER_DRYRUN_MODE_TRIGGER_MODE
+ )
+ );
+ DisplayUtils.printConditional(
+ directive.getConditional()
+ );
+ }
+ Trigger trigger = (Trigger) current;
+ trigger.process();
+ } else {
+ Object representation =
+ CommonUtils.checkClass(
+ Command.class,
+ current
+ ) ?
+ current
+ : String.valueOf(current);
+ logger.info(
+ messages.getMessage(
+ Messages.LOG_INFO_SYSTEM_COMMAND,
+ representation
+ )
+ );
+
+ if (((Boolean) ConfigurationController.
+ getInstance().
+ get("execution.dryrun")) == false) {
+ int code = InterpreterUtils.
+ run(representation);
+ Object check = null;
+ try {
+ Map<String, Object> context =
+ new HashMap<String, Object>();
+ context.put("value", code);
+ check = TemplateRuntime.eval(
+ "@{ ".concat(
+ command.getExit() == null ?
+ "value == 0"
+ : command.getExit()).concat(" }"),
+ context);
+ } catch (RuntimeException exception) {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().
+ concat(
+ messages.getMessage(
+ Messages.ERROR_INTERPRETER_EXIT_RUNTIME_ERROR
+ )
+ ),
+ exception
+ );
+ }
+ if (CommonUtils.
+ checkClass(
+ Boolean.class,
+ check)) {
+ success = (Boolean) check;
+ } else {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().concat(
+ messages.getMessage(
+ Messages.ERROR_INTERPRETER_WRONG_EXIT_CLOSURE_RETURN
+ )
+ )
+ );
+ }
+ } else {
+ DisplayUtils.printAuthors(authors);
+ DisplayUtils.wrapText(
+ messages.getMessage(
+ Messages.INFO_INTERPRETER_DRYRUN_MODE_SYSTEM_COMMAND,
+ representation
+ )
+ );
+ DisplayUtils.printConditional(
+ directive.getConditional()
+ );
+ }
+ }
+
+ DisplayUtils.printEntryResult(success);
+
+ if (((Boolean) ConfigurationController.
+ getInstance().get("trigger.halt"))
+ || (((Boolean) ConfigurationController.
+ getInstance().
+ get("execution.errors.halt")
+ && !success))) {
+ return;
+ }
+ }
+ }
+ }
+ }
+ } while (evaluator.evaluate(directive.getConditional()));
+ }
+ }
+ }
+
+ /**
+ * Gets the rule according to the provided directive.
+ * @param directive The provided directive.
+ * @return The absolute canonical path of the rule, given the provided
+ * directive.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ private File getRule(Directive directive) throws AraraException {
+ File file = InterpreterUtils.buildRulePath(directive.getIdentifier());
+ if (file == null) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_INTERPRETER_RULE_NOT_FOUND,
+ directive.getIdentifier(),
+ CommonUtils.getCollectionElements(
+ CommonUtils.getAllRulePaths(),
+ "(",
+ ")",
+ "; "
+ )
+ )
+ );
+ } else {
+ return file;
+ }
+ }
+
+ /**
+ * Parses the rule against the provided directive.
+ * @param file The file representing the rule.
+ * @param directive The directive to be analyzed.
+ * @return A rule object.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ private Rule parseRule(File file, Directive directive)
+ throws AraraException {
+ return RuleUtils.parseRule(file, directive.getIdentifier());
+ }
+
+ /**
+ * Parses the rule arguments against the provided directive.
+ * @param rule The rule object.
+ * @param directive The directive.
+ * @return A map containing all arguments resolved according to the
+ * directive parameters.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ private Map<String, Object> parseArguments(Rule rule, Directive directive)
+ throws AraraException {
+
+ List<Argument> arguments = rule.getArguments();
+
+ Set<String> unknown = CommonUtils.
+ getUnknownKeys(directive.getParameters(), arguments);
+ unknown.remove("file");
+ unknown.remove("reference");
+ if (!unknown.isEmpty()) {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().concat(
+ messages.getMessage(
+ Messages.ERROR_INTERPRETER_UNKNOWN_KEYS,
+ CommonUtils.getCollectionElements(
+ unknown,
+ "(",
+ ")",
+ ", "
+ )
+ )
+ )
+ );
+ }
+
+ Map<String, Object> mapping = new HashMap<String, Object>();
+ mapping.put("file", directive.getParameters().get("file"));
+ mapping.put("reference", directive.getParameters().get("reference"));
+
+ Map<String, Object> context = new HashMap<String, Object>();
+ context.put("parameters", directive.getParameters());
+ context.put("file", directive.getParameters().get("file"));
+ context.put("reference", directive.getParameters().get("reference"));
+ Methods.addRuleMethods(context);
+
+ for (Argument argument : arguments) {
+ if ((argument.isRequired()) &&
+ (!directive.getParameters().containsKey(
+ argument.getIdentifier()))) {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().concat(
+ messages.getMessage(
+ Messages.ERROR_INTERPRETER_ARGUMENT_IS_REQUIRED,
+ argument.getIdentifier()
+ )
+ )
+ );
+ }
+
+ if (argument.getDefault() != null) {
+ try {
+ Object result = TemplateRuntime.
+ eval(argument.getDefault(), context);
+ mapping.put(argument.getIdentifier(), result);
+ } catch (RuntimeException exception) {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().
+ concat(messages.getMessage(
+ Messages.ERROR_INTERPRETER_DEFAULT_VALUE_RUNTIME_ERROR
+ )
+ ),
+ exception
+ );
+ }
+ } else {
+ mapping.put(argument.getIdentifier(), "");
+ }
+
+ if ((argument.getFlag() != null) &&
+ (directive.getParameters().containsKey(
+ argument.getIdentifier()))) {
+
+ try {
+ Object result = TemplateRuntime.eval(
+ argument.getFlag(),
+ context
+ );
+ mapping.put(argument.getIdentifier(), result);
+ } catch (RuntimeException exception) {
+ throw new AraraException(CommonUtils.getRuleErrorHeader().
+ concat(
+ messages.getMessage(
+ Messages.ERROR_INTERPRETER_FLAG_RUNTIME_EXCEPTION
+ )
+ ),
+ exception
+ );
+ }
+ }
+ }
+
+ return mapping;
+ }
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/Language.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/Language.java
new file mode 100644
index 0000000000..2b0fc8266e
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/Language.java
@@ -0,0 +1,148 @@
+/**
+ * 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.LanguageController;
+import com.github.cereda.arara.utils.CommonUtils;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Implements the language model.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class Language {
+
+ // the language code, based on
+ // ISO 639-1 and language variants
+ private final String code;
+
+ // map containing all languages
+ // supported by nightingale
+ private static final Map<String, Pair<String, Locale>> languages =
+ new HashMap<String, Pair<String, Locale>>();
+
+ // the application messages obtained from the
+ // language controller
+ private static final LanguageController messages =
+ LanguageController.getInstance();
+
+ /**
+ * Initialize the language model. All supported languages are added in here.
+ */
+ public static void init() {
+ languages.put("en", new Pair<String, Locale>(
+ "English",
+ new Locale("en")
+ ));
+ languages.put("de", new Pair<String, Locale>(
+ "German",
+ new Locale("de")
+ ));
+ languages.put("nl", new Pair<String, Locale>(
+ "Dutch",
+ new Locale("nl")
+ ));
+ languages.put("qn", new Pair<String, Locale>(
+ "Broad Norfolk",
+ new Locale("en", "QN")
+ ));
+ languages.put("ptbr", new Pair<String, Locale>(
+ "Brazilian Portuguese",
+ new Locale("pt", "BR")
+ ));
+ languages.put("it", new Pair<String, Locale>(
+ "Italian",
+ new Locale("it")
+ ));
+ }
+
+ /**
+ * Creates a new language object. It might raise an exception if the
+ * provided language does not exist in the map.
+ * @param code The language code, based on ISO 639-1 and language variants.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public Language(String code) throws AraraException {
+ if (languages.containsKey(code)) {
+ this.code = code;
+ } else {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_LANGUAGE_INVALID_CODE,
+ getLanguagesList()
+ )
+ );
+ }
+ }
+
+ /**
+ * Gets the language name.
+ * @return A string representing the language name.
+ */
+ public String getName() {
+ return languages.get(code).getFirstElement();
+ }
+
+ /**
+ * Gets the language locale.
+ * @return The language locale.
+ */
+ public Locale getLocale() {
+ return languages.get(code).getSecondElement();
+ }
+
+ /**
+ * Gets a string representing the list of available languages.
+ * @return String representing the list of available languages.
+ */
+ public static String getLanguagesList() {
+ List<String> entries = new ArrayList<String>();
+ for (String key : languages.keySet()) {
+ entries.add(languages.get(key).
+ getFirstElement().
+ concat(": ").
+ concat(key)
+ );
+ }
+ return CommonUtils.getCollectionElements(entries, "(", ")", ", ");
+ }
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/Messages.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/Messages.java
new file mode 100644
index 0000000000..9916c3c145
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/Messages.java
@@ -0,0 +1,170 @@
+/**
+ * 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 ch.qos.cal10n.BaseName;
+import ch.qos.cal10n.Locale;
+import ch.qos.cal10n.LocaleData;
+
+/**
+ * This enumeration contains all application messages.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+@BaseName("com.github.cereda.arara.localization.messages")
+@LocaleData({
+ @Locale(value = "de", charset = "UTF-8"),
+ @Locale(value = "en", charset = "UTF-8"),
+ @Locale(value = "en_QN", charset = "UTF-8"),
+ @Locale(value = "it", charset = "UTF-8"),
+ @Locale(value = "nl", charset = "UTF-8"),
+ @Locale(value = "pt_BR", charset = "UTF-8")
+})
+public enum Messages {
+
+ ERROR_BASENAME_NOT_A_FILE,
+ ERROR_CALCULATEHASH_IO_EXCEPTION,
+ ERROR_CHECKBOOLEAN_NOT_VALID_BOOLEAN,
+ ERROR_CHECKOS_INVALID_OPERATING_SYSTEM,
+ ERROR_CHECKREGEX_IO_EXCEPTION,
+ ERROR_CONFIGURATION_GENERIC_ERROR,
+ ERROR_CONFIGURATION_INVALID_YAML,
+ ERROR_CONFIGURATION_LOOPS_INVALID_RANGE,
+ ERROR_DISCOVERFILE_FILE_NOT_FOUND,
+ ERROR_EVALUATE_COMPILATION_FAILED,
+ ERROR_EVALUATE_NOT_BOOLEAN_VALUE,
+ ERROR_EXTRACTOR_IO_ERROR,
+ ERROR_FILETYPE_NOT_A_FILE,
+ ERROR_FILETYPE_UNKNOWN_EXTENSION,
+ ERROR_GETAPPLICATIONPATH_ENCODING_EXCEPTION,
+ ERROR_GETCANONICALFILE_IO_EXCEPTION,
+ ERROR_GETCANONICALPATH_IO_EXCEPTION,
+ ERROR_GETPARENTCANONICALPATH_IO_EXCEPTION,
+ ERROR_INTERPRETER_ARGUMENT_IS_REQUIRED,
+ ERROR_INTERPRETER_COMMAND_RUNTIME_ERROR,
+ ERROR_INTERPRETER_DEFAULT_VALUE_RUNTIME_ERROR,
+ ERROR_INTERPRETER_EXIT_RUNTIME_ERROR,
+ ERROR_INTERPRETER_FLAG_RUNTIME_EXCEPTION,
+ ERROR_INTERPRETER_NULL_COMMAND,
+ ERROR_INTERPRETER_RULE_NOT_FOUND,
+ ERROR_INTERPRETER_UNKNOWN_KEYS,
+ ERROR_INTERPRETER_WRONG_EXIT_CLOSURE_RETURN,
+ ERROR_LANGUAGE_INVALID_CODE,
+ ERROR_LOAD_COULD_NOT_LOAD_XML,
+ ERROR_PARSER_INVALID_PREAMBLE,
+ ERROR_PARSER_LOOPS_INVALID_RANGE,
+ ERROR_PARSER_LOOPS_NAN,
+ ERROR_PARSER_TIMEOUT_INVALID_RANGE,
+ ERROR_PARSER_TIMEOUT_NAN,
+ ERROR_PARSERULE_GENERIC_ERROR,
+ ERROR_PARSERULE_INVALID_YAML,
+ ERROR_REPLICATELIST_MISSING_FORMAT_ARGUMENTS_EXCEPTION,
+ ERROR_RULE_IDENTIFIER_AND_PATH,
+ ERROR_RUN_GENERIC_EXCEPTION,
+ ERROR_RUN_INTERRUPTED_EXCEPTION,
+ ERROR_RUN_INVALID_EXIT_VALUE_EXCEPTION,
+ ERROR_RUN_IO_EXCEPTION,
+ ERROR_RUN_TIMEOUT_EXCEPTION,
+ ERROR_RUN_TIMEOUT_INVALID_RANGE,
+ ERROR_SAVE_COULD_NOT_SAVE_XML,
+ ERROR_SESSION_OBTAIN_UNKNOWN_KEY,
+ ERROR_SESSION_REMOVE_UNKNOWN_KEY,
+ ERROR_TRIGGER_ACTION_NOT_FOUND,
+ ERROR_TRIGGER_CALL_EXCEPTION,
+ ERROR_VALIDATE_EMPTY_FILES_LIST,
+ ERROR_VALIDATE_FILE_IS_RESERVED,
+ ERROR_VALIDATE_FILES_IS_NOT_A_LIST,
+ ERROR_VALIDATE_INVALID_DIRECTIVE_FORMAT,
+ ERROR_VALIDATE_NO_DIRECTIVES_FOUND,
+ ERROR_VALIDATE_ORPHAN_LINEBREAK,
+ ERROR_VALIDATE_REFERENCE_IS_RESERVED,
+ ERROR_VALIDATE_YAML_EXCEPTION,
+ ERROR_VALIDATEBODY_ARGUMENT_ID_IS_RESERVED,
+ ERROR_VALIDATEBODY_ARGUMENTS_LIST,
+ ERROR_VALIDATEBODY_DUPLICATE_ARGUMENT_IDENTIFIERS,
+ ERROR_VALIDATEBODY_MISSING_KEYS,
+ ERROR_VALIDATEBODY_NULL_ARGUMENT_ID,
+ ERROR_VALIDATEBODY_NULL_COMMAND,
+ ERROR_VALIDATEBODY_NULL_COMMANDS_LIST,
+ ERROR_VALIDATEHEADER_NULL_ID,
+ ERROR_VALIDATEHEADER_NULL_NAME,
+ ERROR_VALIDATEHEADER_WRONG_IDENTIFIER,
+ ERROR_VELOCITY_FILE_NOT_FOUND,
+ ERROR_VELOCITY_PARSE_EXCEPTION,
+ ERROR_VELOCITY_METHOD_INVOCATION_EXCEPTION,
+ ERROR_VELOCITY_IO_EXCEPTION,
+ INFO_DISPLAY_EXCEPTION_MORE_DETAILS,
+ INFO_DISPLAY_EXECUTION_TIME,
+ INFO_DISPLAY_FILE_INFORMATION,
+ INFO_INTERPRETER_DRYRUN_MODE_SYSTEM_COMMAND,
+ INFO_INTERPRETER_DRYRUN_MODE_TRIGGER_MODE,
+ INFO_INTERPRETER_VERBOSE_MODE_TRIGGER_MODE,
+ INFO_LABEL_AUTHOR,
+ INFO_LABEL_AUTHORS,
+ INFO_LABEL_CONDITIONAL,
+ INFO_LABEL_NO_AUTHORS,
+ INFO_LABEL_ON_DETAILS,
+ INFO_LABEL_ON_ERROR,
+ INFO_LABEL_ON_FAILURE,
+ INFO_LABEL_ON_SUCCESS,
+ INFO_LABEL_UNNAMED_TASK,
+ INFO_PARSER_ALL_RIGHTS_RESERVED,
+ INFO_PARSER_DRYRUN_MODE_DESCRIPTION,
+ INFO_PARSER_HELP_DESCRIPTION,
+ INFO_PARSER_LANGUAGE_DESCRIPTION,
+ INFO_PARSER_LOG_DESCRIPTION,
+ INFO_PARSER_LOOPS_DESCRIPTION,
+ INFO_PARSER_NOTES,
+ INFO_PARSER_ONLY_HEADER,
+ INFO_PARSER_PREAMBLE_DESCRIPTION,
+ INFO_PARSER_SILENT_MODE_DESCRIPTION,
+ INFO_PARSER_TIMEOUT_DESCRIPTION,
+ INFO_PARSER_VERBOSE_MODE_DESCRIPTION,
+ INFO_PARSER_VERSION_DESCRIPTION,
+ LOG_INFO_BEGIN_BUFFER,
+ LOG_INFO_DIRECTIVES_BLOCK,
+ LOG_INFO_END_BUFFER,
+ LOG_INFO_INTERPRET_RULE,
+ LOG_INFO_INTERPRET_TASK,
+ LOG_INFO_POTENTIAL_DIRECTIVE_FOUND,
+ LOG_INFO_POTENTIAL_PATTERN_FOUND,
+ LOG_INFO_RULE_LOCATION,
+ LOG_INFO_SYSTEM_COMMAND,
+ LOG_INFO_TASK_RESULT,
+ LOG_INFO_VALIDATED_DIRECTIVES,
+ LOG_INFO_WELCOME_MESSAGE,
+ ERROR_CONFIGURATION_FILETYPE_MISSING_EXTENSION
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/Pair.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/Pair.java
new file mode 100644
index 0000000000..d8591b6ef7
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/Pair.java
@@ -0,0 +1,92 @@
+/**
+ * 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;
+
+/**
+ * Implements a pair of objects.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class Pair<T, V> {
+
+ // first element of the pair
+ private final T firstElement;
+
+ // second element of the pair
+ private final V secondElement;
+
+ /**
+ * Constructor.
+ * @param firstElement The first element.
+ * @param secondElement The second element.
+ */
+ public Pair(T firstElement, V secondElement) {
+ this.firstElement = firstElement;
+ this.secondElement = secondElement;
+ }
+
+ /**
+ * Gets the first element.
+ * @return The first element.
+ */
+ public T getFirstElement() {
+ return firstElement;
+ }
+
+ /**
+ * Gets the second element.
+ * @return The second element.
+ */
+ public V getSecondElement() {
+ return secondElement;
+ }
+
+ /**
+ * A shorter version for getting the first element.
+ * @return The first element.
+ */
+ public T first() {
+ return getFirstElement();
+ }
+
+ /**
+ * A shorter version for getting the second element.
+ * @return The second element.
+ */
+ public V second() {
+ return getSecondElement();
+ }
+
+}
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
+ )
+ );
+ }
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/Resource.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/Resource.java
new file mode 100644
index 0000000000..2994a4d691
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/Resource.java
@@ -0,0 +1,291 @@
+/**
+ * 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.utils.CommonUtils;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang.SystemUtils;
+import org.mvel2.templates.TemplateRuntime;
+
+/**
+ * Implements the configuration resource model.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class Resource {
+
+ // rule paths
+ private List<String> paths;
+
+ // file types
+ private List<FileTypeResource> filetypes;
+
+ // the application language
+ private String language;
+
+ // maximum number of loops
+ private long loops;
+
+ // verbose flag
+ private boolean verbose;
+
+ // logging flag
+ private boolean logging;
+
+ // database name
+ private String dbname;
+
+ // log name
+ private String logname;
+
+ // header flag
+ private boolean header;
+
+ // map of preambles
+ private Map<String, String> preambles;
+
+ // look and feel
+ private String laf;
+
+ /**
+ * Gets the rule paths.
+ * @return The rule paths.
+ */
+ public List<String> getPaths() {
+ if (paths != null) {
+
+ final Map<String, Object> map = new HashMap<String, Object>();
+ Map<String, Object> user = new HashMap<String, Object>();
+ user.put("home", SystemUtils.USER_HOME);
+ user.put("dir", SystemUtils.USER_DIR);
+ user.put("name", SystemUtils.USER_NAME);
+ map.put("user", user);
+
+ Collection<String> result = CollectionUtils.collect(
+ paths, new Transformer<String, String>() {
+ public String transform(String input) {
+ String path = CommonUtils.removeKeyword(input);
+ try {
+ path = (String) TemplateRuntime.eval(path, map);
+ }
+ catch (RuntimeException nothandled) {
+ // do nothing, gracefully fallback to
+ // the default, unparsed path
+ }
+ return path;
+ }
+ });
+ paths = new ArrayList<String>(result);
+ }
+ return paths;
+ }
+
+ /**
+ * Sets the rule paths.
+ * @param paths The rule paths.
+ */
+ public void setPaths(List<String> paths) {
+ this.paths = paths;
+ }
+
+ /**
+ * Gets the list of file types.
+ * @return The list of file types.
+ */
+ public List<FileTypeResource> getFiletypes() {
+ return filetypes;
+ }
+
+ /**
+ * Sets the list of file types.
+ * @param filetypes The list of file types.
+ */
+ public void setFiletypes(List<FileTypeResource> filetypes) {
+ this.filetypes = filetypes;
+ }
+
+ /**
+ * Gets the language.
+ * @return The language.
+ */
+ public String getLanguage() {
+ return CommonUtils.removeKeyword(language);
+ }
+
+ /**
+ * Sets the language.
+ * @param language The language.
+ */
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
+ /**
+ * Get the maximum number of loops.
+ * @return The maximum number of loops.
+ */
+ public long getLoops() {
+ return loops;
+ }
+
+ /**
+ * Sets the maximum number of loops.
+ * @param loops The maximum number of loops.
+ */
+ public void setLoops(long loops) {
+ this.loops = loops;
+ }
+
+ /**
+ * Checks if verbose mode is active.
+ * @return A boolean value.
+ */
+ public boolean isVerbose() {
+ return verbose;
+ }
+
+ /**
+ * Sets the verbose mode.
+ * @param verbose A boolean value.
+ */
+ public void setVerbose(boolean verbose) {
+ this.verbose = verbose;
+ }
+
+ /**
+ * Checks if logging mode is active.
+ * @return A boolean value.
+ */
+ public boolean isLogging() {
+ return logging;
+ }
+
+ /**
+ * Sets the logging mode.
+ * @param logging A boolean value.
+ */
+ public void setLogging(boolean logging) {
+ this.logging = logging;
+ }
+
+ /**
+ * Gets the database name.
+ * @return The database name.
+ */
+ public String getDbname() {
+ return CommonUtils.removeKeyword(dbname);
+ }
+
+ /**
+ * Sets the database name.
+ * @param dbname The database name.
+ */
+ public void setDbname(String dbname) {
+ this.dbname = dbname;
+ }
+
+ /**
+ * Gets the log name.
+ * @return The log name.
+ */
+ public String getLogname() {
+ return CommonUtils.removeKeyword(logname);
+ }
+
+ /**
+ * Sets the log name.
+ * @param logname The log name.
+ */
+ public void setLogname(String logname) {
+ this.logname = logname;
+ }
+
+ /**
+ * Gets the map of preambles.
+ * @return Map of preambles.
+ */
+ public Map<String, String> getPreambles() {
+ return preambles;
+ }
+
+ /**
+ * Sets the map of preambles.
+ * @param preambles Map of preambles.
+ */
+ public void setPreambles(Map<String, String> preambles) {
+ this.preambles = preambles;
+ }
+
+ /**
+ * Gets the logical value of the header flag.
+ * @return Logical value of the header flag.
+ */
+ public boolean isHeader() {
+ return header;
+ }
+
+ /**
+ * Sets the logical value of the header flag.
+ * @param header The header flag.
+ */
+ public void setHeader(boolean header) {
+ this.header = header;
+ }
+
+ /**
+ * Gets the look and feel reference.
+ * @return The look and feel reference.
+ */
+ public String getLaf() {
+ return CommonUtils.removeKeyword(laf);
+ }
+
+ /**
+ * Sets the look and feel reference.
+ * @param laf The look and feel reference.
+ */
+ public void setLaf(String laf) {
+ this.laf = laf;
+ }
+
+
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/Rule.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/Rule.java
new file mode 100644
index 0000000000..af3ad19950
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/Rule.java
@@ -0,0 +1,155 @@
+/**
+ * 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.utils.CommonUtils;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+
+/**
+ * Implements the rule model.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class Rule {
+
+ // the rule identifier
+ private String identifier;
+
+ // the rule name
+ private String name;
+
+ // the list of authors
+ private List<String> authors;
+
+ // the list of commands
+ private List<RuleCommand> commands;
+
+ // the list of arguments
+ private List<Argument> arguments;
+
+ /**
+ * Gets the rule identifier.
+ * @return The rule identifier.
+ */
+ public String getIdentifier() {
+ return CommonUtils.removeKeyword(identifier);
+ }
+
+ /**
+ * Sets the rule identifier.
+ * @param identifier The rule identifier.
+ */
+ public void setIdentifier(String identifier) {
+ this.identifier = identifier;
+ }
+
+ /**
+ * Gets the rule identifier.
+ * @return The rule identifier.
+ */
+ public String getName() {
+ return CommonUtils.removeKeyword(name);
+ }
+
+ /**
+ * Sets the rule name.
+ * @param name The rule name.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Gets the list of authors.
+ * @return A list of authors.
+ */
+ public List<String> getAuthors() {
+ if (authors != null) {
+ Collection<String> result = CollectionUtils.collect(
+ authors, new Transformer<String, String>() {
+ public String transform(String input) {
+ return CommonUtils.removeKeyword(input);
+ }
+ });
+ authors = new ArrayList<String>(result);
+ }
+ return authors;
+ }
+
+ /**
+ * Sets the list of authors.
+ * @param authors The list of authors.
+ */
+ public void setAuthors(List<String> authors) {
+ this.authors = authors;
+ }
+
+ /**
+ * Gets the list of commands.
+ * @return The list of commands.
+ */
+ public List<RuleCommand> getCommands() {
+ return commands;
+ }
+
+ /**
+ * Sets the list of commands.
+ * @param commands The list of commands.
+ */
+ public void setCommands(List<RuleCommand> commands) {
+ this.commands = commands;
+ }
+
+ /**
+ * Gets the list of arguments.
+ * @return The list of arguments.
+ */
+ public List<Argument> getArguments() {
+ return arguments;
+ }
+
+ /**
+ * Sets the list of arguments.
+ * @param arguments The list of arguments.
+ */
+ public void setArguments(List<Argument> arguments) {
+ this.arguments = arguments;
+ }
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/RuleCommand.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/RuleCommand.java
new file mode 100644
index 0000000000..b209d19bcb
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/RuleCommand.java
@@ -0,0 +1,103 @@
+/**
+ * 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.utils.CommonUtils;
+
+/**
+ * Implements the rule command model.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class RuleCommand {
+
+ // the command name
+ private String name;
+
+ // the command instruction
+ private String command;
+
+ // the exit status expression
+ private String exit;
+
+ /**
+ * Gets the command name.
+ * @return The command name.
+ */
+ public String getName() {
+ return CommonUtils.removeKeyword(name);
+ }
+
+ /**
+ * Sets the command name.
+ * @param name The command name.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Gets the command instruction.
+ * @return The command instruction.
+ */
+ public String getCommand() {
+ return CommonUtils.removeKeyword(command);
+ }
+
+ /**
+ * Sets the command instruction.
+ * @param command The command instruction.
+ */
+ public void setCommand(String command) {
+ this.command = command;
+ }
+
+ /**
+ * Gets the exit status expression.
+ * @return The exit status expression.
+ */
+ public String getExit() {
+ return CommonUtils.removeKeyword(exit);
+ }
+
+ /**
+ * Sets the exit status expression.
+ * @param exit The exit status expression.
+ */
+ public void setExit(String exit) {
+ this.exit = exit;
+ }
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/Session.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/Session.java
new file mode 100644
index 0000000000..c756ae4550
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/Session.java
@@ -0,0 +1,122 @@
+/**
+ * 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.LanguageController;
+import com.github.cereda.arara.controller.SessionController;
+
+/**
+ * Implements the session model.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class Session {
+
+ // get the current instance from the
+ // session controller
+ private static final SessionController session =
+ SessionController.getInstance();
+
+ // the application messages obtained from the
+ // language controller
+ private static final LanguageController messages =
+ LanguageController.getInstance();
+
+ /**
+ * Inserts the object into the session, indexed by the provided key.
+ * @param key The provided key.
+ * @param value The value to be inserted.
+ */
+ public void insert(String key, Object value) {
+ session.put(key, value);
+ }
+
+ /**
+ * Removes the entry indexed by the provided key from the session.
+ * @param key The provided key.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public void remove(String key) throws AraraException {
+ if (session.contains(key)) {
+ session.remove(key);
+ } else {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_SESSION_REMOVE_UNKNOWN_KEY,
+ key
+ )
+ );
+ }
+ }
+
+ /**
+ * Checks if the provided key exists in the session.
+ * @param key The provided key.
+ * @return A boolean value indicating if the provided key exists in the
+ * session.
+ */
+ public boolean exists(String key) {
+ return session.contains(key);
+ }
+
+ /**
+ * Clears the session.
+ */
+ public void forget() {
+ session.clear();
+ }
+
+ /**
+ * Gets the object indexed by the provided key from the session.
+ * @param key The provided key.
+ * @return The object indexed by the provided key.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public Object obtain(String key) throws AraraException {
+ if (session.contains(key)) {
+ return session.get(key);
+ } else {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_SESSION_OBTAIN_UNKNOWN_KEY,
+ key
+ )
+ );
+ }
+ }
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/StopWatch.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/StopWatch.java
new file mode 100644
index 0000000000..45e0969d0b
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/StopWatch.java
@@ -0,0 +1,84 @@
+/**
+ * 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;
+
+/**
+ * Implements a stopwatch.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class StopWatch {
+
+ // two variables indicating the
+ // times the stopwatch started
+ // and stopped
+ private static long beginning = 0;
+ private static long end = 0;
+
+ // a variable to indicate the
+ // stopwatch is enabled; so far,
+ // it hasn't started, then it is
+ // not enabled
+ private static boolean enabled = false;
+
+ /**
+ * Starts the stopwatch.
+ */
+ public static void start() {
+ beginning = System.nanoTime();
+ enabled = true;
+ }
+
+ /**
+ * Stops the stopwatch.
+ */
+ public static void stop() {
+ end = System.nanoTime();
+ }
+
+ /**
+ * Gets the string representation of the elapsed time.
+ * @return A string representation of the elapsed time.
+ */
+ public static String getTime() {
+ Language language = (Language) ConfigurationController.
+ getInstance().get("execution.language");
+ double result = enabled ? (double) (end - beginning) / 1000000000 : 0.0;
+ return String.format(language.getLocale(), "%1.2f", result);
+ }
+
+}
diff --git a/support/arara/source/src/main/java/com/github/cereda/arara/model/Trigger.java b/support/arara/source/src/main/java/com/github/cereda/arara/model/Trigger.java
new file mode 100644
index 0000000000..11da04bfcb
--- /dev/null
+++ b/support/arara/source/src/main/java/com/github/cereda/arara/model/Trigger.java
@@ -0,0 +1,135 @@
+/**
+ * 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 java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+/**
+ * Implements the trigger model. The tool provides triggers, which are a way
+ * to alter its internal behaviour according to a list of parameters.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class Trigger {
+
+ // the action name and its
+ // list of parameters
+ private final String action;
+ private final List<Object> parameters;
+
+ // the application messages obtained from the
+ // language controller
+ private static final LanguageController messages =
+ LanguageController.getInstance();
+
+ /**
+ * Constructor.
+ * @param action The action name.
+ * @param parameters The list of parameters.
+ */
+ public Trigger(String action, List<Object> parameters) {
+ this.action = action;
+ this.parameters = parameters;
+ }
+
+ /**
+ * Gets the action name.
+ * @return The action name.
+ */
+ public String getAction() {
+ return action;
+ }
+
+ /**
+ * Gets the list of parameters.
+ * @return The list of parameters.
+ */
+ public List<Object> getParameters() {
+ return parameters;
+ }
+
+ /**
+ * Returns a textual representation of the current trigger.
+ * @return A string containing a textual representation of the current
+ * trigger.
+ */
+ @Override
+ public String toString() {
+ return "trigger";
+ }
+
+ /**
+ * Processes the current trigger.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public void process() throws AraraException {
+
+ Map<String, Callable<Object>> mapping =
+ new HashMap<String, Callable<Object>>();
+ mapping.put("halt", new Callable<Object>() {
+ public Object call() {
+ ConfigurationController.getInstance().put("trigger.halt", true);
+ return null;
+ }
+ });
+ if (mapping.containsKey(action)) {
+ try {
+ mapping.get(action).call();
+ } catch (Exception exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_TRIGGER_CALL_EXCEPTION,
+ action
+ ),
+ exception
+ );
+ }
+ } else {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_TRIGGER_ACTION_NOT_FOUND,
+ action
+ )
+ );
+ }
+ }
+
+}