October 8, 2009

Groovy Goodness: Using ConfigSlurper with Configuration Scripts

The ConfigSlurper class can be used to parse Groovy scripts with configuration information. This way we can use a real script instead of a properties file to define configuration information in our applications. In a previous post we saw how to use the ConfigSlurper from Java code and in this post we focus on using it in Groovy code.

Using the ConfigSlurper we can parse Groovy scripts into a ConfigObject. The ConfigObject is a subclass of LinkedHashMap and contains the configuration information. A configuration script contains information defined using dot notation or closures. Because it is a script we can use all Groovy constructs, or use any other Groovy and Java class we want.

To support different configuration settings per environment (for example development, test and production) we can define a special environments section in our script. When we create a new ConfigSlurper instance and use a environment name in the constructor, the environment section is used to determine values. If we don't specify the environment in the constructor the environments section is skipped.

Okay that is a lot of explaining, let's see some code:

// Configuration script as String, but can also be URL, file.
def mail = '''

// Dot notation.
mail.hostname = 'localhost'  

// Scoped closure notation.
mail {  
    // Using Groovy constructs.
    ['user', 'password'].each { 
        this."${it}" = 'secret' 

// Environments section.
environments {
    dev {
        mail.hostname = 'local'
    test {
        mail.hostname = 'test'
    prod {
        mail.hostname = 'prod'

// Another configuration script.
def app = '''
app {
    version = version()  // Use method in script.

// Define method to build version info.
def version() {

// Read mail configuration script for the prod environment.
def mailConfig = new ConfigSlurper('prod').parse(mail)

// We can pass information to the configuration with
// the setBinding method.
def appSlurper = new ConfigSlurper()
appSlurper.setBinding([releasedate: new Date(109, 9, 10)])
def appConfig = appSlurper.parse(app)

// Both configurations are merged into one.
def config = mailConfig.merge(appConfig)

assert 'prod' == config.mail.hostname
assert 'secret' == config.mail.user
assert 'secret' == config.mail.password
assert '1.0-2009_10_10' == config.app.version