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.
This commit is contained in:
Matthias Gugel 2021-01-24 01:35:03 +01:00
parent b1f1575809
commit fe1b4db39a

View File

@ -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}"
}
}