summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/support/arara/src/main/java/com/github
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/support/arara/src/main/java/com/github')
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/Arara.java196
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraConfiguration.java221
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraDirective.java148
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraLanguage.java137
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraRuleConfig.java223
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraConstants.java96
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraLocalization.java126
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraLogging.java82
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraMethods.java481
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraUtils.java224
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/CommandLineAnalyzer.java488
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/CommandTrigger.java285
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/ConfigurationLoader.java394
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/DirectiveExtractor.java287
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/DirectiveParser.java321
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/LanguageController.java159
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/TaskDeployer.java532
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/Arara.java205
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/ConfigurationController.java106
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/LanguageController.java120
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/LoggingController.java109
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/SessionController.java124
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/SystemCallController.java153
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/AraraException.java (renamed from Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/exception/AraraException.java)65
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Argument.java (renamed from Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraRuleArgument.java)117
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Command.java122
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Conditional.java139
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Configuration.java246
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Database.java80
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Directive.java146
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Evaluator.java158
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Extractor.java88
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/FileType.java170
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/FileTypeResource.java (renamed from Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraFilePattern.java)55
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Interpreter.java458
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Language.java148
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Messages.java170
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Pair.java92
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Parser.java410
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Resource.java291
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Rule.java155
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/RuleCommand.java (renamed from Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraCommand.java)86
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Session.java122
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/StopWatch.java84
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Trigger.java135
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/ClassLoadingUtils.java166
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/CommonUtils.java929
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/ConfigurationUtils.java239
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/DatabaseUtils.java140
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/DirectiveAssembler.java (renamed from Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraTask.java)99
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/DirectiveResolver.java (renamed from Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraResolver.java)37
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/DirectiveUtils.java438
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/DisplayUtils.java502
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/FileHandlingUtils.java124
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/FileSearchingUtils.java117
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/InterpreterUtils.java257
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/MessageUtils.java313
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/Methods.java1356
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/RuleUtils.java244
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/TeeOutputStream.java (renamed from Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/TeeOutputStream.java)96
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/UnsafeUtils.java87
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/VelocityUtils.java157
62 files changed, 9344 insertions, 4711 deletions
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/Arara.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/Arara.java
deleted file mode 100644
index 48335eaf879..00000000000
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/Arara.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, 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.
- * \endcond
- *
- * Arara: The main class. Basically, this class will get the file name from the
- * arguments list and call the proper methods from the other helper classes.
- */
-// package definition
-package com.github.arara;
-
-// needed imports
-import com.github.arara.model.AraraDirective;
-import com.github.arara.utils.*;
-import java.io.File;
-import java.util.List;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The main arara class. The code logic is encapsulated in the helper class, so
- * if something goes wrong, the generic exception catch here will simply print
- * it. I tried to make the code as easier as possible.
- *
- * @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 1.0
- */
-public class Arara {
-
- // the logger
- final static Logger logger = LoggerFactory.getLogger(Arara.class);
- // the localization class
- final static AraraLocalization localization = AraraLocalization.getInstance();
-
- /**
- * The main method. The idea is to provide to arara only the supported file
- * name and let it handle. The application will remove the file extension
- * (if any) and call the other helper classes.
- *
- * @param args The command line arguments. In fact, arara supports a lot of
- * flags, all listed in the CommandLineAnalyzer.
- */
- public static void main(String[] args) {
-
- // the application status, zero for a normal execution,
- // or nonzero for an abnormal execution
- int exitStatus;
-
- // trying to have a normal execution
- try {
-
- // print the application header
- AraraUtils.printHeader();
-
- // create a configuration instance and load
- // the proper settings, if any
- ConfigurationLoader configuration = new ConfigurationLoader();
- configuration.load();
-
- // create a new analyzer
- CommandLineAnalyzer commandLine = new CommandLineAnalyzer(args, configuration);
-
- // if the minimum parameters are not satisfied or it's a simple
- // help or version request
- if (!commandLine.parse()) {
-
- // simply return
- exitStatus = 0;
-
- // exit right now, good job
- System.exit(exitStatus);
- }
-
- // it's a normal workflow, let's define the main file
- File file;
-
- // create a new file reference
- file = new File(commandLine.getFile());
-
- // welcome message
- logger.info(localization.getMessage("Log_WelcomeMessage"));
-
- // process file
- logger.info(localization.getMessage("Log_ProcessingFile", file.getName()));
-
- // file exists, let's proceed with the directive extractor
- DirectiveExtractor dirExtractor = new DirectiveExtractor(file, configuration);
-
- // extract all directives from the file
- dirExtractor.extract();
-
- // get all directives found
- List<AraraDirective> directives = dirExtractor.getDirectives();
-
- // set the overall result flag
- boolean overallResult = true;
-
- // check if any directive was found
- if (!directives.isEmpty()) {
-
- // now let's parse the directives
- DirectiveParser dirParser = new DirectiveParser(directives);
-
- // set the file
- dirParser.setFile(file);
-
- // parse the directives
- TaskDeployer taskDeployer = new TaskDeployer(dirParser.parse(), configuration);
-
- // deploy the tasks through a command trigger
- CommandTrigger commandTrigger = new CommandTrigger(taskDeployer.deploy());
-
- // set verbose option, if enabled
- commandTrigger.setVerbose(commandLine.isVerbose());
-
- // set an execution timeout, if set
- commandTrigger.setExecutionTimeout(commandLine.getExecutionTimeout());
-
- // execute the tasks
- overallResult = commandTrigger.execute();
- }
- else {
-
- // no directives found, add message to the log
- logger.info(localization.getMessage("Log_NoDirectivesFound", file.getName()));
-
- // print message
- System.out.println(AraraUtils.wrap(localization.getMessage("Msg_NoDirectivesFound", file.getName())));
- }
-
- // final message
- logger.info(localization.getMessage("Log_Done"));
-
- // if everything was ok, that is, every command in the command list
- // returned with an exit status of zero
- if (overallResult) {
-
- // everything fine
- exitStatus = 0;
-
- } else {
-
- // something wrong happened, so let's consider the whole
- // execution as abnormal
- exitStatus = 1;
- }
-
- } catch (Exception exception) {
-
- // something bad happened, print the error message
- System.out.println(AraraUtils.wrap(exception.getMessage()));
-
- // catch error in the log
- logger.error(localization.getMessage("Log_ExceptionRaised"));
- logger.error(exception.getMessage());
-
- // error, set status to an abnormal execution
- exitStatus = 1;
-
- }
-
- // send the exit code to the terminal, and we are done
- System.exit(exitStatus);
- }
-}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraConfiguration.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraConfiguration.java
deleted file mode 100644
index f65c36e447b..00000000000
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraConfiguration.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, 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.
- * \endcond
- *
- * AraraConfiguration: This class holds the model for the arara configuration
- * file.
- */
-// package definition
-package com.github.arara.model;
-
-// needed imports
-import com.github.arara.exception.AraraException;
-import com.github.arara.utils.AraraUtils;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import org.apache.commons.lang3.SystemUtils;
-import org.mvel2.templates.TemplateRuntime;
-
-/**
- * Holds the model for the arara configuration file.
- *
- * @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 3.0
- */
-public class AraraConfiguration {
-
- // the application language
- private String language;
- // the list of search paths
- private List<String> paths;
- // the list of filetypes
- private List<AraraFilePattern> filetypes;
- // the path runtime exception
- private RuntimeException pathRuntimeException;
- // the path IO exception
- private IOException pathIOException;
-
- /**
- * Getter for the search paths.
- *
- * @return The search paths.
- */
- public List<String> getPaths() {
- return paths;
- }
-
- /**
- * Getter for the language.
- *
- * @return The language.
- */
- public String getLanguage() {
- return language;
- }
-
- /**
- * Setter for the language.
- *
- * @param language The language.
- */
- public void setLanguage(String language) {
- this.language = language;
- }
-
- /**
- * Setter for the search paths.
- *
- * @param rules The search paths.
- */
- public void setPaths(List<String> rules) throws AraraException, Exception {
- this.paths = rules;
-
- // refresh paths
- refreshPaths();
- }
-
- /**
- * Getter for the filetypes.
- *
- * @return The filetypes.
- */
- public List<AraraFilePattern> getFiletypes() {
- return filetypes;
- }
-
- /**
- * Setter for the filetypes.
- *
- * @param filetypes The filetypes.
- */
- public void setFiletypes(List<AraraFilePattern> filetypes) {
- this.filetypes = filetypes;
- }
-
- /**
- * Constructor.
- */
- public AraraConfiguration() {
-
- // creates both lists
- paths = new ArrayList<String>();
- filetypes = new ArrayList<AraraFilePattern>();
- pathRuntimeException = null;
- }
-
- /**
- * Refreshes all paths, replacing possible variables in the template
- */
- private void refreshPaths() throws AraraException, Exception {
-
- // create a map
- HashMap map = new HashMap();
-
- // add the variables
- map.put("userhome", SystemUtils.USER_HOME);
-
- // for every path in the list
- for (int i = 0; i < paths.size(); i++) {
-
- try {
-
- // remove the keyword
- String fullPath = AraraUtils.removeKeyword(paths.get(i));
-
- // apply the template
- fullPath = (String) TemplateRuntime.eval(fullPath, map);
-
- try {
-
- // attempt to create a file reference and
- // get the canonical path, if the operation
- // succeeds, it's a valid path
- File validFile = new File(fullPath);
- validFile.getCanonicalPath();
-
- // sanitize the path in order to be displayed correctly
- fullPath = new File(new File(fullPath).toURI()).getPath();
-
- // set the path in the list
- paths.set(i, fullPath);
-
- } catch (IOException ioException) {
-
- // the path is terribly invalid, get the exception,
- // if null
- if (pathIOException == null) {
-
- // set the path IO exception
- pathIOException = ioException;
- }
- }
-
- } catch (RuntimeException runtimeException) {
-
- // an error has occurred, register the exception for
- // later access
-
- // if there isn't an exception yet
- if (pathRuntimeException == null) {
-
- // set the exception
- pathRuntimeException = runtimeException;
- }
-
- }
- }
- }
-
- /**
- * Getter for the path runtime exception.
- *
- * @return The path runtime exception.
- */
- public RuntimeException getPathRuntimeException() {
- return pathRuntimeException;
- }
-
- /**
- * Getter for the path IO exception.
- *
- * @return The path IO exception.
- */
- public IOException getPathIOException() {
- return pathIOException;
- }
-}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraDirective.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraDirective.java
deleted file mode 100644
index 5dc8842456b..00000000000
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraDirective.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, 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.
- * \endcond
- *
- * AraraDirective: This class provides the model for representing the arara
- * directives found in the source file. It's a plain old Java object.
- */
-// package definition
-package com.github.arara.model;
-
-// needed imports
-import java.util.Map;
-
-/**
- * Provides the model for representing the arara directives found in the source
- * file.
- *
- * @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 1.0
- */
-public class AraraDirective {
-
- // the directive name
- private String name;
- // the configuration
- private Map config;
- // the line number
- private int lineNumber = 0;
-
- /**
- * Constructor.
- *
- * @param name The directive name.
- * @param config The configuration.
- */
- public AraraDirective(String name, Map config) {
-
- // set the name
- this.name = name;
-
- // set the configuration
- this.config = config;
- }
-
- /**
- * Constructor.
- */
- public AraraDirective() {
- }
-
- /**
- * Getter for configuration.
- *
- * @return The configuration.
- */
- public Map getConfig() {
-
- // return it
- return config;
- }
-
- /**
- * Setter for configuration.
- *
- * @param config The configuration.
- */
- public void setConfig(Map config) {
-
- // set the configuration
- this.config = config;
- }
-
- /**
- * Getter for the directive name.
- *
- * @return The directive name.
- */
- public String getName() {
-
- // return it
- return name;
- }
-
- /**
- * Setter for the directive name.
- *
- * @param name The directive name.
- */
- public void setName(String name) {
-
- // set it
- this.name = name;
- }
-
- /**
- * Getter for the line number.
- *
- * @return The line number.
- */
- public int getLineNumber() {
-
- // return it
- return lineNumber;
- }
-
- /**
- * Setter for the line number.
- *
- * @param lineNumber The line number.
- */
- public void setLineNumber(int lineNumber) {
-
- // set it
- this.lineNumber = lineNumber;
- }
-}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraLanguage.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraLanguage.java
deleted file mode 100644
index b04e9850236..00000000000
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraLanguage.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, 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.
- * \endcond
- *
- * AraraLanguage: This class holds the data model for the arara language
- * specification.
- */
-// package definition.
-package com.github.arara.model;
-
-// needed import
-import java.util.Locale;
-
-/**
- * Holds the data model for the arara language specification.
- *
- * @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 3.0
- */
-public class AraraLanguage {
-
- // language name
- private String name;
- // language code
- private String code;
- // language locale
- private Locale locale;
-
- /**
- * Getter for the language name.
- *
- * @return The language name.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Setter for the language name.
- *
- * @param name The language name.
- */
- public void setName(String name) {
- this.name = name;
- }
-
- /**
- * Getter for the language code.
- *
- * @return The language code.
- */
- public String getCode() {
- return code;
- }
-
- /**
- * Setter for the language code.
- *
- * @param code The language code.
- */
- public void setCode(String code) {
- this.code = code;
- }
-
- /**
- * Getter for the language locale.
- *
- * @return The language locale.
- */
- public Locale getLocale() {
- return locale;
- }
-
- /**
- * Setter for the language locale.
- *
- * @param locale The language locale.
- */
- public void setLocale(Locale locale) {
- this.locale = locale;
- }
-
- /**
- * Constructor.
- *
- * @param name The language name.
- * @param code The language code.
- * @param locale The language locale.
- */
- public AraraLanguage(String name, String code, Locale locale) {
- this.name = name;
- this.code = code;
- this.locale = locale;
- }
-
- /**
- * Returns a string representation of the object.
- *
- * @return The string representation of the object.
- */
- @Override
- public String toString() {
- return name.concat(" [").concat(code).concat("]");
- }
-}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraRuleConfig.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraRuleConfig.java
deleted file mode 100644
index 5ebe9382bf0..00000000000
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraRuleConfig.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, 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.
- * \endcond
- *
- * PlainAraraRuleConfig: This class provides the model for representing a plain
- * Arara rule configuration based on the YAML files. It's a plain old Java
- * object.
- */
-// package definition
-package com.github.arara.model;
-
-// needed imports
-import com.github.arara.utils.AraraUtils;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Provides the model for representing a plain Arara rule configuration based on
- * the YAML files. This class will be used to map YAML rules into Java objects.
- *
- * @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 1.0
- */
-public class AraraRuleConfig {
-
- // the rule identifier
- private String identifier;
- // the rule name
- private String name;
- // the rule command
- private String command;
- // the rule commands
- private List<String> commands;
- // the arguments list
- private List<AraraRuleArgument> arguments;
-
- public List<String> getCommands() {
- return commands;
- }
-
- /**
- * Setter for the rule commands.
- *
- * @param commands A list containing the rule commands.
- */
- public void setCommands(List<String> commands) {
- this.commands = commands;
-
- // for every entry
- for (int i = 0; i < commands.size(); i++) {
-
- // remove keyword and reinsert into the list
- String currentCommand = AraraUtils.removeKeyword(commands.get(i));
- commands.set(i, currentCommand);
- }
- }
-
- /**
- * Getter for the rule identifier.
- *
- * @return The rule identifier.
- */
- public String getIdentifier() {
-
- // return it
- return identifier;
- }
-
- /**
- * Setter for the rule identifier.
- *
- * @param identifier The rule identifier.
- */
- public void setIdentifier(String identifier) {
-
- // set the identifier
- this.identifier = identifier;
- }
-
- /**
- * Getter for the rule name.
- *
- * @return The rule name.
- */
- public String getName() {
-
- // return it
- return name;
- }
-
- /**
- * Setter for the rule name.
- *
- * @param name The rule name.
- */
- public void setName(String name) {
-
- // set the rule name
- this.name = name;
- }
-
- /**
- * Getter for the rule command.
- *
- * @return The rule command.
- */
- public String getCommand() {
-
- // return it
- return command;
- }
-
- /**
- * Setter for the rule command.
- *
- * @param command The rule command.
- */
- public void setCommand(String command) {
-
- // set the command
- this.command = AraraUtils.removeKeyword(command);
- }
-
- /**
- * Getter for the arguments list.
- *
- * @return The arguments list.
- */
- public List<AraraRuleArgument> getArguments() {
-
- // return the list
- return arguments;
- }
-
- /**
- * Setter for the arguments list.
- *
- * @param arguments The arguments list.
- */
- public void setArguments(List<AraraRuleArgument> arguments) {
-
- // set the list
- this.arguments = arguments;
- }
-
- /**
- * Returns a list containing all argument identifiers.
- *
- * @return A list containing all argument identifiers.
- */
- public List<String> getIdentifiersList() {
-
- // create a new list
- List<String> result = new ArrayList<String>();
-
- // for every argument
- for (AraraRuleArgument argument : getArguments()) {
-
- // add identifier
- result.add(argument.getIdentifier());
- }
-
- // return list
- return result;
- }
-
- /**
- * Returns the forbidden identifier, if any.
- *
- * @return The forbidden identifier, if any.
- */
- public String checkForForbiddenIdentifiers() {
-
- // for every argument
- for (AraraRuleArgument argument : getArguments()) {
-
- // get the current argument value
- String value = argument.getIdentifier().toLowerCase();
-
- // check if it's a forbidden argument identifier
- if ((value.equals("file")) || (value.equals("files")) || (value.equals("item")) || (value.equals("items"))) {
-
- // return the value
- return value;
- }
- }
-
- // nothing wrong was found
- return null;
- }
-}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraConstants.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraConstants.java
deleted file mode 100644
index 38a931f1119..00000000000
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraConstants.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, 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.
- * \endcond
- *
- * AraraConstants: This class contains all the constants used in the main
- * application.
- */
-// package definition
-package com.github.arara.utils;
-
-/**
- * Contains all the constants used in the main application.
- *
- * @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 3.0
- */
-public class AraraConstants {
-
- /**
- * The arara version.
- */
- public static final String VERSION = "3.0a";
- /**
- * The number of characters per line in messages.
- */
- public static final int WRAPLENGTH = 65;
- /**
- * The name of the default configuration file.
- */
- public static final String ARARACONFIG = "araraconfig.yaml";
- /**
- * The directive prefix for the pattern matching method.
- */
- public static final String DIRECTIVEPREFIX = "arara:\\s";
- /**
- * The rule pattern for string reference.
- */
- public static final String RULEPATTERN = "^(\\s)*<arara>\\s";
- /**
- * The name of the log file generated by arara.
- */
- public static final String LOGNAME = "arara";
- /**
- * The copyright year.
- */
- public static final String COPYRIGHTYEAR = "2012";
- /**
- * The variable exception matching pattern.
- */
- public static final String VAREXCEPTIONPATTERN = "^\\[Error: could not access: (.*);";
- /**
- * The method exception matching pattern.
- */
- public static final String METHODEXCEPTIONPATTERN = "^\\[Error: unable to access property \\((.*)\\): (.*)\\]";
- /**
- * The full directive matching pattern.
- */
- public static final String FULLDIRECTIVEPATTERN = "^\\s*(\\w+)\\s*:\\s*\\{.*\\}\\s*$";
- /**
- * The empty directive matching pattern.
- */
- public static final String EMPTYDIRECTIVEPATTERN = "^\\s*(\\w+)\\s*$";
-
-}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraLocalization.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraLocalization.java
deleted file mode 100644
index 1b3f093699f..00000000000
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraLocalization.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, 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.
- * \endcond
- *
- * AraraLocalization: This class contains a few helper methods in order to ease
- * the localization process during the execution. This class is a singleton
- * reference.
- */
-// package definition
-package com.github.arara.utils;
-
-// needed imports
-import java.text.MessageFormat;
-import java.util.Locale;
-import java.util.ResourceBundle;
-
-/**
- * Contains a few helper methods in order to ease the localization process
- * during the execution. This class is a singleton reference.
- *
- * @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 3.0
- */
-public class AraraLocalization {
-
- // the singleton reference
- private static AraraLocalization selfRef;
- // the resource bundle for the whole application
- private ResourceBundle resources;
-
- /**
- * Constructs the singleton instance.
- */
- private AraraLocalization() {
-
- // set the self-reference
- selfRef = this;
-
- // instead of relying in the default locale from the
- // operating system, always fallback to english
- Locale.setDefault(Locale.ENGLISH);
-
- // get the resource bundle
- resources = ResourceBundle.getBundle("com.github.arara.localization.Messages");
- }
-
- /**
- * Provides reference to the singleton object.
- *
- * @return The singleton instance.
- */
- public static final AraraLocalization getInstance() {
-
- // if there's no current object, call the private constructor
- if (selfRef == null) {
- selfRef = new AraraLocalization();
- }
-
- // return the actual object
- return selfRef;
- }
-
- /**
- * Returns a simple message from the resource bundle.
- *
- * @param message The message identifier.
- * @return A string from the resource bundle.
- */
- public String getMessage(String message) {
- return resources.getString(message);
- }
-
- /**
- * Returns a message containing parameters from the resource bundle.
- *
- * @param message The message identifier.
- * @param parameters A list of parameters to be replaced in the message.
- * @return A string from the resource bundle, with the correct parameters.
- */
- public String getMessage(String message, Object... parameters) {
- return MessageFormat.format(resources.getString(message), parameters);
- }
-
- /**
- * Refresh the resource bundle reference, if by any chance, the application
- * language is changed in runtime.
- */
- public void refresh() {
-
- // clear cache and reload the resource bundle
- // ResourceBundle.clearCache(); // not supported by Java 5
- resources = ResourceBundle.getBundle("com.github.arara.localization.Messages");
- }
-}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraLogging.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraLogging.java
deleted file mode 100644
index 3cbad2a970c..00000000000
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraLogging.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, 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.
- * \endcond
- *
- * AraraLogging: This class configures the logging features.
- */
-// package definition
-package com.github.arara.utils;
-
-// needed imports
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.core.joran.spi.JoranException;
-import org.slf4j.LoggerFactory;
-
-/**
- * Configures the logging features.
- *
- * @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 3.0
- */
-public class AraraLogging {
-
- public static void enableLogging(boolean enable) {
-
- // get the context
- LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
-
- try {
-
- // create a new configurator
- JoranConfigurator configurator = new JoranConfigurator();
-
- // set context and reset it
- configurator.setContext(loggerContext);
- loggerContext.reset();
-
- // if logging should be enabled
- if (enable) {
-
- // add the correct properties and load the XML file
- loggerContext.putProperty("araraLogName", AraraConstants.LOGNAME);
- configurator.doConfigure(AraraLogging.class.getResourceAsStream("/com/github/arara/conf/logback.xml"));
- }
-
- } catch (JoranException joranException) {
- // do nothing
- }
- }
-}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraMethods.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraMethods.java
deleted file mode 100644
index 239dd4bf7cf..00000000000
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraMethods.java
+++ /dev/null
@@ -1,481 +0,0 @@
-/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, 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.
- * \endcond
- *
- * AraraMethods: This class contains methods for the MVEL expression language to
- * be used in the rules.
- */
-// package definition
-package com.github.arara.utils;
-
-// needed import
-import java.io.File;
-import org.apache.commons.lang3.SystemUtils;
-
-/**
- * Contains methods for the MVEL expression language to be used in the rules.
- *
- * @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 3.0
- */
-public class AraraMethods {
-
- /**
- * Holds the original filename.
- */
- private static String originalFile;
-
- /**
- * Setter for the original filename.
- *
- * @param originalFile The original filename.
- */
- public static void setOriginalFile(String originalFile) {
- AraraMethods.originalFile = originalFile;
- }
-
- /**
- * Getter for the original filename.
- *
- * @return A string containing the original filename.
- */
- public static String getOriginalFile() {
- return originalFile;
- }
-
- /**
- * Checks if string is empty.
- *
- * @param string The string.
- * @return A logical value according to the condition.
- */
- public static boolean isEmpty(String string) {
- return "".equals(string);
- }
-
- /**
- * Checks if string is not empty.
- *
- * @param string The string.
- * @return A logical value according to the condition.
- */
- public static boolean isNotEmpty(String string) {
- return !"".equals(string);
- }
-
- /**
- * Checks if string is empty.
- *
- * @param string The string.
- * @param ifTrue Value if true.
- * @return A string according the condition.
- */
- public static String isEmpty(String string, String ifTrue) {
- return ("".equals(string) ? ifTrue : string);
- }
-
- /**
- * Checks if string is not empty.
- *
- * @param string The string.
- * @param ifTrue Value if true.
- * @return A string according the condition.
- */
- public static String isNotEmpty(String string, String ifTrue) {
- return (!"".equals(string) ? ifTrue : string);
- }
-
- /**
- * Checks if string is empty.
- *
- * @param string The string.
- * @param ifTrue Value if true.
- * @param ifFalse Value if false.
- * @return A string according the condition.
- */
- public static String isEmpty(String string, String ifTrue, String ifFalse) {
- return ("".equals(string) ? ifTrue : ifFalse);
- }
-
- /**
- * Checks if string is not empty.
- *
- * @param string The string.
- * @param ifTrue Value if true.
- * @param ifFalse Value if false.
- * @return A string according the condition.
- */
- public static String isNotEmpty(String string, String ifTrue, String ifFalse) {
- return (!"".equals(string) ? ifTrue : ifFalse);
- }
-
- /**
- * Checks if string resolves to a logic value representing true.
- *
- * @param string The string.
- * @return A string according the condition.
- */
- public static boolean isTrue(String string) {
- string = string.toLowerCase();
- if ((string.equals("yes")) || (string.equals("on")) || (string.equals("true")) || (string.equals("y")) || (string.equals("1"))) {
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Checks if string resolves to a logic value representing false.
- *
- * @param string The string.
- * @return A string according the condition.
- */
- public static boolean isFalse(String string) {
- string = string.toLowerCase();
- if ((string.equals("no")) || (string.equals("off")) || (string.equals("false")) || (string.equals("n")) || (string.equals("0"))) {
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Checks if string resolves to a logic value representing true.
- *
- * @param string The string.
- * @param ifTrue Value if true.
- * @return A string according the condition.
- */
- public static String isTrue(String string, String ifTrue) {
- return (isTrue(string) ? ifTrue : "");
- }
-
- /**
- * Checks if string resolves to a logic value representing false.
- *
- * @param string The string.
- * @param ifTrue Value if true.
- * @return A string according the condition.
- */
- public static String isFalse(String string, String ifTrue) {
- return (isFalse(string) ? ifTrue : "");
- }
-
- /**
- * Checks if string resolves to a logic value representing true.
- *
- * @param string The string.
- * @param ifTrue Value if true.
- * @param ifFalse Value if false.
- * @return A string according the condition.
- */
- public static String isTrue(String string, String ifTrue, String ifFalse) {
- return (isTrue(string) ? ifTrue : ifFalse);
- }
-
- /**
- * Checks if string resolves to a logic value representing false.
- *
- * @param string The string.
- * @param ifTrue Value if true.
- * @param ifFalse Value if false.
- * @return A string according the condition.
- */
- public static String isFalse(String string, String ifTrue, String ifFalse) {
- return (isFalse(string) ? ifTrue : ifFalse);
- }
-
- /**
- * Checks if string resolves to a logic value representing true.
- *
- * @param string The string.
- * @param ifTrue Value if true.
- * @param ifFalse Value if false.
- * @param defaultValue Value if the string is neither true or false.
- * @return A string according the condition.
- */
- public static String isTrue(String string, String ifTrue, String ifFalse, String defaultValue) {
- if (isTrue(string)) {
- return ifTrue;
- }
- if (isFalse(string)) {
- return ifFalse;
- }
- return defaultValue;
- }
-
- /**
- * Checks if string resolves to a logic value representing false.
- *
- * @param string The string.
- * @param ifTrue Value if true.
- * @param ifFalse Value if false.
- * @param defaultValue Value if the string is neither true or false.
- * @return A string according the condition.
- */
- public static String isFalse(String string, String ifTrue, String ifFalse, String defaultValue) {
- if (isFalse(string)) {
- return ifTrue;
- }
- if (isTrue(string)) {
- return ifFalse;
- }
- return defaultValue;
- }
-
- /**
- * Trim spaces from the string.
- *
- * @param string The string.
- * @return The string with the trailing and leading spaces trimmed.
- */
- public static String trimSpaces(String string) {
- return string.trim();
- }
-
- /**
- * Returns the filename.
- *
- * @param f The string.
- * @return The filename.
- */
- public static String getFilename(String f) {
- try {
- return (new File(f)).getName();
- } catch (Exception exception) {
- return "";
- }
- }
-
- /**
- * Returns the base name.
- *
- * @param f The string.
- * @return The base name.
- */
- public static String getBasename(String f) {
- try {
- f = (new File(f)).getName();
- int i = f.lastIndexOf(".") != -1 ? f.lastIndexOf(".") : f.length();
- return f.substring(0, i);
- } catch (Exception exception) {
- return "";
- }
- }
-
- /**
- * Returns the filetype.
- *
- * @param f The string.
- * @return The filetype.
- */
- public static String getFiletype(String f) {
- try {
- f = (new File(f)).getName();
- if (f.lastIndexOf(".") != -1) {
- return f.substring(f.lastIndexOf(".") + 1, f.length());
- }
- return "";
- } catch (Exception exception) {
- return "";
- }
- }
-
- /**
- * Returns the directory name.
- *
- * @param f The string.
- * @return The directory name.
- */
- public static String getDirname(String f) {
- try {
- return (new File(f)).getParent();
- } catch (Exception exception) {
- return "";
- }
- }
-
- /**
- * Checks if the string is a valid existing file.
- *
- * @param f The string.
- * @return A logic value indicating if the string is a valid existing file.
- */
- public static boolean isFile(String f) {
- try {
- return (new File(f)).isFile();
- } catch (Exception exception) {
- return false;
- }
- }
-
- /**
- * Checks if the string is a valid existing directory.
- *
- * @param f The string.
- * @return A logic value indicating if the string is a valid existing
- * directory.
- */
- public static boolean isDir(String f) {
- try {
- return (new File(f)).isDirectory();
- } catch (Exception exception) {
- return false;
- }
- }
-
- /**
- * Checks if the operating system is Windows.
- *
- * @param ifTrue The value if true.
- * @param ifFalse The value if false.
- * @return A string according the condition.
- */
- public static String isWindows(String ifTrue, String ifFalse) {
- if (SystemUtils.IS_OS_WINDOWS) {
- return ifTrue;
- }
- else {
- return ifFalse;
- }
- }
-
- /**
- * Checks if the operating system is Linux.
- *
- * @param ifTrue The value if true.
- * @param ifFalse The value if false.
- * @return A string according the condition.
- */
- public static String isLinux(String ifTrue, String ifFalse) {
- if (SystemUtils.IS_OS_LINUX) {
- return ifTrue;
- }
- else {
- return ifFalse;
- }
- }
-
- /**
- * Checks if the operating system is Unix.
- *
- * @param ifTrue The value if true.
- * @param ifFalse The value if false.
- * @return A string according the condition.
- */
- public static String isUnix(String ifTrue, String ifFalse) {
- if (SystemUtils.IS_OS_UNIX) {
- return ifTrue;
- }
- else {
- return ifFalse;
- }
- }
-
- /**
- * Checks if the operating system is Mac.
- *
- * @param ifTrue The value if true.
- * @param ifFalse The value if false.
- * @return A string according the condition.
- */
- public static String isMac(String ifTrue, String ifFalse) {
- if (SystemUtils.IS_OS_MAC) {
- return ifTrue;
- }
- else {
- return ifFalse;
- }
- }
-
- /**
- * Checks if the logic condition is true.
- *
- * @param value Logic condition to be evaluated.
- * @param ifTrue The value if true.
- * @return A string according the condition.
- */
- public static String isTrue(boolean value, String ifTrue) {
- if (value) {
- return ifTrue;
- }
- return "";
- }
-
- /**
- * Checks if the logic condition is true.
- *
- * @param value Logic condition to be evaluated.
- * @param ifTrue The value if true.
- * @param ifFalse The value if false.
- * @return A string according the condition.
- */
- public static String isTrue(boolean value, String ifTrue, String ifFalse) {
- if (value) {
- return ifTrue;
- }
- return ifFalse;
- }
-
- /**
- * Checks if the logic condition is false.
- *
- * @param value Logic condition to be evaluated.
- * @param ifTrue The value if true.
- * @return A string according the condition.
- */
- public static String isFalse(boolean value, String ifTrue) {
- if (!value) {
- return ifTrue;
- }
- return "";
- }
-
- /**
- * Checks if the logic condition is false.
- *
- * @param value Logic condition to be evaluated.
- * @param ifTrue The value if true.
- * @param ifFalse The value if false.
- * @return A string according the condition.
- */
- public static String isFalse(boolean value, String ifTrue, String ifFalse) {
- if (!value) {
- return ifTrue;
- }
- return ifFalse;
- }
-
-}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraUtils.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraUtils.java
deleted file mode 100644
index 42eaa6c44a2..00000000000
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraUtils.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, 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.
- * \endcond
- *
- * AraraUtils: This class contains some helper methods used for general purpose.
- */
-// package definition
-package com.github.arara.utils;
-
-// needed imports
-import java.util.StringTokenizer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import org.apache.commons.lang3.text.WordUtils;
-import org.yaml.snakeyaml.error.MarkedYAMLException;
-
-/**
- * Contains some helper methods used for general purpose.
- *
- * @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 3.0
- */
-public class AraraUtils {
-
- // the localization class
- final static AraraLocalization localization = AraraLocalization.getInstance();
-
- /**
- * Removes the reserved keyword in the strings to be analyzed by the MVEL
- * template engine. The keyword is set in AraraConstants.
- *
- * @param line The line to be analyzed.
- * @return The new line without the keyword.
- */
- public static String removeKeyword(String line) {
-
- // set a new pattern and matcher
- Pattern pattern = Pattern.compile(AraraConstants.RULEPATTERN);
- Matcher matcher = pattern.matcher(line);
-
- // if the keyword is found
- if (matcher.find()) {
-
- // remove the keyword
- line = (line.substring(matcher.end(), line.length())).trim();
- }
-
- // and return it
- return line;
- }
-
- /**
- * Prints the arara ASCII header.
- */
- public static void printHeader() {
-
- // print the ASCII art
- System.out.println(" __ _ _ __ __ _ _ __ __ _ ");
- System.out.println(" / _` | '__/ _` | '__/ _` |");
- System.out.println("| (_| | | | (_| | | | (_| |");
- System.out.println(" \\__,_|_| \\__,_|_| \\__,_|\n");
-
- }
-
- /**
- * Wraps the string to several lines, according to the wrap length set in
- * the AraraConstants class.
- *
- * @param message The message to be wrapped.
- * @return A new message.
- */
- public static String wrap(String message) {
-
- // create a new tokenizer in order to allow line breaks, so
- // every line is processed individually
- StringTokenizer tokens = new StringTokenizer(message, "\n", true);
- String result = "";
-
- // iterate through tokens
- while (tokens.hasMoreTokens()) {
-
- // wrap line according to the wrap length
- result = result.concat(WordUtils.wrap(tokens.nextToken(), AraraConstants.WRAPLENGTH));
- }
-
- // return the result
- return result;
- }
-
- /**
- * Gets the variable reference from a RuntimeException object.
- * @param runtimeException The RuntimeException object.
- *
- * @return The variable reference name.
- */
- public static String getVariableFromException(RuntimeException runtimeException) {
-
- // set pattern and matcher
- Pattern pattern = Pattern.compile(AraraConstants.VAREXCEPTIONPATTERN);
- Matcher matcher = pattern.matcher(runtimeException.getMessage());
-
- // if the variable is found
- if (matcher.find()) {
-
- // check if it's a valid reference
- if (matcher.groupCount() != 0) {
-
- // return the variable name
- return matcher.group(1);
- }
-
- } else {
-
- // maybe it's a method call, let's investigate
- pattern = Pattern.compile(AraraConstants.METHODEXCEPTIONPATTERN);
- matcher = pattern.matcher(runtimeException.getMessage());
-
- if (matcher.find()) {
-
- // check if it's a valid reference
- if (matcher.groupCount() > 1) {
-
- // return the method name
- return matcher.group(2);
- }
-
- }
-
- }
-
- // nothing is found, so return an unknown reference
- return "<unknown>";
- }
-
- /**
- * Extracts information from a MarkedYAMLException object.
- *
- * @param yamlException The exception object.
- * @return A string containing all the available information from the
- * exception object.
- */
- public static String extractInformationFromYAMLException(MarkedYAMLException yamlException) {
- StringBuilder stringBuilder = new StringBuilder();
- if (yamlException.getContext() != null) {
- stringBuilder.append(localization.getMessage("YamlError_Context", yamlException.getContext())).append("\n");
- }
- if (yamlException.getProblem() != null) {
- stringBuilder.append(localization.getMessage("YamlError_Problem", yamlException.getProblem())).append("\n");
- }
- if (yamlException.getProblemMark() != null) {
- stringBuilder.append(localization.getMessage("YamlError_ErrorLocation", yamlException.getProblemMark().getLine(), yamlException.getProblemMark().getColumn())).append("\n");
- }
- if (yamlException.getProblemMark().get_snippet() != null) {
- stringBuilder.append(yamlException.getProblemMark().get_snippet());
- }
- return stringBuilder.toString();
- }
-
- /**
- * Checks if the line contains a valid full directive.
- *
- * @param line The current line.
- * @return A logic value indicating if a valid directive was found.
- */
- public static boolean checkForFullDirective(String line) {
- Pattern pattern = Pattern.compile(AraraConstants.FULLDIRECTIVEPATTERN);
- Matcher m = pattern.matcher(line);
- if (m.find()) {
- return true;
- }
- else {
- return false;
- }
- }
-
- /**
- * Checks if the line contains a valid empty directive.
- *
- * @param line The current line.
- * @return A logic value indicating if a valid directive was found.
- */
- public static boolean checkForEmptyDirective(String line) {
- Pattern pattern = Pattern.compile(AraraConstants.EMPTYDIRECTIVEPATTERN);
- Matcher m = pattern.matcher(line);
- if (m.find()) {
- return true;
- }
- else {
- return false;
- }
- }
-}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/CommandLineAnalyzer.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/CommandLineAnalyzer.java
deleted file mode 100644
index 8cf0d2e9122..00000000000
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/CommandLineAnalyzer.java
+++ /dev/null
@@ -1,488 +0,0 @@
-/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, 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.
- * \endcond
- *
- * CommandLineAnalyzer: This class implements a command line parser to provide
- * better control of flags and files to process.
- */
-// package definition
-package com.github.arara.utils;
-
-// needed import
-import java.io.File;
-import org.apache.commons.cli.*;
-
-/**
- * Implements a command line parser to provide better control of flags and files
- * to process.
- *
- * @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 1.0
- */
-public class CommandLineAnalyzer {
-
- // the file to process
- private String theFile;
- // the command line arguments
- private String[] theArgs;
- // the command line options
- private Options commandLineOptions;
- // the verbose option
- private boolean showVerboseOutput;
- // the execution timeout,
- // in milliseconds
- private long executionTimeout;
- // the configuration
- private ConfigurationLoader configuration;
- // the localization class
- final static AraraLocalization localization = AraraLocalization.getInstance();
-
- /**
- * Constructor.
- *
- * @param theArgs The command line arguments.
- * @param configuration The current configuration.
- */
- public CommandLineAnalyzer(String[] theArgs, ConfigurationLoader configuration) {
-
- // set the array
- this.theArgs = theArgs;
-
- // set the configuration
- this.configuration = configuration;
-
- // create new options
- commandLineOptions = new Options();
-
- // set the default value to the output
- showVerboseOutput = false;
-
- }
-
- /**
- * Parses the command line arguments and provides feedback to the main
- * class.
- *
- * @return A boolean value if there is a file to be processed by Arara.
- */
- public boolean parse() {
-
- // create the version option
- Option optVersion = new Option("V", "version", false, localization.getMessage("Help_Version"));
-
- // create the help option
- Option optHelp = new Option("h", "help", false, localization.getMessage("Help_Help"));
-
- // create the log option
- Option optLog = new Option("l", "log", false, localization.getMessage("Help_Log"));
-
- // create the verbose option
- Option optVerbose = new Option("v", "verbose", false, localization.getMessage("Help_Verbose"));
-
- // create the timeout option
- Option optTimeout = new Option("t", "timeout", true, localization.getMessage("Help_Timeout"));
-
- // create the language option
- Option optLanguage = new Option("L", "language", true, localization.getMessage("Help_Language"));
-
- // add version
- commandLineOptions.addOption(optVersion);
-
- // add help
- commandLineOptions.addOption(optHelp);
-
- // add log
- commandLineOptions.addOption(optLog);
-
- // add verbose
- commandLineOptions.addOption(optVerbose);
-
- // add timeout
- commandLineOptions.addOption(optTimeout);
-
- // add language
- commandLineOptions.addOption(optLanguage);
-
- // create a new basic parser
- CommandLineParser parser = new BasicParser();
-
- // lets try to parse everthing
- try {
-
- // parse the arguments
- CommandLine line = parser.parse(commandLineOptions, theArgs);
-
- // if -L or --language found
- if (line.hasOption("language")) {
-
- // create a new language controler
- LanguageController language = new LanguageController();
-
- // if the attempt to set the language according to the command
- // line has failed
- if (!language.setLanguage(line.getOptionValue("language"))) {
-
- // print the list of available languages
- language.printLanguageHelp();
-
- // print the usage
- printUsage();
-
- // and simply return
- return false;
- }
- else {
-
- // new language, refresh the options
- optVersion.setDescription(localization.getMessage("Help_Version"));
- optHelp.setDescription(localization.getMessage("Help_Help"));
- optLog.setDescription(localization.getMessage("Help_Log"));
- optVerbose.setDescription(localization.getMessage("Help_Verbose"));
- optTimeout.setDescription(localization.getMessage("Help_Timeout"));
- optLanguage.setDescription(localization.getMessage("Help_Language"));
- }
- }
-
- // if -h or --help found
- if (line.hasOption("help")) {
-
- // print version
- printVersion();
-
- // and usage
- printUsage();
-
- // return
- return false;
-
- } else {
-
- // if -v or --version found
- if (line.hasOption("version")) {
-
- // print version
- printVersion();
-
- printSpecialThanks();
-
- // and return
- return false;
-
- } else {
-
- // get the list of files
- String[] files = line.getArgs();
-
- // we only expect one file
- if (files.length != 1) {
-
- // print version
- printVersion();
-
- // usage
- printUsage();
-
- // and return
- return false;
-
- } else {
-
- // if -t or --timeout found
- if (line.hasOption("timeout")) {
-
- // try to convert the argument to a number
- try {
-
- // parse the long value
- executionTimeout = Long.parseLong(line.getOptionValue("timeout"));
-
- // if it's not a valid number
- if (executionTimeout <= 0) {
-
- // print version
- printVersion();
-
- // usage
- printUsage();
-
- // and return
- return false;
-
- }
- } catch (NumberFormatException numberFormatException) {
-
- // we have a bad conversion
-
- // print version
- printVersion();
-
- // usage
- printUsage();
-
- // and return
- return false;
- }
- } else {
-
- // fallback to the default value, that is,
- // timeout is disabled
- executionTimeout = 0;
- }
-
- // active logging
- AraraLogging.enableLogging(line.hasOption("log"));
-
- // set verbose flag
- showVerboseOutput = line.hasOption("verbose");
-
- // everything is fine, set
- // the file
- theFile = files[0];
-
- // check if file exists
- if (!checkFile(theFile, configuration.getValidExtensions())) {
-
- // file not found, return false
- return false;
-
- }
-
- // and return
- return true;
- }
- }
- }
-
- } catch (ParseException parseException) {
-
- // something happened, in the last case print version
- printVersion();
-
- // and usage
- printUsage();
-
- // and simply return
- return false;
-
- }
- }
-
- /**
- * Prints the usage message.
- */
- private void printUsage() {
-
- // new formatter
- HelpFormatter formatter = new HelpFormatter();
-
- // add the text and print
- formatter.printHelp("arara [file [--log] [--verbose] [--timeout N] [--language L] | --help | --version]", commandLineOptions);
- }
-
- /**
- * Prints the application version.
- */
- private void printVersion() {
-
- // print the version
- System.out.println("arara ".concat(AraraConstants.VERSION).concat(" - ").concat(localization.getMessage("Header_Slogan")));
- System.out.println("Copyright (c) ".concat(AraraConstants.COPYRIGHTYEAR).concat(", Paulo Roberto Massa Cereda"));
- System.out.println(localization.getMessage("Header_AllRightsReserved").concat("\n"));
- }
-
- /**
- * Getter for file obtained from the command line.
- *
- * @return The file.
- */
- public String getFile() {
-
- // return it
- return theFile;
- }
-
- /**
- * Checks if file is valid.
- *
- * @param filename The file name.
- * @param extensions A priority list of allowed extensions.
- * @return A boolean value to determine if the file is valid.
- */
- private boolean checkFile(String filename, String[] extensions) {
-
- // flag to indicate the file was found
- boolean foundFile = false;
-
- // iterate through all the extensions
- for (String currentExtension : extensions) {
-
- // check if the file has the current extension
- if (filename.toLowerCase().endsWith(currentExtension)) {
-
- // set flag
- foundFile = true;
-
- // set configuration
- configuration.setChosenFilePattern(currentExtension);
-
- // break iteration
- break;
- }
- }
-
- // create a new file status
- File fileStatus = null;
-
- // check if a reference was found
- if (foundFile) {
-
- // create new instance
- fileStatus = new File(filename);
-
- // check if exists
- if (fileStatus.exists()) {
-
- // add file
- theFile = filename;
-
- // found it!
- return true;
- } else {
-
- // print message about it
- System.out.println(localization.getMessage("Error_FileDoesNotExist", filename));
-
- // not found
- return false;
- }
-
- } else {
-
- // there's no extension, we will add them and see if something
- // is found
- for (String currentExtension : extensions) {
-
- // new file with extension
- fileStatus = new File(filename + currentExtension);
-
- // let's check it
- if (fileStatus.exists()) {
-
- // add file
- theFile = filename + currentExtension;
-
- // add reference
- configuration.setChosenFilePattern(currentExtension);
-
- // found it!
- return true;
-
- }
-
- }
-
- // print message about it
- System.out.println(AraraUtils.wrap(localization.getMessage("Error_FileDoesNotExistWithExtensionsList", filename, getExtensionsList(extensions))));
-
- // file not found
- return false;
-
- }
-
- }
-
- /**
- * Returns a string with the extensions list.
- *
- * @param extensions The extensions list.
- * @return A string with the extensions list.
- */
- private String getExtensionsList(String[] extensions) {
-
- // if it's an empty vector
- if (extensions.length == 0) {
-
- // return an empty string
- return "";
-
- } else {
-
- // get first element
- String result = "[".concat(extensions[0]);
-
- // iterate through the other values
- for (int i = 1; i < extensions.length; i++) {
-
- // add the current extension
- result = result.concat(", ").concat(extensions[i]);
- }
-
- // close the list
- result = result.concat("]");
-
- // return it
- return result;
- }
- }
-
- /**
- * Checks if the output must be verbose.
- *
- * @return A boolean value.
- */
- public boolean isVerbose() {
-
- // return it
- return showVerboseOutput;
- }
-
- /**
- * Getter for the execution timeout.
- *
- * @return The execution timeout.
- */
- public long getExecutionTimeout() {
-
- // return it
- return executionTimeout;
- }
-
- /**
- * Prints the special thanks message.
- */
- private void printSpecialThanks() {
- System.out.println(AraraUtils.wrap(localization.getMessage("Msg_SpecialThanks")));
- }
-}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/CommandTrigger.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/CommandTrigger.java
deleted file mode 100644
index 67b4ff98e9f..00000000000
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/CommandTrigger.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, 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.
- * \endcond
- *
- * CommandTrigger: This class is responsible for running the arara commands.
- */
-// package definition
-package com.github.arara.utils;
-
-// needed imports
-import com.github.arara.exception.AraraException;
-import com.github.arara.model.AraraCommand;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.List;
-import org.apache.commons.exec.*;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Implements an environment for running the arara commands.
- *
- * @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 3.0
- */
-public class CommandTrigger {
-
- // the logger
- final static Logger logger = LoggerFactory.getLogger(CommandTrigger.class);
- // the localization class
- final static AraraLocalization localization = AraraLocalization.getInstance();
- // the commands list
- private List<AraraCommand> commands;
- // flag to determine verbose output
- private boolean showVerboseOutput;
- // value for the execution timeout
- private long executionTimeout;
-
- /**
- * Constructor.
- *
- * @param commands The commands list.
- */
- public CommandTrigger(List<AraraCommand> commands) {
-
- // set the list
- this.commands = commands;
- }
-
- /**
- * Setter for the execution timeout.
- *
- * @param executionTimeout The execution timeout.
- */
- public void setExecutionTimeout(long executionTimeout) {
-
- // set the value
- this.executionTimeout = executionTimeout;
- }
-
- /**
- * Setter for the verbose mode.
- *
- * @param verbose A flag to indicate the verbose mode.
- */
- public void setVerbose(boolean verbose) {
-
- // set the flag
- showVerboseOutput = verbose;
- }
-
- /**
- * Executes the arara commands provided in the list.
- *
- * @return A boolean value about the execution. To be honest, I don't think
- * it's necessary to return an actual value, but I kept it for possible
- * future use.
- * @throws AraraException Raised when the command is not found in the
- * underlying system.
- */
- public boolean execute() throws AraraException {
-
- // log action
- logger.info(localization.getMessage("Log_ReadyToRunCommands"));
-
- // for every command in the list
- for (AraraCommand currentAraraCommand : commands) {
-
- // print a message
- System.out.print(localization.getMessage("Msg_RunningCommand", currentAraraCommand.getName()).concat(" "));
-
- // if verbose
- if (showVerboseOutput) {
-
- // add two lines
- System.out.println("\n");
- }
-
- // log action
- logger.info(localization.getMessage("Log_CommandName", currentAraraCommand.getName()));
-
- // log command
- logger.trace(localization.getMessage("Log_Command", currentAraraCommand.getCommand()));
-
- // if the execution was ok
- //if (runCommand(currentAraraCommand)) {
- if (runCommand(currentAraraCommand)) {
-
- // print a message
- System.out.println(localization.getMessage("Msg_Success"));
-
- // log action
- logger.info(localization.getMessage("Log_CommandSuccess", currentAraraCommand.getName()));
-
- } else {
-
- // something bad happened, print message
- System.out.println(localization.getMessage("Msg_Failure"));
-
- // log action
- logger.warn(localization.getMessage("Log_CommandFailure", currentAraraCommand.getName()));
-
- // and return false
- return false;
-
- }
-
- // if verbose
- if (showVerboseOutput) {
-
- // add one line to the output
- System.out.println("");
- }
-
- }
-
- // log action
- logger.info(localization.getMessage("Log_AllCommandsSuccess"));
-
- // everything went ok, simply return true
- return true;
-
- }
-
- /**
- * Run the arara command.
- *
- * @param command The Arara command.
- * @return A boolean indicating if the execution was successful.
- * @throws AraraException Throws an exception in case the command was not
- * found.
- */
- private boolean runCommand(AraraCommand command) throws AraraException {
-
- // create a new byte array for the output logger
- ByteArrayOutputStream stringLogger = new ByteArrayOutputStream();
-
- // let's try
- try {
-
- // set a query
- String query = command.getCommand();
-
- // create a new command line from the query
- CommandLine commandLine = CommandLine.parse(query);
-
- // create a new tee
- TeeOutputStream tee;
-
- // create a new execution handler
- PumpStreamHandler streamHandler;
-
- // if verbose
- if (showVerboseOutput) {
-
- // the new tee should include the normal output
- // and the log
- tee = new TeeOutputStream(System.out, stringLogger);
-
- // verbose mode enables input mode as well
- streamHandler = new PumpStreamHandler(tee, tee, System.in);
-
- } else {
-
- // no verbose, so include only the log output
- tee = new TeeOutputStream(stringLogger);
-
- // define the handler only with the log output
- streamHandler = new PumpStreamHandler(tee);
- }
-
- // create a new executor
- DefaultExecutor executor = new DefaultExecutor();
-
- // set the handler
- executor.setStreamHandler(streamHandler);
-
- // check if there should be an execution timeout
- if (executionTimeout > 0) {
-
- // create a new watch dog
- ExecuteWatchdog watchDog = new ExecuteWatchdog(executionTimeout);
-
- // add it to the execution
- executor.setWatchdog(watchDog);
- }
-
- // set the shutdown hook
- ShutdownHookProcessDestroyer processDestroyer = new ShutdownHookProcessDestroyer();
-
- // add it to the executor
- executor.setProcessDestroyer(processDestroyer);
-
- // execute the command and get the exit code
- int exitValue = executor.execute(commandLine);
-
- // if we are in verbose mode
- if (showVerboseOutput) {
-
- // print the output status
- System.out.print(localization.getMessage("Msg_Status").concat(" "));
-
- }
-
- // add the output to the logger
- logger.trace(localization.getMessage("Log_OutputLogging"));
- logger.trace(stringLogger.toString());
-
- // return the status as a boolean
- return (exitValue == 0 ? true : false);
-
- } catch (ExecuteException executeException) {
-
- // in case of an error, or the watchdog in action,
- // the logger addition is not reached, so we need
- // to replicate it here
- logger.trace(localization.getMessage("Log_OutputLogging"));
- logger.trace(stringLogger.toString());
-
- // something bad happened, return false
- return false;
-
- } catch (IOException ioException) {
-
- // log error
- logger.error(localization.getMessage("Log_CommandNotFound", command.getName(), command.getCommand()));
-
- // command not found, throw exception
- throw new AraraException(localization.getMessage("Error_CommandNotFound", command.getName(), command.getCommand()));
-
- }
- }
-}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/ConfigurationLoader.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/ConfigurationLoader.java
deleted file mode 100644
index db743c2e61f..00000000000
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/ConfigurationLoader.java
+++ /dev/null
@@ -1,394 +0,0 @@
-/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, 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.
- * \endcond
- *
- * ConfigurationLoader: This class provides an object handler for the arara
- * configuration file.
- */
-// package definition
-package com.github.arara.utils;
-
-// needed imports
-import com.github.arara.Arara;
-import com.github.arara.exception.AraraException;
-import com.github.arara.model.AraraConfiguration;
-import com.github.arara.model.AraraFilePattern;
-import java.io.File;
-import java.io.FileReader;
-import java.net.URLDecoder;
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.commons.lang3.SystemUtils;
-import org.yaml.snakeyaml.Yaml;
-import org.yaml.snakeyaml.constructor.Constructor;
-import org.yaml.snakeyaml.error.MarkedYAMLException;
-import org.yaml.snakeyaml.nodes.Tag;
-import org.yaml.snakeyaml.representer.Representer;
-
-/**
- * Provides an object handler for the arara configuration file.
- *
- * @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 3.0
- */
-public class ConfigurationLoader {
-
- // list of search paths
- private List<String> paths;
- // the application path, that is, where arara is located
- private String applicationPath;
- // list of file patterns
- private List<AraraFilePattern> filePatterns;
- // list of valid extensions
- private String[] validExtensions;
- // the chosen pattern
- private AraraFilePattern chosenFilePattern;
- // the localization class
- final static AraraLocalization localization = AraraLocalization.getInstance();
-
- /**
- * Constructor.
- */
- public ConfigurationLoader() {
-
- // create a new list of paths
- paths = new ArrayList<String>();
-
- // try to obtain the application path
- try {
- applicationPath = Arara.class.getProtectionDomain().getCodeSource().getLocation().getPath();
- applicationPath = URLDecoder.decode(applicationPath, "UTF-8");
- applicationPath = new File(applicationPath).getParentFile().getPath();
- } catch (Exception exception) {
- applicationPath = "";
- }
- }
-
- /**
- * Loads the configuration settings, either the default setup or through the
- * configuration file.
- *
- * @throws Exception An exception is thrown if something unexpected happens
- * during the execution of this method.
- */
- public void load() throws Exception {
-
- // create the default patterns
-
- // for .tex files
- AraraFilePattern texPattern = new AraraFilePattern();
- texPattern.setExtension("tex");
- texPattern.setPattern("^(\\s)*%\\s+");
-
- // for .dtx files
- AraraFilePattern dtxPattern = new AraraFilePattern();
- dtxPattern.setExtension("dtx");
- dtxPattern.setPattern("^(\\s)*%\\s+");
-
- // for .ltx files
- AraraFilePattern ltxPattern = new AraraFilePattern();
- ltxPattern.setExtension("ltx");
- ltxPattern.setPattern("^(\\s)*%\\s+");
-
- // create a list of default patterns
- List<AraraFilePattern> defaultPatterns = new ArrayList<AraraFilePattern>();
-
- // add the default ones
- defaultPatterns.add(texPattern);
- defaultPatterns.add(dtxPattern);
- defaultPatterns.add(ltxPattern);
-
- // create a list of file patterns
- filePatterns = new ArrayList<AraraFilePattern>();
-
- // create a file reference
- File configurationFile = new File(SystemUtils.USER_HOME + File.separator + AraraConstants.ARARACONFIG);
-
- // if there is not a configuration file
- if (!configurationFile.exists()) {
-
- // there's only one path to look for rules
- paths.add(applicationPath + File.separator + "rules");
-
- // the only file patterns are the default ones
- filePatterns.addAll(defaultPatterns);
-
- // create an array of valid extensions
- validExtensions = new String[filePatterns.size()];
-
- // add them according to the file patterns
- for (int i = 0; i < filePatterns.size(); i++) {
- validExtensions[i] = ".".concat(filePatterns.get(i).getExtension());
- }
-
- // simply return, there's nothing more to do
- return;
- }
-
- // create the YAML representer
- Representer representer = new Representer();
- representer.addClassTag(AraraConfiguration.class, new Tag("!config"));
- representer.addClassTag(AraraFilePattern.class, new Tag("!pattern"));
-
- // create the YAML parser
- Yaml yaml = new Yaml(new Constructor(AraraConfiguration.class), representer);
-
- // create the file reader
- FileReader fileReader = new FileReader(configurationFile);
-
- // set the new configuration object
- AraraConfiguration configuration = null;
-
- try {
-
- // try to read the configuration object
- configuration = (AraraConfiguration) yaml.load(fileReader);
-
- } catch (MarkedYAMLException yamlException) {
-
- // there's an error with the YAML file, so an exception is thrown
- AraraLogging.enableLogging(false);
- throw new AraraException(localization.getMessage("Error_InvalidYAMLConfigurationFile").concat("\n\n").concat(AraraUtils.extractInformationFromYAMLException(yamlException)));
- }
- catch (Exception e) {
- System.out.println(e.getMessage());
- }
-
- // close the file reader
- fileReader.close();
-
- // check if the configuration is invalid
- if (configuration == null) {
-
- // it's invalid, raise an exception
- AraraLogging.enableLogging(false);
- throw new AraraException(localization.getMessage("Error_InvalidConfigurationFile"));
- }
-
- // check if there's an available language
- if (configuration.getLanguage() != null) {
-
- // create a new language control
- LanguageController languageController = new LanguageController();
-
- // if the language is not valid
- if (languageController.setLanguage(configuration.getLanguage()) == false) {
-
- // it's invalid, raise an exception
- AraraLogging.enableLogging(false);
- throw new AraraException(localization.getMessage("Error_InvalidLanguageConfigurationFile", languageController.getLanguagesList()));
- }
- }
-
- // check if there are new paths
- if (configuration.getPaths() != null) {
-
- // a runtime exception happened when resolving some
- // path names
- if (configuration.getPathRuntimeException() != null) {
-
- // raise an exception
- AraraLogging.enableLogging(false);
- throw new AraraException(localization.getMessage("Error_PathRuntimeErrorConfigurationFile", AraraUtils.getVariableFromException(configuration.getPathRuntimeException())));
- }
-
- // a IO exception happened when checking if it was
- // a valid path entry
- if (configuration.getPathIOException() != null) {
-
- // raise an exception
- AraraLogging.enableLogging(false);
- throw new AraraException(localization.getMessage("Error_PathIOErrorConfigurationFile"));
- }
-
- // for every path set
- for (String currentPath : configuration.getPaths()) {
-
- // add it to the paths list
- paths.add(currentPath);
- }
- }
-
- // the last path to be added is the application path
- paths.add(applicationPath + File.separator + "rules");
-
- // check if there are new file patterns
- if (configuration.getFiletypes() != null) {
-
- // get all file patterns
- List<AraraFilePattern> filetypes = configuration.getFiletypes();
-
- // reorder the list of filetypes
- for (int i = 0; i < defaultPatterns.size(); i++) {
-
- // if the filetype is not in the default list
- if (!isAlreadyDefined(defaultPatterns.get(i), filetypes)) {
-
- // simply add it
- filePatterns.add(defaultPatterns.get(i));
- }
- }
-
- // merge the two lists
- filePatterns.addAll(filetypes);
-
- // create a new array of valid extensions
- validExtensions = new String[filePatterns.size()];
- int counter = 0;
-
- // sanity check, if there are valid extensions and patterns
- for (AraraFilePattern currentPattern : filePatterns) {
-
- // check if either of those fields is missing
- if ((currentPattern.getPattern() == null) || (currentPattern.getExtension() == null)) {
-
- // it's invalid, raise an exception
- AraraLogging.enableLogging(false);
- throw new AraraException(localization.getMessage("Error_InvalidFiletypesConfigurationFile"));
-
- }
-
- // add the dot to the extension
- validExtensions[counter] = ".".concat(currentPattern.getExtension());
- counter++;
- }
- } else {
-
- // no new filetypes, simply merge the lists
- filePatterns.addAll(defaultPatterns);
-
- // create a new array for extensions
- validExtensions = new String[filePatterns.size()];
-
- // iterate through all filetypes and add the extension to the array
- for (int i = 0; i < filePatterns.size(); i++) {
- validExtensions[i] = ".".concat(filePatterns.get(i).getExtension());
- }
- }
-
- }
-
- /**
- * Checks if the filetype is already defined in the list, and updates the
- * latter if needed.
- *
- * @param filePattern The filetype object.
- * @param list The list to be inspected.
- * @return A boolean indicating if the filetype is already defined in the
- * list.
- */
- private boolean isAlreadyDefined(AraraFilePattern filePattern, List<AraraFilePattern> list) {
-
- // iterate through all elements
- for (int i = 0; i < list.size(); i++) {
-
- // check if it already exists
- if (filePattern.getExtension().equalsIgnoreCase(list.get(i).getExtension())) {
-
- // update the element if needed
- if (list.get(i).getPattern() == null) {
- list.set(i, filePattern);
- }
-
- // already defined
- return true;
- }
- }
-
- // not found
- return false;
- }
-
- /**
- * Getter for the paths.
- *
- * @return The paths.
- */
- public List<String> getPaths() {
- return paths;
- }
-
- /**
- * Getter for the file patterns.
- *
- * @return The file patterns.
- */
- public List<AraraFilePattern> getFilePatterns() {
- return filePatterns;
- }
-
- /**
- * Getter for the valid extensions available.
- *
- * @return An array containing the valid extensions.
- */
- public String[] getValidExtensions() {
- return validExtensions;
- }
-
- /**
- * Setter for the chosen file pattern.
- *
- * @param extension A string containing a reference for the file extension.
- */
- public void setChosenFilePattern(String extension) {
-
- // for every file pattern
- for (AraraFilePattern currentPattern : filePatterns) {
-
- // if the extension matches
- if (".".concat(currentPattern.getExtension()).equals(extension)) {
-
- // we found our pattern
- chosenFilePattern = currentPattern;
-
- // return
- return;
- }
- }
-
- // nothing found
- chosenFilePattern = null;
- }
-
- /**
- * Getter for the chosen file pattern.
- *
- * @return The chosen file pattern.
- */
- public AraraFilePattern getChosenFilePattern() {
- return chosenFilePattern;
- }
-}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/DirectiveExtractor.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/DirectiveExtractor.java
deleted file mode 100644
index 0614fcf4306..00000000000
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/DirectiveExtractor.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, 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.
- * \endcond
- *
- * DirectiveExtractor: This class reads the file and extracts all the directives
- * it could find.
- */
-// package definition
-package com.github.arara.utils;
-
-// needed imports
-import com.github.arara.exception.AraraException;
-import com.github.arara.model.AraraDirective;
-import java.io.*;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.yaml.snakeyaml.DumperOptions;
-import org.yaml.snakeyaml.Yaml;
-import org.yaml.snakeyaml.constructor.Constructor;
-import org.yaml.snakeyaml.error.MarkedYAMLException;
-import org.yaml.snakeyaml.representer.Representer;
-
-/**
- * Reads the file and extracts all the directives it could find.
- *
- * @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 1.0
- */
-public class DirectiveExtractor {
-
- // the logger
- final static Logger logger = LoggerFactory.getLogger(DirectiveExtractor.class);
- // the list of directives
- private List<AraraDirective> directives;
- // the file
- private File file;
- // the current line number
- private int currentLineNumber;
- // the configuration object
- private ConfigurationLoader configuration;
- // the localization class
- final static AraraLocalization localization = AraraLocalization.getInstance();
-
- /**
- * Constructor.
- */
- public DirectiveExtractor() {
-
- // create new list
- directives = new ArrayList<AraraDirective>();
-
- // set file to null
- file = null;
- }
-
- /**
- * Constructor.
- *
- * @param file The file.
- */
- public DirectiveExtractor(File file, ConfigurationLoader configuration) {
-
- // create a new list
- directives = new ArrayList<AraraDirective>();
-
- this.configuration = configuration;
-
- // set file
- this.file = file;
- }
-
- /**
- * Setter for file.
- *
- * @param file The file.
- */
- public void setFile(File file) {
-
- // set the file
- this.file = file;
- }
-
- /**
- * Getter for Arara directives.
- *
- * @return A list containing all Arara directives.
- */
- public List<AraraDirective> getDirectives() {
-
- // return the list
- return directives;
- }
-
- /**
- * Extracts the directives from the file.
- *
- * @throws FileNotFoundException Raised when file not found.
- * @throws IOException Raised when an IO error happened.
- * @throws AraraException Raised when there's a problem with the directive.
- */
- public void extract() throws FileNotFoundException, IOException, AraraException {
-
- // create a new file reader
- FileReader fileReader = new FileReader(file);
-
- // create a new buffer
- BufferedReader bufferedReader = new BufferedReader(fileReader);
-
- // variable to hold the current line
- String currentLine;
-
- // the line count
- currentLineNumber = 0;
-
- // log directives
- logger.info("Reading directives from {}.", file.getName());
-
- // while not EOF
- while ((currentLine = bufferedReader.readLine()) != null) {
-
- // increment the current line number
- currentLineNumber++;
-
- // extract directive
- extractDirective(currentLine);
- }
-
- // close the buffer
- bufferedReader.close();
-
- // close the reader
- fileReader.close();
-
- }
-
- /**
- * Extracts the Arara directives from the current line.
- *
- * @param currentLine The current line.
- * @throws AraraException Raised when there is a problem with the directive.
- */
- private void extractDirective(String currentLine) throws AraraException {
-
- // get the pattern for the chosen filetype
- Pattern linePattern = Pattern.compile(configuration.getChosenFilePattern().getPattern());
-
- // create the matcher according to the pattern
- Matcher matcher = linePattern.matcher(currentLine);
-
- // if the pattern is found
- if (matcher.find()) {
-
- // get the substring
- currentLine = (currentLine.substring(matcher.end(), currentLine.length())).trim();
-
- // there is actually something after the keyword
- if (!"".equals(currentLine)) {
-
- // log directive
- logger.trace(localization.getMessage("Log_DirectiveFound", currentLineNumber, currentLine));
-
- // look for a full directive
- if (AraraUtils.checkForFullDirective(currentLine)) {
-
- // add it
- addAraraDirective(currentLine);
- }
- else {
-
- // look for an empty directive
- if (AraraUtils.checkForEmptyDirective(currentLine)) {
-
- // add it
- addEmptyAraraDirective(currentLine.trim());
- }
- else {
-
- // an invalid directive was found, throw error
- throw new AraraException(localization.getMessage("Error_InvalidDirective", currentLineNumber));
- }
- }
-
- }
- }
- }
-
- /**
- * Extracts an empty Arara directive.
- *
- * @param currentLine The current line.
- */
- private void addEmptyAraraDirective(String currentLine) {
-
- // create a new directive
- AraraDirective araraDirective = new AraraDirective();
-
- // set the name
- araraDirective.setName(currentLine);
-
- // set the config
- araraDirective.setConfig(new HashMap());
-
- // set the line number, in case of error
- araraDirective.setLineNumber(currentLineNumber);
-
- // add the directive to the list
- directives.add(araraDirective);
-
- }
-
- /**
- * Extracts am Arara directive.
- *
- * @param currentLine The current line.
- * @throws AraraException Raised when there is a problem with the directive.
- */
- private void addAraraDirective(String currentLine) throws AraraException {
-
- // lets try
- try {
-
- // create a new YAML parser
- Yaml yaml = new Yaml(new Constructor(), new Representer(), new DumperOptions(), new AraraResolver());
-
- // create a new map and load the current line
- Map config = (Map) yaml.load(currentLine);
-
- // create a new directive
- AraraDirective ad = new AraraDirective();
-
- // set the name
- ad.setName(currentLine);
-
- // set the config
- ad.setConfig(config);
-
- // set line number. in case of error
- ad.setLineNumber(currentLineNumber);
-
- // add the directive to the list
- directives.add(ad);
-
- } catch (MarkedYAMLException yamlException) {
-
- // malformed directive, throw exception
- throw new AraraException(localization.getMessage("Error_InvalidYAMLDirective", currentLineNumber).concat("\n\n").concat(AraraUtils.extractInformationFromYAMLException(yamlException)));
- }
- }
-}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/DirectiveParser.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/DirectiveParser.java
deleted file mode 100644
index b79a3741bd8..00000000000
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/DirectiveParser.java
+++ /dev/null
@@ -1,321 +0,0 @@
-/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, 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.
- * \endcond
- *
- * DirectiveParser: This class analyzes the list of directives and converts them
- * to a list of arara tasks.
- */
-// package definition
-package com.github.arara.utils;
-
-// needed imports
-import com.github.arara.exception.AraraException;
-import com.github.arara.model.AraraDirective;
-import com.github.arara.model.AraraTask;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Analyzes the list of directives and converts them to a list of arara tasks.
- *
- * @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 1.0
- */
-public class DirectiveParser {
-
- // the logger
- final static Logger logger = LoggerFactory.getLogger(DirectiveParser.class);
- // the list of directives
- private List<AraraDirective> directives;
- // the list of tasks
- private List<AraraTask> tasks;
- // the list of file names, to use as a temporary variable
- private List<String> fileNames;
- // the list of items
- private List<String> items;
- // the current file reference
- private File file;
- // the localization class
- final static AraraLocalization localization = AraraLocalization.getInstance();
-
- /**
- * Constructor
- */
- public DirectiveParser() {
- }
-
- /**
- * Constructor.
- *
- * @param directives The Arara directives.
- */
- public DirectiveParser(List<AraraDirective> directives) {
-
- // set the directives
- this.directives = directives;
-
- // create a new list of tasks
- this.tasks = new ArrayList<AraraTask>();
-
- // create a new list of file names
- this.fileNames = new ArrayList<String>();
-
- // create a new list of items
- this.items = new ArrayList<String>();
- }
-
- /**
- * Setter for file.
- *
- * @param file The file.
- */
- public void setFile(File file) {
-
- // set the file
- this.file = file;
- }
-
- /**
- * Setter for the list of Arara directives.
- *
- * @param directives The list of Arara directives.
- */
- public void setDirectives(List<AraraDirective> directives) {
-
- // set the list
- this.directives = directives;
- }
-
- /**
- * Parses the list of Arara directives.
- *
- * @return A list of Arara tasks based on the directives.
- * @throws AraraMalformedDirective Raised when a malformed directive is
- * found.
- */
- public List<AraraTask> parse() throws AraraException {
-
- // log message
- logger.info("Parsing directives.");
-
- // for every directive
- for (AraraDirective currentDirective : directives) {
-
- // clear the list of files
- fileNames.clear();
-
- // clear the task name
- String taskName = "";
-
- // create a new map
- Map taskConfig = new HashMap();
-
- // if there's no configuration
- if (currentDirective.getConfig().isEmpty()) {
-
- // set the name
- taskName = currentDirective.getName();
-
- } else {
-
- // get the current config
- Map currentConfig = currentDirective.getConfig();
-
- // and get the directive name
- String directiveName = (String) currentConfig.keySet().iterator().next();
-
- // set the name to the task
- taskName = directiveName;
-
- // get the parameters
- Object currentConfigParameters = currentConfig.get(directiveName);
-
- // if it is a map
- if (currentConfigParameters instanceof Map) {
-
- // get the map
- Map currentParameters = (Map) currentConfigParameters;
-
- // if it is empty, error
- if (currentParameters.isEmpty()) {
-
- // raise an error
- throw new AraraException(localization.getMessage("Error_DirectiveEmptyCurlyBrackets", directiveName, currentDirective.getLineNumber()));
-
- } else {
-
- // for every parameter
- for (Object currentParameterKey : currentParameters.keySet()) {
-
- // if the parameter is a string
- if (currentParameters.get(currentParameterKey) instanceof String) {
-
- // if it is a file reference, error
- if (((String) currentParameterKey).equals("files")) {
-
- // raise an error
- throw new AraraException(localization.getMessage("Error_DirectiveInvalidArgumentList", directiveName, currentDirective.getLineNumber(), "files"));
- }
-
- if (((String) currentParameterKey).equals("items")) {
-
- // raise an error
- throw new AraraException(localization.getMessage("Error_DirectiveInvalidArgumentList", directiveName, currentDirective.getLineNumber(), "items"));
- }
-
- // if it is a file reference, error
- if (((String) currentParameterKey).equals("file")) {
-
- // raise an error
- throw new AraraException(localization.getMessage("Error_DirectiveReservedKeyword", directiveName, currentDirective.getLineNumber(), "file", "files"));
- }
-
- if (((String) currentParameterKey).equals("item")) {
-
- // raise an error
- throw new AraraException(localization.getMessage("Error_DirectiveReservedKeyword", directiveName, currentDirective.getLineNumber(), "item", "items"));
- }
-
-
- // add the parameter to the configuration
- taskConfig.put(currentParameterKey, (String) currentParameters.get(currentParameterKey));
-
- } else {
-
- // if it is a list
- if (currentParameters.get(currentParameterKey) instanceof List) {
-
- // if it is a file reference
- if (((String) currentParameterKey).equals("files")) {
-
- // get the list
- for (Object currentListValue : ((List) currentParameters.get(currentParameterKey))) {
-
- // add the file names
- fileNames.add(currentListValue.toString());
- }
- } else {
-
- if (((String) currentParameterKey).equals("items")) {
-
- // get the list
- for (Object currentListValue : ((List) currentParameters.get(currentParameterKey))) {
-
- // add the file names
- items.add(currentListValue.toString());
- }
- } else {
-
- // raise error
- throw new AraraException(localization.getMessage("Error_DirectiveListError", directiveName, currentDirective.getLineNumber()));
- }
- }
- } else {
-
- // raise error
- throw new AraraException(localization.getMessage("Error_DirectiveGenericError", directiveName, currentDirective.getLineNumber()));
- }
- }
- }
- }
- } else {
-
- // raise error
- throw new AraraException(localization.getMessage("Error_DirectiveGenericError", directiveName, currentDirective.getLineNumber()));
- }
- }
-
- // set original file name
- AraraMethods.setOriginalFile(file.getName());
-
- // if there is not a list of filenames
- if (fileNames.isEmpty()) {
-
- // add the only filename available
- fileNames.add(file.getName());
- }
-
- // if there are no items available
- if (items.isEmpty()) {
-
- // simply add an empty entry
- items.add("");
- }
-
- // for every filename
- for (String filename : fileNames) {
-
- // and for every item
- for (String item : items) {
-
- // create a new task
- AraraTask araraTask = new AraraTask();
-
- // set the name
- araraTask.setName(taskName);
-
- // create a new map based on the current configuration
- HashMap currentTaskConfig = new HashMap(taskConfig);
-
- // add the current file
- currentTaskConfig.put("file", filename);
- currentTaskConfig.put("item", item);
-
- // set the parameters
- araraTask.setParameters(currentTaskConfig);
-
- // and add the task to the list
- tasks.add(araraTask);
-
- // the current task is now null
- araraTask = null;
- }
- }
-
- // clear the list of files and items
- fileNames.clear();
- items.clear();
-
- }
-
- // return the list of tasks
- return tasks;
- }
-}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/LanguageController.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/LanguageController.java
deleted file mode 100644
index ea3468c0443..00000000000
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/LanguageController.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, 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.
- * \endcond
- *
- * LanguageController: This class holds the language model controller for arara.
- */
-// package definition
-package com.github.arara.utils;
-
-// needed imports
-import com.github.arara.model.AraraLanguage;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Holds the language model controller for arara.
- *
- * @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 3.0
- */
-public class LanguageController {
-
- // list of available languages
- private List<AraraLanguage> languages;
- // the localization singleton instance
- final static AraraLocalization localization = AraraLocalization.getInstance();
-
- /**
- * Constructor.
- */
- public LanguageController() {
-
- // create a new list of languages
- languages = new ArrayList<AraraLanguage>();
-
- // add the resources
- languages.add(new AraraLanguage("English", "en", new Locale("en")));
- languages.add(new AraraLanguage("Brazilian Portuguese", "ptbr", new Locale("pt", "BR")));
- languages.add(new AraraLanguage("Italian", "it", new Locale("it")));
- languages.add(new AraraLanguage("French", "fr", new Locale("fr")));
- languages.add(new AraraLanguage("Spanish", "es", new Locale("es")));
- languages.add(new AraraLanguage("German", "de", new Locale("de")));
- languages.add(new AraraLanguage("Turkish", "tr", new Locale("tr", "TR")));
- languages.add(new AraraLanguage("Russian", "ru", new Locale("ru")));
-
- }
-
- /**
- * Sets the current language according to the provided country code.
- *
- * @param code The country code.
- * @return A boolean value indicating if the new language was properly
- * applied.
- */
- public boolean setLanguage(String code) {
-
- // get the index of the language
- int i = getIndex(code);
-
- // if it's valid
- if (i != -1) {
-
- // set locale and refresh the resource bundle
- Locale.setDefault(languages.get(i).getLocale());
- localization.refresh();
-
- // everything went fine
- return true;
- }
-
- // the country code is invalid
- return false;
- }
-
- /**
- * Returns a string containing the list of available languages.
- *
- * @return A string containing the list of available languages.
- */
- public String getLanguagesList() {
-
- // get the first one in the list
- String result = languages.get(0).toString();
-
- // iterate through the rest
- for (int i = 1; i < languages.size(); i++) {
-
- // separate them by commas
- result = result.concat(", ").concat(languages.get(i).toString());
- }
-
- // return the string
- return result;
- }
-
- /**
- * Prints the language help.
- */
- public void printLanguageHelp() {
-
- // print message
- System.out.println(AraraUtils.wrap(localization.getMessage("Error_InvalidLanguage").concat("\n\n").concat(getLanguagesList()).concat("\n")));
- }
-
- /**
- * Gets the index for the country code.
- * @param code The country code.
- * @return An integer representing the index.
- */
- private int getIndex(String code) {
-
- // for every language
- for (int i = 0; i < languages.size(); i++) {
-
- // if the codes are equal
- if (languages.get(i).getCode().equalsIgnoreCase(code)) {
-
- // return the current counter
- return i;
- }
- }
-
- // nothing was found, return a negative value
- return -1;
- }
-}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/TaskDeployer.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/TaskDeployer.java
deleted file mode 100644
index 2a5a9c462e5..00000000000
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/TaskDeployer.java
+++ /dev/null
@@ -1,532 +0,0 @@
-/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, 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.
- * \endcond
- *
- * TaskDeployer: This class is responsible for taking the tasks and turning them
- * into rara commands.
- */
-// package definition
-package com.github.arara.utils;
-
-// needed imports
-import com.github.arara.exception.AraraException;
-import com.github.arara.model.AraraCommand;
-import com.github.arara.model.AraraRuleArgument;
-import com.github.arara.model.AraraRuleConfig;
-import com.github.arara.model.AraraTask;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.*;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang3.SystemUtils;
-import org.mvel2.templates.TemplateRuntime;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.yaml.snakeyaml.Yaml;
-import org.yaml.snakeyaml.constructor.Constructor;
-import org.yaml.snakeyaml.error.MarkedYAMLException;
-import org.yaml.snakeyaml.nodes.Tag;
-import org.yaml.snakeyaml.representer.Representer;
-
-/**
- * Class responsible for taking the tasks and turning them into Arara commands.
- *
- * @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 1.0
- */
-public class TaskDeployer {
-
- // the logger
- final static Logger logger = LoggerFactory.getLogger(TaskDeployer.class);
- // the localization class
- final static AraraLocalization localization = AraraLocalization.getInstance();
- // the tasks list
- private List<AraraTask> tasks;
- //the output list with the proper commands
- private List<AraraCommand> commands;
- // the configuration
- private ConfigurationLoader configuration;
-
- /**
- * Constructor.
- *
- * @param tasks The Arara tasks.
- */
- public TaskDeployer(List<AraraTask> tasks, ConfigurationLoader configuration) {
-
- // set everything
- this.tasks = tasks;
-
- // set the configuration
- this.configuration = configuration;
-
- // create the list
- commands = new ArrayList<AraraCommand>();
-
- }
-
- /**
- * Deploys the tasks and returns the commands list.
- *
- * @return The Arara commands list.
- * @throws Exception Raised if something bad happened.
- */
- public List<AraraCommand> deploy() throws Exception {
-
- // log message
- logger.info("Deploying tasks into commands.");
-
- // for each task
- for (AraraTask currentTask : tasks) {
-
- // get the index where the rule is located
- int pathIndex = findRule(currentTask);
-
- // if it's not a negative index, that is, the rule was found
- if (pathIndex != -1) {
-
- // deploy plain rule
- deployRule(currentTask, pathIndex);
-
- } else {
-
- // not found, throw exception
- throw new AraraException(localization.getMessage("Error_RuleNotFound", currentTask.getName()));
- }
- }
-
- // return the commands
- return commands;
-
- }
-
- /**
- * Finds the rule in the rules directory.
- *
- * @param task The task to find.
- * @return The rule location.
- */
- private int findRule(AraraTask task) {
-
- // get the search path
- List<String> paths = configuration.getPaths();
-
- // for every entry in the search path
- for (int i = 0; i < paths.size(); i++) {
-
- // if the current task is found in the current path
- if (new File(paths.get(i).concat(File.separator).concat(task.getName()).concat(".yaml")).exists()) {
-
- // add an entry to the logger
- logger.trace(localization.getMessage("Log_RuleFound", task.getName(), paths.get(i)));
-
- // return the index of the current path
- return i;
- }
- }
-
- // nothing was found, return a negative value
- return -1;
-
- }
-
- /**
- * Deploys plain rule.
- *
- * @param task The task.
- * @throws Exception The rule has a bad definition.
- */
- private void deployRule(AraraTask task, int pathIndex) throws Exception {
-
- // create a representer
- Representer representer = new Representer();
-
- // add a class tag
- representer.addClassTag(AraraRuleConfig.class, new Tag("!config"));
- representer.addClassTag(AraraRuleArgument.class, new Tag("!argument"));
-
- // create a new YAML parser
- Yaml yaml = new Yaml(new Constructor(AraraRuleConfig.class), representer);
-
- FileReader fileReader = null;
-
- // new file reader
- fileReader = new FileReader(configuration.getPaths().get(pathIndex).concat(File.separator).concat(task.getName()).concat(".yaml"));
-
- // load rule
- AraraRuleConfig plainRule = null;
-
- try {
-
- // try to load the rule
- plainRule = (AraraRuleConfig) yaml.load(fileReader);
-
- } catch (MarkedYAMLException yamlException) {
-
- // YAML syntax error, throw exception
- throw new AraraException(localization.getMessage("Error_InvalidYAMLRule", task.getName(), configuration.getPaths().get(pathIndex)).concat("\n\n").concat(AraraUtils.extractInformationFromYAMLException(yamlException)));
- }
-
- try {
-
- // close reader
- fileReader.close();
-
- } catch (IOException ioException) {
- // do nothing here
- }
-
- // check if the rule is invalid
- if (plainRule == null) {
-
- // raise an error
- throw new AraraException(localization.getMessage("Error_InvalidRule", task.getName(), configuration.getPaths().get(pathIndex)));
- }
-
- // verify if the identifier is empty
- if (plainRule.getIdentifier() == null) {
-
- // raise error
- throw new AraraException(localization.getMessage("Error_EmptyIdentifierRule", task.getName(), configuration.getPaths().get(pathIndex)));
-
- } else {
-
- // check if the rule has a proper name
- if (plainRule.getName() == null) {
-
- // raise error
- throw new AraraException(localization.getMessage("Error_EmptyNameRule", task.getName(), configuration.getPaths().get(pathIndex)));
-
- } else {
-
- // check if the rule has a proper list of arguments
- if (plainRule.getArguments() == null) {
-
- // raise error
- throw new AraraException(localization.getMessage("Error_EmptyArgumentsListRule", task.getName(), configuration.getPaths().get(pathIndex)));
-
- }
- }
- }
-
- // if the rule name doesn't match with the file name
- if (!task.getName().equals(plainRule.getIdentifier())) {
-
- // throw exception
- throw new AraraException(localization.getMessage("Error_WrongIdentifierRule", task.getName(), configuration.getPaths().get(pathIndex), plainRule.getIdentifier()));
- }
-
- // check if the rule has any forbidden identifier
- if (plainRule.checkForForbiddenIdentifiers() != null) {
-
- // raise error
- throw new AraraException(localization.getMessage("Error_ForbiddenIdentifierRule", task.getName(), configuration.getPaths().get(pathIndex), plainRule.checkForForbiddenIdentifiers()));
- }
-
- // get the list of all arguments available in the rule
- List<String> availableArgumentsInRule = plainRule.getIdentifiersList();
-
- // add the two reserved keywords
- availableArgumentsInRule.add("file");
- availableArgumentsInRule.add("item");
-
- // get the parameters for the task
- HashMap directiveMap = task.getParameters();
-
- // for every entry in the parameters map of the task, add it to the
- // list of available parameters in the directive
- List<String> availableArgumentsInDirective = new ArrayList<String>();
- for (Object theKey : directiveMap.keySet()) {
- availableArgumentsInDirective.add((String) theKey);
- }
-
- // find out which arguments are not defined in the directive and in
- // the rule
- List<String> argumentsNotDefinedInDirective = (List<String>) CollectionUtils.subtract(availableArgumentsInRule, availableArgumentsInDirective);
- List<String> argumentsNotDefinedInRule = (List<String>) CollectionUtils.subtract(availableArgumentsInDirective, availableArgumentsInRule);
-
- // if there are invalid arguments in the directive
- if (!argumentsNotDefinedInRule.isEmpty()) {
-
- // raise error
- throw new AraraException(localization.getMessage("Error_ArgumentsNotDefinedInRule", task.getName(), configuration.getPaths().get(pathIndex), argumentsNotDefinedInRule.toString()));
- }
-
- // for all arguments in the rule not mapped in the directive, set
- // their default value to an empty string
- for (String currentKey : argumentsNotDefinedInDirective) {
- directiveMap.put(currentKey, "");
- }
-
- // add entries in the arguments map
- HashMap argumentMap = new HashMap();
- argumentMap.put("file", directiveMap.get("file"));
- argumentMap.put("item", directiveMap.get("item"));
- directiveMap.remove("file");
- directiveMap.remove("item");
- argumentMap.put("parameters", directiveMap);
-
- // helper functions added
- argumentMap.put("SystemUtils", SystemUtils.class);
- argumentMap.put("isEmpty", AraraMethods.class.getMethod("isEmpty", String.class));
- argumentMap.put("isNotEmpty", AraraMethods.class.getMethod("isNotEmpty", String.class));
- argumentMap.put("isEmpty", AraraMethods.class.getMethod("isEmpty", String.class, String.class));
- argumentMap.put("isNotEmpty", AraraMethods.class.getMethod("isNotEmpty", String.class, String.class));
- argumentMap.put("isEmpty", AraraMethods.class.getMethod("isEmpty", String.class, String.class, String.class));
- argumentMap.put("isNotEmpty", AraraMethods.class.getMethod("isNotEmpty", String.class, String.class, String.class));
- argumentMap.put("isTrue", AraraMethods.class.getMethod("isTrue", String.class));
- argumentMap.put("isFalse", AraraMethods.class.getMethod("isFalse", String.class));
- argumentMap.put("isTrue", AraraMethods.class.getMethod("isTrue", String.class, String.class));
- argumentMap.put("isFalse", AraraMethods.class.getMethod("isFalse", String.class, String.class));
- argumentMap.put("isTrue", AraraMethods.class.getMethod("isTrue", String.class, String.class, String.class));
- argumentMap.put("isFalse", AraraMethods.class.getMethod("isFalse", String.class, String.class, String.class));
- argumentMap.put("isTrue", AraraMethods.class.getMethod("isTrue", String.class, String.class, String.class, String.class));
- argumentMap.put("isFalse", AraraMethods.class.getMethod("isFalse", String.class, String.class, String.class, String.class));
- argumentMap.put("trimSpaces", AraraMethods.class.getMethod("trimSpaces", String.class));
- argumentMap.put("getFilename", AraraMethods.class.getMethod("getFilename", String.class));
- argumentMap.put("getBasename", AraraMethods.class.getMethod("getBasename", String.class));
- argumentMap.put("getFiletype", AraraMethods.class.getMethod("getFiletype", String.class));
- argumentMap.put("getDirname", AraraMethods.class.getMethod("getDirname", String.class));
- argumentMap.put("isFile", AraraMethods.class.getMethod("isFile", String.class));
- argumentMap.put("isDir", AraraMethods.class.getMethod("isDir", String.class));
- argumentMap.put("isWindows", AraraMethods.class.getMethod("isWindows", String.class, String.class));
- argumentMap.put("isLinux", AraraMethods.class.getMethod("isLinux", String.class, String.class));
- argumentMap.put("isUnix", AraraMethods.class.getMethod("isUnix", String.class, String.class));
- argumentMap.put("isMac", AraraMethods.class.getMethod("isMac", String.class, String.class));
-
- argumentMap.put("isTrue", AraraMethods.class.getMethod("isTrue", boolean.class, String.class));
- argumentMap.put("isTrue", AraraMethods.class.getMethod("isTrue", boolean.class, String.class, String.class));
- argumentMap.put("isFalse", AraraMethods.class.getMethod("isFalse", boolean.class, String.class));
- argumentMap.put("isFalse", AraraMethods.class.getMethod("isFalse", boolean.class, String.class, String.class));
-
- argumentMap.put("getOriginalFile", AraraMethods.class.getMethod("getOriginalFile"));
-
- // create a rule map
- HashMap ruleMap = new HashMap();
-
- // for every argument in the rule
- for (AraraRuleArgument currentArgument : plainRule.getArguments()) {
-
- // if there's not a default value
- if (currentArgument.getDefault() == null) {
-
- // set the default to an empty string
- ruleMap.put(currentArgument.getIdentifier(), "");
-
- } else {
-
- // there's actually a default value
- try {
-
- // get the default value and apply the template
- String defaultValue = (String) TemplateRuntime.eval(currentArgument.getDefault(), argumentMap);
-
- // put the new default value into the rule map
- ruleMap.put(currentArgument.getIdentifier(), defaultValue);
-
- } catch (RuntimeException runtimeException) {
-
- // an error occurred, throw exception
- throw new AraraException(localization.getMessage("Error_DefaultValueRuntimeErrorRule", currentArgument.getIdentifier(), task.getName(), configuration.getPaths().get(pathIndex), AraraUtils.getVariableFromException(runtimeException)));
-
- }
- }
- }
-
- // after setting the default values into the rule map, let's add
- // the directive parameters and both file and item references
- ruleMap.put("parameters", directiveMap);
- ruleMap.put("file", argumentMap.get("file"));
- ruleMap.put("item", argumentMap.get("item"));
-
- // helper classes
- ruleMap.put("SystemUtils", SystemUtils.class);
- ruleMap.put("isEmpty", AraraMethods.class.getMethod("isEmpty", String.class));
- ruleMap.put("isNotEmpty", AraraMethods.class.getMethod("isNotEmpty", String.class));
- ruleMap.put("isEmpty", AraraMethods.class.getMethod("isEmpty", String.class, String.class));
- ruleMap.put("isNotEmpty", AraraMethods.class.getMethod("isNotEmpty", String.class, String.class));
- ruleMap.put("isEmpty", AraraMethods.class.getMethod("isEmpty", String.class, String.class, String.class));
- ruleMap.put("isNotEmpty", AraraMethods.class.getMethod("isNotEmpty", String.class, String.class, String.class));
- ruleMap.put("isTrue", AraraMethods.class.getMethod("isTrue", String.class));
- ruleMap.put("isFalse", AraraMethods.class.getMethod("isFalse", String.class));
- ruleMap.put("isTrue", AraraMethods.class.getMethod("isTrue", String.class, String.class));
- ruleMap.put("isFalse", AraraMethods.class.getMethod("isFalse", String.class, String.class));
- ruleMap.put("isTrue", AraraMethods.class.getMethod("isTrue", String.class, String.class, String.class));
- ruleMap.put("isFalse", AraraMethods.class.getMethod("isFalse", String.class, String.class, String.class));
- ruleMap.put("isTrue", AraraMethods.class.getMethod("isTrue", String.class, String.class, String.class, String.class));
- ruleMap.put("isFalse", AraraMethods.class.getMethod("isFalse", String.class, String.class, String.class, String.class));
- ruleMap.put("trimSpaces", AraraMethods.class.getMethod("trimSpaces", String.class));
- ruleMap.put("getFilename", AraraMethods.class.getMethod("getFilename", String.class));
- ruleMap.put("getBasename", AraraMethods.class.getMethod("getBasename", String.class));
- ruleMap.put("getFiletype", AraraMethods.class.getMethod("getFiletype", String.class));
- ruleMap.put("getDirname", AraraMethods.class.getMethod("getDirname", String.class));
- ruleMap.put("isFile", AraraMethods.class.getMethod("isFile", String.class));
- ruleMap.put("isDir", AraraMethods.class.getMethod("isDir", String.class));
- ruleMap.put("isWindows", AraraMethods.class.getMethod("isWindows", String.class, String.class));
- ruleMap.put("isLinux", AraraMethods.class.getMethod("isLinux", String.class, String.class));
- ruleMap.put("isUnix", AraraMethods.class.getMethod("isUnix", String.class, String.class));
- ruleMap.put("isMac", AraraMethods.class.getMethod("isMac", String.class, String.class));
-
- ruleMap.put("isTrue", AraraMethods.class.getMethod("isTrue", boolean.class, String.class));
- ruleMap.put("isTrue", AraraMethods.class.getMethod("isTrue", boolean.class, String.class, String.class));
- ruleMap.put("isFalse", AraraMethods.class.getMethod("isFalse", boolean.class, String.class));
- ruleMap.put("isFalse", AraraMethods.class.getMethod("isFalse", boolean.class, String.class, String.class));
-
- ruleMap.put("getOriginalFile", AraraMethods.class.getMethod("getOriginalFile"));
-
- // remove references to file and item
- availableArgumentsInDirective.remove("file");
- availableArgumentsInDirective.remove("item");
-
- // for all arguments in the rule
- for (AraraRuleArgument currentArgument : plainRule.getArguments()) {
-
- // if the current argument is defined in the directive
- if (isArgumentDefinedInDirective(availableArgumentsInDirective, currentArgument)) {
-
- // if there is a valid flag
- if (currentArgument.getFlag() != null) {
-
- try {
-
- // get the flag and apply template
- String defaultFlag = (String) TemplateRuntime.eval(currentArgument.getFlag(), ruleMap);
-
- // put the new flag reference into the rule map
- ruleMap.put(currentArgument.getIdentifier(), defaultFlag);
- } catch (RuntimeException runtimeException) {
-
- // an error occurred, throw exception
- throw new AraraException(localization.getMessage("Error_FlagRuntimeErrorRule", currentArgument.getIdentifier(), task.getName(), configuration.getPaths().get(pathIndex), AraraUtils.getVariableFromException(runtimeException)));
-
- }
- }
- }
- }
-
- // create a new list of commands to be executed by the current task
- List<String> commandsList = new ArrayList<String>();
-
- // if there is a command element in the rule
- if (plainRule.getCommand() != null) {
-
- // and if there isn't a list of commands
- if (plainRule.getCommands() == null) {
-
- // add the current command to the list of commands to
- // be executed
- commandsList.add(plainRule.getCommand());
-
- } else {
-
- // both are defined, throw an error
- throw new AraraException(localization.getMessage("Error_DuplicatedCommandElementsRule", task.getName(), configuration.getPaths().get(pathIndex)));
-
- }
- } else {
-
- // none of the fields is defined
- if (plainRule.getCommands() == null) {
-
- // neither of the elements is defined, throw an error
- throw new AraraException(localization.getMessage("Error_MissingCommandElementsRule", task.getName(), configuration.getPaths().get(pathIndex)));
-
- } else {
-
- // there's a list of commands, add them to the list
- commandsList.addAll(plainRule.getCommands());
- }
- }
-
- // for every command to be processed
- for (String commandTemplate : commandsList) {
-
- try {
- // get the current command and apply template
- commandTemplate = (String) TemplateRuntime.eval(commandTemplate, ruleMap);
-
- } catch (RuntimeException runtimeException) {
-
- // an error occurred, throw exception
- throw new AraraException(localization.getMessage("Error_CommandRuntimeErrorRule", task.getName(), configuration.getPaths().get(pathIndex), AraraUtils.getVariableFromException(runtimeException)));
-
- }
-
- // check if it's a valid command
- if (!"".equals(commandTemplate.trim())) {
-
- // create a new command
- AraraCommand araraCommand = new AraraCommand();
-
- // add the command
- araraCommand.setCommand(commandTemplate);
-
- // add the name
- araraCommand.setName(plainRule.getName());
-
- // add to the list
- commands.add(araraCommand);
-
- }
- }
- }
-
- /**
- * Checks if the current argument is included in the list of arguments from
- * the directive.
- *
- * @param arguments List of arguments from the directive.
- * @param argument The current argument to be analyzed.
- * @return A logic value indicating if the current argument is included in
- * the list of arguments from the directive.
- */
- private boolean isArgumentDefinedInDirective(List<String> arguments, AraraRuleArgument argument) {
-
- // for every argument in the list
- for (String current : arguments) {
-
- // if the identifiers match
- if (current.equalsIgnoreCase(argument.getIdentifier())) {
-
- // found it
- return true;
- }
- }
-
- // not found
- return false;
- }
-}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/Arara.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/Arara.java
new file mode 100644
index 00000000000..c644978c93b
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/Arara.java
@@ -0,0 +1,205 @@
+/**
+ * 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;
+
+import com.github.cereda.arara.controller.LanguageController;
+import com.github.cereda.arara.controller.LoggingController;
+import com.github.cereda.arara.model.AraraException;
+import com.github.cereda.arara.model.Configuration;
+import com.github.cereda.arara.model.Directive;
+import com.github.cereda.arara.model.Extractor;
+import com.github.cereda.arara.model.Interpreter;
+import com.github.cereda.arara.model.Parser;
+import com.github.cereda.arara.model.StopWatch;
+import com.github.cereda.arara.utils.CommonUtils;
+import com.github.cereda.arara.utils.DirectiveUtils;
+import com.github.cereda.arara.utils.DisplayUtils;
+import java.util.List;
+
+/**
+ * Main class. This class wraps all classes from the application model as well
+ * as utilitary classes in order to provide modularity.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class Arara {
+
+ /**
+ * Main method. This is the application entry point.
+ * @param args A string array containing all command line arguments.
+ */
+ public static void main(String[] args) {
+
+ // the first component to be initialized is the
+ // language controller; note that init() actually
+ // has no body at all, but it's a dirty maneuver to
+ // trigger the static class startup
+ LanguageController.init();
+
+ // the second component to be initalized is the
+ // logging controller; note init() actually disables
+ // the logging, so early exceptions won't generate
+ // a lot of noise in the terminal
+ LoggingController.init();
+
+ // print the arara logo in the terminal; I just
+ // hope people use this tool in a good terminal with
+ // fixed-width fonts, otherwise the logo will be messed
+ DisplayUtils.printLogo();
+
+ try {
+
+ // first of all, let's try to load a potential
+ // configuration file located at the current
+ // user's home directory; if there's a bad
+ // configuration file, arara will panic and
+ // end the execution
+ Configuration.load();
+
+ // if we are here, either there was no configuration
+ // file at all or we managed to load the settings; now,
+ // it's time to properly parse the command line arguments;
+ // this is done by creating a brand new instance of arara's
+ // command line parser and providing the string array to it
+ Parser parser = new Parser(args);
+
+ // now let's see if we are good to go; parse() will return
+ // a boolean value indicating if the provided arguments
+ // allow the tool to continue (we might reach some special
+ // flags as well, like --help or --version, which simply
+ // do their jobs and return false, since there's no point
+ // of continuing processing with such flags)
+ if (parser.parse()) {
+
+ // let's print the current file information; it is a
+ // basic display, just the file name, the size properly
+ // formatted as a human readable format, and the last
+ // modification date; also, in this point, the logging
+ // feature starts to collect data (of course, if enabled
+ // either through the configuration file or manually
+ // in the command line)
+ DisplayUtils.printFileInformation();
+
+ // time to read the file and try to extract the directives;
+ // this class does a pretty good job on finding directives,
+ // including the multiline ones; it was a long awaited
+ // feature people were asking me to implement, so here
+ // it is!
+ Extractor extractor = new Extractor();
+
+ // extract() brings us a list of directives properly parsed
+ // and almost ready to be handled; note that no directives
+ // in the provided file will raise an exception; this is
+ // by design and I opted to not include a default fallback
+ // (although it wouldn't be so difficult to write one,
+ // I decided not to take the risk)
+ List<Directive> directives = extractor.extract();
+
+ // once we have our nice list of directives, it is time to
+ // actually validate them (for example, we have a couple of
+ // keywords that cannot be used as directive parameters);
+ // another interesting feature of the validate() method is
+ // to replicate a directive that has the 'files' keyword on
+ // it, since it's the whole point of having 'files' in the
+ // first place; if you check the log file, you will see
+ // that the list of extracted directives might differ from
+ // the final list of directives to be effectively processed
+ // by arara
+ directives = DirectiveUtils.validate(directives);
+
+ // arara features now a cool stopwatch, so we can see how
+ // much time has passed since everything started; start(),
+ // for obvious reasons, starts the stopwatch and keeps track
+ // of time for us; internally, this class makes use of
+ // nano time, so we might get an interesting precision here
+ // (although timing is not a serious business in here, it's
+ // just a cool addition)
+ StopWatch.start();
+
+ // this is surely the golden heart of arara; this class
+ // implements a powerful interpreter that will handle all
+ // rules and their corresponding tasks
+ Interpreter interpreter = new Interpreter();
+
+ // once we have this bad boy ready, let's provide the list
+ // of directives previously extracted and validated; it is
+ // like loading a cannon, I guess
+ interpreter.setDirectives(directives);
+
+ // time to shine, now the interpreter class will interpret
+ // one directive at a time, get the corresponding rule,
+ // set the parameters, evaluate it, get the tasks, run them,
+ // evaluate the result and print the status; note that
+ // arara, from this version on, will try to evaluate things
+ // progressively, so in case of an error, the previous tasks
+ // were already processed and potentially executed
+ interpreter.execute();
+ }
+
+ } catch (AraraException exception) {
+
+ // something bad just happened, so arara will print the proper
+ // exception and provide details on it, if available; the idea
+ // here is to propagate an exception throughout the whole
+ // application and catch it here instead of a local treatment
+ DisplayUtils.printException(exception);
+ }
+
+ // we are done here (with or without errors, that makes no difference
+ // at this point), so let's stop our stopwatch; now it's just an easy
+ // subtraction to be made (note that the values are internally
+ // represented as nanoseconds, but the result is printed as seconds)
+ StopWatch.stop();
+
+ // this is the last command from arara; once the execution time is
+ // available, print it; note that this notification is suppressed
+ // when the command line parsing returns false as result (it makes
+ // no sense to print the execution time for a help message, I guess)
+ DisplayUtils.printTime();
+
+ // gets the application exit status; the rule here is:
+ // 0 : everything went just fine (note that the dry-run mode always
+ // makes arara exit with 0, unless it is an error in the directive
+ // builder itself).
+ // 1 : one of the tasks failed, so the execution ended abruptly. This
+ // means the error relies on the command line call, not with arara.
+ // 2 : arara just handled an exception, meaning that something bad
+ // just happened and might require user intervention.
+ System.exit(CommonUtils.getExitStatus());
+
+ // I owe David Carlisle $10
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/ConfigurationController.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/ConfigurationController.java
new file mode 100644
index 00000000000..f3868b488f5
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/ConfigurationController.java
@@ -0,0 +1,106 @@
+/**
+ * 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.controller;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Implements the configuration controller. The idea here is to provide a map
+ * that holds all configuration settings used by model and utilitary classes
+ * throughout the execution. This controller is implemented as a singleton.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class ConfigurationController {
+
+ // the controller itself, since we have a singleton;
+ // this is the reference instance, instantiated once
+ private static final ConfigurationController instance =
+ new ConfigurationController();
+
+ // the configuration settings are stored in a map;
+ // pretty much everything can be stored in this map,
+ // as long as you know what to retrieve later on
+ private final Map<String, Object> map;
+
+ /**
+ * Private constructor. Called once for creating the proper singleton.
+ */
+ private ConfigurationController() {
+ map = new HashMap<String, Object>();
+ }
+
+ /**
+ * Gets the current configuration controller. Since this class is
+ * implemented as a singleton, you will get the same controller every
+ * single time, and that's good.
+ * @return The configuration controller, which hold the settings map.
+ */
+ public static ConfigurationController getInstance() {
+ return instance;
+ }
+
+ /**
+ * Returns the object indexed by the provided key. This method provides an
+ * easy access to the underlying map.
+ * @param key A string representing the key.
+ * @return An object indexed by the provided key.
+ */
+ public Object get(String key) {
+ return map.get(key);
+ }
+
+ /**
+ * Puts the object in the map and indexes it in the provided key. This
+ * method provides an easy access to the underlying map.
+ * @param key A string representing the key.
+ * @param value The object to be indexed by the provided key.
+ */
+ public void put(String key, Object value) {
+ map.put(key, value);
+ }
+
+ /**
+ * Checks if the map contains the provided key. This is actually a wrapper
+ * to the private map's method of the same name.
+ * @param key The key to be checked.
+ * @return A boolean value indicating if the map contains the provided key.
+ */
+ public boolean contains(String key) {
+ return map.containsKey(key);
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/LanguageController.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/LanguageController.java
new file mode 100644
index 00000000000..a0ccc2a9586
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/LanguageController.java
@@ -0,0 +1,120 @@
+/**
+ * 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.controller;
+
+import ch.qos.cal10n.IMessageConveyor;
+import ch.qos.cal10n.MessageConveyor;
+import java.util.Locale;
+
+/**
+ * Implements the language controller. This controller provides a singleton
+ * object that holds the application messages, easily available to all model
+ * and utilitary classes.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class LanguageController {
+
+ // the controller itself, since we have a singleton;
+ // this is the reference instance, instantiated once
+ private static final LanguageController instance =
+ new LanguageController();
+
+ // the message conveyor helps us to get localized messages
+ // according to the provided locale
+ private IMessageConveyor conveyor;
+
+ /**
+ * Private constructor. The fallback language is set to English for all
+ * messages in arara.
+ */
+ private LanguageController() {
+ conveyor = new MessageConveyor(new Locale("en"));
+ }
+
+ /**
+ * Initializes the class. This method actually does nothing, it just
+ * triggers the static attributions. Dirty, isn't it?
+ */
+ public static void init() {
+ // quack, quack, quack!
+ }
+
+ /**
+ * Gets the singleton reference. Since this class is implemented as a
+ * singleton, you will get the same controller every single time.
+ * @return The language controller which holds the conveyor.
+ */
+ public static LanguageController getInstance() {
+ return instance;
+ }
+
+ /**
+ * Sets the current locale. This method actually resets the language
+ * conveyor in order to use the new locale. It's quite simple.
+ * @param locale The new locale for localized messages through the language
+ * conveyor.
+ */
+ public void setLocale(Locale locale) {
+ conveyor = new MessageConveyor(locale);
+ }
+
+ /**
+ * Gets the localized message indexed by the provided enumeration key,
+ * applying an array of objects as parameters. This method is a wrapper to
+ * the conveyor's method of the same name.
+ * @param <E> Enumeration type that represents the conveyor messages.
+ * @param key Key set in the provided enumeration type.
+ * @param parameters Array of objects to be used as parameters.
+ * @return A string containing a localized message indexed by the provided
+ * enumeration key and applied the array of objects as parameters.
+ */
+ public <E extends Enum<?>> String getMessage(E key, Object... parameters) {
+ return conveyor.getMessage(key, parameters);
+ }
+
+ /**
+ * Gets the localized message indexed by the provided enumeration key. This
+ * method is a wrapper to the conveyor's method of the same name.
+ * @param <E> Enumeration type that represents the conveyor messages.
+ * @param key Key set in the provided enumeration type.
+ * @return A string containing a localized message indexed by the provided
+ * enumeration key.
+ */
+ public <E extends Enum<?>> String getMessage(E key) {
+ return conveyor.getMessage(key);
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/LoggingController.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/LoggingController.java
new file mode 100644
index 00000000000..193726fcc42
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/LoggingController.java
@@ -0,0 +1,109 @@
+/**
+ * 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.controller;
+
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.core.joran.spi.JoranException;
+import java.io.InputStream;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implements the logging controller. This class actually sets the logging
+ * configuration in order to allow appending results to a file.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class LoggingController {
+
+ /**
+ * Sets the logging configuration according to the provided boolean value.
+ * If the value is set to true, the log entries will be appended to a file,
+ * otherwise the logging feature will keep silent.
+ * @param enable A boolean value that indicates the logging behaviour
+ * throughout the application.
+ */
+ public static void enableLogging(boolean enable) {
+
+ // get the logger context from a factory, set a
+ // new context and reset it
+ LoggerContext loggerContext =
+ (LoggerContext) LoggerFactory.getILoggerFactory();
+
+ try {
+
+ // get a new configuration and set
+ // the context
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(loggerContext);
+ loggerContext.reset();
+
+ // if enabled, the log entries will be
+ // appended to a file, otherwise it will
+ // remain silent
+ if (enable) {
+
+ // set the file name and configure
+ // the logging controller to append
+ // entries to the file
+ String name = (String) ConfigurationController.
+ getInstance().get("execution.log.name");
+ loggerContext.putProperty("name", name);
+ configurator.doConfigure(getResource());
+ }
+ } catch (JoranException exception) {
+ // quack, quack, quack!
+ }
+ }
+
+ /**
+ * Get the configuration resource as an input stream. The configuration
+ * is actually a XML file.
+ * @return An input stream of the provided configuration XML resource.
+ */
+ private static InputStream getResource() {
+ String resource = "/com/github/cereda/arara/configuration/logback.xml";
+ return LoggingController.class.getResourceAsStream(resource);
+ }
+
+ /**
+ * Initializes the logging controller by disabling it. I don't want an odd
+ * behaviour out of the box.
+ */
+ public static void init() {
+ enableLogging(false);
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/SessionController.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/SessionController.java
new file mode 100644
index 00000000000..ac5a45d2b3e
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/SessionController.java
@@ -0,0 +1,124 @@
+/**
+ * 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.controller;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Implements a session controller. This class wraps a map that holds the
+ * execution session, that is, a dirty maneuver to exchange pretty much any
+ * data between commands and even rules.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class SessionController {
+
+ // the controller itself, since we have a singleton;
+ // this is the reference instance, instantiated once
+ private static final SessionController instance =
+ new SessionController();
+
+ // the session map which holds the execution session;
+ // the idea here is to provide wrappers to the map
+ // methods, so it could be easily manipulated
+ private final Map<String, Object> map;
+
+ /**
+ * Private constructor. Called once when the singleton is created.
+ */
+ private SessionController() {
+ map = new HashMap<String, Object>();
+ }
+
+ /**
+ * Gets the singleton reference. Since this class is implemented as a
+ * singleton, you will get the same controller every single time.
+ * @return The session controller which holds the session map.
+ */
+ public static SessionController getInstance() {
+ return instance;
+ }
+
+ /**
+ * Gets the object indexed by the provided key. This method actually holds
+ * the map method of the very same name.
+ * @param key The provided map key.
+ * @return The object indexed by the provided map key.
+ */
+ public Object get(String key) {
+ return map.get(key);
+ }
+
+ /**
+ * Puts the object in the session map and indexes it under the provided
+ * key. This method actually holds the map method of the very same name.
+ * @param key The provided map key.
+ * @param value The object to be indexed under the provided key.
+ */
+ public void put(String key, Object value) {
+ map.put(key, value);
+ }
+
+ /**
+ * Checks if the session map contains the provided key. This method holds
+ * the map method of the very same name.
+ * @param key The key to be checked.
+ * @return A boolean value indicating if the session map contains the
+ * provided key.
+ */
+ public boolean contains(String key) {
+ return map.containsKey(key);
+ }
+
+ /**
+ * Remove an entry from the map according to the provided key. This method
+ * holds the map method of the same name.
+ * @param key The provided key to indicate which session map entry should
+ * be removed.
+ */
+ public void remove(String key) {
+ map.remove(key);
+ }
+
+ /**
+ * Clears the session map. This method, as usual, holds the map method of
+ * the same name.
+ */
+ public void clear() {
+ map.clear();
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/SystemCallController.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/SystemCallController.java
new file mode 100644
index 00000000000..9a592853f69
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/controller/SystemCallController.java
@@ -0,0 +1,153 @@
+/**
+ * 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.controller;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.zeroturnaround.exec.ProcessExecutor;
+
+/**
+ * Implements a system call controller. This class wraps a map that holds the
+ * result of system specific variables not directly available at runtime.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class SystemCallController {
+
+ /**
+ * Implements a private command interface.
+ */
+ private interface Command {
+
+ /**
+ * Executes the command body.
+ * @return An object.
+ */
+ public Object execute();
+ }
+
+ // the controller itself, since we have a singleton;
+ // this is the reference instance, instantiated once
+ private static final SystemCallController instance =
+ new SystemCallController();
+
+ // the system call map which holds the result of
+ // system specific variables not directly available
+ // at runtime; the idea here is to provide wrappers
+ // to the map getter, so it could be easily manipulated
+ private final Map<String, Object> map;
+
+ // the commands map will allow the system call map being
+ // populated only on demand, that is, if the key is not
+ // found, this map will provide the corresponding method
+ // and update the value
+ private final Map<String, Command> commands;
+
+ /**
+ * Private constructor. Called once when the singleton is created.
+ */
+ private SystemCallController() {
+
+ // create the new map instance to be
+ // populated on demand
+ map = new HashMap<String, Object>();
+
+ // create the new map of commands and
+ // add the corresponding system calls
+ commands = new HashMap<String, Command>();
+
+ // add the check for a Cygwin
+ // environment in here
+ commands.put("cygwin", new Command() {
+
+ /**
+ * Implements the body of the command. In this particular
+ * instance, it checks if we are inside a Cygwin environment.
+ * @return A boolean value indicating if we are inside a Cygwin
+ * environment.
+ */
+ public Object execute() {
+ try {
+
+ // execute a new system call to 'uname -s', read the output
+ // as an UTF-8 string, lowercase it and check if it starts
+ // with the 'cygwin' string; if so, we are inside Cygwin
+ return (
+ new ProcessExecutor().command("uname", "-s").
+ readOutput(true).execute().outputUTF8()
+ ).toLowerCase().startsWith("cygwin");
+
+ } catch (Exception exception) {
+
+ // gracefully fallback in case of any nasty and evil
+ // exception, e.g, if the command is unavailable
+ return false;
+ }
+ }
+ });
+ }
+
+ /**
+ * Gets the singleton reference. Since this class is implemented as a
+ * singleton, you will get the same controller every single time.
+ * @return The system call controller which holds the system call map.
+ */
+ public static SystemCallController getInstance() {
+ return instance;
+ }
+
+ /**
+ * Gets the object indexed by the provided key. This method actually holds
+ * the map method of the very same name.
+ * @param key The provided map key.
+ * @return The object indexed by the provided map key.
+ */
+ public Object get(String key) {
+
+ // if key is not found, meaning that
+ // the value wasn't required before
+ if (!map.containsKey(key)) {
+
+ // perform the system call and
+ // populate the corresponding value
+ map.put(key, commands.get(key).execute());
+ }
+
+ // simply return the corresponding
+ // value based on the provided key
+ return map.get(key);
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/exception/AraraException.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/AraraException.java
index daa1b4ac48a..f2a340fd01f 100644
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/exception/AraraException.java
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/AraraException.java
@@ -1,7 +1,6 @@
/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, Paulo Roberto Massa Cereda
+ * 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
@@ -31,57 +30,59 @@
* 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.
- * \endcond
- *
- * AraraException: This class aims at reducing every exception that happens in the
- * whole application to a single self-contained exception.
*/
-// package definition
-package com.github.arara.exception;
+package com.github.cereda.arara.model;
/**
- * Aims at reducing every exception that happens in the whole application to a
- * single self-contained exception.
- *
+ * Implements the specific exception model for arara.
* @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 3.0
+ * @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.
+ * Constructor. Takes the exception message.
+ * @param message The exception message.
*/
- public AraraException() {
- super();
+ public AraraException(String message) {
+ super(message);
}
/**
- * Constructor with a message.
- *
- * @param message A message containing the cause of the exception thrown.
+ * Constructor. Takes the exception message and the underlying exception.
+ * @param message The exception message.
+ * @param exception The underlying exception object.
*/
- public AraraException(String message) {
+ public AraraException(String message, Exception exception) {
super(message);
+ this.exception = exception;
}
/**
- * Constructor with both message and the cause of the exception.
- *
- * @param message A message containing the cause of the exception thrown.
- * @param cause The throwable cause.
+ * Gets the underlying exception.
+ * @return The underlying message.
*/
- public AraraException(String message, Throwable cause) {
- super(message, cause);
+ public Exception getException() {
+ return exception;
}
/**
- * Constructor with the cause of the exception.
- *
- * @param cause The throwable cause.
+ * 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 AraraException(Throwable cause) {
- super(cause);
+ public boolean hasException() {
+ if (exception != null) {
+ return (exception.getMessage() != null);
+ } else {
+ return false;
+ }
}
}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraRuleArgument.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Argument.java
index 5f38418060a..0b15baf9d70 100644
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraRuleArgument.java
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Argument.java
@@ -1,7 +1,6 @@
/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, Paulo Roberto Massa Cereda
+ * 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
@@ -31,94 +30,96 @@
* 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.
- * \endcond
- *
- * PlainAraraRuleArgument: This class provides the model for representing a
- * plain Arara rule argument based on the YAML files. It's a plain old Java
- * object.
*/
-// package definition
-package com.github.arara.model;
+package com.github.cereda.arara.model;
-// needed import
-import com.github.arara.utils.AraraUtils;
+import com.github.cereda.arara.utils.CommonUtils;
/**
- * Provides the model for representing a plain Arara rule argument based on the
- * YAML files. This class will be used to map YAML rules into Java objects.
- *
+ * The rule argument model.
* @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 1.0
+ * @version 4.0
+ * @since 4.0
*/
-public class AraraRuleArgument {
+public class Argument {
- // the rule argument identifier
+ // the argument identifier
private String identifier;
- // the command flag
+
+ // a boolean indicating if the
+ // current argument is required
+ private boolean required;
+
+ // the flag to hold the argument
+ // value manipulation
private String flag;
- // the default value
- private String defaultValue;
+
+ // the argument fallback if it is
+ // not defined in the directive
+ private String fallback;
/**
- * Getter for the default value.
- *
- * @return The default value.
+ * Gets the identifier.
+ * @return The identifier.
*/
- public String getDefault() {
- return defaultValue;
+ public String getIdentifier() {
+ return CommonUtils.removeKeyword(identifier);
}
/**
- * Setter for the default value.
- *
- * @param defaultValue The default value.
+ * Sets the identifier.
+ * @param identifier The identifier.
*/
- public void setDefault(String defaultValue) {
- this.defaultValue = AraraUtils.removeKeyword(defaultValue);
+ public void setIdentifier(String identifier) {
+ this.identifier = identifier;
}
/**
- * Getter for flag.
- *
- * @return The command flag.
+ * Checks if the argument is required.
+ * @return A boolean value indicating if the argument is required.
*/
- public String getFlag() {
-
- // return it
- return flag;
+ public boolean isRequired() {
+ return required;
}
/**
- * Setter for flag.
- *
- * @param flag The command flag.
+ * Sets the argument requirement.
+ * @param required A boolean value.
*/
- public void setFlag(String flag) {
-
- // set the flag
- this.flag = AraraUtils.removeKeyword(flag);
+ public void setRequired(boolean required) {
+ this.required = required;
}
/**
- * Getter for the argument identifier.
- *
- * @return The argument identifier.
+ * Gets the argument flag.
+ * @return The flag.
*/
- public String getIdentifier() {
+ public String getFlag() {
+ return CommonUtils.removeKeyword(flag);
+ }
- // return it
- return identifier;
+ /**
+ * Sets the argument flag.
+ * @param flag The argument flag.
+ */
+ public void setFlag(String flag) {
+ this.flag = flag;
}
/**
- * Setter for the argument identifier.
- *
- * @param identifier The argument identifier.
+ * Gets the argument fallback.
+ * @return The argument fallback.
*/
- public void setIdentifier(String identifier) {
+ public String getDefault() {
+ return CommonUtils.removeKeyword(fallback);
+ }
- // set the identifier
- this.identifier = identifier;
+ /**
+ * Sets the argument fallback.
+ * @param fallback The argument fallback.
+ */
+ public void setDefault(String fallback) {
+ this.fallback = fallback;
}
+
}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Command.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Command.java
new file mode 100644
index 00000000000..30583898327
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/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/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Conditional.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Conditional.java
new file mode 100644
index 00000000000..4c830f0a1b6
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/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/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Configuration.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Configuration.java
new file mode 100644
index 00000000000..0c2c2949586
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/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/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Database.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Database.java
new file mode 100644
index 00000000000..66d360fdc08
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/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/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Directive.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Directive.java
new file mode 100644
index 00000000000..e311477125c
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/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/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Evaluator.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Evaluator.java
new file mode 100644
index 00000000000..41f8d099430
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/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/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Extractor.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Extractor.java
new file mode 100644
index 00000000000..84edef1eb05
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/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/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/FileType.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/FileType.java
new file mode 100644
index 00000000000..b9f2a01e032
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/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/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraFilePattern.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/FileTypeResource.java
index 91e1e4759f9..29340358581 100644
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraFilePattern.java
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/FileTypeResource.java
@@ -1,7 +1,6 @@
/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, Paulo Roberto Massa Cereda
+ * 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
@@ -31,63 +30,55 @@
* 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.
- * \endcond
- *
- * AraraFilePattern: This class maps the supported filetypes.
*/
-// package definition
-package com.github.arara.model;
+package com.github.cereda.arara.model;
-// needed imports
-import com.github.arara.utils.AraraConstants;
+import com.github.cereda.arara.utils.CommonUtils;
/**
- * Maps the supported filetypes.
- *
+ * Implements the file type resource model.
* @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 3.0
+ * @version 4.0
+ * @since 4.0
*/
-public class AraraFilePattern {
+public class FileTypeResource {
- // file extension
+ // the file extension
private String extension;
- // file pattern
+
+ // the file pattern
private String pattern;
/**
- * Getter for the file extension.
- *
- * @return The file extension.
+ * Gets the extension.
+ * @return The extension.
*/
public String getExtension() {
- return extension;
+ return CommonUtils.removeKeyword(extension);
}
/**
- * Setter for the file extension.
- *
- * @param extension The file extension.
+ * Sets the extension.
+ * @param extension The extension.
*/
public void setExtension(String extension) {
this.extension = extension;
}
/**
- * Getter for the file pattern.
- *
- * @return The file pattern.
+ * Gets the pattern.
+ * @return The pattern.
*/
public String getPattern() {
- return pattern;
+ return CommonUtils.removeKeyword(pattern);
}
/**
- * Setter for the file pattern.
- *
- * @param pattern The file pattern.
+ * Sets the pattern.
+ * @param pattern The pattern.
*/
public void setPattern(String pattern) {
- this.pattern = pattern.concat(AraraConstants.DIRECTIVEPREFIX);
+ this.pattern = pattern;
}
+
}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Interpreter.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Interpreter.java
new file mode 100644
index 00000000000..7c8f6e3928a
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/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/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Language.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Language.java
new file mode 100644
index 00000000000..2b0fc8266e8
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/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/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Messages.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Messages.java
new file mode 100644
index 00000000000..9916c3c145b
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/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/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Pair.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Pair.java
new file mode 100644
index 00000000000..d8591b6ef75
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/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/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Parser.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Parser.java
new file mode 100644
index 00000000000..723e24e76e4
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/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/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Resource.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Resource.java
new file mode 100644
index 00000000000..2994a4d6912
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/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/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Rule.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Rule.java
new file mode 100644
index 00000000000..af3ad199506
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/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/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraCommand.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/RuleCommand.java
index 80da972003d..b209d19bcb0 100644
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraCommand.java
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/RuleCommand.java
@@ -1,7 +1,6 @@
/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, Paulo Roberto Massa Cereda
+ * 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
@@ -31,69 +30,74 @@
* 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.
- * \endcond
- *
- * AraraCommand: This class provides the model for commands to be executed by
- * the runtime. It's a plain old Java object.
*/
-// package definition
-package com.github.arara.model;
+package com.github.cereda.arara.model;
+
+import com.github.cereda.arara.utils.CommonUtils;
/**
- * Provides the model for commands to be executed by the runtime.
- *
+ * Implements the rule command model.
* @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 1.0
+ * @version 4.0
+ * @since 4.0
*/
-public class AraraCommand {
+public class RuleCommand {
- // the name to be displayed in the command line
+ // the command name
private String name;
- // the command itself
+
+ // the command instruction
private String command;
+
+ // the exit status expression
+ private String exit;
/**
- * Getter for command.
- *
- * @return The command to be executed by the runtime.
+ * Gets the command name.
+ * @return The command name.
*/
- public String getCommand() {
+ public String getName() {
+ return CommonUtils.removeKeyword(name);
+ }
- // return it
- return command;
+ /**
+ * Sets the command name.
+ * @param name The command name.
+ */
+ public void setName(String name) {
+ this.name = name;
}
/**
- * Setter for command.
- *
- * @param command The command, already expanded.
+ * Gets the command instruction.
+ * @return The command instruction.
*/
- public void setCommand(String command) {
+ public String getCommand() {
+ return CommonUtils.removeKeyword(command);
+ }
- // set the command
+ /**
+ * Sets the command instruction.
+ * @param command The command instruction.
+ */
+ public void setCommand(String command) {
this.command = command;
}
/**
- * Getter for the command name.
- *
- * @return The command name, provided by the rule.
+ * Gets the exit status expression.
+ * @return The exit status expression.
*/
- public String getName() {
-
- // return it
- return name;
+ public String getExit() {
+ return CommonUtils.removeKeyword(exit);
}
/**
- * Setter for the command name.
- *
- * @param name The command name.
+ * Sets the exit status expression.
+ * @param exit The exit status expression.
*/
- public void setName(String name) {
-
- // set the name
- this.name = name;
+ public void setExit(String exit) {
+ this.exit = exit;
}
+
}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Session.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Session.java
new file mode 100644
index 00000000000..c756ae4550e
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/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/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/StopWatch.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/StopWatch.java
new file mode 100644
index 00000000000..45e0969d0b7
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/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/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Trigger.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/model/Trigger.java
new file mode 100644
index 00000000000..11da04bfcb9
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/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
+ )
+ );
+ }
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/ClassLoadingUtils.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/ClassLoadingUtils.java
new file mode 100644
index 00000000000..c40536ce08f
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/ClassLoadingUtils.java
@@ -0,0 +1,166 @@
+/**
+ * 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.utils;
+
+import com.github.cereda.arara.model.Pair;
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+/**
+ * Implements utilitary methods for classloading and object instantiation.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class ClassLoadingUtils {
+
+ /**
+ * Loads a class from the provided file, potentially a Java archive.
+ * @param file File containing the Java bytecode (namely, a JAR).
+ * @param name The canonical name of the class.
+ * @return A pair representing the status and the class.
+ */
+ public static Pair<Integer, Class> loadClass(File file, String name) {
+
+ // status and class to be returned,
+ // it defaults to an object class
+ int status = 0;
+ Class value = Object.class;
+
+ // if file does not exist, nothing
+ // can be done, status is changed
+ if (!file.exists()) {
+ status = 1;
+ } else {
+
+ // classloading involves defining
+ // a classloader and fetching the
+ // desired class from it, based on
+ // the provided file archive
+ try {
+
+ // creates a new classloader with
+ // the provided file (potentially
+ // a JAR file)
+ URLClassLoader classloader = new URLClassLoader(
+ new URL[]{
+ file.toURI().toURL()
+ },
+ ClassLoadingUtils.class.getClassLoader()
+ );
+
+ // fetches the class from the
+ // instantiated classloader
+ value = Class.forName(name, true, classloader);
+
+ } catch (MalformedURLException nothandled1) {
+
+ // the file URL is incorrect,
+ // update status accordingly
+ status = 2;
+
+ } catch (ClassNotFoundException nothandled2) {
+
+ // the class was not found,
+ // update status accordingly
+ status = 3;
+
+ }
+ }
+
+ // return a new pair based on the
+ // current status and class holder
+ return new Pair<Integer, Class>(status, value);
+ }
+
+ /**
+ * Loads a class from the provided file, instantiating it.
+ * @param file File containing the Java bytecode (namely, a JAR).
+ * @param name The canonical name of the class.
+ * @return A pair representing the status and the class object.
+ */
+ public static Pair<Integer, Object> loadObject(File file, String name) {
+
+ // load the corresponding class
+ // based on the qualified name
+ Pair<Integer, Class> pair = loadClass(file, name);
+
+ // status and object to be returned,
+ // it defaults to an object
+ int status = pair.getFirstElement();
+ Object value = new Object();
+
+ // checks if the class actually
+ // exists, otherwise simply
+ // ignore instantiation
+ if (status == 0) {
+
+ // object instantiation relies
+ // on the default constructor
+ // (without arguments), class
+ // must implement it
+
+ // OBS: constructors with arguments
+ // must be invoked through reflection
+ try {
+
+ // get the class reference from
+ // the pair and instantiate it
+ // by invoking the default
+ // constructor (without arguments)
+ value = pair.getSecondElement().newInstance();
+
+ } catch (IllegalAccessException nothandled1) {
+
+ // the object instantiation violated
+ // an access policy, status is updated
+ status = 4;
+
+ } catch (InstantiationException nothandled2) {
+
+ // an instantiation exception has
+ // occurred, status is updated
+ status = 5;
+
+ }
+ }
+
+ // return a new pair based on the
+ // current status and object holder
+ return new Pair<Integer, Object>(status, value);
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/CommonUtils.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/CommonUtils.java
new file mode 100644
index 00000000000..621634749ef
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/CommonUtils.java
@@ -0,0 +1,929 @@
+/**
+ * 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.utils;
+
+import com.github.cereda.arara.controller.ConfigurationController;
+import com.github.cereda.arara.controller.LanguageController;
+import com.github.cereda.arara.controller.SystemCallController;
+import com.github.cereda.arara.model.AraraException;
+import com.github.cereda.arara.model.Argument;
+import com.github.cereda.arara.model.Database;
+import com.github.cereda.arara.model.FileType;
+import com.github.cereda.arara.model.Messages;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.MissingFormatArgumentException;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.filefilter.NameFileFilter;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.SystemUtils;
+
+/**
+ * Implements common utilitary methods.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class CommonUtils {
+
+ // the application messages obtained from the
+ // language controller
+ private static final LanguageController messages =
+ LanguageController.getInstance();
+
+ /**
+ * Checks if the input string is equal to a valid boolean value.
+ * @param value The input string.
+ * @return A boolean value represented by the provided string.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean checkBoolean(String value) throws AraraException {
+ List<String> yes = Arrays.asList(
+ new String[]{"yes", "true", "1", "on"}
+ );
+ List<String> no = Arrays.asList(
+ new String[]{"no", "false", "0", "off"}
+ );
+ if (!union(yes, no).contains(value.toLowerCase())) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_CHECKBOOLEAN_NOT_VALID_BOOLEAN,
+ value
+ )
+ );
+ } else {
+ return yes.contains(value.toLowerCase());
+ }
+ }
+
+ /**
+ * Provides a union set operation between two lists.
+ * @param <T> The list type.
+ * @param list1 The first list.
+ * @param list2 The second list.
+ * @return The union of those two lists.
+ */
+ private static <T> List<T> union(List<T> list1, List<T> list2) {
+ Set<T> elements = new HashSet<T>();
+ elements.addAll(list1);
+ elements.addAll(list2);
+ return new ArrayList<T>(elements);
+ }
+
+ /**
+ * Build a system-dependant path based on the path and the file.
+ * @param path A string representing the path to be prepended.
+ * @param file A string representing the file to be appended.
+ * @return The full path as a string.
+ */
+ public static String buildPath(String path, String file) {
+ return path.endsWith(File.separator) ?
+ path.concat(file) : path.concat(File.separator).concat(file);
+ }
+
+ /**
+ * Checks if the provided string is empty. It does not handle a null value.
+ * @param string A string.
+ * @return A boolean value indicating if the string is empty.
+ */
+ public static boolean checkEmptyString(String string) {
+ return "".equals(string);
+ }
+
+ /**
+ * Removes the keyword from the beginning of the provided string.
+ * @param line A string to be analyzed.
+ * @return The provided string without the keyword.
+ */
+ public static String removeKeyword(String line) {
+ if (line != null) {
+ Pattern pattern = Pattern.compile("^(\\s)*<arara>\\s");
+ Matcher matcher = pattern.matcher(line);
+ if (matcher.find()) {
+ line = (line.substring(matcher.end(), line.length()));
+ }
+ line = line.trim();
+ }
+ return line;
+ }
+
+ /**
+ * Discovers the file through string reference lookup and sets the
+ * configuration accordingly.
+ * @param reference The string reference.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static void discoverFile(String reference) throws AraraException {
+ File file = lookupFile(reference);
+ if (file == null) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_DISCOVERFILE_FILE_NOT_FOUND,
+ reference,
+ getFileTypesList()
+ )
+ );
+ }
+ }
+
+ /**
+ * Performs a file lookup based on a string reference.
+ * @param reference The file reference as a string.
+ * @return The file as result of the lookup operation.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ private static File lookupFile(String reference) throws AraraException {
+ @SuppressWarnings("unchecked")
+ List<FileType> types = (List<FileType>) ConfigurationController.
+ getInstance().get("execution.filetypes");
+ File file = new File(reference);
+ String name = file.getName();
+ String parent = getParentCanonicalPath(file);
+ String path = buildPath(parent, name);
+
+ // direct search, so we are considering
+ // the reference as a complete name
+ for (FileType type : types) {
+ if (path.endsWith(".".concat(type.getExtension()))) {
+ file = new File(path);
+ if (file.exists()) {
+ if (file.isFile()) {
+ ConfigurationController.
+ getInstance().
+ put("execution.file.pattern",
+ type.getPattern());
+ ConfigurationController.
+ getInstance().
+ put("execution.reference", file);
+ return file;
+ }
+ }
+ }
+ }
+
+ // indirect search; in this case, we are considering
+ // that the file reference has an implict extension,
+ // so we need to add it and look again
+ for (FileType type : types) {
+ path = buildPath(parent, name.concat(".").
+ concat(type.getExtension()));
+ file = new File(path);
+ if (file.exists()) {
+ if (file.isFile()) {
+ ConfigurationController.getInstance().
+ put("execution.file.pattern", type.getPattern());
+ ConfigurationController.getInstance().
+ put("execution.reference", file);
+ return file;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Gets the parent canonical path of a file.
+ * @param file The file.
+ * @return The parent canonical path of a file.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static String getParentCanonicalPath(File file)
+ throws AraraException {
+ try {
+ String path = file.getCanonicalFile().getParent();
+ return path;
+ } catch (IOException exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_GETPARENTCANONICALPATH_IO_EXCEPTION
+ ),
+ exception
+ );
+ }
+ }
+
+ /**
+ * Gets the canonical file from a file.
+ * @param file The file.
+ * @return The canonical file.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static File getCanonicalFile(String file) throws AraraException {
+ try {
+ return (new File(file)).getCanonicalFile();
+ } catch (IOException exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_GETCANONICALFILE_IO_EXCEPTION
+ ),
+ exception
+ );
+ }
+ }
+
+ /**
+ * Checks if the provided object is from a certain class.
+ * @param clazz The class.
+ * @param object The object.
+ * @return A boolean value indicating if the provided object is from a
+ * certain class.
+ */
+ public static boolean checkClass(Class clazz, Object object) {
+ return clazz.isInstance(object);
+ }
+
+ /**
+ * Helper method to flatten a potential list of lists into a list of
+ * objects.
+ * @param list First list.
+ * @param flat Second list.
+ */
+ private static void flatten(List<?> list, List<Object> flat) {
+ for (Object item : list) {
+ if (item instanceof List<?>) {
+ flatten((List<?>) item, flat);
+ } else {
+ flat.add(item);
+ }
+ }
+ }
+
+ /**
+ * Flattens a potential list of lists into a list of objects.
+ * @param list The list to be flattened.
+ * @return The flattened list.
+ */
+ public static List<Object> flatten(List<?> list) {
+ List<Object> result = new ArrayList<Object>();
+ flatten(list, result);
+ return result;
+ }
+
+ /**
+ * Gets the list of file types, in order.
+ * @return A string representation of the list of file types, in order.
+ */
+ public static String getFileTypesList() {
+ @SuppressWarnings("unchecked")
+ List<FileType> types = (List<FileType>) ConfigurationController.
+ getInstance().get("execution.filetypes");
+ return getCollectionElements(types, "[ ", " ]", " | ");
+ }
+
+ /**
+ * Gets a string representation of a collection.
+ * @param collection The collection.
+ * @param open The opening string.
+ * @param close The closing string.
+ * @param separator The element separator.
+ * @return A string representation of the provided collection.
+ */
+ public static String getCollectionElements(Collection collection,
+ String open, String close, String separator) {
+ StringBuilder builder = new StringBuilder();
+ builder.append(open);
+ builder.append(StringUtils.join(collection, separator));
+ builder.append(close);
+ return builder.toString();
+ }
+
+ /**
+ * Gets a set of strings containing unknown keys from a map and a list. It
+ * is a set difference from the keys in the map and the entries in the list.
+ * @param parameters The map of parameters.
+ * @param arguments The list of arguments.
+ * @return A set of strings representing unknown keys from a map and a list.
+ */
+ public static Set<String> getUnknownKeys(Map<String, Object> parameters,
+ List<Argument> arguments) {
+ Collection<String> found = parameters.keySet();
+ Collection<String> expected = CollectionUtils.collect(
+ arguments, new Transformer<Argument, String>() {
+ public String transform(Argument argument) {
+ return argument.getIdentifier();
+ }
+ });
+ Collection<String> difference = CollectionUtils.
+ subtract(found, expected);
+ return new HashSet<String>(difference);
+ }
+
+ /**
+ * Gets the rule error header, containing the identifier and the path, if
+ * any.
+ * @return A string representation of the rule error header, containing the
+ * identifier and the path, if any.
+ */
+ public static String getRuleErrorHeader() {
+ if ((ConfigurationController.getInstance().
+ contains("execution.info.rule.id")) &&
+ (ConfigurationController.getInstance().
+ contains("execution.info.rule.path"))) {
+ String id = (String) ConfigurationController.getInstance().
+ get("execution.info.rule.id");
+ String path = (String) ConfigurationController.getInstance().
+ get("execution.info.rule.path");
+ return messages.getMessage(
+ Messages.ERROR_RULE_IDENTIFIER_AND_PATH,
+ id,
+ path
+ ).concat(" ");
+ } else {
+ return "";
+ }
+ }
+
+ /**
+ * Trims spaces from every string of a list of strings.
+ * @param input The list of strings.
+ * @return A new list of strings, with each element trimmed.
+ */
+ public static List<String> trimSpaces(List<String> input) {
+ Collection<String> result = CollectionUtils.collect(
+ input, new Transformer<String, String>() {
+ public String transform(String input) {
+ return input.trim();
+ }
+ });
+ return new ArrayList<String>(result);
+ }
+
+ /**
+ * Gets a human readable representation of a file size.
+ * @param file The file.
+ * @return A string representation of the file size.
+ */
+ public static String calculateFileSize(File file) {
+ return FileUtils.byteCountToDisplaySize(file.length());
+ }
+
+ /**
+ * Gets the date the provided file was last modified.
+ * @param file The file.
+ * @return A string representation of the date the provided file was last
+ * modified.
+ */
+ public static String getLastModifiedInformation(File file) {
+ SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
+ return format.format(file.lastModified());
+ }
+
+ /**
+ * Gets a list of all rule paths.
+ * @return A list of all rule paths.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static List<String> getAllRulePaths() throws AraraException {
+ @SuppressWarnings("unchecked")
+ List<String> paths = (List<String>) ConfigurationController.
+ getInstance().get("execution.rule.paths");
+ List<String> result = new ArrayList<String>();
+ for (String path : paths) {
+ File location = new File(InterpreterUtils.construct(path, "quack"));
+ result.add(getParentCanonicalPath(location));
+ }
+ return result;
+ }
+
+ /**
+ * Gets the reference of the current file in execution. Note that this
+ * method might return a value different than the main file provided in
+ * the command line.
+ * @return A reference of the current file in execution. Might be different
+ * than the main file provided in the command line.
+ */
+ private static File getCurrentReference() {
+ return (File) ConfigurationController.getInstance().
+ get("execution.file");
+ }
+
+ /**
+ * Calculates the CRC32 checksum of the provided file.
+ * @param file The file.
+ * @return A string containing the CRC32 checksum of the provided file.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static String calculateHash(File file) throws AraraException {
+ try {
+ long result = FileUtils.checksumCRC32(file);
+ return String.format("%08x", result);
+ } catch (IOException exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_CALCULATEHASH_IO_EXCEPTION
+ ),
+ exception
+ );
+ }
+ }
+
+ /**
+ * Gets the file type of a file.
+ * @param file The file.
+ * @return The corresponding file type.
+ */
+ public static String getFiletype(File file) {
+ return getFiletype(file.getName());
+ }
+
+ /**
+ * Gets the file type of a string representing the file.
+ * @param name A string representing the file.
+ * @return The corresponding file type.
+ */
+ public static String getFiletype(String name) {
+ name = name.lastIndexOf(".") != -1 ?
+ name.substring(name.lastIndexOf(".") + 1, name.length()) : "";
+ return name;
+ }
+
+ /**
+ * Gets the base name of a file.
+ * @param file The file.
+ * @return The corresponding base name.
+ */
+ public static String getBasename(File file) {
+ return getBasename(file.getName());
+ }
+
+ /**
+ * Gets the base name of a string representing the file.
+ * @param name A string representing the file.
+ * @return The corresponding base name.
+ */
+ public static String getBasename(String name) {
+ int index = name.lastIndexOf(".") != -1 ?
+ name.lastIndexOf(".") : name.length();
+ return name.substring(0, index);
+ }
+
+ /**
+ * Encloses the provided object in double quotes.
+ * @param object The object.
+ * @return A string representation of the provided object enclosed in double
+ * quotes.
+ */
+ public static String addQuotes(Object object) {
+ return "\"".concat(String.valueOf(object)).concat("\"");
+ }
+
+ /**
+ * Generates a string based on a list of objects, separating each one of
+ * them by one space.
+ * @param objects A list of objects.
+ * @return A string based on the list of objects, separating each one of
+ * them by one space. Empty values are not considered.
+ */
+ public static String generateString(Object... objects) {
+ List<String> values = new ArrayList<String>();
+ for (Object object : objects) {
+ if (!CommonUtils.checkEmptyString(String.valueOf(object))) {
+ values.add(String.valueOf(object));
+ }
+ }
+ return StringUtils.join(values, " ");
+ }
+
+ /**
+ * Checks if a file exists.
+ * @param file The file.
+ * @return A boolean value indicating if the file exists.
+ */
+ public static boolean exists(File file) {
+ return file.exists();
+ }
+
+ /**
+ * Checks if a file exists based on its extension.
+ * @param extension The extension.
+ * @return A boolean value indicating if the file exists.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean exists(String extension) throws AraraException {
+ File file = new File(getPath(extension));
+ return file.exists();
+ }
+
+ /**
+ * Checks if a file has changed since the last verification.
+ * @param file The file.
+ * @return A boolean value indicating if the file has changed since the last
+ * verification.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean hasChanged(File file) throws AraraException {
+ Database database = DatabaseUtils.load();
+ HashMap<String, String> map = database.getMap();
+ String path = getCanonicalPath(file);
+ if (!file.exists()) {
+ if (map.containsKey(path)) {
+ map.remove(path);
+ database.setMap(map);
+ DatabaseUtils.save(database);
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ String hash = calculateHash(file);
+ if (map.containsKey(path)) {
+ String value = map.get(path);
+ if (hash.equals(value)) {
+ return false;
+ } else {
+ map.put(path, hash);
+ database.setMap(map);
+ DatabaseUtils.save(database);
+ return true;
+ }
+ } else {
+ map.put(path, hash);
+ database.setMap(map);
+ DatabaseUtils.save(database);
+ return true;
+ }
+ }
+ }
+
+ /**
+ * Checks if the file has changed since the last verification based on the
+ * provided extension.
+ * @param extension The provided extension.
+ * @return A boolean value indicating if the file has changed since the last
+ * verification.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean hasChanged(String extension) throws AraraException {
+ File file = new File(getPath(extension));
+ return hasChanged(file);
+ }
+
+ /**
+ * Gets the full file path based on the provided extension.
+ * @param extension The extension.
+ * @return A string containing the full file path.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ private static String getPath(String extension) throws AraraException {
+ String name = getBasename(getCurrentReference());
+ String path = getParentCanonicalPath(getCurrentReference());
+ name = name.concat(".").concat(extension);
+ return buildPath(path, name);
+ }
+
+ /**
+ * Gets the canonical path from the provided file.
+ * @param file The file.
+ * @return The canonical path from the provided file.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static String getCanonicalPath(File file) throws AraraException {
+ try {
+ return file.getCanonicalPath();
+ } catch (IOException exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_GETCANONICALPATH_IO_EXCEPTION
+ ),
+ exception
+ );
+ }
+ }
+
+ /**
+ * Checks if the file based on the provided extension contains the provided
+ * regex.
+ * @param extension The file extension.
+ * @param regex The regex.
+ * @return A boolean value indicating if the file contains the provided
+ * regex.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean checkRegex(String extension, String regex)
+ throws AraraException {
+ File file = new File(getPath(extension));
+ return checkRegex(file, regex);
+ }
+
+ /**
+ * Checks if the file contains the provided regex.
+ * @param file The file.
+ * @param regex The regex.
+ * @return A boolean value indicating if the file contains the provided
+ * regex.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean checkRegex(File file, String regex)
+ throws AraraException {
+ Charset charset = (Charset) ConfigurationController.
+ getInstance().get("directives.charset");
+ try {
+ String text = FileUtils.readFileToString(file, charset.name());
+ Pattern pattern = Pattern.compile(regex);
+ Matcher matcher = pattern.matcher(text);
+ return matcher.find();
+ } catch (IOException exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_CHECKREGEX_IO_EXCEPTION,
+ file.getName()
+ ),
+ exception
+ );
+ }
+ }
+
+ /**
+ * Replicates a string pattern based on a list of objects, generating a list
+ * as result.
+ * @param pattern The string pattern.
+ * @param values The list of objects to be merged with the pattern.
+ * @return A list containing the string pattern replicated to each object
+ * from the list.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static List<Object> replicateList(String pattern,
+ List<Object> values) throws AraraException {
+ List<Object> result = new ArrayList<Object>();
+ for (Object value : values) {
+ try {
+ result.add(String.format(pattern, value));
+ } catch (MissingFormatArgumentException exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_REPLICATELIST_MISSING_FORMAT_ARGUMENTS_EXCEPTION
+ ),
+ exception
+ );
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Checks if the provided operating system string holds according to the
+ * underlying operating system.
+ * @param value A string representing an operating system.
+ * @return A boolean value indicating if the provided string refers to the
+ * underlying operating system.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean checkOS(String value) throws AraraException {
+ Map<String, Boolean> values = new HashMap<String, Boolean>();
+ values.put("windows", SystemUtils.IS_OS_WINDOWS);
+ values.put("linux", SystemUtils.IS_OS_LINUX);
+ values.put("mac", SystemUtils.IS_OS_MAC_OSX);
+ values.put("unix", SystemUtils.IS_OS_UNIX);
+ values.put("aix", SystemUtils.IS_OS_AIX);
+ values.put("irix", SystemUtils.IS_OS_IRIX);
+ values.put("os2", SystemUtils.IS_OS_OS2);
+ values.put("solaris", SystemUtils.IS_OS_SOLARIS);
+ values.put("cygwin", (Boolean) SystemCallController.
+ getInstance().get("cygwin"));
+ if (!values.containsKey(value.toLowerCase())) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_CHECKOS_INVALID_OPERATING_SYSTEM,
+ value
+ )
+ );
+ }
+ return values.get(value.toLowerCase());
+ }
+
+ /**
+ * Returns the exit status of the application.
+ * @return An integer representing the exit status of the application.
+ */
+ public static int getExitStatus() {
+ return (Integer) ConfigurationController.
+ getInstance().get("execution.status");
+ }
+
+ /**
+ * Gets the system property according to the provided key, or resort to the
+ * fallback value if an exception is thrown or if the key is invalid.
+ * @param key The system property key.
+ * @param fallback The fallback value.
+ * @return A string containing the system property value or the fallback.
+ */
+ public static String getSystemProperty(String key, String fallback) {
+ try {
+ String result = System.getProperty(key, fallback);
+ return result.equals("") ? fallback : result;
+ } catch (Exception exception) {
+ return fallback;
+ }
+ }
+
+ /**
+ * Gets the preamble content, converting a single string into a list of
+ * strings, based on new lines.
+ * @return A list of strings representing the preamble content.
+ */
+ public static List<String> getPreambleContent() {
+ if (((Boolean) ConfigurationController.
+ getInstance().get("execution.preamble.active")) == true) {
+ return new ArrayList<String>(
+ Arrays.asList(
+ ((String) ConfigurationController.getInstance().
+ get("execution.preamble.content")
+ ).split("\n"))
+ );
+ }
+ else {
+ return new ArrayList<String>();
+ }
+ }
+
+ /**
+ * Generates a list of filenames from the provided command based on a list
+ * of extensions for each underlying operating system.
+ * @param command A string representing the command.
+ * @return A list of filenames.
+ */
+ private static List<String> appendExtensions(String command) {
+
+ // the resulting list, to hold the
+ // filenames generated from the
+ // provided command
+ List<String> result = new ArrayList<String>();
+
+ // list of extensions, specific for
+ // each operating system (in fact, it
+ // is more Windows specific)
+ List<String> extensions;
+
+ // the application is running on
+ // Windows, so let's look for the
+ // following extensions in order
+ if (SystemUtils.IS_OS_WINDOWS) {
+
+ // this list is actually a sublist from
+ // the original Windows PATHEXT environment
+ // variable which holds the list of executable
+ // extensions that Windows supports
+ extensions = Arrays.asList(".com", ".exe", ".bat", ".cmd");
+ }
+ else {
+
+ // no Windows, so the default
+ // extension will be just an
+ // empty string
+ extensions = Arrays.asList("");
+ }
+
+ // for each and every extension in the
+ // list, let's build the corresponding
+ // filename and add to the result
+ for (String extension : extensions) {
+ result.add(command.concat(extension));
+ }
+
+ // return the resulting list
+ // holding the filenames
+ return result;
+ }
+
+ /**
+ * Checks if the provided command name is reachable from the system path.
+ * @param command A string representing the command.
+ * @return A logic value.
+ */
+ public static boolean isOnPath(String command) {
+ try {
+
+ // first and foremost, let's build the list
+ // of filenames based on the underlying
+ // operating system
+ List<String> filenames = appendExtensions(command);
+
+ // break the path into several parts
+ // based on the path separator symbol
+ StringTokenizer tokenizer = new StringTokenizer(
+ System.getenv("PATH"),
+ File.pathSeparator
+ );
+
+ // iterate through every part of the
+ // path looking for each filename
+ while (tokenizer.hasMoreTokens()) {
+
+ // if the search does not return an empty
+ // list, one of the filenames got a match,
+ // and the command is available somewhere
+ // in the system path
+ if (
+ !FileUtils.listFiles(
+ new File(tokenizer.nextToken()),
+ new NameFileFilter(filenames),
+ null
+ ).isEmpty()) {
+
+ // command is found somewhere,
+ // so it is on path
+ return true;
+ }
+ }
+
+ // nothing was found,
+ // command is not on path
+ return false;
+ }
+ catch (Exception exception) {
+
+ // an exception was raised, simply
+ // return and forget about it
+ return false;
+ }
+ }
+
+ /**
+ * Gets the full base name of a file.
+ * @param file The file.
+ * @return The corresponding full base name.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static String getFullBasename(File file) throws AraraException {
+
+ // if the provided file does not contain a
+ // file separator, fallback to the usual
+ // base name lookup
+ if (!file.toString().contains(File.separator)) {
+ return getBasename(file);
+ }
+ else {
+
+ // we need to get the parent file, get the
+ // canonical path and build the corresponding
+ // full base name path
+ File parent = file.getParentFile();
+ String path = getCanonicalPath(parent == null ? file : parent);
+ return buildPath(path, getBasename(file));
+ }
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/ConfigurationUtils.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/ConfigurationUtils.java
new file mode 100644
index 00000000000..0b7d3b8a5b4
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/ConfigurationUtils.java
@@ -0,0 +1,239 @@
+/**
+ * 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.utils;
+
+import com.github.cereda.arara.Arara;
+import com.github.cereda.arara.controller.LanguageController;
+import com.github.cereda.arara.model.AraraException;
+import com.github.cereda.arara.model.FileType;
+import com.github.cereda.arara.model.FileTypeResource;
+import com.github.cereda.arara.model.Messages;
+import com.github.cereda.arara.model.Resource;
+import java.io.File;
+import java.io.FileReader;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.lang.SystemUtils;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+import org.yaml.snakeyaml.error.MarkedYAMLException;
+import org.yaml.snakeyaml.nodes.Tag;
+import org.yaml.snakeyaml.representer.Representer;
+
+/**
+ * Implements configuration utilitary methods.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class ConfigurationUtils {
+
+ // the application messages obtained from the
+ // language controller
+ private static final LanguageController messages =
+ LanguageController.getInstance();
+
+ /**
+ * Gets the list of default file types provided by nightingale, in order.
+ * @return The list of default file types, in order.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static List<FileType> getDefaultFileTypes() throws AraraException {
+ return Arrays.asList(
+ new FileType("tex"),
+ new FileType("dtx"),
+ new FileType("ltx"),
+ new FileType("drv"),
+ new FileType("ins")
+ );
+ }
+
+ /**
+ * Gets the configuration file located at the user home directory, if any.
+ * @return The file reference to the external configuration, if any.
+ */
+ public static File getConfigFile() {
+ List<String> names = Arrays.asList(
+ ".araraconfig.yaml",
+ "araraconfig.yaml",
+ ".arararc.yaml",
+ "arararc.yaml"
+ );
+
+ // look for configuration files in the user's working directory first
+ for (String name : names) {
+ String path = CommonUtils.buildPath(SystemUtils.USER_DIR, name);
+ File file = new File(path);
+ if (file.exists()) {
+ return file;
+ }
+ }
+
+ // if no configuration files are found in the user's working directory,
+ // try to look up in a global directory, that is, the user home
+ for (String name : names) {
+ String path = CommonUtils.buildPath(SystemUtils.USER_HOME, name);
+ File file = new File(path);
+ if (file.exists()) {
+ return file;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Validates the configuration file.
+ * @param file The configuration file.
+ * @return The configuration file as a resource.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Resource validateConfiguration(File file)
+ throws AraraException {
+
+ Representer representer = new Representer();
+ representer.addClassTag(Resource.class, new Tag("!config"));
+ Yaml yaml = new Yaml(new Constructor(Resource.class), representer);
+ try {
+ Resource resource = yaml.loadAs(new FileReader(file),
+ Resource.class);
+ if (resource.getFiletypes() != null) {
+ List<FileTypeResource> filetypes = resource.getFiletypes();
+ if (CollectionUtils.exists(filetypes,
+ new Predicate<FileTypeResource>() {
+ public boolean evaluate(FileTypeResource filetype) {
+ return (filetype.getExtension() == null);
+ }
+ })) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_CONFIGURATION_FILETYPE_MISSING_EXTENSION
+ )
+ );
+ }
+ }
+ return resource;
+ } catch (MarkedYAMLException yamlException) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_CONFIGURATION_INVALID_YAML
+ ),
+ yamlException
+ );
+ } catch (Exception exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_CONFIGURATION_GENERIC_ERROR
+ )
+ );
+ }
+ }
+
+ /**
+ * Normalize a list of rule paths, removing all duplicates.
+ * @param paths The list of rule paths.
+ * @return A list of normalized paths, without duplicates.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static List<String> normalizePaths(List<String> paths)
+ throws AraraException {
+ paths.add(CommonUtils.buildPath(getApplicationPath(), "rules"));
+ Set<String> set = new LinkedHashSet<String>(paths);
+ List<String> result = new ArrayList<String>(set);
+ return result;
+ }
+
+ /**
+ * Normalize a list of file types, removing all duplicates.
+ * @param types The list of file types.
+ * @return A list of normalized file types, without duplicates.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static List<FileType> normalizeFileTypes(List<FileType> types)
+ throws AraraException {
+ types.addAll(getDefaultFileTypes());
+ Set<FileType> set = new LinkedHashSet<FileType>(types);
+ List<FileType> result = new ArrayList<FileType>(set);
+ return result;
+ }
+
+ /**
+ * Gets the canonical absolute application path.
+ * @return The string representation of the canonical absolute application
+ * path.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static String getApplicationPath() throws AraraException {
+ try {
+ String path = Arara.class.getProtectionDomain().
+ getCodeSource().getLocation().getPath();
+ path = URLDecoder.decode(path, "UTF-8");
+ path = new File(path).getParentFile().getPath();
+ return path;
+ } catch (UnsupportedEncodingException exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_GETAPPLICATIONPATH_ENCODING_EXCEPTION
+ ),
+ exception
+ );
+ }
+ }
+
+ /**
+ * Cleans the file name to avoid invalid entries.
+ * @param name The file name.
+ * @return A cleaned file name.
+ */
+ public static String cleanFileName(String name) {
+ String result = (new File(name)).getName().trim();
+ if (CommonUtils.checkEmptyString(result)) {
+ return "arara";
+ } else {
+ return result.trim();
+ }
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/DatabaseUtils.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/DatabaseUtils.java
new file mode 100644
index 00000000000..8861ff7e5ee
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/DatabaseUtils.java
@@ -0,0 +1,140 @@
+/**
+ * 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.utils;
+
+import com.github.cereda.arara.controller.ConfigurationController;
+import com.github.cereda.arara.controller.LanguageController;
+import com.github.cereda.arara.model.AraraException;
+import com.github.cereda.arara.model.Database;
+import com.github.cereda.arara.model.Messages;
+import java.io.File;
+import org.simpleframework.xml.Serializer;
+import org.simpleframework.xml.core.Persister;
+
+/**
+ * Implements database utilitary methods.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class DatabaseUtils {
+
+ // the application messages obtained from the
+ // language controller
+ private static final LanguageController messages =
+ LanguageController.getInstance();
+
+ /**
+ * Loads the XML file representing the database.
+ * @return The database object.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Database load() throws AraraException {
+ if (!exists()) {
+ return new Database();
+ } else {
+ File file = new File(getPath());
+ try {
+ Serializer serializer = new Persister();
+ Database database = serializer.read(Database.class, file);
+ return database;
+ } catch (Exception exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_LOAD_COULD_NOT_LOAD_XML,
+ file.getName()
+ ),
+ exception
+ );
+ }
+ }
+ }
+
+ /**
+ * Saves the database on a XML file.
+ * @param database The database object.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static void save(Database database) throws AraraException {
+ File file = new File(getPath());
+ try {
+ Serializer serializer = new Persister();
+ serializer.write(database, file);
+ } catch (Exception exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_SAVE_COULD_NOT_SAVE_XML,
+ file.getName()
+ ),
+ exception
+ );
+ }
+ }
+
+ /**
+ * Checks if the XML file representing the database exists.
+ * @return A boolean value indicating if the XML file exists.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ private static boolean exists() throws AraraException {
+ File file = new File(getPath());
+ return file.exists();
+ }
+
+ /**
+ * Gets the path to the XML file representing the database.
+ * @return A string representing the path to the XML file.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ private static String getPath() throws AraraException {
+ String name = ((String) ConfigurationController.
+ getInstance().get("execution.database.name")).concat(".xml");
+ String path = CommonUtils.getParentCanonicalPath(getReference());
+ return CommonUtils.buildPath(path, name);
+ }
+
+ /**
+ * Gets the main file reference.
+ * @return The main file reference.
+ */
+ private static File getReference() {
+ return (File) ConfigurationController.
+ getInstance().get("execution.reference");
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraTask.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/DirectiveAssembler.java
index cd8c8d674b0..d2dd5889967 100644
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/model/AraraTask.java
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/DirectiveAssembler.java
@@ -1,7 +1,6 @@
/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, Paulo Roberto Massa Cereda
+ * 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
@@ -31,79 +30,77 @@
* 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.
- * \endcond
- *
- * AraraTask: This class provides the model for representing the Arara tasks
- * based on the directives and rules. It's a plain old Java object.
*/
-// package definition
-package com.github.arara.model;
+package com.github.cereda.arara.utils;
-// needed import
-import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.List;
/**
- * Provides the model for representing the Arara tasks based on the directives
- * and rules.
- *
+ * Implements a directive assembler in order to help build a directive from a
+ * list of strings.
* @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 1.0
+ * @version 4.0
+ * @since 4.0
*/
-public class AraraTask {
+public class DirectiveAssembler {
- // the task name
- private String name;
- // a map to hold the tasks parameters
- private HashMap parameters;
+ // this variable holds a list of
+ // line numbers indicating which
+ // lines composed the resulting
+ // potential directive
+ private final List<Integer> lineNumbers;
+
+ // this variable holds the textual
+ // representation of the directive
+ private String text;
/**
- * Empty constructor.
+ * Constructor.
*/
- public AraraTask() {
+ public DirectiveAssembler() {
+ lineNumbers = new ArrayList<Integer>();
+ text = "";
}
- /**
- * Getter for name.
- *
- * @return The task name.
+ /**
+ * Checks if an append operation is allowed.
+ * @return A boolean value indicating if an append operation is allowed.
*/
- public String getName() {
-
- // return it
- return name;
+ public boolean isAppendAllowed() {
+ return !lineNumbers.isEmpty();
}
/**
- * Setter for name.
- *
- * @param name The task name.
+ * Adds a line number to the assembler.
+ * @param line An integer representing the line number.
*/
- public void setName(String name) {
-
- // set the name
- this.name = name;
+ public void addLineNumber(int line) {
+ lineNumbers.add(line);
}
/**
- * Getter for parameters.
- *
- * @return A map containing all the task parameters.
+ * Appends the provided line to the assembler text.
+ * @param line The provided line.
*/
- public HashMap getParameters() {
-
- // return it
- return parameters;
+ public void appendLine(String line) {
+ text = text.concat(" ").concat(line.trim());
}
/**
- * Setter for parameters.
- *
- * @param parameters The task parameters as a map.
+ * Gets the list of line numbers.
+ * @return The list of line numbers.
*/
- public void setParameters(HashMap parameters) {
+ public List<Integer> getLineNumbers() {
+ return lineNumbers;
+ }
- // set parameters
- this.parameters = parameters;
+ /**
+ * Gets the text.
+ * @return The assembler text, properly trimmed.
+ */
+ public String getText() {
+ return text.trim();
}
+
}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraResolver.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/DirectiveResolver.java
index 6ac807f6564..6ea18e31ba5 100644
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/AraraResolver.java
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/DirectiveResolver.java
@@ -1,7 +1,6 @@
/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, Paulo Roberto Massa Cereda
+ * 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
@@ -31,44 +30,30 @@
* 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.
- * \endcond
- *
- * AraraResolver: This class extends a Resolver class to disable mapping of
- * numeric times, as arara works better with text.
*/
-// package definition
-package com.github.arara.utils;
+package com.github.cereda.arara.utils;
-// needed import
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.resolver.Resolver;
/**
- * Extends a Resolver class to disable mapping of numeric times, as Arara works
- * better with text.
- *
+ * This class implements a directive resolver.
* @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 1.0
+ * @version 4.0
+ * @since 4.0
*/
-public class AraraResolver extends Resolver {
+public class DirectiveResolver extends Resolver {
/**
- * Adds the implicit resolvers to the Yaml mechanism.
+ * Adds implicit resolvers to the YAML model. For arara, I disabled
+ * boolean and numeric values to be automatically parsed. They still can
+ * be used through an explicit conversion in the rule context.
*/
@Override
protected void addImplicitResolvers() {
-
- // for merges
addImplicitResolver(Tag.MERGE, MERGE, "<");
-
- // for null values
addImplicitResolver(Tag.NULL, NULL, "~nN\0");
-
- // for empty values
addImplicitResolver(Tag.NULL, EMPTY, null);
-
- // for values
- addImplicitResolver(Tag.VALUE, VALUE, "=");
}
+
}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/DirectiveUtils.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/DirectiveUtils.java
new file mode 100644
index 00000000000..d4d2a88ac7e
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/DirectiveUtils.java
@@ -0,0 +1,438 @@
+/**
+ * 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.utils;
+
+import com.github.cereda.arara.controller.ConfigurationController;
+import com.github.cereda.arara.controller.LanguageController;
+import com.github.cereda.arara.model.AraraException;
+import com.github.cereda.arara.model.Conditional;
+import com.github.cereda.arara.model.Directive;
+import com.github.cereda.arara.model.Messages;
+import com.github.cereda.arara.model.Pair;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.yaml.snakeyaml.DumperOptions;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+import org.yaml.snakeyaml.error.MarkedYAMLException;
+import org.yaml.snakeyaml.representer.Representer;
+
+/**
+ * Implements directive utilitary methods.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class DirectiveUtils {
+
+ // the application messages obtained from the
+ // language controller
+ private static final LanguageController messages =
+ LanguageController.getInstance();
+
+ // get the logger context from a factory
+ private static final Logger logger =
+ LoggerFactory.getLogger(DirectiveUtils.class);
+
+ /**
+ * Extracts a list of directives from a list of strings.
+ * @param lines List of strings.
+ * @return A list of directives.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static List<Directive> extractDirectives(List<String> lines)
+ throws AraraException {
+
+ boolean header = (Boolean) ConfigurationController.
+ getInstance().get("execution.header");
+ String regex = (String) ConfigurationController.
+ getInstance().get("execution.file.pattern");
+ Pattern linecheck = Pattern.compile(regex);
+ regex = regex.concat((String) ConfigurationController.
+ getInstance().get("application.pattern"));
+ Pattern pattern = Pattern.compile(regex);
+ List<Pair<Integer, String>> pairs =
+ new ArrayList<Pair<Integer, String>>();
+ Matcher matcher;
+ for (int i = 0; i < lines.size(); i++) {
+ matcher = pattern.matcher(lines.get(i));
+ if (matcher.find()) {
+ String line = lines.get(i).substring(
+ matcher.end(),
+ lines.get(i).length()
+ );
+ Pair<Integer, String> pair =
+ new Pair<Integer, String>(i + 1, line);
+ pairs.add(pair);
+
+ logger.info(
+ messages.getMessage(
+ Messages.LOG_INFO_POTENTIAL_PATTERN_FOUND,
+ (i + 1),
+ line.trim()
+ )
+ );
+ }
+ else {
+ if (header) {
+ if (!checkLinePattern(linecheck, lines.get(i))) {
+ break;
+ }
+ }
+ }
+ }
+
+ if (pairs.isEmpty()) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_VALIDATE_NO_DIRECTIVES_FOUND
+ )
+ );
+ }
+
+ List<DirectiveAssembler> assemblers
+ = new ArrayList<DirectiveAssembler>();
+ DirectiveAssembler assembler = new DirectiveAssembler();
+ regex = (String) ConfigurationController.getInstance().
+ get("directives.linebreak.pattern");
+ pattern = Pattern.compile(regex);
+ for (Pair<Integer, String> pair : pairs) {
+ matcher = pattern.matcher(pair.getSecondElement());
+ if (matcher.find()) {
+ if (!assembler.isAppendAllowed()) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_VALIDATE_ORPHAN_LINEBREAK,
+ pair.getFirstElement()
+ )
+ );
+ } else {
+ assembler.addLineNumber(pair.getFirstElement());
+ assembler.appendLine(matcher.group(1));
+ }
+ } else {
+ if (assembler.isAppendAllowed()) {
+ assemblers.add(assembler);
+ }
+ assembler = new DirectiveAssembler();
+ assembler.addLineNumber(pair.getFirstElement());
+ assembler.appendLine(pair.getSecondElement());
+ }
+ }
+ if (assembler.isAppendAllowed()) {
+ assemblers.add(assembler);
+ }
+
+ List<Directive> directives = new ArrayList<Directive>();
+ for (DirectiveAssembler current : assemblers) {
+ directives.add(generateDirective(current));
+ }
+ return directives;
+
+ }
+
+ /**
+ * Generates a directive from a directive assembler.
+ * @param assembler The directive assembler.
+ * @return The corresponding directive.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Directive generateDirective(DirectiveAssembler assembler)
+ throws AraraException {
+ String regex = (String) ConfigurationController.getInstance().
+ get("directives.pattern");
+ Pattern pattern = Pattern.compile(regex);
+ Matcher matcher = pattern.matcher(assembler.getText());
+ if (matcher.find()) {
+ Directive directive = new Directive();
+ directive.setIdentifier(matcher.group(1));
+ directive.setParameters(
+ getParameters(matcher.group(3), assembler.getLineNumbers())
+ );
+ Conditional conditional = new Conditional();
+ conditional.setType(getType(matcher.group(5)));
+ conditional.setCondition(getCondition(matcher.group(6)));
+ directive.setConditional(conditional);
+ directive.setLineNumbers(assembler.getLineNumbers());
+
+ logger.info(
+ messages.getMessage(
+ Messages.LOG_INFO_POTENTIAL_DIRECTIVE_FOUND,
+ directive
+ )
+ );
+
+ return directive;
+ } else {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_VALIDATE_INVALID_DIRECTIVE_FORMAT,
+ CommonUtils.getCollectionElements(
+ assembler.getLineNumbers(),
+ "(",
+ ")",
+ ", "
+ )
+ )
+ );
+ }
+ }
+
+ /**
+ * Gets the conditional type based on the input string.
+ * @param text The input string.
+ * @return The conditional type.
+ */
+ private static Conditional.ConditionalType getType(String text) {
+ if (text == null) {
+ return Conditional.ConditionalType.NONE;
+ } else {
+ if (text.equals("if")) {
+ return Conditional.ConditionalType.IF;
+ } else {
+ if (text.equals("while")) {
+ return Conditional.ConditionalType.WHILE;
+ } else {
+ if (text.equals("until")) {
+ return Conditional.ConditionalType.UNTIL;
+ } else {
+ return Conditional.ConditionalType.UNLESS;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Gets the condition from the input string.
+ * @param text The input string.
+ * @return A string representing the condition.
+ */
+ private static String getCondition(String text) {
+ return text == null ? "" : text;
+ }
+
+ /**
+ * Gets the parameters from the input string.
+ * @param text The input string.
+ * @param numbers The list of line numbers.
+ * @return A map containing the directive parameters.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ private static Map<String, Object> getParameters(String text,
+ List<Integer> numbers) throws AraraException {
+
+ if (text == null) {
+ return new HashMap<String, Object>();
+ }
+
+ Yaml yaml = new Yaml(
+ new Constructor(),
+ new Representer(),
+ new DumperOptions(),
+ new DirectiveResolver()
+ );
+ try {
+ @SuppressWarnings("unchecked")
+ HashMap<String, Object> map = yaml.loadAs(text, HashMap.class);
+ return map;
+ } catch (MarkedYAMLException exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_VALIDATE_YAML_EXCEPTION,
+ CommonUtils.getCollectionElements(
+ numbers,
+ "(",
+ ")",
+ ", "
+ )
+ ),
+ exception
+ );
+ }
+ }
+
+ /**
+ * Validates the list of directives, returning a new list.
+ * @param directives The list of directives.
+ * @return A new list of directives.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static List<Directive> validate(List<Directive> directives)
+ throws AraraException {
+
+ ArrayList<Directive> result = new ArrayList<Directive>();
+ for (Directive directive : directives) {
+ Map<String, Object> parameters = directive.getParameters();
+
+ if (parameters.containsKey("file")) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_VALIDATE_FILE_IS_RESERVED,
+ CommonUtils.getCollectionElements(
+ directive.getLineNumbers(),
+ "(",
+ ")",
+ ", "
+ )
+ )
+ );
+ }
+
+ if (parameters.containsKey("reference")) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_VALIDATE_REFERENCE_IS_RESERVED,
+ CommonUtils.getCollectionElements(
+ directive.getLineNumbers(),
+ "(",
+ ")",
+ ", "
+ )
+ )
+ );
+ }
+
+ if (parameters.containsKey("files")) {
+
+ Object holder = parameters.get("files");
+ if (holder instanceof List) {
+ @SuppressWarnings("unchecked")
+ List<Object> files = (List<Object>) holder;
+ parameters.remove("files");
+ if (files.isEmpty()) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_VALIDATE_EMPTY_FILES_LIST,
+ CommonUtils.getCollectionElements(
+ directive.getLineNumbers(),
+ "(",
+ ")",
+ ", "
+ )
+ )
+ );
+ }
+ for (Object file : files) {
+ Map<String, Object> map = new HashMap<String, Object>();
+ for (String key : parameters.keySet()) {
+ map.put(key, parameters.get(key));
+ }
+ File representation = CommonUtils.
+ getCanonicalFile(String.valueOf(file));
+
+ map.put("reference", representation);
+ map.put("file", representation.getName());
+
+ Directive addition = new Directive();
+ Conditional conditional = new Conditional();
+ conditional.setCondition(directive.getConditional().
+ getCondition()
+ );
+ conditional.setType(directive.getConditional().
+ getType()
+ );
+ addition.setIdentifier(directive.getIdentifier());
+ addition.setConditional(conditional);
+ addition.setParameters(map);
+ addition.setLineNumbers(directive.getLineNumbers());
+ result.add(addition);
+ }
+ } else {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_VALIDATE_FILES_IS_NOT_A_LIST,
+ CommonUtils.getCollectionElements(
+ directive.getLineNumbers(),
+ "(",
+ ")",
+ ", "
+ )
+ )
+ );
+ }
+ } else {
+ File representation = (File) ConfigurationController.
+ getInstance().get("execution.reference");
+ parameters.put("file", representation.getName());
+ parameters.put("reference", representation);
+ directive.setParameters(parameters);
+ result.add(directive);
+ }
+ }
+
+ logger.info(
+ messages.getMessage(
+ Messages.LOG_INFO_VALIDATED_DIRECTIVES
+ )
+ );
+ logger.info(DisplayUtils.displayOutputSeparator(
+ messages.getMessage(
+ Messages.LOG_INFO_DIRECTIVES_BLOCK
+ )
+ ));
+ for (Directive directive : result) {
+ logger.info(directive.toString());
+ }
+
+ logger.info(DisplayUtils.displaySeparator());
+
+ return result;
+ }
+
+ /**
+ * Checks if the provided line contains the corresponding pattern, based on
+ * the file type, or an empty line.
+ * @param pattern Pattern to be matched, based on the file type.
+ * @param line Provided line.
+ * @return Logical value indicating if the provided line contains the
+ * corresponding pattern, based on the file type, or an empty line.
+ */
+ private static boolean checkLinePattern(Pattern pattern, String line) {
+ return CommonUtils.checkEmptyString(line.trim()) ||
+ pattern.matcher(line).find();
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/DisplayUtils.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/DisplayUtils.java
new file mode 100644
index 00000000000..879119e60e2
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/DisplayUtils.java
@@ -0,0 +1,502 @@
+/**
+ * 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.utils;
+
+import com.github.cereda.arara.controller.ConfigurationController;
+import com.github.cereda.arara.controller.LanguageController;
+import com.github.cereda.arara.model.AraraException;
+import com.github.cereda.arara.model.Conditional;
+import com.github.cereda.arara.model.Messages;
+import com.github.cereda.arara.model.StopWatch;
+import java.io.File;
+import java.util.List;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.WordUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implements display utilitary methods.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class DisplayUtils {
+
+ // the application messages obtained from the
+ // language controller
+ private static final LanguageController messages =
+ LanguageController.getInstance();
+
+ // get the logger context from a factory
+ private static final Logger logger =
+ LoggerFactory.getLogger(DisplayUtils.class);
+
+ /**
+ * Displays the short version of the current entry in the terminal.
+ * @param name Rule name.
+ * @param task Task name.
+ */
+ private static void buildShortEntry(String name, String task) {
+ int width = getWidth();
+ int result = getLongestMatch();
+ if (result >= width) {
+ result = 10;
+ }
+ int space = width - result - 1;
+ StringBuilder entry = new StringBuilder();
+ entry.append("(").append(name).append(") ");
+ entry.append(task).append(" ");
+ String line = StringUtils.abbreviate(entry.toString(), space - 4);
+ entry = new StringBuilder();
+ entry.append(StringUtils.rightPad(line, space, ".")).append(" ");
+ System.out.print(entry);
+ }
+
+ /**
+ * Displays the short version of the current entry result in the terminal.
+ * @param value The boolean value to be displayed.
+ */
+ private static void buildShortResult(boolean value) {
+ int result = getLongestMatch();
+ System.out.println(StringUtils.leftPad(getResult(value), result));
+ }
+
+ /**
+ * Displays the current entry result in the terminal.
+ * @param value The boolean value to be displayed.
+ */
+ public static void printEntryResult(boolean value) {
+ ConfigurationController.getInstance().put("display.line", false);
+ ConfigurationController.getInstance().put("display.result", true);
+ ConfigurationController.getInstance()
+ .put("execution.status", value ? 0 : 1);
+ logger.info(
+ messages.getMessage(
+ Messages.LOG_INFO_TASK_RESULT
+ ).concat(" ").concat(getResult(value))
+ );
+ if (!isDryRunMode()) {
+ if (!isVerboseMode()) {
+ buildShortResult(value);
+ } else {
+ buildLongResult(value);
+ }
+ }
+ }
+
+ /**
+ * Displays a long version of the current entry result in the terminal.
+ * @param value The boolean value to be displayed
+ */
+ private static void buildLongResult(boolean value) {
+ int width = getWidth();
+ System.out.println("\n".concat(StringUtils.leftPad(
+ " ".concat(getResult(value)), width, "-"
+ )));
+ }
+
+ /**
+ * Displays the current entry in the terminal.
+ * @param name The rule name.
+ * @param task The task name.
+ */
+ public static void printEntry(String name, String task) {
+ logger.info(
+ messages.getMessage(
+ Messages.LOG_INFO_INTERPRET_TASK,
+ task,
+ name
+ )
+ );
+ ConfigurationController.getInstance().put("display.line", true);
+ ConfigurationController.getInstance().put("display.result", false);
+ if (!isDryRunMode()) {
+ if (!isVerboseMode()) {
+ buildShortEntry(name, task);
+ } else {
+ buildLongEntry(name, task);
+ }
+ } else {
+ buildDryRunEntry(name, task);
+ }
+ }
+
+ /**
+ * Gets the length of the longest result match.
+ * @return An integer value representing the longest result match.
+ */
+ private static int getLongestMatch() {
+ String[] values = new String[]{
+ messages.getMessage(Messages.INFO_LABEL_ON_SUCCESS),
+ messages.getMessage(Messages.INFO_LABEL_ON_FAILURE),
+ messages.getMessage(Messages.INFO_LABEL_ON_ERROR)
+ };
+ int max = values[0].length();
+ for (String value : values) {
+ if (max < value.length()) {
+ max = value.length();
+ }
+ }
+ return max;
+ }
+
+ /**
+ * Displays a long version of the current entry in the terminal.
+ * @param name Rule name.
+ * @param task Task name.
+ */
+ private static void buildLongEntry(String name, String task) {
+ if (ConfigurationController.getInstance().contains("display.rolling")) {
+ addNewLine();
+ } else {
+ ConfigurationController.getInstance().put("display.rolling", true);
+ }
+ StringBuilder line = new StringBuilder();
+ line.append("(").append(name).append(") ");
+ line.append(task);
+ System.out.println(displaySeparator());
+ System.out.println(StringUtils.abbreviate(line.toString(), getWidth()));
+ System.out.println(displaySeparator());
+ }
+
+ /**
+ * Displays a dry-run version of the current entry in the terminal.
+ * @param name The rule name.
+ * @param task The task name.
+ */
+ private static void buildDryRunEntry(String name, String task) {
+ if (ConfigurationController.getInstance().contains("display.rolling")) {
+ addNewLine();
+ } else {
+ ConfigurationController.getInstance().put("display.rolling", true);
+ }
+ StringBuilder line = new StringBuilder();
+ line.append("[DR] (").append(name).append(") ");
+ line.append(task);
+ System.out.println(StringUtils.abbreviate(line.toString(), getWidth()));
+ System.out.println(displaySeparator());
+ }
+
+ /**
+ * Displays the exception in the terminal.
+ * @param exception The exception object.
+ */
+ public static void printException(AraraException exception) {
+ ConfigurationController.getInstance().put("display.exception", true);
+ ConfigurationController.getInstance().put("execution.status", 2);
+ boolean display = false;
+ if (ConfigurationController.getInstance().contains("display.line")) {
+ display = (Boolean) ConfigurationController.
+ getInstance().get("display.line");
+ }
+ if (ConfigurationController.getInstance().contains("display.result")) {
+ if (((Boolean) ConfigurationController.
+ getInstance().get("display.result")) == true) {
+ addNewLine();
+ }
+ }
+ if (display) {
+ if (!isDryRunMode()) {
+ if (!isVerboseMode()) {
+ buildShortError();
+ } else {
+ buildLongError();
+ }
+ addNewLine();
+ }
+ }
+ String text = exception.hasException() ?
+ exception.getMessage().concat(" ").concat(
+ messages.getMessage(
+ Messages.INFO_DISPLAY_EXCEPTION_MORE_DETAILS
+ )
+ )
+ : exception.getMessage();
+ logger.error(text);
+ wrapText(text);
+ if (exception.hasException()) {
+ addNewLine();
+ displayDetailsLine();
+ String details = exception.getException().getMessage();
+ logger.error(details);
+ wrapText(details);
+ }
+ }
+
+ /**
+ * Gets the string representation of the provided boolean value.
+ * @param value The boolean value.
+ * @return The string representation.
+ */
+ private static String getResult(boolean value) {
+ return (value == true ?
+ messages.getMessage(
+ Messages.INFO_LABEL_ON_SUCCESS
+ )
+ : messages.getMessage(Messages.INFO_LABEL_ON_FAILURE));
+ }
+
+ /**
+ * Displays the short version of an error in the terminal.
+ */
+ private static void buildShortError() {
+ int result = getLongestMatch();
+ System.out.println(StringUtils.leftPad(
+ messages.getMessage(
+ Messages.INFO_LABEL_ON_ERROR
+ ),
+ result
+ ));
+ }
+
+ /**
+ * Displays the long version of an error in the terminal.
+ */
+ private static void buildLongError() {
+ String line = StringUtils.leftPad(
+ " ".concat(messages.getMessage(Messages.INFO_LABEL_ON_ERROR)),
+ getWidth(), "-");
+ System.out.println(line);
+ }
+
+ /**
+ * Gets the default terminal width defined in the settings.
+ * @return An integer representing the terminal width.
+ */
+ private static int getWidth() {
+ return (Integer) ConfigurationController.
+ getInstance().get("application.width");
+ }
+
+ /**
+ * Displays the provided text wrapped nicely according to the default
+ * terminal width.
+ * @param text The text to be displayed.
+ */
+ public static void wrapText(String text) {
+ System.out.println(WordUtils.wrap(text, getWidth()));
+ }
+
+ /**
+ * Checks if the execution is in dry-run mode.
+ * @return A boolean value indicating if the execution is in dry-run mode.
+ */
+ private static boolean isDryRunMode() {
+ return (Boolean) ConfigurationController.
+ getInstance().get("execution.dryrun");
+ }
+
+ /**
+ * Checks if the execution is in verbose mode.
+ * @return A boolean value indicating if the execution is in verbose mode.
+ */
+ private static boolean isVerboseMode() {
+ return (Boolean) ConfigurationController.
+ getInstance().get("execution.verbose");
+ }
+
+ /**
+ * Displays the rule authors in the terminal.
+ * @param authors The list of authors.
+ */
+ public static void printAuthors(List<String> authors) {
+ StringBuilder line = new StringBuilder();
+ line.append(authors.size() == 1 ?
+ messages.getMessage(Messages.INFO_LABEL_AUTHOR)
+ : messages.getMessage(Messages.INFO_LABEL_AUTHORS));
+ String text = authors.isEmpty() ?
+ messages.getMessage(Messages.INFO_LABEL_NO_AUTHORS)
+ : CommonUtils.getCollectionElements(
+ CommonUtils.trimSpaces(authors), "", "", ", ");
+ line.append(" ").append(text);
+ wrapText(line.toString());
+ }
+
+ /**
+ * Displays the current conditional in the terminal.
+ * @param conditional The conditional object.
+ */
+ public static void printConditional(Conditional conditional) {
+ if (conditional.getType() != Conditional.ConditionalType.NONE) {
+ StringBuilder line = new StringBuilder();
+ line.append(messages.getMessage(Messages.INFO_LABEL_CONDITIONAL));
+ line.append(" (");
+ line.append(String.valueOf(conditional.getType()));
+ line.append(") ").append(conditional.getCondition());
+ wrapText(line.toString());
+ }
+ }
+
+ /**
+ * Displays the file information in the terminal.
+ */
+ public static void printFileInformation() {
+ File file = (File) ConfigurationController.
+ getInstance().get("execution.reference");
+ String version = (String) ConfigurationController.
+ getInstance().get("application.version");
+ String revision = (String) ConfigurationController.
+ getInstance().get("application.revision");
+ String line = messages.getMessage(
+ Messages.INFO_DISPLAY_FILE_INFORMATION,
+ file.getName(),
+ CommonUtils.calculateFileSize(file),
+ CommonUtils.getLastModifiedInformation(file)
+ );
+ logger.info(messages.getMessage(
+ Messages.LOG_INFO_WELCOME_MESSAGE,
+ version,
+ revision
+ ));
+ logger.info(displaySeparator());
+ logger.info(String.format("::: arara @ %s",
+ getApplicationPath()
+ ));
+ logger.info(String.format("::: Java %s, %s",
+ CommonUtils.getSystemProperty("java.version",
+ "[unknown version]"),
+ CommonUtils.getSystemProperty("java.vendor",
+ "[unknown vendor]")
+ ));
+ logger.info(String.format("::: %s",
+ CommonUtils.getSystemProperty("java.home",
+ "[unknown location]")
+ ));
+ logger.info(String.format("::: %s, %s, %s",
+ CommonUtils.getSystemProperty("os.name",
+ "[unknown OS name]"),
+ CommonUtils.getSystemProperty("os.arch",
+ "[unknown OS arch]"),
+ CommonUtils.getSystemProperty("os.version",
+ "[unknown OS version]")
+ ));
+ logger.info(String.format("::: user.home @ %s",
+ CommonUtils.getSystemProperty("user.home",
+ "[unknown user's home directory]")
+ ));
+ logger.info(String.format("::: user.dir @ %s",
+ CommonUtils.getSystemProperty("user.dir",
+ "[unknown user's working directory]")
+ ));
+ logger.info(String.format("::: CF @ %s",
+ (String) ConfigurationController.
+ getInstance().get("execution.configuration.name")
+ ));
+ logger.info(displaySeparator());
+ logger.info(line);
+ wrapText(line);
+ addNewLine();
+ }
+
+ /**
+ * Displays the elapsed time in the terminal.
+ */
+ public static void printTime() {
+ if (ConfigurationController.getInstance().contains("display.time")) {
+ if ((ConfigurationController.getInstance().contains("display.line"))
+ || (ConfigurationController.getInstance().
+ contains("display.exception"))) {
+ addNewLine();
+ }
+ String text = messages.getMessage(
+ Messages.INFO_DISPLAY_EXECUTION_TIME, StopWatch.getTime());
+ logger.info(text);
+ wrapText(text);
+ }
+ }
+
+ /**
+ * Displays the application logo in the terminal.
+ */
+ public static void printLogo() {
+ StringBuilder builder = new StringBuilder();
+ builder.append(" __ _ _ __ __ _ _ __ __ _ ").append("\n");
+ builder.append(" / _` | '__/ _` | '__/ _` |").append("\n");
+ builder.append("| (_| | | | (_| | | | (_| |").append("\n");
+ builder.append(" \\__,_|_| \\__,_|_| \\__,_|");
+ System.out.println(builder.toString());
+ addNewLine();
+ }
+
+ /**
+ * Adds a new line in the terminal.
+ */
+ private static void addNewLine() {
+ System.out.println();
+ }
+
+ /**
+ * Displays a line containing details.
+ */
+ private static void displayDetailsLine() {
+ String line = messages.getMessage(
+ Messages.INFO_LABEL_ON_DETAILS).concat(" ");
+ line = StringUtils.rightPad(
+ StringUtils.abbreviate(line, getWidth()), getWidth(), "-");
+ System.out.println(line);
+ }
+
+ /**
+ * Gets the output separator with the provided text.
+ * @param message The provided text.
+ * @return A string containing the output separator with the provided text.
+ */
+ public static String displayOutputSeparator(String message) {
+ return StringUtils.center(" ".concat(message).concat(" "),
+ getWidth(), "-");
+ }
+
+ /**
+ * Gets the line separator.
+ * @return A string containing the line separator.
+ */
+ public static String displaySeparator() {
+ return StringUtils.repeat("-", getWidth());
+ }
+
+ /**
+ * Gets the application path.
+ * @return A string containing the application path.
+ */
+ private static String getApplicationPath() {
+ try {
+ return ConfigurationUtils.getApplicationPath();
+ }
+ catch (AraraException ae) {
+ return "[unknown application path]";
+ }
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/FileHandlingUtils.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/FileHandlingUtils.java
new file mode 100644
index 00000000000..9f56c92f5d9
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/FileHandlingUtils.java
@@ -0,0 +1,124 @@
+/**
+ * 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.utils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.io.FileUtils;
+
+/**
+ * Implements file handling utilitary methods.
+ *
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class FileHandlingUtils {
+
+ /**
+ * Writes the string to a file, using UTF-8 as default encoding.
+ * @param file The file.
+ * @param text The string to be written.
+ * @param append A flag whether to append the content.
+ * @return A logical value indicating whether it was successful.
+ */
+ public static boolean writeToFile(File file, String text, boolean append) {
+ try {
+
+ // try to write the provided
+ // string to the file, with
+ // UTF-8 as encoding
+ FileUtils.writeStringToFile(file, text, "UTF-8", append);
+ return true;
+
+ } catch (IOException nothandled) {
+
+ // if something bad happens,
+ // gracefully fallback to
+ // reporting the failure
+ return false;
+ }
+ }
+
+ /**
+ * Writes the string list to a file, using UTF-8 as default encoding.
+ * @param file The file.
+ * @param lines The string list to be written.
+ * @param append A flag whether to append the content.
+ * @return A logical value indicating whether it was successful.
+ */
+ public static boolean writeToFile(File file, List<String> lines,
+ boolean append) {
+ try {
+
+ // try to write the provided
+ // string lists to the file,
+ // with UTF-8 as encoding
+ FileUtils.writeLines(file, "UTF-8", lines, append);
+ return true;
+
+ } catch (IOException nothandled) {
+
+ // if something bad happens,
+ // gracefully fallback to
+ // reporting the failure
+ return false;
+ }
+ }
+
+ /**
+ * Reads the provided file into a list of strings.
+ * @param file The file.
+ * @return A list of strings.
+ */
+ public static List<String> readFromFile(File file) {
+ try {
+
+ // returns the contents of
+ // the provided file as
+ // a list of strings
+ return FileUtils.readLines(file, "UTF-8");
+
+ } catch (IOException nothandled) {
+
+ // if something bad happens,
+ // gracefully fallback to
+ // an empty file list
+ return new ArrayList<String>();
+ }
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/FileSearchingUtils.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/FileSearchingUtils.java
new file mode 100644
index 00000000000..473674cbc50
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/FileSearchingUtils.java
@@ -0,0 +1,117 @@
+/**
+ * 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.utils;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.filefilter.FalseFileFilter;
+import org.apache.commons.io.filefilter.TrueFileFilter;
+import org.apache.commons.io.filefilter.WildcardFileFilter;
+
+/**
+ * Implements file searching utilitary methods.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class FileSearchingUtils {
+
+ /**
+ * List all files from the provided directory according to the list of
+ * extensions. The leading dot must be omitted, unless it is part of the
+ * extension.
+ * @param directory The provided directory.
+ * @param extensions The list of extensions.
+ * @param recursive A flag indicating whether the search is recursive.
+ * @return A list of files.
+ */
+ public static List<File> listFilesByExtensions(File directory,
+ List<String> extensions, boolean recursive) {
+ try {
+
+ // convert the provided extension
+ // list to an extension array
+ String[] array = new String[extensions.size()];
+ array = extensions.toArray(array);
+
+ // return the result of the
+ // provided search
+ return new ArrayList<File>(
+ FileUtils.listFiles(directory, array, recursive)
+ );
+ } catch (Exception nothandled) {
+
+ // if something bad happens,
+ // gracefully fallback to
+ // an empty file list
+ return new ArrayList<File>();
+ }
+ }
+
+ /**
+ * List all files from the provided directory matching the list of file
+ * name patterns. Such list can contain wildcards.
+ * @param directory The provided directory.
+ * @param patterns The list of file name patterns.
+ * @param recursive A flag indicating whether the search is recursive.
+ * @return A list of files.
+ */
+ public static List<File> listFilesByPatterns(File directory,
+ List<String> patterns, boolean recursive) {
+ try {
+
+ // return the result of the provided
+ // search, with the wildcard filter
+ // and a potential recursive search
+ return new ArrayList<File>(
+ FileUtils.listFiles(
+ directory,
+ new WildcardFileFilter(patterns),
+ recursive
+ ? TrueFileFilter.INSTANCE
+ : FalseFileFilter.INSTANCE
+ )
+ );
+ } catch (Exception nothandled) {
+
+ // if something bad happens,
+ // gracefully fallback to
+ // an empty file list
+ return new ArrayList<File>();
+ }
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/InterpreterUtils.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/InterpreterUtils.java
new file mode 100644
index 00000000000..978cb07374f
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/InterpreterUtils.java
@@ -0,0 +1,257 @@
+/**
+ * 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.utils;
+
+import com.github.cereda.arara.controller.ConfigurationController;
+import com.github.cereda.arara.controller.LanguageController;
+import com.github.cereda.arara.model.AraraException;
+import com.github.cereda.arara.model.Argument;
+import com.github.cereda.arara.model.Command;
+import com.github.cereda.arara.model.Conditional;
+import com.github.cereda.arara.model.Messages;
+import com.github.cereda.arara.model.Rule;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.zeroturnaround.exec.InvalidExitValueException;
+import org.zeroturnaround.exec.ProcessExecutor;
+import org.zeroturnaround.exec.listener.ShutdownHookProcessDestroyer;
+
+/**
+ * Implements interpreter utilitary methods.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class InterpreterUtils {
+
+ // the application messages obtained from the
+ // language controller
+ private static final LanguageController messages =
+ LanguageController.getInstance();
+
+ // get the logger context from a factory
+ private static final Logger logger =
+ LoggerFactory.getLogger(InterpreterUtils.class);
+
+ /**
+ * Gets a list of all rule arguments.
+ * @param rule The provided rule.
+ * @return A list of strings containing all rule arguments.
+ */
+ public static List<String> getRuleArguments(Rule rule) {
+ Collection<String> result = CollectionUtils.collect(
+ rule.getArguments(), new Transformer<Argument, String>() {
+ public String transform(Argument input) {
+ return input.getIdentifier();
+ }
+ });
+ return new ArrayList<String>(result);
+ }
+
+ /**
+ * Checks if the current conditional has a prior evaluation.
+ * @param conditional The current conditional object.
+ * @return A boolean value indicating if the current conditional has a prior
+ * evaluation.
+ */
+ public static boolean runPriorEvaluation(Conditional conditional) {
+ if (((Boolean) ConfigurationController.getInstance().
+ get("execution.dryrun")) == true) {
+ return false;
+ }
+ switch (conditional.getType()) {
+ case IF:
+ case WHILE:
+ case UNLESS:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Runs the command in the underlying operating system.
+ * @param command An object representing the command.
+ * @return An integer value representing the exit code.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static int run(Object command) throws AraraException {
+ boolean verbose = (Boolean) ConfigurationController.
+ getInstance().get("execution.verbose");
+ boolean timeout = (Boolean) ConfigurationController.
+ getInstance().get("execution.timeout");
+ long value = (Long) ConfigurationController.
+ getInstance().get("execution.timeout.value");
+ TimeUnit unit = (TimeUnit) ConfigurationController.
+ getInstance().get("execution.timeout.unit");
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ ProcessExecutor executor = new ProcessExecutor();
+ if (CommonUtils.checkClass(Command.class, command)) {
+ executor = executor.command(((Command) command).getElements());
+ if (((Command) command).hasWorkingDirectory()) {
+ executor = executor.directory(
+ ((Command) command).getWorkingDirectory()
+ );
+ }
+ } else {
+ executor = executor.commandSplit((String) command);
+ }
+ if (timeout) {
+ if (value == 0) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_RUN_TIMEOUT_INVALID_RANGE
+ )
+ );
+ }
+ executor = executor.timeout(value, unit);
+ }
+ TeeOutputStream tee;
+ if (verbose) {
+ tee = new TeeOutputStream(System.out, buffer);
+ executor = executor.redirectInput(System.in);
+ } else {
+ tee = new TeeOutputStream(buffer);
+ }
+ executor = executor.redirectOutput(tee).redirectError(tee);
+ ShutdownHookProcessDestroyer hook = new ShutdownHookProcessDestroyer();
+ executor = executor.addDestroyer(hook);
+ try {
+ int exit = executor.execute().getExitValue();
+ logger.info(DisplayUtils.displayOutputSeparator(
+ messages.getMessage(
+ Messages.LOG_INFO_BEGIN_BUFFER
+ )
+ ));
+ logger.info(buffer.toString());
+ logger.info(DisplayUtils.displayOutputSeparator(
+ messages.getMessage(
+ Messages.LOG_INFO_END_BUFFER
+ )
+ ));
+ return exit;
+ } catch (IOException ioexception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_RUN_IO_EXCEPTION
+ ),
+ ioexception
+ );
+ } catch (InterruptedException iexception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_RUN_INTERRUPTED_EXCEPTION
+ ),
+ iexception
+ );
+ } catch (InvalidExitValueException ievexception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_RUN_INVALID_EXIT_VALUE_EXCEPTION
+ ),
+ ievexception
+ );
+ } catch (TimeoutException texception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_RUN_TIMEOUT_EXCEPTION
+ ),
+ texception
+ );
+ } catch (Exception exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_RUN_GENERIC_EXCEPTION
+ ),
+ exception
+ );
+ }
+ }
+
+ /**
+ * Builds the rule path based on the rule name and returns the corresponding
+ * file location.
+ * @param name The rule name.
+ * @return The rule file.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static File buildRulePath(String name) throws AraraException {
+ @SuppressWarnings("unchecked")
+ List<String> paths = (List<String>) ConfigurationController.
+ getInstance().get("execution.rule.paths");
+ for (String path : paths) {
+ File location = new File(construct(path, name));
+ if (location.exists()) {
+ return location;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Constructs the path given the current path and the rule name.
+ * @param path The current path.
+ * @param name The rule name.
+ * @return The constructed path.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static String construct(String path, String name)
+ throws AraraException {
+ name = name.concat(".yaml");
+ File location = new File(path);
+ if (location.isAbsolute()) {
+ return CommonUtils.buildPath(path, name);
+ } else {
+ File reference = (File) ConfigurationController.
+ getInstance().get("execution.reference");
+ String parent = CommonUtils.buildPath(
+ CommonUtils.getParentCanonicalPath(reference), path);
+ return CommonUtils.buildPath(parent, name);
+ }
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/MessageUtils.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/MessageUtils.java
new file mode 100644
index 00000000000..52a5d095a8e
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/MessageUtils.java
@@ -0,0 +1,313 @@
+/**
+ * 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.utils;
+
+import com.github.cereda.arara.controller.ConfigurationController;
+import javax.swing.JOptionPane;
+import javax.swing.UIManager;
+
+/**
+ * Implements utilitary methods for displaying messages.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class MessageUtils {
+
+ // holds the default width for the
+ // message body, in pixels
+ private static final int WIDTH = 250;
+
+ // let's start the UI manager and set
+ // the default look and feel to be as
+ // close as possible to the system
+ static {
+
+ // get the current look and feel
+ String laf = (String) ConfigurationController.
+ getInstance().get("ui.lookandfeel");
+
+ // check if one is actually set
+ if (!laf.equals("none")) {
+
+ // use a special keyword to indicate
+ // the use of a system look and feel
+ if (laf.equals("system")) {
+ laf = UIManager.getSystemLookAndFeelClassName();
+ }
+
+ // let's try it, in case it fails,
+ // rely to the default look and feel
+ try {
+
+ // get the system look and feel name
+ // and try to set it as default
+ UIManager.setLookAndFeel(laf);
+ }
+ catch (Exception exception) {
+ // quack, quack, quack
+ }
+
+ }
+ }
+
+ /**
+ * Normalizes the icon type to one of the five available icons.
+ * @param value An integer value.
+ * @return The normalized integer value.
+ */
+ private static int normalizeIconType(int value) {
+
+ // do the normalization according to the available
+ // icons in the underlying message implementation
+ switch (value) {
+ case 1:
+ value = JOptionPane.ERROR_MESSAGE;
+ break;
+ case 2:
+ value = JOptionPane.INFORMATION_MESSAGE;
+ break;
+ case 3:
+ value = JOptionPane.WARNING_MESSAGE;
+ break;
+ case 4:
+ value = JOptionPane.QUESTION_MESSAGE;
+ break;
+ default:
+ value = JOptionPane.PLAIN_MESSAGE;
+ break;
+ }
+ return value;
+ }
+
+ /**
+ * Normalizes the message width, so only valid nonzero values are accepted.
+ * @param value An integer value corresponding to the message width.
+ * @return The normalized width.
+ */
+ private static int normalizeMessageWidth(int value) {
+ return (value > 0 ? value : WIDTH);
+ }
+
+ /**
+ * Shows the message.
+ * @param width Integer value, in pixels.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ */
+ public static void showMessage(int width, int type,
+ String title, String text) {
+
+ // effectively shows the message based
+ // on the provided parameters
+ JOptionPane.showMessageDialog(
+ null,
+ String.format(
+ "<html><body style=\"width:%dpx\">%s</body></html>",
+ normalizeMessageWidth(width),
+ text
+ ),
+ title,
+ normalizeIconType(type)
+ );
+ }
+
+ /**
+ * Shows the message. It relies on the default width.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ */
+ public static void showMessage(int type, String title, String text) {
+ showMessage(WIDTH, type, title, text);
+ }
+
+ /**
+ * Shows a message with options presented as an array of buttons.
+ * @param width Integer value, in pixels.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ * @param buttons An array of objects to be presented as buttons.
+ * @return The index of the selected button, starting from 1.
+ */
+ public static int showOptions(int width, int type, String title,
+ String text, Object... buttons) {
+
+ // returns the index of the selected button,
+ // zero if nothing is selected
+ return JOptionPane.showOptionDialog(
+ null,
+ String.format(
+ "<html><body style=\"width:%dpx\">%s</body></html>",
+ normalizeMessageWidth(width),
+ text
+ ),
+ title,
+ JOptionPane.DEFAULT_OPTION,
+ normalizeIconType(type),
+ null,
+ buttons,
+ buttons[0]
+ ) + 1;
+ }
+
+ /**
+ * Shows a message with options presented as an array of buttons. It relies
+ * on the default width.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ * @param buttons An array of objects to be presented as buttons.
+ * @return The index of the selected button, starting from 1.
+ */
+ public static int showOptions(int type, String title,
+ String text, Object... buttons) {
+ return showOptions(WIDTH, type, title, text, buttons);
+ }
+
+ /**
+ * Shows a message with a text input.
+ * @param width Integer value, in pixels.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ * @return The string representing the input text.
+ */
+ public static String showInput(int width, int type,
+ String title, String text) {
+
+ // get the string from the
+ // input text, if any
+ String input = JOptionPane.showInputDialog(
+ null,
+ String.format(
+ "<html><body style=\"width:%dpx\">%s</body></html>",
+ normalizeMessageWidth(width),
+ text
+ ),
+ title,
+ normalizeIconType(type)
+ );
+
+ // if the input is not null, that is,
+ // the user actually typed something
+ if (input != null) {
+
+ // return the trimmed string
+ return input.trim();
+ }
+
+ // nothing was typed, so let's
+ // return an empty string
+ return "";
+ }
+
+ /**
+ * Shows a message with a text input. It relies on the default width.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ * @return The string representing the input text.
+ */
+ public static String showInput(int type, String title, String text) {
+ return showInput(WIDTH, type, title, text);
+ }
+
+ /**
+ * Shows a message with options presented as a dropdown list of elements.
+ * @param width Integer value, in pixels.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ * @param elements An array of objects representing the elements.
+ * @return The index of the selected element, starting from 1.
+ */
+ public static int showDropdown(int width, int type, String title,
+ String text, Object... elements) {
+
+ // show the dropdown list and get
+ // the selected object, if any
+ Object index = JOptionPane.showInputDialog(
+ null,
+ String.format(
+ "<html><body style=\"width:%dpx\">%s</body></html>",
+ normalizeMessageWidth(width),
+ text
+ ),
+ title,
+ normalizeIconType(type),
+ null,
+ elements,
+ elements[0]
+ );
+
+ // if it's not a null object, let's
+ // find the corresponding index
+ if (index != null) {
+
+ // iterate through the array of elements
+ for (int i = 0; i < elements.length; i++) {
+
+ // if the element is found, simply
+ // return the index plus 1, as zero
+ // corresponds to no selection at all
+ if (elements[i].equals(index)) {
+ return i + 1;
+ }
+
+ }
+ }
+
+ // nothing was selected,
+ // simply return zero
+ return 0;
+ }
+
+ /**
+ * Shows a message with options presented as a dropdown list of elements. It
+ * relies on the default width.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ * @param elements An array of objects representing the elements.
+ * @return The index of the selected element, starting from 1.
+ */
+ public static int showDropdown(int type, String title,
+ String text, Object... elements) {
+ return showDropdown(WIDTH, type, title, text, elements);
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/Methods.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/Methods.java
new file mode 100644
index 00000000000..15c66049342
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/Methods.java
@@ -0,0 +1,1356 @@
+/**
+ * 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.utils;
+
+import com.github.cereda.arara.controller.ConfigurationController;
+import com.github.cereda.arara.controller.LanguageController;
+import com.github.cereda.arara.model.AraraException;
+import com.github.cereda.arara.model.Command;
+import com.github.cereda.arara.model.Messages;
+import com.github.cereda.arara.model.Pair;
+import com.github.cereda.arara.model.Session;
+import com.github.cereda.arara.model.Trigger;
+import java.io.File;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Implements some auxiliary methods for runtime evaluation.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class Methods {
+
+ // the language controller
+ private static final LanguageController messages =
+ LanguageController.getInstance();
+
+ // the session controller
+ private static final Session session = new Session();
+
+ /**
+ * Adds the rule methods to the provided map.
+ * @param map The map.
+ */
+ public static void addRuleMethods(Map<String, Object> map) {
+ addConditionalMethods(map);
+ try {
+ map.put("getOriginalFile", Methods.class.getMethod("getOriginalFile"));
+ map.put("getOriginalReference", Methods.class.getMethod("getOriginalReference"));
+ map.put("isEmpty", Methods.class.getMethod("isEmpty", String.class));
+ map.put("isNotEmpty", Methods.class.getMethod("isNotEmpty", String.class));
+ map.put("isEmpty", Methods.class.getMethod("isEmpty", String.class, Object.class));
+ map.put("isNotEmpty", Methods.class.getMethod("isNotEmpty", String.class, Object.class));
+ map.put("isEmpty", Methods.class.getMethod("isEmpty", String.class, Object.class, Object.class));
+ map.put("isNotEmpty", Methods.class.getMethod("isNotEmpty", String.class, Object.class, Object.class));
+ map.put("isTrue", Methods.class.getMethod("isTrue", String.class));
+ map.put("isFalse", Methods.class.getMethod("isFalse", String.class));
+ map.put("isTrue", Methods.class.getMethod("isTrue", String.class, Object.class));
+ map.put("isFalse", Methods.class.getMethod("isFalse", String.class, Object.class));
+ map.put("isTrue", Methods.class.getMethod("isTrue", String.class, Object.class, Object.class));
+ map.put("isFalse", Methods.class.getMethod("isFalse", String.class, Object.class, Object.class));
+ map.put("isTrue", Methods.class.getMethod("isTrue", String.class, Object.class, Object.class, Object.class));
+ map.put("isFalse", Methods.class.getMethod("isFalse", String.class, Object.class, Object.class, Object.class));
+ map.put("trimSpaces", Methods.class.getMethod("trimSpaces", String.class));
+ map.put("isTrue", Methods.class.getMethod("isTrue", boolean.class, Object.class));
+ map.put("isFalse", Methods.class.getMethod("isFalse", boolean.class, Object.class));
+ map.put("isTrue", Methods.class.getMethod("isTrue", boolean.class, Object.class, Object.class));
+ map.put("isFalse", Methods.class.getMethod("isFalse", boolean.class, Object.class, Object.class));
+ map.put("getBasename", Methods.class.getMethod("getBasename", File.class));
+ map.put("getBasename", Methods.class.getMethod("getBasename", String.class));
+ map.put("getFullBasename", Methods.class.getMethod("getFullBasename", File.class));
+ map.put("getFullBasename", Methods.class.getMethod("getFullBasename", String.class));
+ map.put("getFiletype", Methods.class.getMethod("getFiletype", File.class));
+ map.put("getFiletype", Methods.class.getMethod("getFiletype", String.class));
+ map.put("throwError", Methods.class.getMethod("throwError", String.class));
+ map.put("getSession", Methods.class.getMethod("getSession"));
+ map.put("isWindows", Methods.class.getMethod("isWindows"));
+ map.put("isLinux", Methods.class.getMethod("isLinux"));
+ map.put("isMac", Methods.class.getMethod("isMac"));
+ map.put("isUnix", Methods.class.getMethod("isUnix"));
+ map.put("isAIX", Methods.class.getMethod("isAIX"));
+ map.put("isIrix", Methods.class.getMethod("isIrix"));
+ map.put("isOS2", Methods.class.getMethod("isOS2"));
+ map.put("isSolaris", Methods.class.getMethod("isSolaris"));
+ map.put("isCygwin", Methods.class.getMethod("isCygwin"));
+ map.put("isWindows", Methods.class.getMethod("isWindows", Object.class, Object.class));
+ map.put("isLinux", Methods.class.getMethod("isLinux", Object.class, Object.class));
+ map.put("isMac", Methods.class.getMethod("isMac", Object.class, Object.class));
+ map.put("isUnix", Methods.class.getMethod("isUnix", Object.class, Object.class));
+ map.put("isAIX", Methods.class.getMethod("isAIX", Object.class, Object.class));
+ map.put("isIrix", Methods.class.getMethod("isIrix", Object.class, Object.class));
+ map.put("isOS2", Methods.class.getMethod("isOS2", Object.class, Object.class));
+ map.put("isSolaris", Methods.class.getMethod("isSolaris", Object.class, Object.class));
+ map.put("isCygwin", Methods.class.getMethod("isCygwin", Object.class, Object.class));
+ map.put("replicatePattern", Methods.class.getMethod("replicatePattern", String.class, List.class));
+ map.put("buildString", Methods.class.getMethod("buildString", Object[].class));
+ map.put("addQuotes", Methods.class.getMethod("addQuotes", Object.class));
+ map.put("getCommand", Methods.class.getMethod("getCommand", List.class));
+ map.put("getCommand", Methods.class.getMethod("getCommand", Object[].class));
+ map.put("getTrigger", Methods.class.getMethod("getTrigger", String.class));
+ map.put("getTrigger", Methods.class.getMethod("getTrigger", String.class, Object[].class));
+ map.put("checkClass", Methods.class.getMethod("checkClass", Class.class, Object.class));
+ map.put("isString", Methods.class.getMethod("isString", Object.class));
+ map.put("isList", Methods.class.getMethod("isList", Object.class));
+ map.put("isMap", Methods.class.getMethod("isMap", Object.class));
+ map.put("isBoolean", Methods.class.getMethod("isBoolean", Object.class));
+ map.put("isVerboseMode", Methods.class.getMethod("isVerboseMode"));
+ map.put("showMessage", Methods.class.getMethod("showMessage", int.class, String.class, String.class));
+ map.put("showMessage", Methods.class.getMethod("showMessage", int.class, int.class, String.class, String.class));
+ map.put("isOnPath", Methods.class.getMethod("isOnPath", String.class));
+ map.put("unsafelyExecuteSystemCommand", Methods.class.getMethod("unsafelyExecuteSystemCommand", Command.class));
+ map.put("mergeVelocityTemplate", Methods.class.getMethod("mergeVelocityTemplate", File.class, File.class, Map.class));
+ map.put("getCommandWithWorkingDirectory", Methods.class.getMethod("getCommandWithWorkingDirectory", String.class, List.class));
+ map.put("getCommandWithWorkingDirectory", Methods.class.getMethod("getCommandWithWorkingDirectory", String.class, Object[].class));
+ map.put("getCommandWithWorkingDirectory", Methods.class.getMethod("getCommandWithWorkingDirectory", File.class, List.class));
+ map.put("getCommandWithWorkingDirectory", Methods.class.getMethod("getCommandWithWorkingDirectory", File.class, Object[].class));
+ map.put("listFilesByExtensions", Methods.class.getMethod("listFilesByExtensions", File.class, List.class, boolean.class));
+ map.put("listFilesByExtensions", Methods.class.getMethod("listFilesByExtensions", String.class, List.class, boolean.class));
+ map.put("listFilesByPatterns", Methods.class.getMethod("listFilesByPatterns", File.class, List.class, boolean.class));
+ map.put("listFilesByPatterns", Methods.class.getMethod("listFilesByPatterns", String.class, List.class, boolean.class));
+ map.put("writeToFile", Methods.class.getMethod("writeToFile", File.class, String.class, boolean.class));
+ map.put("writeToFile", Methods.class.getMethod("writeToFile", File.class, List.class, boolean.class));
+ map.put("writeToFile", Methods.class.getMethod("writeToFile", String.class, String.class, boolean.class));
+ map.put("writeToFile", Methods.class.getMethod("writeToFile", String.class, List.class, boolean.class));
+ map.put("readFromFile", Methods.class.getMethod("readFromFile", File.class));
+ map.put("readFromFile", Methods.class.getMethod("readFromFile", String.class));
+ } catch (Exception exception) {
+ // quack, quack, quack
+ }
+ }
+
+ /**
+ * Adds conditional methods to the provided map.
+ * @param map The map.
+ */
+ public static void addConditionalMethods(Map<String, Object> map) {
+ try {
+ map.put("exists", Methods.class.getMethod("exists", String.class));
+ map.put("exists", Methods.class.getMethod("exists", File.class));
+ map.put("missing", Methods.class.getMethod("missing", String.class));
+ map.put("missing", Methods.class.getMethod("missing", File.class));
+ map.put("changed", Methods.class.getMethod("changed", String.class));
+ map.put("changed", Methods.class.getMethod("changed", File.class));
+ map.put("unchanged", Methods.class.getMethod("unchanged", String.class));
+ map.put("unchanged", Methods.class.getMethod("unchanged", File.class));
+ map.put("found", Methods.class.getMethod("found", String.class, String.class));
+ map.put("found", Methods.class.getMethod("found", File.class, String.class));
+ map.put("toFile", Methods.class.getMethod("toFile", String.class));
+ map.put("showDropdown", Methods.class.getMethod("showDropdown", int.class, String.class, String.class, Object[].class));
+ map.put("showDropdown", Methods.class.getMethod("showDropdown", int.class, int.class, String.class, String.class, Object[].class));
+ map.put("showInput", Methods.class.getMethod("showInput", int.class, String.class, String.class));
+ map.put("showInput", Methods.class.getMethod("showInput", int.class, int.class, String.class, String.class));
+ map.put("showOptions", Methods.class.getMethod("showOptions", int.class, String.class, String.class, Object[].class));
+ map.put("showOptions", Methods.class.getMethod("showOptions", int.class, int.class, String.class, String.class, Object[].class));
+ map.put("currentFile", Methods.class.getMethod("currentFile"));
+ map.put("loadClass", Methods.class.getMethod("loadClass", File.class, String.class));
+ map.put("loadClass", Methods.class.getMethod("loadClass", String.class, String.class));
+ map.put("loadObject", Methods.class.getMethod("loadObject", File.class, String.class));
+ map.put("loadObject", Methods.class.getMethod("loadObject", String.class, String.class));
+ } catch (Exception exception) {
+ // quack, quack, quack
+ }
+ }
+
+ /**
+ * Gets the original file.
+ * @return The original file.
+ */
+ public static String getOriginalFile() {
+ File file = (File) ConfigurationController.getInstance().get("execution.reference");
+ return file.getName();
+ }
+
+ /**
+ * Gets the original reference.
+ * @return The original reference.
+ */
+ public static File getOriginalReference() {
+ return (File) ConfigurationController.getInstance().get("execution.reference");
+ }
+
+ /**
+ * Checks if the string is empty.
+ * @param string The string.
+ * @return A boolean value.
+ */
+ public static boolean isEmpty(String string) {
+ return CommonUtils.checkEmptyString(string);
+ }
+
+ /**
+ * Checks if the string is not empty.
+ * @param string The string.
+ * @return A boolean value.
+ */
+ public static boolean isNotEmpty(String string) {
+ return !isEmpty(string);
+ }
+
+ /**
+ * Checks if the string is empty.
+ * @param string The string.
+ * @param yes Object to return if true.
+ * @return An object or empty string.
+ */
+ public static Object isEmpty(String string, Object yes) {
+ return isEmpty(string) ? yes : "";
+ }
+
+ /**
+ * Checks if the string is not empty.
+ * @param string The string.
+ * @param yes Object to return if true.
+ * @return An object or empty string.
+ */
+ public static Object isNotEmpty(String string, Object yes) {
+ return isNotEmpty(string) ? yes : "";
+ }
+
+ /**
+ * Checks if the string is empty.
+ * @param string The string.
+ * @param yes Object to return if true.
+ * @param no Object to return if false.
+ * @return One of the two objects.
+ */
+ public static Object isEmpty(String string, Object yes, Object no) {
+ return isEmpty(string) ? yes : no;
+ }
+
+ /**
+ * Checks if the string is not empty.
+ * @param string The string.
+ * @param yes Object to return if true.
+ * @param no Object to return if false.
+ * @return One of the two objects.
+ */
+ public static Object isNotEmpty(String string, Object yes, Object no) {
+ return isNotEmpty(string) ? yes : no;
+ }
+
+ /**
+ * Checks if the string holds a true value.
+ * @param string The string.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean isTrue(String string) throws AraraException {
+ return isEmpty(string) ? false : CommonUtils.checkBoolean(string);
+ }
+
+ /**
+ * Checks if the string holds a false value.
+ * @param string The string.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean isFalse(String string) throws AraraException {
+ return isEmpty(string) ? false : !CommonUtils.checkBoolean(string);
+ }
+
+ /**
+ * Checks if the string holds a true value.
+ * @param string The string.
+ * @param yes Object to return if true.
+ * @return An object or an empty string.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Object isTrue(String string, Object yes)
+ throws AraraException {
+ return isTrue(string) ? yes : "";
+ }
+
+ /**
+ * Checks if the string holds a false value.
+ * @param string The string.
+ * @param yes Object to return if true.
+ * @return An object or an empty string.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Object isFalse(String string, Object yes)
+ throws AraraException {
+ return (isFalse(string) ? yes : "");
+ }
+
+ /**
+ * Checks if the string holds a true value.
+ * @param string The string.
+ * @param yes Object to return if true.
+ * @param no Object to return if false.
+ * @return One of the two objects.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Object isTrue(String string, Object yes, Object no)
+ throws AraraException {
+ return (isTrue(string) ? yes : no);
+ }
+
+ /**
+ * Checks if the string holds a false value.
+ * @param string The string.
+ * @param yes Object to return if true.
+ * @param no Object to return if false.
+ * @return One of the two objects.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Object isFalse(String string, Object yes, Object no)
+ throws AraraException {
+ return (isFalse(string) ? yes : no);
+ }
+
+ /**
+ * Checks if the string holds a true value.
+ * @param string The string.
+ * @param yes Object to return if true.
+ * @param no Object to return if false.
+ * @param fallback Object to return if string is empty.
+ * @return One of the three options.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Object isTrue(String string, Object yes, Object no,
+ Object fallback) throws AraraException {
+ return isEmpty(string) ? fallback : (isTrue(string) ? yes : no);
+ }
+
+ /**
+ * Checks if the string holds a false value.
+ * @param string The string.
+ * @param yes Object to return if true.
+ * @param no Object to return if false.
+ * @param fallback Object to return if string is empty.
+ * @return One of the three options.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Object isFalse(String string, Object yes, Object no,
+ Object fallback) throws AraraException {
+ return isEmpty(string) ? fallback : (isFalse(string) ? yes : no);
+ }
+
+ /**
+ * Trim spaces from the string.
+ * @param string The string.
+ * @return A trimmed string.
+ */
+ public static String trimSpaces(String string) {
+ return string.trim();
+ }
+
+ /**
+ * Checks if the expression resolves to true.
+ * @param value The expression.
+ * @param yes Object to return if true.
+ * @return An object or an empty string.
+ */
+ public static Object isTrue(boolean value, Object yes) {
+ return value ? yes : "";
+ }
+
+ /**
+ * Checks if the expression resolves to false.
+ * @param value The expression.
+ * @param yes Object to return if true.
+ * @return An object or an empty string.
+ */
+ public static Object isFalse(boolean value, Object yes) {
+ return !value ? yes : "";
+ }
+
+ /**
+ * Checks if the expression resolves to true.
+ * @param value The expression.
+ * @param yes Object to return if true.
+ * @param no Object to return if false.
+ * @return One of the two objects.
+ */
+ public static Object isTrue(boolean value, Object yes, Object no) {
+ return value ? yes : no;
+ }
+
+ /**
+ * Checks if the expression resolves to false.
+ * @param value The expression.
+ * @param yes Object to return if true.
+ * @param no Object to return if false.
+ * @return One of the two objects.
+ */
+ public static Object isFalse(boolean value, Object yes, Object no) {
+ return !value ? yes : no;
+ }
+
+ /**
+ * Gets the basename.
+ * @param file The file.
+ * @return The basename of the provided file.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static String getBasename(File file) throws AraraException {
+ if (file.isFile()) {
+ return CommonUtils.getBasename(file);
+ } else {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().concat(
+ messages.getMessage(
+ Messages.ERROR_BASENAME_NOT_A_FILE,
+ file.getName()
+ )
+ )
+ );
+ }
+ }
+
+ /**
+ * Gets the basename.
+ * @param filename The string.
+ * @return The basename.
+ */
+ public static String getBasename(String filename) {
+ return CommonUtils.getBasename(filename);
+ }
+
+ /**
+ * Gets the file type.
+ * @param file The provided file.
+ * @return The file type.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static String getFiletype(File file) throws AraraException {
+ if (file.isFile()) {
+ return CommonUtils.getFiletype(file);
+ } else {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().concat(
+ messages.getMessage(
+ Messages.ERROR_FILETYPE_NOT_A_FILE,
+ file.getName()
+ )
+ )
+ );
+ }
+ }
+
+ /**
+ * Gets the file type.
+ * @param filename The provided string.
+ * @return The file type.
+ */
+ public static String getFiletype(String filename) {
+ return CommonUtils.getFiletype(filename);
+ }
+
+ /**
+ * Replicates the pattern to each element of a list.
+ * @param pattern The pattern.
+ * @param values The list.
+ * @return A list of strings containing the pattern applied to the list.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static List<Object> replicatePattern(String pattern,
+ List<Object> values) throws AraraException {
+ return CommonUtils.replicateList(pattern, values);
+ }
+
+ /**
+ * Throws an exception.
+ * @param text The text to be thrown as the exception message.
+ * @throws AraraException The exception to be thrown by this method.
+ */
+ public static void throwError(String text) throws AraraException {
+ throw new AraraException(text);
+ }
+
+ /**
+ * Gets the session.
+ * @return The session.
+ */
+ public static Session getSession() {
+ return session;
+ }
+
+ /**
+ * Checks if Windows is the underlying operating system.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean isWindows() throws AraraException {
+ return CommonUtils.checkOS("windows");
+ }
+
+ /**
+ * Checks if we are inside a Cygwin environment.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean isCygwin() throws AraraException {
+ return CommonUtils.checkOS("cygwin");
+ }
+
+ /**
+ * Checks if Linux is the underlying operating system.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean isLinux() throws AraraException {
+ return CommonUtils.checkOS("linux");
+ }
+
+ /**
+ * Checks if Mac is the underlying operating system.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean isMac() throws AraraException {
+ return CommonUtils.checkOS("mac");
+ }
+
+ /**
+ * Checks if Unix is the underlying operating system.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean isUnix() throws AraraException {
+ return CommonUtils.checkOS("unix");
+ }
+
+ /**
+ * Checks if AIX is the underlying operating system.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean isAIX() throws AraraException {
+ return CommonUtils.checkOS("aix");
+ }
+
+ /**
+ * Checks if Irix is the underlying operating system.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean isIrix() throws AraraException {
+ return CommonUtils.checkOS("irix");
+ }
+
+ /**
+ * Checks if OS2 is the underlying operating system.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean isOS2() throws AraraException {
+ return CommonUtils.checkOS("os2");
+ }
+
+ /**
+ * Checks if Solaris is the underlying operating system.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean isSolaris() throws AraraException {
+ return CommonUtils.checkOS("solaris");
+ }
+
+ /**
+ * Checks if Windows is the underlying operating system.
+ * @param yes Object to return if true.
+ * @param no Object to return if false.
+ * @return One of the two objects.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Object isWindows(Object yes, Object no)
+ throws AraraException {
+ return CommonUtils.checkOS("windows") ? yes : no;
+ }
+
+ /**
+ * Checks if we are inside a Cygwin environment.
+ * @param yes Object to return if true.
+ * @param no Object to return if false.
+ * @return One of the two objects.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Object isCygwin(Object yes, Object no) throws AraraException {
+ return CommonUtils.checkOS("cygwin") ? yes : no;
+ }
+
+ /**
+ * Checks if Linux is the underlying operating system.
+ * @param yes Object to return if true.
+ * @param no Object to return if false.
+ * @return One of the two objects.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Object isLinux(Object yes, Object no) throws AraraException {
+ return CommonUtils.checkOS("linux") ? yes : no;
+ }
+
+ /**
+ * Checks if Mac is the underlying operating system.
+ * @param yes Object to return if true.
+ * @param no Object to return if false.
+ * @return One of the two objects.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Object isMac(Object yes, Object no) throws AraraException {
+ return CommonUtils.checkOS("mac") ? yes : no;
+ }
+
+ /**
+ * Checks if Unix is the underlying operating system.
+ * @param yes Object to return if true.
+ * @param no Object to return if false.
+ * @return One of the two objects.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Object isUnix(Object yes, Object no) throws AraraException {
+ return CommonUtils.checkOS("unix") ? yes : no;
+ }
+
+ /**
+ * Checks if AIX is the underlying operating system.
+ * @param yes Object to return if true.
+ * @param no Object to return if false.
+ * @return One of the two objects.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Object isAIX(Object yes, Object no) throws AraraException {
+ return CommonUtils.checkOS("aix") ? yes : no;
+ }
+
+ /**
+ * Checks if Irix is the underlying operating system.
+ * @param yes Object to return if true.
+ * @param no Object to return if false.
+ * @return One of the two objects.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Object isIrix(Object yes, Object no) throws AraraException {
+ return CommonUtils.checkOS("irix") ? yes : no;
+ }
+
+ /**
+ * Checks if OS2 is the underlying operating system.
+ * @param yes Object to return if true.
+ * @param no Object to return if false.
+ * @return One of the two objects.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Object isOS2(Object yes, Object no) throws AraraException {
+ return CommonUtils.checkOS("os2") ? yes : no;
+ }
+
+ /**
+ * Checks if Solaris is the underlying operating system.
+ * @param yes Object to return if true.
+ * @param no Object to return if false.
+ * @return One of the two objects.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Object isSolaris(Object yes, Object no) throws AraraException {
+ return CommonUtils.checkOS("solaris") ? yes : no;
+ }
+
+ /**
+ * Checks if the file exists according to its extension.
+ * @param extension The extension.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean exists(String extension) throws AraraException {
+ return CommonUtils.exists(extension);
+ }
+
+ /**
+ * Checks if the file is missing according to its extension.
+ * @param extension The extension.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean missing(String extension) throws AraraException {
+ return !exists(extension);
+ }
+
+ /**
+ * Checks if the file has changed, according to its extension.
+ * @param extension The extension.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean changed(String extension) throws AraraException {
+ return CommonUtils.hasChanged(extension);
+ }
+
+ /**
+ * Checks if the file is unchanged according to its extension.
+ * @param extension The extension.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean unchanged(String extension) throws AraraException {
+ return !changed(extension);
+ }
+
+ /**
+ * Checks if the file exists.
+ * @param filename The file.
+ * @return A boolean value.
+ */
+ public static boolean exists(File filename) {
+ return CommonUtils.exists(filename);
+ }
+
+ /**
+ * Checks if the file is missing.
+ * @param filename The file.
+ * @return A boolean value.
+ */
+ public static boolean missing(File filename) {
+ return !exists(filename);
+ }
+
+ /**
+ * Checks if the file has changed.
+ * @param filename The file.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean changed(File filename) throws AraraException {
+ return CommonUtils.hasChanged(filename);
+ }
+
+ /**
+ * Checks if the file is unchanged.
+ * @param filename The file.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean unchanged(File filename) throws AraraException {
+ return !changed(filename);
+ }
+
+ /**
+ * Build a string based on an array of objects.
+ * @param objects Array of objects.
+ * @return A string built from the array.
+ */
+ public static String buildString(Object... objects) {
+ return CommonUtils.generateString(objects);
+ }
+
+ /**
+ * Encloses the provided object into double quotes.
+ * @param object The object.
+ * @return The object enclosed in double quotes.
+ */
+ public static String addQuotes(Object object) {
+ return CommonUtils.addQuotes(object);
+ }
+
+ /**
+ * Checks if the file contains the regex, based on its extension.
+ * @param extension The extension.
+ * @param regex The regex.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean found(String extension, String regex)
+ throws AraraException {
+ return CommonUtils.checkRegex(extension, regex);
+ }
+
+ /**
+ * Checks if the file contains the provided regex.
+ * @param file The file.
+ * @param regex The regex.
+ * @return A boolean value.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean found(File file, String regex)
+ throws AraraException {
+ return CommonUtils.checkRegex(file, regex);
+ }
+
+ /**
+ * Gets the command based on a list of strings.
+ * @param elements The list of strings.
+ * @return A command.
+ */
+ public static Command getCommand(List<String> elements) {
+ return new Command(elements);
+ }
+
+ /**
+ * Gets the command based on an array of objects.
+ * @param elements Array of objects.
+ * @return A command.
+ */
+ public static Command getCommand(Object... elements) {
+ return new Command(elements);
+ }
+
+ /**
+ * Gets the command based on an array of objects and with the provided
+ * working directory as string.
+ * @param path String path representing the working directory.
+ * @param elements Array of elements.
+ * @return A command.
+ */
+ public static Command getCommandWithWorkingDirectory(String path,
+ Object... elements) {
+ Command command = new Command(elements);
+ command.setWorkingDirectory(new File(path));
+ return command;
+ }
+
+ /**
+ * Gets the command based on an array of objects and with the provided
+ * working directory as file.
+ * @param file File representing the working directory.
+ * @param elements Array of elements.
+ * @return A command.
+ */
+ public static Command getCommandWithWorkingDirectory(File file,
+ Object... elements) {
+ Command command = new Command(elements);
+ command.setWorkingDirectory(file);
+ return command;
+ }
+
+ /**
+ * Gets the command based on a list of strings and with the provided
+ * working directory as string.
+ * @param path String path representing the working directory.
+ * @param elements List of strings.
+ * @return A command.
+ */
+ public static Command getCommandWithWorkingDirectory(String path,
+ List<String> elements) {
+ Command command = new Command(elements);
+ command.setWorkingDirectory(new File(path));
+ return command;
+ }
+
+ /**
+ * Gets the command based on a list of strings and with the provided
+ * working directory as file.
+ * @param file File representing the working directory.
+ * @param elements List of strings.
+ * @return A command.
+ */
+ public static Command getCommandWithWorkingDirectory(File file,
+ List<String> elements) {
+ Command command = new Command(elements);
+ command.setWorkingDirectory(file);
+ return command;
+ }
+
+ /**
+ * Gets the trigger.
+ * @param action The action name.
+ * @return The trigger.
+ */
+ public static Trigger getTrigger(String action) {
+ return new Trigger(action, null);
+ }
+
+ /**
+ * Gets the trigger.
+ * @param action The action name.
+ * @param parameters The trigger parameters.
+ * @return A trigger.
+ */
+ public static Trigger getTrigger(String action, Object... parameters) {
+ return new Trigger(action, Arrays.asList(parameters));
+ }
+
+ /**
+ * Checks if the object is an intance of the provided class.
+ * @param clazz The class.
+ * @param object The object.
+ * @return A boolean value.
+ */
+ public static boolean checkClass(Class clazz, Object object) {
+ return CommonUtils.checkClass(clazz, object);
+ }
+
+ /**
+ * Checks if the object is a string.
+ * @param object The object.
+ * @return A boolean value.
+ */
+ public static boolean isString(Object object) {
+ return checkClass(String.class, object);
+ }
+
+ /**
+ * Checks if the object is a list.
+ * @param object The object.
+ * @return A boolean value.
+ */
+ public static boolean isList(Object object) {
+ return checkClass(List.class, object);
+ }
+
+ /**
+ * Checks if the object is a map.
+ * @param object The object.
+ * @return A boolean value.
+ */
+ public static boolean isMap(Object object) {
+ return checkClass(Map.class, object);
+ }
+
+ /**
+ * Checks if the object is a boolean.
+ * @param object The object.
+ * @return A boolean value.
+ */
+ public static boolean isBoolean(Object object) {
+ return checkClass(Boolean.class, object);
+ }
+
+ /**
+ * Checks if the execution is in verbose mode.
+ * @return A boolean value indicating if the execution is in verbose mode.
+ */
+ public static boolean isVerboseMode() {
+ return (Boolean) ConfigurationController.
+ getInstance().get("execution.verbose");
+ }
+
+ /**
+ * Returns a file object based on the provided name.
+ * @param name The file name.
+ * @return A file object.
+ */
+ public static File toFile(String name) {
+ return new File(name);
+ }
+
+ /**
+ * Shows the message.
+ * @param width Integer value, in pixels.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ */
+ public static void showMessage(int width, int type,
+ String title, String text) {
+ MessageUtils.showMessage(width, type, title, text);
+ }
+
+ /**
+ * Shows the message. It relies on the default width.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ */
+ public static void showMessage(int type, String title, String text) {
+ MessageUtils.showMessage(type, title, text);
+ }
+
+ /**
+ * Shows a message with options presented as an array of buttons.
+ * @param width Integer value, in pixels.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ * @param buttons An array of objects to be presented as buttons.
+ * @return The index of the selected button, starting from 1.
+ */
+ public static int showOptions(int width, int type, String title,
+ String text, Object... buttons) {
+ return MessageUtils.showOptions(width, type, title, text, buttons);
+ }
+
+ /**
+ * Shows a message with options presented as an array of buttons. It relies
+ * on the default width.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ * @param buttons An array of objects to be presented as buttons.
+ * @return The index of the selected button, starting from 1.
+ */
+ public static int showOptions(int type, String title,
+ String text, Object... buttons) {
+ return MessageUtils.showOptions(type, title, text, buttons);
+ }
+
+ /**
+ * Shows a message with a text input.
+ * @param width Integer value, in pixels.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ * @return The string representing the input text.
+ */
+ public static String showInput(int width, int type,
+ String title, String text) {
+ return MessageUtils.showInput(width, type, title, text);
+ }
+
+ /**
+ * Shows a message with a text input. It relies on the default width.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ * @return The string representing the input text.
+ */
+ public static String showInput(int type, String title, String text) {
+ return MessageUtils.showInput(type, title, text);
+ }
+
+ /**
+ * Shows a message with options presented as a dropdown list of elements.
+ * @param width Integer value, in pixels.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ * @param elements An array of objects representing the elements.
+ * @return The index of the selected element, starting from 1.
+ */
+ public static int showDropdown(int width, int type, String title,
+ String text, Object... elements) {
+ return MessageUtils.showDropdown(width, type, title, text, elements);
+ }
+
+ /**
+ * Shows a message with options presented as a dropdown list of elements. It
+ * relies on the default width.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ * @param elements An array of objects representing the elements.
+ * @return The index of the selected element, starting from 1.
+ */
+ public static int showDropdown(int type, String title,
+ String text, Object... elements) {
+ return MessageUtils.showDropdown(type, title, text, elements);
+ }
+
+ /**
+ * Checks if the provided command name is reachable from the system path.
+ * @param command A string representing the command.
+ * @return A logic value.
+ */
+ public static boolean isOnPath(String command) {
+ return CommonUtils.isOnPath(command);
+ }
+
+ /**
+ * Gets the full basename.
+ * @param file The file.
+ * @return The full basename of the provided file.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static String getFullBasename(File file) throws AraraException {
+ if (file.isFile()) {
+ return CommonUtils.getFullBasename(file);
+ } else {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().concat(
+ messages.getMessage(
+ Messages.ERROR_BASENAME_NOT_A_FILE,
+ file.getName()
+ )
+ )
+ );
+ }
+ }
+
+ /**
+ * Gets the full basename.
+ * @param name The string.
+ * @return The full basename.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static String getFullBasename(String name) throws AraraException {
+ return getFullBasename(new File(name));
+ }
+
+ /**
+ * Unsafely executes a system command from the underlying operating system
+ * and returns a pair containing the exit status and the command output as a
+ * string.
+ * @param command The system command to be executed.
+ * @return A pair containing the exit status and the system command output
+ * as a string.
+ */
+ public static Pair<Integer, String>
+ unsafelyExecuteSystemCommand(Command command) {
+ return UnsafeUtils.executeSystemCommand(command);
+ }
+
+ /**
+ * Merges the provided template with a context map and writes the result in
+ * an output file. This method relies on Apache Velocity.
+ * @param input The input file.
+ * @param output The output file.
+ * @param map The context map.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static void mergeVelocityTemplate(File input, File output,
+ Map<String, Object> map) throws AraraException {
+ VelocityUtils.mergeVelocityTemplate(input, output, map);
+ }
+
+ /**
+ * Gets the file reference for the current directive. It is important to
+ * observe that version 4.0 of arara replicates the directive when 'files'
+ * is detected amongst the parameters, so each instance will have a
+ * different reference.
+ * @return A file reference for the current directive.
+ */
+ public static File currentFile() {
+ return (File) ConfigurationController.getInstance().
+ get("execution.directive.reference");
+ }
+
+ /**
+ * Loads a class from the provided file, potentially a Java archive.
+ * @param file File containing the Java bytecode (namely, a JAR).
+ * @param name The canonical name of the class.
+ * @return A pair representing the status and the class.
+ */
+ public static Pair<Integer, Class> loadClass(File file, String name) {
+ return ClassLoadingUtils.loadClass(file, name);
+ }
+
+ /**
+ * Loads a class from the provided string reference, representing a file.
+ * @param ref String reference representing a file.
+ * @param name The canonical name of the class.
+ * @return A pair representing the status and the class.
+ */
+ public static Pair<Integer, Class> loadClass(String ref, String name) {
+ return ClassLoadingUtils.loadClass(new File(ref), name);
+ }
+
+ /**
+ * Loads a class from the provided file, instantiating it.
+ * @param file File containing the Java bytecode (namely, a JAR).
+ * @param name The canonical name of the class.
+ * @return A pair representing the status and the class object.
+ */
+ public static Pair<Integer, Object> loadObject(File file, String name) {
+ return ClassLoadingUtils.loadObject(file, name);
+ }
+
+ /**
+ * Loads a class from the provided string reference, instantiating it.
+ * @param ref String reference representing a file.
+ * @param name The canonical name of the class.
+ * @return A pair representing the status and the class object.
+ */
+ public static Pair<Integer, Object> loadObject(String ref, String name) {
+ return ClassLoadingUtils.loadObject(new File(ref), name);
+ }
+
+ /**
+ * List all files from the provided directory according to the list of
+ * extensions. The leading dot must be omitted, unless it is part of the
+ * extension.
+ * @param directory The provided directory.
+ * @param extensions The list of extensions.
+ * @param recursive A flag indicating whether the search is recursive.
+ * @return A list of files.
+ */
+ public static List<File> listFilesByExtensions(File directory,
+ List<String> extensions, boolean recursive) {
+ return FileSearchingUtils.listFilesByExtensions(
+ directory,
+ extensions,
+ recursive
+ );
+ }
+
+ /**
+ * List all files from the provided string path according to the list of
+ * extensions. The leading dot must be omitted, unless it is part of the
+ * extension.
+ * @param path The provided path as plain string.
+ * @param extensions The list of extensions.
+ * @param recursive A flag indicating whether the search is recursive.
+ * @return A list of files.
+ */
+ public static List<File> listFilesByExtensions(String path,
+ List<String> extensions, boolean recursive) {
+ return FileSearchingUtils.listFilesByExtensions(
+ new File(path),
+ extensions,
+ recursive
+ );
+ }
+
+ /**
+ * List all files from the provided directory matching the list of file
+ * name patterns. Such list can contain wildcards.
+ * @param directory The provided directory.
+ * @param patterns The list of file name patterns.
+ * @param recursive A flag indicating whether the search is recursive.
+ * @return A list of files.
+ */
+ public static List<File> listFilesByPatterns(File directory,
+ List<String> patterns, boolean recursive) {
+ return FileSearchingUtils.listFilesByPatterns(
+ directory,
+ patterns,
+ recursive
+ );
+ }
+
+ /**
+ * List all files from the provided path matching the list of file
+ * name patterns. Such list can contain wildcards.
+ * @param path The provided path as plain string.
+ * @param patterns The list of file name patterns.
+ * @param recursive A flag indicating whether the search is recursive.
+ * @return A list of files.
+ */
+ public static List<File> listFilesByPatterns(String path,
+ List<String> patterns, boolean recursive) {
+ return FileSearchingUtils.listFilesByPatterns(
+ new File(path),
+ patterns,
+ recursive
+ );
+ }
+
+ /**
+ * Writes the string to a file, using UTF-8 as default encoding.
+ * @param file The file.
+ * @param text The string to be written.
+ * @param append A flag whether to append the content.
+ * @return A logical value indicating whether it was successful.
+ */
+ public static boolean writeToFile(File file, String text, boolean append) {
+ return FileHandlingUtils.writeToFile(file, text, append);
+ }
+
+ /**
+ * Writes the string to a file, using UTF-8 as default encoding.
+ * @param path The path.
+ * @param text The string to be written.
+ * @param append A flag whether to append the content.
+ * @return A logical value indicating whether it was successful.
+ */
+ public static boolean writeToFile(String path, String text,
+ boolean append) {
+ return FileHandlingUtils.writeToFile(new File(path), text, append);
+ }
+
+ /**
+ * Writes the string list to a file, using UTF-8 as default encoding.
+ * @param file The file.
+ * @param lines The string list to be written.
+ * @param append A flag whether to append the content.
+ * @return A logical value indicating whether it was successful.
+ */
+ public static boolean writeToFile(File file, List<String> lines,
+ boolean append) {
+ return FileHandlingUtils.writeToFile(file, lines, append);
+ }
+
+ /**
+ * Writes the string list to a file, using UTF-8 as default encoding.
+ * @param path The path.
+ * @param lines The string list to be written.
+ * @param append A flag whether to append the content.
+ * @return A logical value indicating whether it was successful.
+ */
+ public static boolean writeToFile(String path, List<String> lines,
+ boolean append) {
+ return FileHandlingUtils.writeToFile(new File(path), lines, append);
+ }
+
+ /**
+ * Reads the provided file into a list of strings.
+ * @param file The file.
+ * @return A list of strings.
+ */
+ public static List<String> readFromFile(File file) {
+ return FileHandlingUtils.readFromFile(file);
+ }
+
+ /**
+ * Reads the provided file into a list of strings.
+ * @param path The path.
+ * @return A list of strings.
+ */
+ public static List<String> readFromFile(String path) {
+ return FileHandlingUtils.readFromFile(new File(path));
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/RuleUtils.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/RuleUtils.java
new file mode 100644
index 00000000000..d855344762d
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/RuleUtils.java
@@ -0,0 +1,244 @@
+/**
+ * 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.utils;
+
+import com.github.cereda.arara.controller.LanguageController;
+import com.github.cereda.arara.model.AraraException;
+import com.github.cereda.arara.model.Argument;
+import com.github.cereda.arara.model.Messages;
+import com.github.cereda.arara.model.RuleCommand;
+import com.github.cereda.arara.model.Rule;
+import java.io.File;
+import java.io.FileReader;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+import org.yaml.snakeyaml.error.MarkedYAMLException;
+import org.yaml.snakeyaml.nodes.Tag;
+import org.yaml.snakeyaml.representer.Representer;
+
+/**
+ * Implements rule utilitary methods.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class RuleUtils {
+
+ // the application messages obtained from the
+ // language controller
+ private static final LanguageController messages =
+ LanguageController.getInstance();
+
+ /**
+ * Parses the provided file, checks the identifier and returns a rule
+ * representation.
+ * @param file The rule file.
+ * @param identifier The directive identifier.
+ * @return The rule object.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static Rule parseRule(File file, String identifier)
+ throws AraraException {
+ Representer representer = new Representer();
+ representer.addClassTag(Rule.class, new Tag("!config"));
+ Yaml yaml = new Yaml(new Constructor(Rule.class), representer);
+ Rule rule = null;
+ try {
+ rule = yaml.loadAs(new FileReader(file), Rule.class);
+ } catch (MarkedYAMLException yamlException) {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().concat(
+ messages.getMessage(
+ Messages.ERROR_PARSERULE_INVALID_YAML
+ )
+ ),
+ yamlException
+ );
+ } catch (Exception exception) {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().concat(
+ messages.getMessage(
+ Messages.ERROR_PARSERULE_GENERIC_ERROR
+ )
+ )
+ );
+ }
+ validateHeader(rule, identifier);
+ validateBody(rule);
+ return rule;
+ }
+
+ /**
+ * Validates the rule header according to the directive identifier.
+ * @param rule The rule object.
+ * @param identifier The directive identifier.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ private static void validateHeader(Rule rule, String identifier)
+ throws AraraException {
+ if (rule.getIdentifier() != null) {
+ if (!rule.getIdentifier().equals(identifier)) {
+ throw new AraraException(CommonUtils.getRuleErrorHeader().
+ concat(
+ messages.getMessage(
+ Messages.ERROR_VALIDATEHEADER_WRONG_IDENTIFIER,
+ rule.getIdentifier(),
+ identifier
+ )
+ )
+ );
+ }
+ } else {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().concat(
+ messages.getMessage(
+ Messages.ERROR_VALIDATEHEADER_NULL_ID
+ )
+ )
+ );
+ }
+ if (rule.getName() == null) {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().concat(
+ messages.getMessage(
+ Messages.ERROR_VALIDATEHEADER_NULL_NAME
+ )
+ )
+ );
+ }
+ }
+
+ /**
+ * Validates the rule body.
+ * @param rule The rule object.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ private static void validateBody(Rule rule) throws AraraException {
+ if (rule.getCommands() == null) {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().concat(
+ messages.getMessage(
+ Messages.ERROR_VALIDATEBODY_NULL_COMMANDS_LIST
+ )
+ )
+ );
+ } else {
+ if (CollectionUtils.exists(rule.getCommands(),
+ new Predicate<RuleCommand>() {
+ public boolean evaluate(RuleCommand command) {
+ return (command.getCommand() == null);
+ }
+ })) {
+ throw new AraraException(CommonUtils.getRuleErrorHeader().
+ concat(
+ messages.getMessage(
+ Messages.ERROR_VALIDATEBODY_NULL_COMMAND
+ )
+ )
+ );
+ }
+ }
+ if (rule.getArguments() == null) {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().concat(
+ messages.getMessage(
+ Messages.ERROR_VALIDATEBODY_ARGUMENTS_LIST
+ )
+ )
+ );
+ } else {
+ String[] keywords = new String[]{"file", "files", "reference"};
+
+ List<String> arguments = new ArrayList<String>();
+ for (Argument argument : rule.getArguments()) {
+ if (argument.getIdentifier() != null) {
+ if ((argument.getFlag() != null) ||
+ (argument.getDefault() != null)) {
+ arguments.add(argument.getIdentifier());
+ } else {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().concat(
+ messages.getMessage(
+ Messages.ERROR_VALIDATEBODY_MISSING_KEYS
+ )
+ )
+ );
+ }
+ } else {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().concat(
+ messages.getMessage(
+ Messages.ERROR_VALIDATEBODY_NULL_ARGUMENT_ID
+ )
+ )
+ );
+ }
+ }
+
+ for (String keyword : keywords) {
+ if (arguments.contains(keyword)) {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().concat(
+ messages.getMessage(
+ Messages.ERROR_VALIDATEBODY_ARGUMENT_ID_IS_RESERVED,
+ keyword
+ )
+ )
+ );
+ }
+ }
+
+ int expected = arguments.size();
+ int found = (new HashSet<String>(arguments)).size();
+ if (expected != found) {
+ throw new AraraException(
+ CommonUtils.getRuleErrorHeader().concat(
+ messages.getMessage(
+ Messages.ERROR_VALIDATEBODY_DUPLICATE_ARGUMENT_IDENTIFIERS
+ )
+ )
+ );
+ }
+ }
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/TeeOutputStream.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/TeeOutputStream.java
index 36b5df82f59..65d3d58ffba 100644
--- a/Master/texmf-dist/source/support/arara/src/main/java/com/github/arara/utils/TeeOutputStream.java
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/TeeOutputStream.java
@@ -1,7 +1,6 @@
/**
- * \cond LICENSE
- * Arara -- the cool TeX automation tool
- * Copyright (c) 2012, Paulo Roberto Massa Cereda
+ * 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
@@ -31,125 +30,80 @@
* 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.
- * \endcond
- *
- * TeeOutputStream: This class implements an output stream that handles other
- * streams, so the flow is propagated to all of them in an easy way.
*/
-// package definition
-package com.github.arara.utils;
+package com.github.cereda.arara.utils;
-// needed importa
import java.io.IOException;
import java.io.OutputStream;
+import org.apache.commons.io.IOUtils;
/**
- * Implements an output stream that handles other streams, so the flow is
- * propagated to all of them in an easy way.
- *
+ * Implements a stream splitter.
* @author Paulo Roberto Massa Cereda
- * @version 3.0a
- * @since 2.0
+ * @version 4.0
+ * @since 4.0
*/
public class TeeOutputStream extends OutputStream {
- // the list of the output streams
+ // an array of streams in which
+ // an object of this class will
+ // split data
private final OutputStream[] streams;
/**
* Constructor.
- *
- * @param outputStreams An array containing the output streams.
+ * @param outputStreams An array of output streams.
*/
public TeeOutputStream(OutputStream... outputStreams) {
-
- // set the array
streams = outputStreams;
}
/**
- * Writes the byte to all the output streams.
- *
- * @param b The byte to write.
- * @throws IOException Exception if an error ocurred.
+ * Writes the provided integer to each stream.
+ * @param b The provided integer
+ * @throws IOException An IO exception.
*/
@Override
public void write(int b) throws IOException {
-
- // for every stream
for (OutputStream ostream : streams) {
-
- // write the byte
ostream.write(b);
}
}
/**
- * Writes an array of bytes to all the output streams.
- *
- * @param b The bytes to write.
+ * Writes the provided byte array to each stream, with the provided offset
+ * and length.
+ * @param b The byte array.
* @param offset The offset.
- * @param length Number of bytes.
- * @throws IOException Exception if an error ocurred.
+ * @param length The length.
+ * @throws IOException An IO exception.
*/
@Override
public void write(byte[] b, int offset, int length) throws IOException {
-
- // for every stream
for (OutputStream ostream : streams) {
-
- // write the array
ostream.write(b, offset, length);
}
}
/**
- * Flushes the stream.
- *
- * @throws IOException Exception if an error ocurred.
+ * Flushes every stream.
+ * @throws IOException An IO exception.
*/
@Override
public void flush() throws IOException {
-
- // for every stream
for (OutputStream ostream : streams) {
-
- // flush the stream
ostream.flush();
}
}
/**
- * Closes the stream.
- *
- * @throws IOException Exception if an error ocurred.
+ * Closes every stream silently.
*/
@Override
- public void close() throws IOException {
-
- // for every stream
+ public void close() {
for (OutputStream ostream : streams) {
-
- // try to close the stream
- forceClose(ostream);
- }
- }
-
- /**
- * Forces the stream to close without raising exceptions.
- *
- * @param ostream The stream.
- */
- private void forceClose(OutputStream ostream) {
-
- // try to close
- try {
-
- // close it
- ostream.close();
-
- } catch (IOException exception) {
- // do nothing
+ IOUtils.closeQuietly(ostream);
}
}
+
}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/UnsafeUtils.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/UnsafeUtils.java
new file mode 100644
index 00000000000..b989e074c8f
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/UnsafeUtils.java
@@ -0,0 +1,87 @@
+/**
+ * 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.utils;
+
+import com.github.cereda.arara.model.Command;
+import com.github.cereda.arara.model.Pair;
+import org.zeroturnaround.exec.ProcessExecutor;
+import org.zeroturnaround.exec.ProcessResult;
+
+/**
+ * Implements unsafe utilitary methods.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class UnsafeUtils {
+
+ /**
+ * Executes a system command from the underlying operating system and
+ * returns a pair containing the exit status and the command output as a
+ * string.
+ * @param command The system command to be executed.
+ * @return A pair containing the exit status and the system command output
+ * as a string.
+ */
+ public static Pair<Integer, String> executeSystemCommand(Command command) {
+
+ try {
+
+ // create a process result with the provided
+ // command, capturing the output
+ ProcessResult result = new ProcessExecutor(
+ command.getElements()
+ ).readOutput(true).execute();
+
+ // return the pair containing the exit status
+ // and the output string as UTF-8
+ return new Pair<Integer, String>(
+ result.getExitValue(),
+ result.outputUTF8()
+ );
+
+ } catch (Exception exception) {
+
+ // quack, quack, do nothing, just
+ // return a default error code
+
+ // if something goes wrong, the default
+ // error branch returns an exit status of
+ // -99 and an empty string
+ return new Pair<Integer, String>(-99, "");
+
+ }
+ }
+
+}
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/VelocityUtils.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/VelocityUtils.java
new file mode 100644
index 00000000000..2040b671b70
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/VelocityUtils.java
@@ -0,0 +1,157 @@
+/**
+ * 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.utils;
+
+import com.github.cereda.arara.controller.LanguageController;
+import com.github.cereda.arara.model.AraraException;
+import com.github.cereda.arara.model.Messages;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.Map;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.exception.MethodInvocationException;
+import org.apache.velocity.exception.ParseErrorException;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.apache.velocity.runtime.RuntimeConstants;
+
+/**
+ * Implements the template merging from Apache Velocity.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class VelocityUtils {
+
+ // the language controller
+ private static final LanguageController messages =
+ LanguageController.getInstance();
+
+ /**
+ * Merges the provided template with the context map and writes the result
+ * in an output file. The operation relies on the Apache Velocity project.
+ * @param input The input file.
+ * @param output The output file.
+ * @param map The context map.
+ * @throws AraraException Something terribly wrong happened, to be caught
+ * in the higher levels.
+ */
+ public static void mergeVelocityTemplate(File input, File output,
+ Map<String, Object> map) throws AraraException {
+
+ // let us try
+ try {
+
+ // create the template engine instance
+ VelocityEngine engine = new VelocityEngine();
+
+ // use the resource path trick: set the default
+ // location to the input file's parent directory,
+ // so our file is easily located
+ engine.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH,
+ input.getCanonicalFile().getParent());
+
+ // set the logging feature of Apache Velocity to
+ // register the occurrences in a null provider
+ // (we do not want unnecessary verbose output)
+ engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS,
+ "org.apache.velocity.runtime.log.NullLogSystem");
+
+ // init the engine with the
+ // provided settings
+ engine.init();
+
+ // create a context for Apache Velocity,
+ // based on the provided map
+ VelocityContext context = new VelocityContext(map);
+
+ // get the template from the engine and
+ // read it as an UTF-8 file
+ Template template = engine.getTemplate(input.getName(), "UTF-8");
+
+ // create an output stream from
+ // the file output reference
+ FileOutputStream stream = new FileOutputStream(output);
+
+ // create a writer based on the
+ // previously created stream
+ Writer writer = new OutputStreamWriter(stream, "UTF-8");
+
+ // merge the context map with the
+ // template file and write the result
+ // to the output stream writer
+ template.merge(context, writer);
+
+ // close both writer
+ // and output stream
+ writer.close();
+ stream.close();
+
+ } catch(ResourceNotFoundException rnfexception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_VELOCITY_FILE_NOT_FOUND
+ ),
+ rnfexception
+ );
+ } catch(ParseErrorException peexception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_VELOCITY_PARSE_EXCEPTION
+ ),
+ peexception
+ );
+ } catch(MethodInvocationException miexception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_VELOCITY_METHOD_INVOCATION_EXCEPTION
+ ),
+ miexception
+ );
+ } catch (IOException ioexception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_VELOCITY_FILE_NOT_FOUND
+ ),
+ ioexception
+ );
+ }
+
+ }
+
+}