Hocon: Read an array of objects from a configuration file

17,935

Solution 1

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.

Solution 2

What are you trying to accomplish with this part y.toList.map{z =>? If you want a collection of Project as the result, why not just do:

val simpleConfig = x.configration.getObjectList("projects").map{y =>
   Project(y.get("name").toString, y.get("url").toString)
}

In this case, the map operation should be taking instances of ConfigObject which is what y is. That seems to be all you need to get your Project instances, so I'm not sure why you are toListing that ConfigObject (which is a Map) into a List of Tuple2 and then further mapping that again.

Solution 3

If a normal HOCON configuration then similar to strangefeatures answer this will work

import javax.inject._
import play.api.Configuration

trait Barfoo {
  def configuration: Configuration     
  def projects = for {
    projectsFound <- configuration.getConfigList("projects").toList
    projectConfig <- projectsFound
    name <- projectConfig.getString("name").toList
    url  <- projectConfig.getString("url").toList
  } yield Project(name,url)
}

class Foobar @Inject() (val configuration: Configuration) extends Barfoo

(Using Play 2.4+ Injection)

Solution 4

Given that the contents of the array are Json and you have a case class, you could try to use the Json Play API and work with the objects in that way. The Inception part should make it trivial.

Share:
17,935
Sonson123
Author by

Sonson123

Updated on June 20, 2022

Comments

  • Sonson123
    Sonson123 almost 2 years

    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?