Hocon: Read an array of objects from a configuration file

Sonson123 picture Sonson123 · Jun 19, 2013 · Viewed 16.2k times · Source

I have created an Play application (2.1) which uses the configuration in conf/application.conf in the Hocon format.

I want to add an array of projects in the configuration. The file conf/application.conf looks like this:

...
projects = [
  {name: "SO", url: "http://stackoverflow.com/"},
  {name: "google", url: "http://google.com"}
]

I try to read this configuration in my Scala project:

import scala.collection.JavaConversions._
case class Project(name: String, url: String)

val projectList: List[Project] =
  Play.maybeApplication.map{x =>
    val simpleConfig = x.configration.getObjectList("projects").map{y =>
      y.toList.map{z =>
        Project(z.get("name").toString, z.get("url").toString) // ?!? doesn't work

      ... 
   }}}}}}}}  // *arg*

This approach seems to be very complicated, I am lost in a lot of Options, and my Eclipse IDE cannot give me any hints about the classes.

Has anybody an example how you can read an array of objects from a Hocon configuration file? Or should I use for this a JSON-file with an JSON-parser instead of Hocon?

Answer

Andy MacKinlay picture Andy MacKinlay · Jul 25, 2013

The following works for me in Play 2.1.2 (I don't have a .maybeApplication on my play.Play object though, and I'm not sure why you do):

import play.Play
import scala.collection.JavaConversions._
case class Project(name: String, url: String)

val projectList: List[Project] = {
  val projs = Play.application.configuration.getConfigList("projects") map { p => 
    Project(p.getString("name"), p.getString("url")) }
  projs.toList
}

println(projectList)

Giving output:

List(Project(SO,http://stackoverflow.com/), Project(google,http://google.com))

There's not a whole lot different, although I don't get lost in a whole lot of Option instances either (again, different from the API you seem to have).

More importantly, getConfigList seems to be a closer match for what you want to do, since it returns List[play.Configuration], which enables you to specify types on retrieval instead of resorting to casts or .toString() calls.