From fe1b4db39a123ab248246844e7deb639551ae796 Mon Sep 17 00:00:00 2001 From: Matthias Gugel Date: Sun, 24 Jan 2021 01:35:03 +0100 Subject: [PATCH] Refactor placeholder processing Iterate over the characters of the template string and process placeholders from left to right instead of replacing placeholders in an arbitrary order. The main benefit to this approach is avoiding regex to locate the placeholders. Finding the placeholders with regex is trickier than it looks like at first glance especially when nested placeholder boundary characters have to be considered. For example '{' and '}' are reserved date pattern characters which might be used within a date placeholder in the future. --- .../CreateFileWithFilenameTemplateAction.kt | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt b/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt index f7ea062..2e9cacf 100644 --- a/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt +++ b/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt @@ -14,6 +14,7 @@ import java.awt.event.InputEvent import java.time.LocalDateTime import java.time.ZoneOffset import java.util.function.Consumer +import kotlin.math.max class CreateFileWithFilenameTemplateAction( text: String, @@ -52,7 +53,47 @@ class CreateFileWithFilenameTemplateAction( } private fun processTemplate(template: String): String { - val epoch = LocalDateTime.now(ZoneOffset.UTC).toEpochSecond(ZoneOffset.UTC) - return template.replace("{EPOCH}", epoch.toString()) + var placeholderLevel = 0 + var placeholder = "" + var filename = "" + + for (character in template) { + when (character) { + '{' -> { + if (0 < placeholderLevel) { + placeholder += character + } + + placeholderLevel += 1 + } + '}' -> { + if (placeholderLevel == 1) { + filename += processPlaceholder(placeholder) + placeholder = "" + } + + placeholderLevel = max(0, placeholderLevel - 1) + + if (0 < placeholderLevel) { + placeholder += character + } + } + else -> { + if (0 < placeholderLevel) { + placeholder += character + } else { + filename += character + } + } + } + } + + return filename } + + private fun processPlaceholder(placeholder: String): String = + when (placeholder) { + "EPOCH" -> LocalDateTime.now(ZoneOffset.UTC).toEpochSecond(ZoneOffset.UTC).toString() + else -> "{$placeholder}" + } }