summaryrefslogtreecommitdiff
path: root/support/arara/source/src/main/kotlin/org/islandoftex/arara/ruleset/DirectiveUtils.kt
diff options
context:
space:
mode:
Diffstat (limited to 'support/arara/source/src/main/kotlin/org/islandoftex/arara/ruleset/DirectiveUtils.kt')
-rw-r--r--support/arara/source/src/main/kotlin/org/islandoftex/arara/ruleset/DirectiveUtils.kt312
1 files changed, 0 insertions, 312 deletions
diff --git a/support/arara/source/src/main/kotlin/org/islandoftex/arara/ruleset/DirectiveUtils.kt b/support/arara/source/src/main/kotlin/org/islandoftex/arara/ruleset/DirectiveUtils.kt
deleted file mode 100644
index e901e25fcf..0000000000
--- a/support/arara/source/src/main/kotlin/org/islandoftex/arara/ruleset/DirectiveUtils.kt
+++ /dev/null
@@ -1,312 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-package org.islandoftex.arara.ruleset
-
-import com.fasterxml.jackson.databind.ObjectMapper
-import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
-import com.fasterxml.jackson.module.kotlin.readValue
-import com.fasterxml.jackson.module.kotlin.registerKotlinModule
-import java.io.File
-import java.util.regex.Pattern
-import org.islandoftex.arara.Arara
-import org.islandoftex.arara.configuration.AraraSpec
-import org.islandoftex.arara.filehandling.FileHandlingUtils
-import org.islandoftex.arara.localization.LanguageController
-import org.islandoftex.arara.localization.Messages
-import org.islandoftex.arara.model.AraraException
-import org.islandoftex.arara.utils.DisplayUtils
-import org.slf4j.LoggerFactory
-
-/**
- * Implements directive utilitary methods.
- *
- * @author Island of TeX
- * @version 5.0
- * @since 4.0
- */
-@UseExperimental(kotlinx.serialization.ImplicitReflectionSerializer::class)
-object DirectiveUtils {
- // the application messages obtained from the
- // language controller
- private val messages = LanguageController
-
- // get the logger context from a factory
- private val logger = LoggerFactory.getLogger(DirectiveUtils::class.java)
-
- /**
- * This function filters the lines of a file to identify the potential
- * directives.
- *
- * @param lines The lines of the file.
- * @return A map containing the line number and the line's content.
- */
- private fun getPotentialDirectiveLines(lines: List<String>):
- Map<Int, String> {
- val header = Arara.config[AraraSpec.Execution.onlyHeader]
- val validLineRegex = Arara.config[AraraSpec.Execution.filePattern]
- val validLinePattern = validLineRegex.toPattern()
- val validLineStartPattern = (validLineRegex + Arara.config[AraraSpec
- .Application.namePattern]).toPattern()
- val map = mutableMapOf<Int, String>()
- for ((i, text) in lines.withIndex()) {
- val validLineMatcher = validLineStartPattern.matcher(text)
- if (validLineMatcher.find()) {
- val line = text.substring(validLineMatcher.end())
- map[i + 1] = line
-
- logger.info(messages.getMessage(
- Messages.LOG_INFO_POTENTIAL_PATTERN_FOUND,
- i + 1, line.trim()))
- } else if (header && !checkLinePattern(validLinePattern, text)) {
- // if we should only look within the file's header and reached
- // a point where the line pattern does not match anymore, we
- // assume we have left the header and break
- break
- }
- }
- return map
- }
-
- /**
- * Extracts a list of directives from a list of strings.
- *
- * @param lines List of strings.
- * @return A list of directives.
- * @throws AraraException Something wrong happened, to be caught in the
- * higher levels.
- */
- @Throws(AraraException::class)
- @Suppress("MagicNumber")
- fun extractDirectives(lines: List<String>): List<Directive> {
- val pairs = getPotentialDirectiveLines(lines)
- .takeIf { it.isNotEmpty() }
- ?: throw AraraException(messages.getMessage(
- Messages.ERROR_VALIDATE_NO_DIRECTIVES_FOUND))
-
- val assemblers = mutableListOf<DirectiveAssembler>()
- var assembler = DirectiveAssembler()
- val linebreakPattern = Arara.config[AraraSpec.Directive
- .linebreakPattern].toPattern()
- for ((lineno, content) in pairs) {
- val linebreakMatcher = linebreakPattern.matcher(content)
- if (linebreakMatcher.find()) {
- if (!assembler.isAppendAllowed) {
- throw AraraException(
- messages.getMessage(
- Messages.ERROR_VALIDATE_ORPHAN_LINEBREAK,
- lineno
- )
- )
- } else {
- assembler.addLineNumber(lineno)
- assembler.appendLine(linebreakMatcher.group(1))
- }
- } else {
- if (assembler.isAppendAllowed) {
- assemblers.add(assembler)
- }
- assembler = DirectiveAssembler()
- assembler.addLineNumber(lineno)
- assembler.appendLine(content)
- }
- }
- if (assembler.isAppendAllowed) {
- assemblers.add(assembler)
- }
-
- return assemblers.map { generateDirective(it) }
- }
-
- /**
- * Generates a directive from a directive assembler.
- *
- * @param assembler The directive assembler.
- * @return The corresponding directive.
- * @throws AraraException Something wrong happened, to be caught in the
- * higher levels.
- */
- @Throws(AraraException::class)
- @Suppress("MagicNumber")
- fun generateDirective(assembler: DirectiveAssembler): Directive {
- val matcher = Arara.config[AraraSpec.Directive.directivePattern]
- .toPattern().matcher(assembler.getText())
- if (matcher.find()) {
- val directive = Directive(
- identifier = matcher.group(1)!!,
- parameters = getParameters(matcher.group(3),
- assembler.getLineNumbers()),
- conditional = Conditional(
- type = getType(matcher.group(5)),
- condition = matcher.group(6) ?: ""
- ),
- lineNumbers = assembler.getLineNumbers()
- )
-
- logger.info(messages.getMessage(
- Messages.LOG_INFO_POTENTIAL_DIRECTIVE_FOUND, directive))
-
- return directive
- } else {
- throw AraraException(
- messages.getMessage(
- Messages.ERROR_VALIDATE_INVALID_DIRECTIVE_FORMAT,
- "(" + assembler.getLineNumbers()
- .joinToString(", ") + ")"
- )
- )
- }
- }
-
- /**
- * Gets the conditional type based on the input string.
- *
- * @param text The input string.
- * @return The conditional type.
- */
- private fun getType(text: String?): Conditional.ConditionalType {
- return when (text) {
- null -> Conditional.ConditionalType.NONE
- "if" -> Conditional.ConditionalType.IF
- "while" -> Conditional.ConditionalType.WHILE
- "until" -> Conditional.ConditionalType.UNTIL
- else -> Conditional.ConditionalType.UNLESS
- }
- }
-
- /**
- * Gets the parameters from the input string.
- *
- * @param text The input string.
- * @param numbers The list of line numbers.
- * @return A map containing the directive parameters.
- * @throws AraraException Something wrong happened, to be caught in the
- * higher levels.
- */
- @Throws(AraraException::class)
- private fun getParameters(
- text: String?,
- numbers: List<Int>
- ): Map<String, Any> {
- if (text == null)
- return mapOf()
-
- /* Before using kotlinx.serialization, there has been a dedicated
- * directive resolver which instructed SnakeYAML to do the following:
- *
- * addImplicitResolver(Tag.MERGE, MERGE, "<")
- * addImplicitResolver(Tag.NULL, NULL, "~nN\u0000")
- * addImplicitResolver(Tag.NULL, EMPTY, null)
- *
- * This has been removed.
- */
- return ObjectMapper(YAMLFactory()).registerKotlinModule().runCatching {
- readValue<Map<String, Any>>(text)
- }.getOrElse {
- throw AraraException(messages.getMessage(
- Messages.ERROR_VALIDATE_YAML_EXCEPTION,
- "(" + numbers.joinToString(", ") + ")"),
- it)
- }
- }
-
- /**
- * Replicate a directive for given files.
- *
- * @param holder The list of files.
- * @param parameters The parameters for the directive.
- * @param directive The directive to clone.
- * @return List of cloned directives.
- * @throws AraraException If there is an error validating the [holder]
- * object.
- */
- @Throws(AraraException::class)
- private fun replicateDirective(
- holder: Any,
- parameters: Map<String, Any>,
- directive: Directive
- ): List<Directive> {
- return if (holder is List<*>) {
- // we received a file list, so we map that list to files
- holder.filterIsInstance<Any>()
- .asSequence()
- .map { File(it.toString()) }
- .map(FileHandlingUtils::getCanonicalFile)
- // and because we want directives, we replicate our
- // directive to be applied to that file
- .map { reference ->
- directive.copy(parameters = parameters
- .plus("reference" to reference))
- }
- .toList()
- // we take the result if and only if we have at least one
- // file and we did not filter out any invalid argument
- .takeIf { it.isNotEmpty() && holder.size == it.size }
- // TODO: check exception according to condition
- ?: throw AraraException(
- messages.getMessage(
- Messages.ERROR_VALIDATE_EMPTY_FILES_LIST,
- "(" + directive.lineNumbers
- .joinToString(", ") + ")"
- )
- )
- } else {
- throw AraraException(
- messages.getMessage(
- Messages.ERROR_VALIDATE_FILES_IS_NOT_A_LIST,
- "(" + directive.lineNumbers.joinToString(", ") + ")"
- )
- )
- }
- }
-
- /**
- * Validates the list of directives, returning a new list.
- *
- * @param directives The list of directives.
- * @return A new list of directives.
- * @throws AraraException Something wrong happened, to be caught in the
- * higher levels.
- */
- @Throws(AraraException::class)
- fun process(directives: List<Directive>): List<Directive> {
- val result = mutableListOf<Directive>()
- directives.forEach { directive ->
- val parameters = directive.parameters
-
- if (parameters.containsKey("reference"))
- throw AraraException(messages.getMessage(
- Messages.ERROR_VALIDATE_REFERENCE_IS_RESERVED,
- "(" + directive.lineNumbers.joinToString(", ") + ")"))
-
- if (parameters.containsKey("files")) {
- result.addAll(replicateDirective(parameters.getValue("files"),
- parameters.minus("files"), directive))
- } else {
- result.add(directive.copy(parameters = parameters
- .plus("reference" to
- Arara.config[AraraSpec.Execution.reference])))
- }
- }
-
- logger.info(messages.getMessage(
- Messages.LOG_INFO_VALIDATED_DIRECTIVES))
- logger.info(DisplayUtils.displayOutputSeparator(
- messages.getMessage(Messages.LOG_INFO_DIRECTIVES_BLOCK)))
- result.forEach { logger.info(it.toString()) }
- logger.info(DisplayUtils.displaySeparator())
-
- return result
- }
-
- /**
- * Checks if the provided line contains the corresponding pattern, based on
- * the file type, or an empty line.
- *
- * @param pattern Pattern to be matched, based on the file type.
- * @param line Provided line.
- * @return Logical value indicating if the provided line contains the
- * corresponding pattern, based on the file type, or an empty line.
- */
- private fun checkLinePattern(pattern: Pattern, line: String): Boolean {
- return line.isBlank() || pattern.matcher(line).find()
- }
-}