Use ConfigSluper Instead Of Properites Files
>> Thursday, September 9, 2010
I often use Java property files as configuration for prototypes, proofs of concepts, utility applications, etc. Groovy has a more powerful way of doing this called a ConfigSlurper (JavaDoc).
A ConfigSlurper just uses a Groovy script as input instead of a .properties file. This lets you do better (in my opinion) configuration like having typed properties (instead of them all being Strings you have to convert) including lists and maps, tree-structures of properties, even deriving a property value based on some calculation or closure.
Here are some examples. All the code can be downloaded here (box.net)
//Config1.groovy
stringProperty="Some string"
numberProperty=42
booleanProperty=false
listProperty=["Monday", "Tuesday", "Wednesday"]
Here is a basic configuration file using some different types. Here is how to read and use it:
def config = new ConfigSlurper().parse(new File('src/Config1.groovy').toURL())
assert "Some string" == config.stringProperty
assert config.stringProperty.class == String
assert 42 == config.numberProperty
assert config.numberProperty.class == Integer
assert false == config.booleanProperty
assert config.booleanProperty.class == Boolean
assert ["Monday", "Tuesday", "Wednesday"] == config.listProperty
assert 3 == config.listProperty.size()
assert config.listProperty.class == ArrayList
Another powerful feature is being able to use trees of data like this:
//Config2.groovy
teams {
packers {
quarterback="Aaron Rodgers"
recievers=["Greg Jennings", "Donald Driver"]
}
vikings {
quarterback="Brett Favre"
}
}
And then reading them like this:
def config = new ConfigSlurper().parse(new File('src/Config2.groovy').toURL())
assert "Aaron Rodgers" == config.teams.packers.quarterback
assert ["Greg Jennings", "Donald Driver"] == config.teams.packers.recievers
assert "Brett Favre" == config.teams.vikings.quarterback
Along those lines, there is a special configuration called "environment." This allows you to use different configurations based on what "environment" you are in.
//Config3.groovy
website {
//default values
url = "http://default.mycompany.com"
port = 80
user = "test"
}
environments {
development {
website {
url = "http://dev.mycompany.com"
port = 8080
}
}
production {
website {
url = "http://www.mycompany.com"
user = "prodUser"
}
}
}
In this example, there are some default values for the website properties. Then, the different environments overwrite some of the defaults. Here is how you call the ConfigSlurper to use the different environments.
//defaults
def config = new ConfigSlurper().parse(new File('src/Config3.groovy').toURL())
assert config.website.url=="http://default.mycompany.com"
assert config.website.port==80
assert config.website.user=="test"
//development environment
config = new ConfigSlurper("development").parse(new File('src/Config3.groovy').toURL())
assert config.website.url=="http://dev.mycompany.com"
assert config.website.port==8080
assert config.website.user=="test"
//production environment
config = new ConfigSlurper("production").parse(new File('src/Config3.groovy').toURL())
assert config.website.url=="http://www.mycompany.com"
assert config.website.port==80
assert config.website.user=="prodUser"
Finally (for this article), here are a few fun things you can do with a ConfigSlurper including calculated values and merging configs.
//Config4.groovy
//set the value as some calculation
calculation = 2+2
//base the value off of some other property
calc2 = calculation * 2
//set the value using a closure
doubling = 1
5.times{ doubling = doubling * 2 }
And using those values:
def config = new ConfigSlurper().parse(new File('src/Config4.groovy').toURL())
assert 4 == config.calculation
assert 8 == config.calc2
assert 32 == config.doubling
//merge config files
def config1 = new ConfigSlurper().parse(new File('src/Config1.groovy').toURL())
def config2 = new ConfigSlurper().parse(new File('src/Config2.groovy').toURL())
config1 = config1.merge(config2)
assert 42 == config1.numberProperty
assert "Aaron Rodgers" == config1.teams.packers.quarterback
Leave a comment if you have any questions or suggestions!
4 comments:
awesome awesome post!
note that calculations are not done lazy in case of environment
so if you are "calculating" url = host + port
you need to do that in each dev/test/prod etc
fantastic....thank you so much Matt...i just got the ease of working on ConfigSlurper
Post a Comment