Создание экземпляра класса Case из Typesafe Config

Предположим, у меня есть класс case scala с возможностью сериализации в json (используя json4s или другую библиотеку):

case class Weather(zip : String, temp : Double, isRaining : Boolean)

Если я использую файл конфигурации HOCON:

allWeather {

   BeverlyHills {
    zip : 90210
    temp : 75.0
    isRaining : false
  }

  Cambridge {
    zip : 10013
    temp : 32.0
    isRainging : true
  }

}

Есть ли способ использовать безопасную конфигурацию для автоматического создания экземпляра объекта Weather?

Я ищу что-то в форме

val config : Config = ConfigFactory.parseFile(new java.io.File("weather.conf"))

val bevHills : Weather = config.getObject("allWeather.BeverlyHills").as[Weather]

Решение могло бы использовать тот факт, что значение, на которое ссылается "allWeather.BeverlyHills", является json "blob".

Очевидно, я мог бы написать свой собственный парсер:

def configToWeather(config : Config) = 
  Weather(config.getString("zip"), 
          config.getDouble("temp"), 
          config.getBoolean("isRaining"))

val bevHills = configToWeather(config.getConfig("allWeather.BeverlyHills"))

Но это кажется неэлегантным, поскольку любое изменение определения погоды также потребует изменения в configToWeather.

Заранее благодарим вас за обзор и ответ.


person Ramón J Romero y Vigil    schedule 27.07.2016    source источник


Ответы (3)


Библиотека конфигурации typesafe имеет API для создания экземпляра объекта из конфигурации, который использует соглашение о компонентах Java. Но, насколько я понимаю, кейс-класс этим правилам не подчиняется.

Существует несколько библиотек scala, которые обертывают безопасную конфигурацию и предоставляют Scala специфическая функциональность, которую вы ищете.

Например, при использовании pureconfig конфигурация чтения может выглядеть так:

val weather:Try[Weather] = loadConfig[Weather]

где Weather - это класс case для значений в config

person Nazarii Bardiuk    schedule 27.07.2016
comment
+1 за pureconfig. Был знаком с отличным Spring Boot управление конфигурацией, pureconfig - это последняя вещь, которую я смог найти в Scala. - person Abhijit Sarkar; 04.12.2017

Расширяя ответ Назария, у меня сработало следующее:

import scala.beans.BeanProperty

//The @BeanProperty and var are both necessary
case class Weather(@BeanProperty var zip : String,
                   @BeanProperty var temp : Double,
                   @BeanProperty var isRaining : Boolean) {

  //needed by configfactory to conform to java bean standard
  def this() = this("", 0.0, false)
}

import com.typesafe.config.ConfigFactory

val config = ConfigFactory.parseFile(new java.io.File("allWeather.conf"))

import com.typesafe.config.ConfigBeanFactory

val bevHills = 
  ConfigBeanFactory.create(config.getConfig("allWeather.BeverlyHills"), classOf[Weather])
person Ramón J Romero y Vigil    schedule 01.08.2016
comment
Обратите внимание, что для этой работы требуются все три конструктора без аргументов, @BeanPropery и var. Если вы забудете var, вы автоматически получите пустое значение (назначенное в конструкторе) вместо настроенного. - person Stefan L; 17.01.2017

Другой вариант - использовать circe.config с приведенным ниже кодом. См. https://github.com/circe/circe-config.

import io.circe.generic.auto._
import io.circe.config.syntax._

def configToWeather(conf: Config): Weather = {
  conf.as[Weather]("allWeather.BeverlyHills") match {
    case Right(c) => c
    case _ => throw new Exception("invalid configuration")
  }
}
person esumitra    schedule 03.12.2018