##### Configuration

- Home
- Download
- User's Guide
- Howtos (Release 1.2)
- Runtime Dependencies
- Building
- Roadmap
- Javadoc (Release 1.3)
- Javadoc (Release 1.2)
- Javadoc (Release 1.1)
- Javadoc (Release 1.0)
- SVN

##### Extensions

- Avalon Component

##### Project Documentation

- About
- Downloads
- Project Info
- Project Reports
- Development Process

##### Commons

- Home
- Components
- Sandbox
- Dormant
- Volunteering
- Contributing Patches
- Building Components
- Releasing Components
- Wiki

##### Legend

- External Link
- Opens in a new window

## Using DefaultConfigurationBuilder

The `ConfigurationFactory` class that was introduced in the last section is a powerful tool for dealing with multiple different configuration sources, but it also has some shortcommings:

- The format for configuration definition files is not extensible.
- Complex initializations of the declared configuration sources (e.g. for assigning a reloading strategy) are not supported.
- The returned configuration object is not hierarchical, which limits the query facilities somewhat.
- Declared configuration sources can only be accessed by index from the returned composite configuration, which means that code using a `ConfigurationFactory` depends on the order of declarations in a configuration definition file.

To work around these limitations the class `DefaultConfigurationBuilder` was introduced.

### Differences to ConfigurationFactory

From its basic usage scenarios `DefaultConfigurationBuilder` is very similar to `ConfigurationFactory`. It is able to process the same configuration definition files as can be read by `ConfigurationFactory`, but supports some more options. It follows a list with the main differences between these classes:

- `DefaultConfigurationBuilder` extends `XMLConfiguration`. This means that it is a file-based configuration, and thus supports multiple ways of specifying the location of the configuration definition file (e.g. as `java.io.File` object, as URL, etc.).
- The configuration object returned by a `DefaultConfigurationBuilder` is an instance of the CombinedConfiguration class, i.e. a truely hierarchical configuration supporting enhanced query facilities.
- Each declaration of a configuration source in the configuration definition file is interpreted as a bean declaration, so complex initializations are supported.
- `DefaultConfigurationBuilder` supports custom tags in its configuration definition file. For this purpose a so-called configuration provider has to be registered, which will be called when a corresponding tag is encountered.

### Enhancements of the configuration definition file

As was already pointed out, `DefaultConfigurationBuilder` maintains compatibility to `ConfigurationFactory` in that it understands the same configuration definition files. In addition to the elements that are allowed in a configuration definition file for `ConfigurationFactory` the data files for `DefaultConfigurationBuilder` support some additional options providing a greater flexibility. This section explains these enhanced features.

Overall structure of a configuration definition file

A configuration definition file for `DefaultConfigurationBuilder` can contain three sections, all of which are optional. A skeleton looks as follows:

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

    <configuration>
      <header>
        <!-- Meta data about the resulting combined configuration -->
      </header>
      <override>
        <!-- Configuration declarations with override semantics -->
      </override>
      <additional>
        <!-- Configuration declarations that form a union configuration -->
      </additional>
    </configuration>

Declaring configuration sources

The `override` and `additional` sections should look familar to users that have already worked with `ConfigurationFactory`. They have the exact same purpose here, i.e. they contain declarations for the configuration sources to be embedded. For compatibility reasons it is also allowed to declare configuration sources outside these sections; they are then treated as if they were placed inside the `override` section.

Each declaration of a configuration source is represented by an XML element whose name determines the type of the configuration source (e.g. `properties` for properties files, or `xml` for XML documents). Per default all configuration types are supported that are also allowed for `ConfigurationFactory`. A list of all supported tags can be found here. In addition to the default tags provided by `ConfigurationFactory` `DefaultConfigurationBuilder` knows the following tags:

configuration
  The `configuration` tag allows to include other configuration definition files. This makes it possible to nest these definition files up to an arbitrary depth. In fact, this tag will create another `DefaultConfigurationBuilder` object, initialize it, and obtain the `CombinedConfiguation` from it. This combined configuration will then be added to the resulting combined configuration. Like for other file-based configurations the `fileName` attribute can be used to specify the configuration definition file to be loaded. This file must be an XML document that conforms to the format described here.

In the declaration of a configuration source it is possible to set properties on the corresponding configuration objects. Configuration declarations are indeed Bean declarations. That means they can have attributes matching simple properties of the configuration object to create and sub elements matching complex properties. The following example fragment shows how complex initialization can be performed in a configuration declaration:

      <properties fileName="test.properties" throwExceptionOnMissing="true">
        <reloadingStrategy refreshDelay="10000"
        config-class="org.apache.commons.configuration.reloading.FileChangedReloadingStrategy"/>
      </properties>
      <xml fileName="test.xml" delimiterParsingDisabled="true">
        <expressionEngine config-class="org.apache.commons.configuration.tree.DefaultExpressionEngine"
          propertyDelimiter="/" indexStart="[" indexEnd="]"/>
      </xml>

