Перебирать поля в конфигурации typesafe

У меня есть perks.conf:

autoshield {
    name="autoshield"
    price=2
    description="autoshield description"
}
immunity {
    name="immunity"
    price=2
    description="autoshield description"
}
premium {
    name="premium"
    price=2
    description="premium description"
}
starter {
    name="starter"
    price=2
    description="starter description"
}
jetpack {
    name="jetpack"
    price=2
    description="jetpack description"
}

И я хочу перебрать перки в своем приложении примерно так:

val conf: Config = ConfigFactory.load("perks.conf")
val entries = conf.getEntries()
for (entry <- entries) yield {
  Perk(entry.getString("name"), entry.getInt("price"), entry.getString("description"))
}

Но я не могу найти подходящий метод, который возвращает все записи из config. Я пробовал config.root(), но кажется, что он возвращает все свойства, включая system, akka и множество других свойств.


person Egor Koshelko    schedule 11.07.2013    source источник
comment
Пробовали ли вы entrySet ?   -  person vidit    schedule 11.07.2013


Ответы (5)


Например, у вас есть следующий код в вашем Settings.scala

val conf = ConfigFactory.load("perks.conf")

если вы вызовете entrySet в корневой конфигурации (не conf.root(), а корневой объект этой конфигурации), он вернет много мусора, что вам нужно сделать, это поместить все свои перки по какому-то пути в perks.conf:

perks {
  autoshield {
    name="autoshield"
    price=2
    description="autoshield description"
  }
  immunity {
    name="immunity"
    price=2
    description="autoshield description"
  }
}

а затем в файле Settings.scala получить этот конфиг:

val conf = ConfigFactory.load("perks.conf").getConfig("perks")

а потом вызовите entrySet на этом конфиге и вы получите все записи не из корневого объекта, а из перков. Не забывайте, что Typesafe Config написан на java, а entrySet возвращает java.util.Set, поэтому вам нужно импортировать scala.collection.JavaConversions._

person 4lex1v    schedule 11.07.2013

entrySet сворачивает дерево. Если вы хотите перебирать только непосредственные дочерние элементы, используйте:

conf.getObject("perks").asScala.foreach({ case (k, v) => ... })

k будет "autoshield" и "иммунитет", но не "autoshield.name", "autoshield.price" и т.д.

Для этого необходимо импортировать scala.collection.JavaConverters._.

person Yuri Geinish    schedule 26.02.2014
comment
ЭТО должен быть принятый ответ. JavaConversions очень полезная штука. - person sph21; 11.08.2017
comment
Нет такого метода :-( - person user123; 23.02.2018

getObject дал мне квалифицированный объект json (например, timeout.ms = 5 становится { timeout: { ms: 5 }).

Я закончил с:

conf.getConfig(baseKey).entrySet().foreach { entry =>
   println(s"${entry.getKey} = ${entry.getValue.unwrapped().toString}")
}
person AlonL    schedule 07.12.2016

val common = allConfig.getConfig("column.audit")
   val commonList = common.root().keySet()
      commonList.iterator().foreach( x => { 
      println("Value is :: " + x) 
    }
   )

Это должно работать. Но если ваш набор ключей будет печататься в другом порядке, чем app.conf.

e.g.:

> cat application.conf

`column {
  audit {
    load_ts = "current_timestamp",
    load_file_nm = "current_filename",
    load_id = "load_id"
  }`

приведенный выше скрипт напечатает это:

Value is :: [load_id, load_ts, load_file_nm]
person Balaji Tr    schedule 05.02.2019

Кому может понадобиться:

val sysProperties = System.getProperties
val allConfig = ConfigFactory.load("perks.conf")
val appConfig = allConfig.entrySet().filter { entry =>
  !sysProperties.containsKey(entry.getKey)
}
person wood    schedule 02.02.2016
comment
ConfigFactory.parseResourcesAnySyntax(perks.conf) будет извлекать только конфигурации из файла и не добавлять системные свойства. - person PJ Fanning; 13.06.2018
comment
Вы можете использовать ConfigFactory.systemProperties().withFallback(yourConfig) - person Mahmoud Hanafy; 09.06.2020