Using Configuration

One of the strength of Commons Configuration is its ability to mix configurations from heterogeneous sources, this section will introduce you to the different configurations available and will show you how to combine them.

Configuration Sources

Currently there are quite a number of different sources of Configuration objects. But, by just using a Configuration object versus a specific type like XMLConfiguration or JNDIConfiguration, you are sheltered from the mechanics of actually retrieving the configuration values. These various sources include:

  • PropertiesConfiguration Loads configuration values from a properties file.
  • XMLConfiguration Takes values from an XML document.
  • PropertyListConfiguration Loads values from an OpenStep .plist file. XMLPropertyListConfiguration is also available to read the XML variant used by Mac OSX.
  • JNDIConfiguration Using a key in the JNDI tree, can retrieve values as configuration properties.
  • BaseConfiguration An in-memory method of populating a Configuration object.
  • SystemConfiguration A configuration using the system properties
  • ConfigurationConverter Takes a java.util.Properties or an o.a.c.collections.ExtendedProperties and converts it to a Configuration object.

Mixing Configuration Sources

Often you want to provide a base set of configuration values, but allow the user to easily override them for their specific environment. Well one way is to hard code the default values into your code, and have then provide a property file that overrides this. However, this is a very rigid way of doing things. Instead, with the CompositeConfiguration you can provide many different ways of setting up a configuration. You can either do it manually:

CompositeConfiguration config = new CompositeConfiguration();
config.addConfiguration(new SystemConfiguration());
config.addConfiguration(new PropertiesConfiguration("application.properties"));

or via the ConfigurationFactory class:

ConfigurationFactory factory = new ConfigurationFactory("config.xml");
Configuration config = factory.getConfiguration();

The config.xml file used in the example above is a configuration descriptor, it specifies the Configuration objects to load. Here is an example of descriptor:

<?xml version="1.0" encoding="ISO-8859-1" ?>

<configuration>
  <system/>
  <properties fileName="application.properties"/>
</configuration>

What this says is that we are loading up all system properties, as well as the properties file application.properties. The order of precedence is first to last. So in the above example, if a property is not found in the system properties, it'll be searched in the properties file. This allows you to set up default values in a properties file, and override them with the system properties.

Configuration Details

Configuration is done by taking the configuration descriptor XML file and parsing the individual configurations. Make sure to include the various dependencies required for each type of configuration!

Classic Properties File

  <properties fileName="conf/test.properties"/>

This configuration file is very simple. You just need to specify the path to the property file.

XML Properties File

  <xml fileName="conf/test.xml"/>

The configuration is very similar to the classic properties file. However, the xml file must be in a specific format. Currently there is no DTD.

<baseElement>
  <element>value</element>
  <element2>
    <subelement>
      <subsubelement>I'm complex!</subsubelement>
    </subelement>
  </element2>
  <test>
    <short>8</short>
  </test>
</baseElement>

In the above example, the root element is ignored. So to get the value "8", you would request from your Configuration object the key "test.short". The root element can be called anything.

JNDI Environment Properties

  <jndi prefix="java:comp/env"/>

This configuration is very useful for setting environment specific settings like mail servers! The prefix tells the ConfigurationFactory what the root will be to look up your configuration settings.

    <env-entry>
        <env-entry-name>smtp</env-entry-name>
        <env-entry-value>127.0.0.1</env-entry-value>
        <env-entry-type>java.lang.String</env-entry-type>
    </env-entry>

    <env-entry>
        <env-entry-name>test/short</env-entry-name>
        <env-entry-value>80</env-entry-value>
        <env-entry-type>java.lang.Short</env-entry-type>
    </env-entry>

Note! If you have a property called "test.short" with spaces in it, then it will be translated as the key "test/short". Therefore, you should NOT use spaces in the name of properties that are loaded from JNDI! If you do want to use them, then make sure to convert in your web.xml the "." characters to "/" characters, like in the test.short example above.