Your application calls for a multilayered configuration where a set of default properties can be selectively overridden by local or user configuration preferences.
Create a configuration.xml
file that contains references to multiple properties files, and pass
this file to a ConfigurationFactory
.
A ConfigurationFactory
will then
return a Configuration
implementation
that obtains configuration parameters from multiple properties
file.
Table 7-1 lists configuration properties for an application. A global configuration layer defines default values for configuration parameters. A local configuration layer allows you to customize the behavior of a system at a particular site, and the user configuration layer refines configuration parameters for a specific user. When an application retrieves the value of "name," the user layer's value of "Sean" overrides the global layer's value of "Default User."
Table 7-1. Three layers of configuration
Property |
Global |
Local |
User |
---|---|---|---|
threads.max |
50 |
30 |
|
threads.min |
20 |
1 |
|
timeout |
15.52 |
||
interactive |
TRUE |
||
color |
red |
black |
|
speed |
50 |
55 |
75 |
name |
Default User |
Sean |
Properties are stored in three separate files shown in Examples
Example 7-2 (global.properties
), Example 7-3 (local.properties
), and Example 7-4 (user.properties
).
A configuration.xml
file
provides a configuration for the ConfigurationFactory
. This file is stored as a
resource in the classpath, and the URL for this resource is passed to
the setConfigurationURL( )
method of
ConfigurationFactory
. The following
configuration.xml
will create a
Configuration
object, which locates
properties from properties files using the override order defined in the
XML document. user.properties
overrides local.properties
, which
overrides global.properties
:
<?xml version="1.0" encoding="ISO-8859-1" ?> <configuration> <properties fileName="user.properties"/> <properties fileName="local.properties"/> <properties fileName="global.properties"/> </configuration>
The following code passes the URL of the configuration.xml
resource to a ConfigurationFactory
, and a Configuration
instance is returned, which
resolves application configuration parameters according to the rules
outlined above:
import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationFactory; // Configure Factory ConfigurationFactory factory = new ConfigurationFactory( ); URL configURL = this.getClass( ).getResource("configuration.xml"); factory.setConfigurationURL( configURL ); Configuration config = factory.getConfiguration( ); // Print out properties System.out.println( "Timeout: " + config.getFloat("timeout")); System.out.println( "Max Threads: " + config.getString("threads.max")); System.out.println( "Name: " + config.getString("name")); System.out.println( "Speed: " + config.getInt("speed"));
This code executes and prints the value of four properties to the
console. The timeout
property is
retrieved from global.properties
,
the threads.max
property is retrieved
from local.properties
, and both
speed
and name
are retrieved from user.properties
:
Timeout: 15.52 Max Threads: 30 Name: Sean Speed: 75
The configuration.xml
file instructs the ConfigurationFactory
to create a Configuration
implementation based on multiple
properties files. In the previous example, when the application
retrieves a property, there is no parameter signifying the source of the
property. There is no mechanism for obtaining the source of a
configuration property; in other words, there is no way for our
application to see which properties file a particular value was obtained
from, and there is no mechanism for enumerating the properties in a
single properties file. The configuration.xml
file "configures" the
ConfigurationFactory
to create a
Configuration
—complexity is hidden
from the application and the source of configuration can be changed with
no effect to this example.
A configuration.xml
file can
also instruct a ConfigurationFactory
to use a mixture of properties files and XML documents.
The following configuration.xml
instructs the ConfigurationFactory
to
create a Configuration
instance that
looks for properties from a properties file and an XML document:
<?xml version="1.0" encoding="ISO-8859-1" ?> <configuration> <properties fileName="test.properties"/> <dom4j fileName="test.xml"/> </configuration>
With this configuration, a Configuration
instance will attempt to locate
a property with a matching key in test.properties
before it attempts to locate
the matching property in test.xml
.
See Recipe 7.7 for more
information about retrieving configuration from XML documents.
In addition to properties files and XML documents, Commons
Configuration can also be instructed to resolve configuration properties
from a JNDI tree using org.apache.commons.configuration.JNDIConfiguration
.
For more information on accessing properties in a JNDI tree using
Commons Configuration, see the "Configuration Overview" page on the
Commons Configuration project site (http://commons.apache.org/configuration/overview.html).