In this example a configuration source for a properties file and one for an XML document are defined. For the properties source the `throwExceptionOnMissing` property is set to true, which means that it should throw an exception if a requested property is not found. In addition it is assigned a reloading strategy, which is declared and configured in a sub element. The XML configuration source is initialized in a similar way: a simple property is set, and an expression engine is assigned. More information about the format for declaring objects and initializing their properties can be found in the section about bean declarations.

In addition to the attributes that correspond to properties of the configuration object to be created a configuration declaration can have a set of special attributes that are evaluated by `DefaultConfigurationBuilder` when it creates the objects. These attributes are listed in the following table:

Attribute | Meaning
--- | ---
`config-name` | Allows to specify a name for this configuration. This name can be used to obtain a reference to the configuration from the resulting combined configuration (see below).
`config-at` | With this attribute an optional prefix can be specified for the properties of the corresponding configuration.
`config-optional` | Declares a configuration as optional. This means that errors that occur when creating the configuration are silently ignored. Note that in case of an error no configuration is added to the resulting combined configuration. This fact can be used to find out whether an optional configuration could be successfully created or not: If you specify a name for the optional configuration (using the `config-name` attribute), you can later check the combined configuration whether it contains a configuration with this name.

The `config-at` and `config-optional` attributes have the same meaning as the `at` and `optional` attributes for `ConfigurationFactory`. For compatibility reasons the old attributes without the `config-` prefix are still supported. Note that the `config-at` is now allowed for override configurations, too (`ConfigurationFactory` evaluated the `at` attribute only for configuration declarations in the `additional` section).

Another useful feature is the built-in support for interpolation (i.e. variable substitution): You can use variables in your configuration definition file that are defined in declared configuration sources. For instance, if the name of a configuration file to be loaded is defined by the system property `CONFIG_FILE`, you can do something like this:

    <configuration>
      <!-- Load the system properties -->
      <system/>
      <!-- Now load the config file, using a system property as file name -->
      <properties fileName="${CONFIG_FILE}"/>
    </configuration>

Note that you can refer only to properties that have already been loaded. If you change the order of the `<system>` and the `<properties>` elements in the example above, an error will occur because the `${CONFIG_FILE}` variable will then be undefined at the moment it is evaluated.

The header section

In the header section properties of the resulting combined configuration object can be set. The main part of this section is a bean declaration that is used for creating the resulting configuration object. Other elements can be used for customizing the Node combiners used by the override and the union combined configuration. The following example shows a header section that uses all supported properties:

      <header>
        <result delimiterParsingDisabled="true">
          <nodeCombiner config-class="org.apache.commons.configuration.tree.OverrideCombiner"/>
          <expressionEngine config-class="org.apache.commons.configuration.tree.xpath.XPathExpressionEngine"/>
        </result>
        <combiner>
          <override>
            <list-nodes>
              <node>table</node>
              <node>list</node>
            </list-nodes>
          </override>
          <additional>
            <list-nodes>
              <node>table</node>
            </list-nodes>
          </additional>
        </combiner>
      </header>

The `result` element points to the bean declaration for the resulting combined configuration. In this example we set an attribute and initialize the node combiner (which is not necessary because the default override combiner is specified) and the expression engine to be used. Note that the `config-class` attribute makes it possible to inject custom classes for the resulting configuration or the node combiner.

The `combiner` section allows to define nodes as list nodes. This can be necessary for certain node combiner implementations to work correctly. More information can be found in the section about Node combiners.

### An example

After all that theory let's go through an example! We start with the configuration definition file that looks like the following:

    <?xml version="1.0" encoding="ISO-8859-1" ?>
    <!-- Test configuration definition file that demonstrates complex initialization -->
    <configuration>
      <header>
        <result delimiterParsingDisabled="true">
          <expressionEngine config-class="org.apache.commons.configuration.tree.xpath.XPathExpressionEngine"/>
        </result>
        <combiner>
          <additional>
            <list-nodes>
              <node>table</node>
            </list-nodes>
          </additional>
        </combiner>
      </header>
      <override>
        <properties fileName="user.properties" throwExceptionOnMissing="true"
          config-name="properties" config-optional="true">
          <reloadingStrategy refreshDelay="10000"
          config-class="org.apache.commons.configuration.reloading.FileChangedReloadingStrategy"/>
        </properties>
        <xml fileName="settings.xml" config-name="xml"/>
      </override>
      <additional>
        <xml config-name="tab1" fileName="table1.xml" config-at="database.tables"/>
        <xml config-name="tab2" fileName="table2.xml" config-at="database.tables"/>
      </additional>
    </configuration>

