7.8. Using Composite Configuration

Problem

Your application calls for a multilayered configuration where a set of default properties can be selectively overridden by local or user configuration preferences.

Solution

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).

Example 7-2. global. properties

threads.max=50
threads.min=2
timeout=15.52
interactive=true
color=red
speed=50
name=Default User

Example 7-3. local .properties

# Overrides Global Props
threads.max=30
speed=55

Example 7-4. user. properties

# Overrides Local Props
threads.min=1
color=black
speed=5000
name=Sean

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

Discussion

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.

See Also

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://jakarta.apache.org/commons/configuration/overview.html).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.124.145