Итерация по полям в config-config

У меня 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 и многие другие свойства.

Ответ 1

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

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

если вы вызываете entrySet в корневой config (не 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 в этой конфигурации, и вы получите все записи не от корневого объекта, а от перков. Не забывайте, что Configafe Config написан в java, а entrySet возвращает java.util.Set, поэтому вам нужно импортировать scala.collection.JavaConversions._

Ответ 2

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

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

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

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

Ответ 3

Тем, кому это может понадобиться:

val sysProperties = System.getProperties
val allConfig = ConfigFactory.load("perks.conf")
val appConfig = allConfig.entrySet().filter { entry =>
  !sysProperties.containsKey(entry.getKey)
}

Ответ 4

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

Я закончил с:

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

Ответ 5

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

this should work. but if your keyset is will print indifferent order than app.conf.

eg: 

'> cat application.conf'

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

above scrip will print as 

Value is :: [load_id, load_ts, load_file_nm]