This configuration definition file includes four configuration sources. With the following code we can create a `DefaultConfigurationBuilder` and load this file:

    DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
    builder.setFile(new File("configuration.xml"));
    CombinedConfiguration cc = builder.getConfiguration(true);

It would have been possible to specifiy the location of the configuration definition file in multiple other ways, e.g. as a URL. The boolean argument in the call to `getConfiguration()` determines whether the configuration definition file should be loaded. For our simple example we want this to happen, but it would also be possible to load the file manually (by calling the `load()` method), and after that updating the configuration. (Remember that `DefaultConfigurationBuilder` is a hierarchical configuration, that means you can use all methods provided by this class to alter its data, e.g. to add further configuration sources.) If the configuration's data was manually changed, you should call `getConfiguration()` with the argument false.

In the `header` section we have chosen an XPATH expression engine for the resulting configuration. So we can query our properties using the convenient XPATH syntax. By providing the `config-name` attribute we have given all configuration sources a name. This name can be used to obtain the corresponding sources from the combined configuration. For configurations in the override section this is directly possible:

    Configuration propertiesConfig = cc.getConfiguration("properties");
    Configuration xmlConfig = cc.getConfiguration("xml");

Configurations in the `additional` section are treated a bit differently: they are all packed together in another combined configuration and then added to the resulting combined configuration. So in our example the combined configuration `cc` will contain three configurations: the two configurations from the override section, and the combined configuration with the `additional` configurations. The latter is stored under a name determined by the `ADDITIONAL_NAME` constant of `DefaultConfigurationBuilder`. The following code shows how the configurations of the `additional` section can be accessed:

    CombinedConfiguration ccAdd = (CombinedConfiguration)
      cc.getConfiguration(DefaultConfigurationBuilder.ADDITIONAL_NAME);
    Configuration tab1Config = ccAdd.getConfiguration("tab1");
    Configuration tab2Config = ccAdd.getConfiguration("tab2");

### Extending the configuration definition file format

If you have written a custom configuration class, you might want to declare instances of this class in a configuration definition file, too. With `DefaultConfigurationBuilder` this is now possible by registering a ConfigurationProvider.

`ConfigurationProvider` is an inner class defined in `DefaultConfigurationBuilder`. Its task is to create and initialize a configuration object. Whenever `DefaultConfigurationBuilder` encounters a tag in the `override` or the `additional` section it checks whether for this tag a `ConfigurationProvider` was registered. If this is the case, the provider is asked to create a new configuration instance; otherwise an exception will be thrown.

So for adding support for a new configuration class you have to create an instance of `ConfigurationProvider` (or a derived class) and register it at the configuration builder using the `addConfigurationProvider()` method. This method expects the name of the associated tag and the provider instance as arguments.

If your custom configuration class does not need any special initialization, you can use the `ConfigurationProvider` class directly. It is able of creating an instance of a specified class (which must be derived from `AbstractConfiguration`). Let's take a look at an example where we want to add support for a configuration class called `MyConfiguration`. The corresponding tag in the configuration definition file should have the name `myconfig`. The code for registering the new provider and loading the configuration definition file looks as follows:

    DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
    DefaultConfigurationBuilder.ConfigurationProvider provider = new
      DefaultConfigurationBuilder.ConfigurationProvider(MyConfiguration.class);
    builder.addConfigurationProvider("myconfig", provider);

    builder.setFileName("configuration.xml");
    Configuration config = builder.getConfiguration();

If your configuration provider is registered this way, your configuration definition file can contain the `myconfig` tag just as any other tag for declaring a configuration source:

    <configuration>
      <additional>
        <xml fileName="settings.xml"/>
        <myconfig delimiterParsingDisabled="true"/>
      </additional>
    </configuration>

As is demonstrated in this example, it is possible to specify attributes for initializing properties of your configuration object. In this example we set the default `delimiterParsingDisabled` property inherited from `AbstractConfiguration`. Of course you can set custom properties of your configuration class, too.

If your custom configuration class is a file-based configuration, you should use the `FileConfigurationProvider` class instead of `ConfigurationProvider`. `FileConfigurationProvider` is another inner class of `DefaultConfigurationBuilder` that knows how to deal with file-based configurations: it ensures that the correct base path is set and takes care of invoking the `load()` method.

If your custom configuration class requires special initialization, you need to create your own provider class that extends `ConfigurationProvider`. Here you will have to override the `getConfiguration(ConfigurationDeclaration)` method, which is responsible for creating the configuration instance (all information necessary for this purpose can be obtained from the passed in declaration object). It is recommended that you call the inherited method first, which will instantiate and initialize the new configuration object. Then you can perform your specific initialization.