Динамическая подстановка конфигурационного файла HOCON

Я использую HOCON для настройки сообщений журнала и ищу способ динамической замены значений заполнителей.

Я знаю, что ${?PLACEHOLDER} прочитает переменную среды и вернет пустую строку, если переменная среды PLACEHOLDER не существует.

Пример

Это пример того, что я имел в виду:

(Я использую config4k для загрузки HOCON)

data class LogMessage(val message: String, val code: String)

fun getMessage(key: String, placeholderValues: Array<String> = arrayOf()): LogMessage {
    val config = ConfigFactory.parseString("MY_LOG_MESSAGE {code = ABC-123456, message = My log message with dynamic value %0% and another dynamic value %1% }")

    val messageObject = config.extract<LogMessage>(key)
    var message = messageObject.message

    placeholderValues.forEachIndexed { placeholderIndex, value ->
        message = message.replace("%$placeholderIndex%", value)
    }

    return messageObject.copy(message = message)
}

fun main(args: Array<String>) {    
    println(getMessage("MY_LOG_MESSAGE", arrayOf("value 1", "value 2")))

    // prints: LogMessage(message=My log message with dynamic value value 1 and another dynamic value value 2, code=ABC-123456)
}

Несмотря на то, что это работает, это не похоже на лучшее решение, и я предполагаю, что решение для этого уже есть.

Может кто подскажет, есть ли встроенное решение?


person Johan Vergeer    schedule 23.08.2018    source источник


Ответы (1)


Перво-наперво.
HOCON - это просто прославленный формат JSON. config4k - это просто оболочка.
Вся ваша работа выполняется с помощью Typesafe Config, как и вы наверное, заметили.
И, судя по их документации и коду, они поддерживают заполнители только внутри файла или из среды:

Эта библиотека ограничивается файлами конфигурации. Если вы хотите загрузить конфигурацию из базы данных или чего-то еще, вам нужно будет написать собственный код.

Но для того, что вы делаете, достаточно простого String.format():

fun interpolate(message: String, vararg args: Any) = String.format(message, *args)

println(interpolate("My message was %s %s %s %s", "a", 1, 3.32, true)) 
// My message was a 1 3.32 true

Обратите внимание, что вы можете использовать * для деструктуризации вашего массива.

person Alexey Soshin    schedule 24.08.2018