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?
HOCON (Human-Optimized Config Object Notation) is an easy-to-use configuration format. It is used by Sponge and individual plugins utilizing SpongeAPI to store important data, such as configuration or player data. HOCON files typically use the suffix .
Comment Characters As in standard JSON and standard HOCON, any text between // or # and the next newline is considered a comment and is ignored (unless the // or # is inside a quoted string).
Multi-line strings If the three-character sequence """ appears, then all Unicode characters until a closing """ sequence are used unmodified to create a string value. Newlines and whitespace receive no special treatment.
Creating a Typesafe Config With Fallbacks In this case, we first load our overrides. conf , then set a fallback of our defaults. conf from above. When searching for any property, it will first search the original config, then traverse down the fallbacks until a value is found.
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.
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 toList
ing that ConfigObject
(which is a Map
) into a List of Tuple2
and then further mapping that again.
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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With