I frequently use standard Java property files for configuring my Groovy applications. One feature I have been missing is the ability to use variables as part of the property value so they can be expand dynamically during use. I thought I could provide this functionality using the following design:
- Use a special format to annotate the properties that should be expanded. I have chosen to enclose such templates in double exclamation marks (!!). These property values are essentially a template to be expanded with the local variables
- Before using the properties in the application, use the groovy 'evaluate' method to expand application variables in the template
- Re-assign the original property key to the new value before use
So, if I have a property file config.properties with properties like:
version=2.3
local_lib=!!${env['GROOVY_HOME']}/${configProps.getProperty('version')}/lib!!
The local_lib property will be expanded from the GROOVY_HOME environment variable and the version property value.
In my application, I have coded this as follows:
//Load the environment variables and configuration file
env=System.getenv()
configFile=new File('config.properties')
configProps= new Properties()
configProps.load(configFile.newDataInputStream())
//Replace configuration property values with their expanded equivalent
configProps.each{
//if a property value is a template we evaluate it
if (it.value.startsWith('!!')){
valTemplate=it.value.replace('!!','"')
it.value=evaluate(valTemplate)
}
}
//then we use the expanded property values
This seems to work. When I do
println configProps
I see that the value is expanded and not null
However, the getProperty method for the expanded property returns null.
assert configProps.getProperty('local_lib')=='C:\\DEVTOOLS\\groovy-2.4.7/2.3/lib'
| | |
| null false
[local_lib:C:\DEVTOOLS\groovy-2.4.7/2.3/lib, version:2.3]
What is causing this discrepancy? I would have expected to return the value shown in the property map.