Как стать автором
Обновить

Комментарии 19

Пишу конфиги на котлин скрипте, по большому счету принцип тот же что в груви, только есть автодополнение и нет methodMissing:


config {
    jetty {
        httpConnector {
            port = 4242
            host = "0.0.0.0"
        }
    }
}

Можно еще вспонить проект https://github.com/gradle/kotlin-dsl для gradle который приносит те же прелести нормального тулинга

результат очень напоминает hocon, возможно, вам не стоит городить таких огородов с груви и котлин
Я смотрел в его сторону и написал, почему он нам не подошел: эта библиотека плохо маппит конфиг на бины, а кроме того, не умеет работать ни с какими мапами, кроме <String, Object>. То есть, нельзя, например, использовать enum в качестве ключей.
да, прошу прощения, пропустил абзац с объяснением
Сначала написали такое же на groovy DSL. Потом переписали на kotlin DSL. Намного лучше стало.
У нас ещё была причина на груви писать- тогда котлин ещё не поддерживал DSL (появилось в 1.1.1)- но сейчас груви не нужен.
А там нужно объявлять методы для каждого из полей, или есть какой-то аналог methodMissing или, может быть, аннотация над полем, чтобы к нему лямбда применялась?
Методы не нужно- паблик поля и так работают (методы будут, там сахар).
methodMissing — нет и я не понимаю зачем это надо. Мы ж хотим бины- зачем делать свалку, куда попадёт куча мусора? нужно лишь описать классы с полями- и всё.
А аннотация с лямбдой- это о чём?
В первом комментарии приведен пример конфига. Поле jetty, например, как заполнится? Что для этого надо сделать? Достаточно просто объявить его как паблик и все?
Да. Именно.
А про какое вообще поле речь и где оно заполнится автоматически? Я знаю только один способ сделать такое, но тут нужно и методы писать, и их реализацию. Неужели я упустил что-то очень крутое?!..
class HttpConnector(var port: Int? = null, var host: String? = null)
class JettyBuilder {
    fun httpConnector(f: HttpConnector.() -> Unit): Unit = TODO()
}
class ConfigBuilder {
    fun jetty(f: JettyBuilder.() -> Unit): Unit = TODO()
}
fun config(f: ConfigBuilder.() -> Unit): Unit = TODO()
тогда котлин ещё не поддерживал DSL (появилось в 1.1.1)

А поясните пожалуйста. kotlin dsl — это экстеншн лямбды и возможность писать лямбду-последний аргумент «за пределами вызова функции» как блок кода. Обе эти штуки были с релиза.
Может, для этого уже есть библиотека?

Да полно. Вот очень неплохой вариант: http://owner.aeonbits.org/.
Для себя я уже давно решил проблему конфигов: использую стандартный JAXB. Структура описывается прямо в бинах при помощи парочки аннотаций. Все сериализуется в XML. Maven автоматически генерит XSD, который понимает IDE и позволяет делать autocomplete при редактировании конфига.

У нас как раз все через JAXB было сделано, но не хватало «наследования» конфигов, приходилось править в 30 местах примерно.

Не совсем понял, что вы имеете ввиду под "наследованием" конфигов. Если это наследование бинов, то у JAXB с этим проблем нет. А если дефолтные значения для полей, то их можно указывать прямо при описании самих полей:


public class DatabaseConfig {
    public String url = "jdbc:h2:mem:test";
    public String username = "sa";
    public String password = "";
}
Я не знаю, как это назвать, но суть такая. У нас есть, условно, 5 конфигов для разных тестовых площадок, которые совпадают на 90%. Хотелось бы иметь некий «родительский» конфиг, в котором описан условный дефолтный тест, а в этих пяти конфигах переопределить необходимые им 10%.

Дык, захардкодьте весь дефолтный конфиг значениями прямо в бинах, как я показал выше. А в xml нужно будет прописывать только элементы, значения которых отличаются. JAXB будет создавать объект с дефолтными параметрами, и перезаписывать только поля, указанные в xml. В идеале с пустым xml будет создаваться полный дефолтный конфиг.

Можно ли потом готовый бин изменить программно и записать обратно в такой файл, в таком же формате? Мне бы это пригодилось для хранения настроек моих парсеров. Настройки пользователи меняют в процессе работы.
Нет, какого-то простого способа для этого нет, надо делать какой-то свой сериализатор, перечисляя поля через reflection, например.

Если у вас есть кложур с делегатом, выставляйте аннотацию DelegatesTo, тогда ваш DSL будет подерживать систему типов, автокомплит, и статическую компиляцию

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации