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