summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/CommonUtils.java
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/CommonUtils.java')
-rw-r--r--Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/CommonUtils.java929
1 files changed, 929 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/CommonUtils.java b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/CommonUtils.java
new file mode 100644
index 00000000000..621634749ef
--- /dev/null
+++ b/Master/texmf-dist/source/support/arara/src/main/java/com/github/cereda/arara/utils/CommonUtils.java
@@ -0,0 +1,929 @@
+/**
+ * Arara, the cool TeX automation tool
+ * Copyright (c) 2012 -- 2018, Paulo Roberto Massa Cereda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the project's author nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.github.cereda.arara.utils;
+
+import com.github.cereda.arara.controller.ConfigurationController;
+import com.github.cereda.arara.controller.LanguageController;
+import com.github.cereda.arara.controller.SystemCallController;
+import com.github.cereda.arara.model.AraraException;
+import com.github.cereda.arara.model.Argument;
+import com.github.cereda.arara.model.Database;
+import com.github.cereda.arara.model.FileType;
+import com.github.cereda.arara.model.Messages;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.MissingFormatArgumentException;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.filefilter.NameFileFilter;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.SystemUtils;
+
+/**
+ * Implements common utilitary methods.
+ * @author Paulo Roberto Massa Cereda
+ * @version 4.0
+ * @since 4.0
+ */
+public class CommonUtils {
+
+ // the application messages obtained from the
+ // language controller
+ private static final LanguageController messages =
+ LanguageController.getInstance();
+
+ /**
+ * Checks if the input string is equal to a valid boolean value.
+ * @param value The input string.
+ * @return A boolean value represented by the provided string.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean checkBoolean(String value) throws AraraException {
+ List<String> yes = Arrays.asList(
+ new String[]{"yes", "true", "1", "on"}
+ );
+ List<String> no = Arrays.asList(
+ new String[]{"no", "false", "0", "off"}
+ );
+ if (!union(yes, no).contains(value.toLowerCase())) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_CHECKBOOLEAN_NOT_VALID_BOOLEAN,
+ value
+ )
+ );
+ } else {
+ return yes.contains(value.toLowerCase());
+ }
+ }
+
+ /**
+ * Provides a union set operation between two lists.
+ * @param <T> The list type.
+ * @param list1 The first list.
+ * @param list2 The second list.
+ * @return The union of those two lists.
+ */
+ private static <T> List<T> union(List<T> list1, List<T> list2) {
+ Set<T> elements = new HashSet<T>();
+ elements.addAll(list1);
+ elements.addAll(list2);
+ return new ArrayList<T>(elements);
+ }
+
+ /**
+ * Build a system-dependant path based on the path and the file.
+ * @param path A string representing the path to be prepended.
+ * @param file A string representing the file to be appended.
+ * @return The full path as a string.
+ */
+ public static String buildPath(String path, String file) {
+ return path.endsWith(File.separator) ?
+ path.concat(file) : path.concat(File.separator).concat(file);
+ }
+
+ /**
+ * Checks if the provided string is empty. It does not handle a null value.
+ * @param string A string.
+ * @return A boolean value indicating if the string is empty.
+ */
+ public static boolean checkEmptyString(String string) {
+ return "".equals(string);
+ }
+
+ /**
+ * Removes the keyword from the beginning of the provided string.
+ * @param line A string to be analyzed.
+ * @return The provided string without the keyword.
+ */
+ public static String removeKeyword(String line) {
+ if (line != null) {
+ Pattern pattern = Pattern.compile("^(\\s)*<arara>\\s");
+ Matcher matcher = pattern.matcher(line);
+ if (matcher.find()) {
+ line = (line.substring(matcher.end(), line.length()));
+ }
+ line = line.trim();
+ }
+ return line;
+ }
+
+ /**
+ * Discovers the file through string reference lookup and sets the
+ * configuration accordingly.
+ * @param reference The string reference.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static void discoverFile(String reference) throws AraraException {
+ File file = lookupFile(reference);
+ if (file == null) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_DISCOVERFILE_FILE_NOT_FOUND,
+ reference,
+ getFileTypesList()
+ )
+ );
+ }
+ }
+
+ /**
+ * Performs a file lookup based on a string reference.
+ * @param reference The file reference as a string.
+ * @return The file as result of the lookup operation.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ private static File lookupFile(String reference) throws AraraException {
+ @SuppressWarnings("unchecked")
+ List<FileType> types = (List<FileType>) ConfigurationController.
+ getInstance().get("execution.filetypes");
+ File file = new File(reference);
+ String name = file.getName();
+ String parent = getParentCanonicalPath(file);
+ String path = buildPath(parent, name);
+
+ // direct search, so we are considering
+ // the reference as a complete name
+ for (FileType type : types) {
+ if (path.endsWith(".".concat(type.getExtension()))) {
+ file = new File(path);
+ if (file.exists()) {
+ if (file.isFile()) {
+ ConfigurationController.
+ getInstance().
+ put("execution.file.pattern",
+ type.getPattern());
+ ConfigurationController.
+ getInstance().
+ put("execution.reference", file);
+ return file;
+ }
+ }
+ }
+ }
+
+ // indirect search; in this case, we are considering
+ // that the file reference has an implict extension,
+ // so we need to add it and look again
+ for (FileType type : types) {
+ path = buildPath(parent, name.concat(".").
+ concat(type.getExtension()));
+ file = new File(path);
+ if (file.exists()) {
+ if (file.isFile()) {
+ ConfigurationController.getInstance().
+ put("execution.file.pattern", type.getPattern());
+ ConfigurationController.getInstance().
+ put("execution.reference", file);
+ return file;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Gets the parent canonical path of a file.
+ * @param file The file.
+ * @return The parent canonical path of a file.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static String getParentCanonicalPath(File file)
+ throws AraraException {
+ try {
+ String path = file.getCanonicalFile().getParent();
+ return path;
+ } catch (IOException exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_GETPARENTCANONICALPATH_IO_EXCEPTION
+ ),
+ exception
+ );
+ }
+ }
+
+ /**
+ * Gets the canonical file from a file.
+ * @param file The file.
+ * @return The canonical file.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static File getCanonicalFile(String file) throws AraraException {
+ try {
+ return (new File(file)).getCanonicalFile();
+ } catch (IOException exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_GETCANONICALFILE_IO_EXCEPTION
+ ),
+ exception
+ );
+ }
+ }
+
+ /**
+ * Checks if the provided object is from a certain class.
+ * @param clazz The class.
+ * @param object The object.
+ * @return A boolean value indicating if the provided object is from a
+ * certain class.
+ */
+ public static boolean checkClass(Class clazz, Object object) {
+ return clazz.isInstance(object);
+ }
+
+ /**
+ * Helper method to flatten a potential list of lists into a list of
+ * objects.
+ * @param list First list.
+ * @param flat Second list.
+ */
+ private static void flatten(List<?> list, List<Object> flat) {
+ for (Object item : list) {
+ if (item instanceof List<?>) {
+ flatten((List<?>) item, flat);
+ } else {
+ flat.add(item);
+ }
+ }
+ }
+
+ /**
+ * Flattens a potential list of lists into a list of objects.
+ * @param list The list to be flattened.
+ * @return The flattened list.
+ */
+ public static List<Object> flatten(List<?> list) {
+ List<Object> result = new ArrayList<Object>();
+ flatten(list, result);
+ return result;
+ }
+
+ /**
+ * Gets the list of file types, in order.
+ * @return A string representation of the list of file types, in order.
+ */
+ public static String getFileTypesList() {
+ @SuppressWarnings("unchecked")
+ List<FileType> types = (List<FileType>) ConfigurationController.
+ getInstance().get("execution.filetypes");
+ return getCollectionElements(types, "[ ", " ]", " | ");
+ }
+
+ /**
+ * Gets a string representation of a collection.
+ * @param collection The collection.
+ * @param open The opening string.
+ * @param close The closing string.
+ * @param separator The element separator.
+ * @return A string representation of the provided collection.
+ */
+ public static String getCollectionElements(Collection collection,
+ String open, String close, String separator) {
+ StringBuilder builder = new StringBuilder();
+ builder.append(open);
+ builder.append(StringUtils.join(collection, separator));
+ builder.append(close);
+ return builder.toString();
+ }
+
+ /**
+ * Gets a set of strings containing unknown keys from a map and a list. It
+ * is a set difference from the keys in the map and the entries in the list.
+ * @param parameters The map of parameters.
+ * @param arguments The list of arguments.
+ * @return A set of strings representing unknown keys from a map and a list.
+ */
+ public static Set<String> getUnknownKeys(Map<String, Object> parameters,
+ List<Argument> arguments) {
+ Collection<String> found = parameters.keySet();
+ Collection<String> expected = CollectionUtils.collect(
+ arguments, new Transformer<Argument, String>() {
+ public String transform(Argument argument) {
+ return argument.getIdentifier();
+ }
+ });
+ Collection<String> difference = CollectionUtils.
+ subtract(found, expected);
+ return new HashSet<String>(difference);
+ }
+
+ /**
+ * Gets the rule error header, containing the identifier and the path, if
+ * any.
+ * @return A string representation of the rule error header, containing the
+ * identifier and the path, if any.
+ */
+ public static String getRuleErrorHeader() {
+ if ((ConfigurationController.getInstance().
+ contains("execution.info.rule.id")) &&
+ (ConfigurationController.getInstance().
+ contains("execution.info.rule.path"))) {
+ String id = (String) ConfigurationController.getInstance().
+ get("execution.info.rule.id");
+ String path = (String) ConfigurationController.getInstance().
+ get("execution.info.rule.path");
+ return messages.getMessage(
+ Messages.ERROR_RULE_IDENTIFIER_AND_PATH,
+ id,
+ path
+ ).concat(" ");
+ } else {
+ return "";
+ }
+ }
+
+ /**
+ * Trims spaces from every string of a list of strings.
+ * @param input The list of strings.
+ * @return A new list of strings, with each element trimmed.
+ */
+ public static List<String> trimSpaces(List<String> input) {
+ Collection<String> result = CollectionUtils.collect(
+ input, new Transformer<String, String>() {
+ public String transform(String input) {
+ return input.trim();
+ }
+ });
+ return new ArrayList<String>(result);
+ }
+
+ /**
+ * Gets a human readable representation of a file size.
+ * @param file The file.
+ * @return A string representation of the file size.
+ */
+ public static String calculateFileSize(File file) {
+ return FileUtils.byteCountToDisplaySize(file.length());
+ }
+
+ /**
+ * Gets the date the provided file was last modified.
+ * @param file The file.
+ * @return A string representation of the date the provided file was last
+ * modified.
+ */
+ public static String getLastModifiedInformation(File file) {
+ SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
+ return format.format(file.lastModified());
+ }
+
+ /**
+ * Gets a list of all rule paths.
+ * @return A list of all rule paths.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static List<String> getAllRulePaths() throws AraraException {
+ @SuppressWarnings("unchecked")
+ List<String> paths = (List<String>) ConfigurationController.
+ getInstance().get("execution.rule.paths");
+ List<String> result = new ArrayList<String>();
+ for (String path : paths) {
+ File location = new File(InterpreterUtils.construct(path, "quack"));
+ result.add(getParentCanonicalPath(location));
+ }
+ return result;
+ }
+
+ /**
+ * Gets the reference of the current file in execution. Note that this
+ * method might return a value different than the main file provided in
+ * the command line.
+ * @return A reference of the current file in execution. Might be different
+ * than the main file provided in the command line.
+ */
+ private static File getCurrentReference() {
+ return (File) ConfigurationController.getInstance().
+ get("execution.file");
+ }
+
+ /**
+ * Calculates the CRC32 checksum of the provided file.
+ * @param file The file.
+ * @return A string containing the CRC32 checksum of the provided file.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static String calculateHash(File file) throws AraraException {
+ try {
+ long result = FileUtils.checksumCRC32(file);
+ return String.format("%08x", result);
+ } catch (IOException exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_CALCULATEHASH_IO_EXCEPTION
+ ),
+ exception
+ );
+ }
+ }
+
+ /**
+ * Gets the file type of a file.
+ * @param file The file.
+ * @return The corresponding file type.
+ */
+ public static String getFiletype(File file) {
+ return getFiletype(file.getName());
+ }
+
+ /**
+ * Gets the file type of a string representing the file.
+ * @param name A string representing the file.
+ * @return The corresponding file type.
+ */
+ public static String getFiletype(String name) {
+ name = name.lastIndexOf(".") != -1 ?
+ name.substring(name.lastIndexOf(".") + 1, name.length()) : "";
+ return name;
+ }
+
+ /**
+ * Gets the base name of a file.
+ * @param file The file.
+ * @return The corresponding base name.
+ */
+ public static String getBasename(File file) {
+ return getBasename(file.getName());
+ }
+
+ /**
+ * Gets the base name of a string representing the file.
+ * @param name A string representing the file.
+ * @return The corresponding base name.
+ */
+ public static String getBasename(String name) {
+ int index = name.lastIndexOf(".") != -1 ?
+ name.lastIndexOf(".") : name.length();
+ return name.substring(0, index);
+ }
+
+ /**
+ * Encloses the provided object in double quotes.
+ * @param object The object.
+ * @return A string representation of the provided object enclosed in double
+ * quotes.
+ */
+ public static String addQuotes(Object object) {
+ return "\"".concat(String.valueOf(object)).concat("\"");
+ }
+
+ /**
+ * Generates a string based on a list of objects, separating each one of
+ * them by one space.
+ * @param objects A list of objects.
+ * @return A string based on the list of objects, separating each one of
+ * them by one space. Empty values are not considered.
+ */
+ public static String generateString(Object... objects) {
+ List<String> values = new ArrayList<String>();
+ for (Object object : objects) {
+ if (!CommonUtils.checkEmptyString(String.valueOf(object))) {
+ values.add(String.valueOf(object));
+ }
+ }
+ return StringUtils.join(values, " ");
+ }
+
+ /**
+ * Checks if a file exists.
+ * @param file The file.
+ * @return A boolean value indicating if the file exists.
+ */
+ public static boolean exists(File file) {
+ return file.exists();
+ }
+
+ /**
+ * Checks if a file exists based on its extension.
+ * @param extension The extension.
+ * @return A boolean value indicating if the file exists.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean exists(String extension) throws AraraException {
+ File file = new File(getPath(extension));
+ return file.exists();
+ }
+
+ /**
+ * Checks if a file has changed since the last verification.
+ * @param file The file.
+ * @return A boolean value indicating if the file has changed since the last
+ * verification.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean hasChanged(File file) throws AraraException {
+ Database database = DatabaseUtils.load();
+ HashMap<String, String> map = database.getMap();
+ String path = getCanonicalPath(file);
+ if (!file.exists()) {
+ if (map.containsKey(path)) {
+ map.remove(path);
+ database.setMap(map);
+ DatabaseUtils.save(database);
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ String hash = calculateHash(file);
+ if (map.containsKey(path)) {
+ String value = map.get(path);
+ if (hash.equals(value)) {
+ return false;
+ } else {
+ map.put(path, hash);
+ database.setMap(map);
+ DatabaseUtils.save(database);
+ return true;
+ }
+ } else {
+ map.put(path, hash);
+ database.setMap(map);
+ DatabaseUtils.save(database);
+ return true;
+ }
+ }
+ }
+
+ /**
+ * Checks if the file has changed since the last verification based on the
+ * provided extension.
+ * @param extension The provided extension.
+ * @return A boolean value indicating if the file has changed since the last
+ * verification.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean hasChanged(String extension) throws AraraException {
+ File file = new File(getPath(extension));
+ return hasChanged(file);
+ }
+
+ /**
+ * Gets the full file path based on the provided extension.
+ * @param extension The extension.
+ * @return A string containing the full file path.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ private static String getPath(String extension) throws AraraException {
+ String name = getBasename(getCurrentReference());
+ String path = getParentCanonicalPath(getCurrentReference());
+ name = name.concat(".").concat(extension);
+ return buildPath(path, name);
+ }
+
+ /**
+ * Gets the canonical path from the provided file.
+ * @param file The file.
+ * @return The canonical path from the provided file.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static String getCanonicalPath(File file) throws AraraException {
+ try {
+ return file.getCanonicalPath();
+ } catch (IOException exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_GETCANONICALPATH_IO_EXCEPTION
+ ),
+ exception
+ );
+ }
+ }
+
+ /**
+ * Checks if the file based on the provided extension contains the provided
+ * regex.
+ * @param extension The file extension.
+ * @param regex The regex.
+ * @return A boolean value indicating if the file contains the provided
+ * regex.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean checkRegex(String extension, String regex)
+ throws AraraException {
+ File file = new File(getPath(extension));
+ return checkRegex(file, regex);
+ }
+
+ /**
+ * Checks if the file contains the provided regex.
+ * @param file The file.
+ * @param regex The regex.
+ * @return A boolean value indicating if the file contains the provided
+ * regex.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean checkRegex(File file, String regex)
+ throws AraraException {
+ Charset charset = (Charset) ConfigurationController.
+ getInstance().get("directives.charset");
+ try {
+ String text = FileUtils.readFileToString(file, charset.name());
+ Pattern pattern = Pattern.compile(regex);
+ Matcher matcher = pattern.matcher(text);
+ return matcher.find();
+ } catch (IOException exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_CHECKREGEX_IO_EXCEPTION,
+ file.getName()
+ ),
+ exception
+ );
+ }
+ }
+
+ /**
+ * Replicates a string pattern based on a list of objects, generating a list
+ * as result.
+ * @param pattern The string pattern.
+ * @param values The list of objects to be merged with the pattern.
+ * @return A list containing the string pattern replicated to each object
+ * from the list.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static List<Object> replicateList(String pattern,
+ List<Object> values) throws AraraException {
+ List<Object> result = new ArrayList<Object>();
+ for (Object value : values) {
+ try {
+ result.add(String.format(pattern, value));
+ } catch (MissingFormatArgumentException exception) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_REPLICATELIST_MISSING_FORMAT_ARGUMENTS_EXCEPTION
+ ),
+ exception
+ );
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Checks if the provided operating system string holds according to the
+ * underlying operating system.
+ * @param value A string representing an operating system.
+ * @return A boolean value indicating if the provided string refers to the
+ * underlying operating system.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static boolean checkOS(String value) throws AraraException {
+ Map<String, Boolean> values = new HashMap<String, Boolean>();
+ values.put("windows", SystemUtils.IS_OS_WINDOWS);
+ values.put("linux", SystemUtils.IS_OS_LINUX);
+ values.put("mac", SystemUtils.IS_OS_MAC_OSX);
+ values.put("unix", SystemUtils.IS_OS_UNIX);
+ values.put("aix", SystemUtils.IS_OS_AIX);
+ values.put("irix", SystemUtils.IS_OS_IRIX);
+ values.put("os2", SystemUtils.IS_OS_OS2);
+ values.put("solaris", SystemUtils.IS_OS_SOLARIS);
+ values.put("cygwin", (Boolean) SystemCallController.
+ getInstance().get("cygwin"));
+ if (!values.containsKey(value.toLowerCase())) {
+ throw new AraraException(
+ messages.getMessage(
+ Messages.ERROR_CHECKOS_INVALID_OPERATING_SYSTEM,
+ value
+ )
+ );
+ }
+ return values.get(value.toLowerCase());
+ }
+
+ /**
+ * Returns the exit status of the application.
+ * @return An integer representing the exit status of the application.
+ */
+ public static int getExitStatus() {
+ return (Integer) ConfigurationController.
+ getInstance().get("execution.status");
+ }
+
+ /**
+ * Gets the system property according to the provided key, or resort to the
+ * fallback value if an exception is thrown or if the key is invalid.
+ * @param key The system property key.
+ * @param fallback The fallback value.
+ * @return A string containing the system property value or the fallback.
+ */
+ public static String getSystemProperty(String key, String fallback) {
+ try {
+ String result = System.getProperty(key, fallback);
+ return result.equals("") ? fallback : result;
+ } catch (Exception exception) {
+ return fallback;
+ }
+ }
+
+ /**
+ * Gets the preamble content, converting a single string into a list of
+ * strings, based on new lines.
+ * @return A list of strings representing the preamble content.
+ */
+ public static List<String> getPreambleContent() {
+ if (((Boolean) ConfigurationController.
+ getInstance().get("execution.preamble.active")) == true) {
+ return new ArrayList<String>(
+ Arrays.asList(
+ ((String) ConfigurationController.getInstance().
+ get("execution.preamble.content")
+ ).split("\n"))
+ );
+ }
+ else {
+ return new ArrayList<String>();
+ }
+ }
+
+ /**
+ * Generates a list of filenames from the provided command based on a list
+ * of extensions for each underlying operating system.
+ * @param command A string representing the command.
+ * @return A list of filenames.
+ */
+ private static List<String> appendExtensions(String command) {
+
+ // the resulting list, to hold the
+ // filenames generated from the
+ // provided command
+ List<String> result = new ArrayList<String>();
+
+ // list of extensions, specific for
+ // each operating system (in fact, it
+ // is more Windows specific)
+ List<String> extensions;
+
+ // the application is running on
+ // Windows, so let's look for the
+ // following extensions in order
+ if (SystemUtils.IS_OS_WINDOWS) {
+
+ // this list is actually a sublist from
+ // the original Windows PATHEXT environment
+ // variable which holds the list of executable
+ // extensions that Windows supports
+ extensions = Arrays.asList(".com", ".exe", ".bat", ".cmd");
+ }
+ else {
+
+ // no Windows, so the default
+ // extension will be just an
+ // empty string
+ extensions = Arrays.asList("");
+ }
+
+ // for each and every extension in the
+ // list, let's build the corresponding
+ // filename and add to the result
+ for (String extension : extensions) {
+ result.add(command.concat(extension));
+ }
+
+ // return the resulting list
+ // holding the filenames
+ return result;
+ }
+
+ /**
+ * Checks if the provided command name is reachable from the system path.
+ * @param command A string representing the command.
+ * @return A logic value.
+ */
+ public static boolean isOnPath(String command) {
+ try {
+
+ // first and foremost, let's build the list
+ // of filenames based on the underlying
+ // operating system
+ List<String> filenames = appendExtensions(command);
+
+ // break the path into several parts
+ // based on the path separator symbol
+ StringTokenizer tokenizer = new StringTokenizer(
+ System.getenv("PATH"),
+ File.pathSeparator
+ );
+
+ // iterate through every part of the
+ // path looking for each filename
+ while (tokenizer.hasMoreTokens()) {
+
+ // if the search does not return an empty
+ // list, one of the filenames got a match,
+ // and the command is available somewhere
+ // in the system path
+ if (
+ !FileUtils.listFiles(
+ new File(tokenizer.nextToken()),
+ new NameFileFilter(filenames),
+ null
+ ).isEmpty()) {
+
+ // command is found somewhere,
+ // so it is on path
+ return true;
+ }
+ }
+
+ // nothing was found,
+ // command is not on path
+ return false;
+ }
+ catch (Exception exception) {
+
+ // an exception was raised, simply
+ // return and forget about it
+ return false;
+ }
+ }
+
+ /**
+ * Gets the full base name of a file.
+ * @param file The file.
+ * @return The corresponding full base name.
+ * @throws AraraException Something wrong happened, to be caught in the
+ * higher levels.
+ */
+ public static String getFullBasename(File file) throws AraraException {
+
+ // if the provided file does not contain a
+ // file separator, fallback to the usual
+ // base name lookup
+ if (!file.toString().contains(File.separator)) {
+ return getBasename(file);
+ }
+ else {
+
+ // we need to get the parent file, get the
+ // canonical path and build the corresponding
+ // full base name path
+ File parent = file.getParentFile();
+ String path = getCanonicalPath(parent == null ? file : parent);
+ return buildPath(path, getBasename(file));
+ }
+ }
+
+}