/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.configuration2.builder.combined;

import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.configuration2.CombinedConfiguration;
import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.ConfigurationLookup;
import org.apache.commons.configuration2.HierarchicalConfiguration;
import org.apache.commons.configuration2.SystemConfiguration;
import org.apache.commons.configuration2.XMLConfiguration;
import org.apache.commons.configuration2.beanutils.BeanDeclaration;
import org.apache.commons.configuration2.beanutils.BeanHelper;
import org.apache.commons.configuration2.beanutils.CombinedBeanDeclaration;
import org.apache.commons.configuration2.beanutils.XMLBeanDeclaration;
import org.apache.commons.configuration2.builder.BasicBuilderParameters;
import org.apache.commons.configuration2.builder.BasicConfigurationBuilder;
import org.apache.commons.configuration2.builder.BuilderParameters;
import org.apache.commons.configuration2.builder.ConfigurationBuilder;
import org.apache.commons.configuration2.builder.ConfigurationBuilderEvent;
import org.apache.commons.configuration2.builder.FileBasedBuilderParametersImpl;
import org.apache.commons.configuration2.builder.FileBasedBuilderProperties;
import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
import org.apache.commons.configuration2.builder.XMLBuilderParametersImpl;
import org.apache.commons.configuration2.builder.XMLBuilderProperties;
import org.apache.commons.configuration2.event.EventListener;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.configuration2.interpol.ConfigurationInterpolator;
import org.apache.commons.configuration2.interpol.Lookup;
import org.apache.commons.configuration2.io.FileSystem;
import org.apache.commons.configuration2.resolver.CatalogResolver;
import org.apache.commons.configuration2.tree.DefaultExpressionEngineSymbols;
import org.apache.commons.configuration2.tree.OverrideCombiner;
import org.apache.commons.configuration2.tree.UnionCombiner;
import org.xml.sax.EntityResolver;

A specialized ConfigurationBuilder implementation that creates a CombinedConfiguration from multiple configuration sources defined by an XML-based configuration definition file.

This class provides an easy and flexible means for loading multiple configuration sources and combining the results into a single configuration object. The sources to be loaded are defined in an XML document that can contain certain tags representing the different supported configuration classes. If such a tag is found, a corresponding ConfigurationBuilder class is instantiated and initialized using the classes of the beanutils package (namely XMLBeanDeclaration will be used to extract the configuration's initialization parameters, which allows for complex initialization scenarios).

It is also possible to add custom tags to the configuration definition file. For this purpose an implementation of CombinedConfigurationBuilderProvider has to be created which is responsible for the creation of a ConfigurationBuilder associated with the custom tag. An instance of this class has to be registered at the CombinedBuilderParametersImpl object which is used to initialize this CombinedConfigurationBuilder. This provider will then be called when the corresponding custom tag is detected. For many default configuration classes providers are already registered.

The configuration definition file has the following basic structure:

<configuration systemProperties="properties file name">
  <header>
    <!-- Optional meta information about the combined configuration -->
  </header>
  <override>
    <!-- Declarations for override configurations -->
  </override>
  <additional>
    <!-- Declarations for union configurations -->
  </additional>
</configuration>

The name of the root element (here configuration) is arbitrary. The optional systemProperties attribute identifies the path to a property file containing properties that should be added to the system properties. If specified on the root element, the system properties are set before the rest of the configuration is processed.

There are two sections (both of them are optional) for declaring override and additional configurations. Configurations in the former section are evaluated in the order of their declaration, and properties of configurations declared earlier hide those of configurations declared later. Configurations in the latter section are combined to a union configuration, i.e. all of their properties are added to a large hierarchical configuration. Configuration declarations that occur as direct children of the root element are treated as override declarations.

Each configuration declaration consists of a tag whose name is associated with a CombinedConfigurationBuilderProvider. This can be one of the predefined tags like properties, or xml, or a custom tag, for which a configuration builder provider was registered (as described above). Attributes and sub elements with specific initialization parameters can be added. There are some reserved attributes with a special meaning that can be used in every configuration declaration:

Standard attributes for configuration declarations
Attribute Meaning
config-name Allows specifying a name for this configuration. This name can be used to obtain a reference to the configuration from the resulting combined configuration (see below). It can also be passed to the getNamedBuilder(String) method.
config-at With this attribute an optional prefix can be specified for the properties of the corresponding configuration.
config-optional Declares a configuration source as optional. This means that errors that occur when creating the configuration are ignored.
config-reload Many configuration sources support a reloading mechanism. For those sources it is possible to enable reloading by providing this attribute with a value of true.

The optional header section can contain some meta data about the created configuration itself. For instance, it is possible to set further properties of the NodeCombiner objects used for constructing the resulting configuration.

The default configuration object returned by this builder is an instance of the CombinedConfiguration class. This allows for convenient access to the configuration objects maintained by the combined configuration (e.g. for updates of single configuration objects). It has also the advantage that the properties stored in all declared configuration objects are collected and transformed into a single hierarchical structure, which can be accessed using different expression engines. The actual CombinedConfiguration implementation can be overridden by specifying the class in the config-class attribute of the result element.

A custom EntityResolver can be used for all XMLConfigurations by adding

<entity-resolver config-class="EntityResolver fully qualified class name">

A specific CatalogResolver can be specified for all XMLConfiguration sources by adding

<entity-resolver catalogFiles="comma separated list of catalog files">

Additional ConfigurationProviders can be added by configuring them in the header section.

<providers>
  <provider config-tag="tag name" config-class="provider fully qualified class name"/>
</providers>

Additional variable resolvers can be added by configuring them in the header section.

<lookups>
  <lookup config-prefix="prefix" config-class="StrLookup fully qualified class name"/>
</lookups>

All declared override configurations are directly added to the resulting combined configuration. If they are given names (using the config-name attribute), they can directly be accessed using the getConfiguration(String) method of CombinedConfiguration. The additional configurations are altogether added to another combined configuration, which uses a union combiner. Then this union configuration is added to the resulting combined configuration under the name defined by the ADDITIONAL_NAME constant. The getNamedBuilder(String) method can be used to access the ConfigurationBuilder objects for all configuration sources which have been assigned a name; care has to be taken that these names are unique.

Since:1.3
/** * <p> * A specialized {@code ConfigurationBuilder} implementation that creates a * {@link CombinedConfiguration} from multiple configuration sources defined by * an XML-based <em>configuration definition file</em>. * </p> * <p> * This class provides an easy and flexible means for loading multiple * configuration sources and combining the results into a single configuration * object. The sources to be loaded are defined in an XML document that can * contain certain tags representing the different supported configuration * classes. If such a tag is found, a corresponding {@code ConfigurationBuilder} * class is instantiated and initialized using the classes of the * {@code beanutils} package (namely * {@link org.apache.commons.configuration2.beanutils.XMLBeanDeclaration * XMLBeanDeclaration} will be used to extract the configuration's * initialization parameters, which allows for complex initialization * scenarios). * </p> * <p> * It is also possible to add custom tags to the configuration definition file. * For this purpose an implementation of * {@link CombinedConfigurationBuilderProvider} has to be created which is * responsible for the creation of a {@code ConfigurationBuilder} associated * with the custom tag. An instance of this class has to be registered at the * {@link CombinedBuilderParametersImpl} object which is used to initialize this * {@code CombinedConfigurationBuilder}. This provider will then be called when * the corresponding custom tag is detected. For many default configuration * classes providers are already registered. * </p> * <p> * The configuration definition file has the following basic structure: * </p> * * <pre> * &lt;configuration systemProperties="properties file name"&gt; * &lt;header&gt; * &lt;!-- Optional meta information about the combined configuration --&gt; * &lt;/header&gt; * &lt;override&gt; * &lt;!-- Declarations for override configurations --&gt; * &lt;/override&gt; * &lt;additional&gt; * &lt;!-- Declarations for union configurations --&gt; * &lt;/additional&gt; * &lt;/configuration&gt; * </pre> * * <p> * The name of the root element (here {@code configuration}) is arbitrary. The * optional {@code systemProperties} attribute identifies the path to a property * file containing properties that should be added to the system properties. If * specified on the root element, the system properties are set before the rest * of the configuration is processed. * </p> * <p> * There are two sections (both of them are optional) for declaring * <em>override</em> and <em>additional</em> configurations. Configurations in * the former section are evaluated in the order of their declaration, and * properties of configurations declared earlier hide those of configurations * declared later. Configurations in the latter section are combined to a union * configuration, i.e. all of their properties are added to a large hierarchical * configuration. Configuration declarations that occur as direct children of * the root element are treated as override declarations. * </p> * <p> * Each configuration declaration consists of a tag whose name is associated * with a {@code CombinedConfigurationBuilderProvider}. This can be one of the * predefined tags like {@code properties}, or {@code xml}, or a custom tag, for * which a configuration builder provider was registered (as described above). * Attributes and sub elements with specific initialization parameters can be * added. There are some reserved attributes with a special meaning that can be * used in every configuration declaration: * </p> * <table border="1"> * <caption>Standard attributes for configuration declarations</caption> * <tr> * <th>Attribute</th> * <th>Meaning</th> * </tr> * <tr> * <td valign="top">{@code config-name}</td> * <td>Allows specifying a name for this configuration. This name can be used to * obtain a reference to the configuration from the resulting combined * configuration (see below). It can also be passed to the * {@link #getNamedBuilder(String)} method.</td> * </tr> * <tr> * <td valign="top">{@code config-at}</td> * <td>With this attribute an optional prefix can be specified for the * properties of the corresponding configuration.</td> * </tr> * <tr> * <td valign="top">{@code config-optional}</td> * <td>Declares a configuration source as optional. This means that errors that * occur when creating the configuration are ignored.</td> * </tr> * <tr> * <td valign="top">{@code config-reload}</td> * <td>Many configuration sources support a reloading mechanism. For those * sources it is possible to enable reloading by providing this attribute with a * value of <strong>true</strong>.</td> * </tr> * </table> * <p> * The optional <em>header</em> section can contain some meta data about the * created configuration itself. For instance, it is possible to set further * properties of the {@code NodeCombiner} objects used for constructing the * resulting configuration. * </p> * <p> * The default configuration object returned by this builder is an instance of * the {@link CombinedConfiguration} class. This allows for convenient access to * the configuration objects maintained by the combined configuration (e.g. for * updates of single configuration objects). It has also the advantage that the * properties stored in all declared configuration objects are collected and * transformed into a single hierarchical structure, which can be accessed using * different expression engines. The actual {@code CombinedConfiguration} * implementation can be overridden by specifying the class in the * <em>config-class</em> attribute of the result element. * </p> * <p> * A custom EntityResolver can be used for all XMLConfigurations by adding * </p> * * <pre> * &lt;entity-resolver config-class="EntityResolver fully qualified class name"&gt; * </pre> * * <p> * A specific CatalogResolver can be specified for all XMLConfiguration sources * by adding * </p> * <pre> * &lt;entity-resolver catalogFiles="comma separated list of catalog files"&gt; * </pre> * * <p> * Additional ConfigurationProviders can be added by configuring them in the * <em>header</em> section. * </p> * * <pre> * &lt;providers&gt; * &lt;provider config-tag="tag name" config-class="provider fully qualified class name"/&gt; * &lt;/providers&gt; * </pre> * * <p> * Additional variable resolvers can be added by configuring them in the * <em>header</em> section. * </p> * * <pre> * &lt;lookups&gt; * &lt;lookup config-prefix="prefix" config-class="StrLookup fully qualified class name"/&gt; * &lt;/lookups&gt; * </pre> * * <p> * All declared override configurations are directly added to the resulting * combined configuration. If they are given names (using the * {@code config-name} attribute), they can directly be accessed using the * {@code getConfiguration(String)} method of {@code CombinedConfiguration}. The * additional configurations are altogether added to another combined * configuration, which uses a union combiner. Then this union configuration is * added to the resulting combined configuration under the name defined by the * {@code ADDITIONAL_NAME} constant. The {@link #getNamedBuilder(String)} method * can be used to access the {@code ConfigurationBuilder} objects for all * configuration sources which have been assigned a name; care has to be taken * that these names are unique. * </p> * * @since 1.3 */
public class CombinedConfigurationBuilder extends BasicConfigurationBuilder<CombinedConfiguration> {
Constant for the name of the additional configuration. If the configuration definition file contains an additional section, a special union configuration is created and added under this name to the resulting combined configuration.
/** * Constant for the name of the additional configuration. If the * configuration definition file contains an {@code additional} * section, a special union configuration is created and added under this * name to the resulting combined configuration. */
public static final String ADDITIONAL_NAME = CombinedConfigurationBuilder.class .getName() + "/ADDITIONAL_CONFIG";
Constant for the name of the configuration bean factory.
/** Constant for the name of the configuration bean factory. */
static final String CONFIG_BEAN_FACTORY_NAME = CombinedConfigurationBuilder.class .getName() + ".CONFIG_BEAN_FACTORY_NAME";
Constant for the reserved name attribute.
/** Constant for the reserved name attribute. */
static final String ATTR_NAME = DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_START + XMLBeanDeclaration.RESERVED_PREFIX + "name" + DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_END;
Constant for the name of the at attribute.
/** Constant for the name of the at attribute. */
static final String ATTR_ATNAME = "at";
Constant for the reserved at attribute.
/** Constant for the reserved at attribute. */
static final String ATTR_AT_RES = DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_START + XMLBeanDeclaration.RESERVED_PREFIX + ATTR_ATNAME + DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_END;
Constant for the at attribute without the reserved prefix.
/** Constant for the at attribute without the reserved prefix. */
static final String ATTR_AT = DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_START + ATTR_ATNAME + DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_END;
Constant for the name of the optional attribute.
/** Constant for the name of the optional attribute. */
static final String ATTR_OPTIONALNAME = "optional";
Constant for the reserved optional attribute.
/** Constant for the reserved optional attribute. */
static final String ATTR_OPTIONAL_RES = DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_START + XMLBeanDeclaration.RESERVED_PREFIX + ATTR_OPTIONALNAME + DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_END;
Constant for the optional attribute without the reserved prefix.
/** Constant for the optional attribute without the reserved prefix. */
static final String ATTR_OPTIONAL = DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_START + ATTR_OPTIONALNAME + DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_END;
Constant for the forceCreate attribute.
/** Constant for the forceCreate attribute. */
static final String ATTR_FORCECREATE = DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_START + XMLBeanDeclaration.RESERVED_PREFIX + "forceCreate" + DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_END;
Constant for the reload attribute.
/** Constant for the reload attribute. */
static final String ATTR_RELOAD = DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_START + XMLBeanDeclaration.RESERVED_PREFIX + "reload" + DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_END;
Constant for the tag attribute for providers.
/** * Constant for the tag attribute for providers. */
static final String KEY_SYSTEM_PROPS = "[@systemProperties]";
Constant for the name of the header section.
/** Constant for the name of the header section. */
static final String SEC_HEADER = "header";
Constant for an expression that selects the union configurations.
/** Constant for an expression that selects the union configurations. */
static final String KEY_UNION = "additional";
An array with the names of top level configuration sections.
/** An array with the names of top level configuration sections.*/
static final String[] CONFIG_SECTIONS = { "additional", "override", SEC_HEADER };
Constant for an expression that selects override configurations in the override section.
/** * Constant for an expression that selects override configurations in the * override section. */
static final String KEY_OVERRIDE = "override";
Constant for the key that points to the list nodes definition of the override combiner.
/** * Constant for the key that points to the list nodes definition of the * override combiner. */
static final String KEY_OVERRIDE_LIST = SEC_HEADER + ".combiner.override.list-nodes.node";
Constant for the key that points to the list nodes definition of the additional combiner.
/** * Constant for the key that points to the list nodes definition of the * additional combiner. */
static final String KEY_ADDITIONAL_LIST = SEC_HEADER + ".combiner.additional.list-nodes.node";
Constant for the key for defining providers in the configuration file.
/** * Constant for the key for defining providers in the configuration file. */
static final String KEY_CONFIGURATION_PROVIDERS = SEC_HEADER + ".providers.provider";
Constant for the tag attribute for providers.
/** * Constant for the tag attribute for providers. */
static final String KEY_PROVIDER_KEY = XMLBeanDeclaration.ATTR_PREFIX + "tag]";
Constant for the key for defining variable resolvers
/** * Constant for the key for defining variable resolvers */
static final String KEY_CONFIGURATION_LOOKUPS = SEC_HEADER + ".lookups.lookup";
Constant for the key for defining entity resolvers
/** * Constant for the key for defining entity resolvers */
static final String KEY_ENTITY_RESOLVER = SEC_HEADER + ".entity-resolver";
Constant for the prefix attribute for lookups.
/** * Constant for the prefix attribute for lookups. */
static final String KEY_LOOKUP_KEY = XMLBeanDeclaration.ATTR_PREFIX + "prefix]";
Constant for the FileSystem.
/** * Constant for the FileSystem. */
static final String FILE_SYSTEM = SEC_HEADER + ".fileSystem";
Constant for the key of the result declaration. This key can point to a bean declaration, which defines properties of the resulting combined configuration.
/** * Constant for the key of the result declaration. This key can point to a * bean declaration, which defines properties of the resulting combined * configuration. */
static final String KEY_RESULT = SEC_HEADER + ".result";
Constant for the key of the combiner in the result declaration.
/** Constant for the key of the combiner in the result declaration.*/
static final String KEY_COMBINER = KEY_RESULT + ".nodeCombiner";
Constant for the XML file extension.
/** Constant for the XML file extension. */
static final String EXT_XML = "xml";
Constant for the basic configuration builder class.
/** Constant for the basic configuration builder class. */
private static final String BASIC_BUILDER = "org.apache.commons.configuration2.builder.BasicConfigurationBuilder";
Constant for the file-based configuration builder class.
/** Constant for the file-based configuration builder class. */
private static final String FILE_BUILDER = "org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder";
Constant for the reloading file-based configuration builder class.
/** Constant for the reloading file-based configuration builder class. */
private static final String RELOADING_BUILDER = "org.apache.commons.configuration2.builder.ReloadingFileBasedConfigurationBuilder";
Constant for the name of the file-based builder parameters class.
/** Constant for the name of the file-based builder parameters class. */
private static final String FILE_PARAMS = "org.apache.commons.configuration2.builder.FileBasedBuilderParametersImpl";
Constant for the provider for properties files.
/** Constant for the provider for properties files. */
private static final ConfigurationBuilderProvider PROPERTIES_PROVIDER = new FileExtensionConfigurationBuilderProvider( FILE_BUILDER, RELOADING_BUILDER, "org.apache.commons.configuration2.XMLPropertiesConfiguration", "org.apache.commons.configuration2.PropertiesConfiguration", EXT_XML, Collections.singletonList(FILE_PARAMS));
Constant for the provider for XML files.
/** Constant for the provider for XML files. */
private static final ConfigurationBuilderProvider XML_PROVIDER = new BaseConfigurationBuilderProvider(FILE_BUILDER, RELOADING_BUILDER, "org.apache.commons.configuration2.XMLConfiguration", Collections.singletonList("org.apache.commons.configuration2.builder.XMLBuilderParametersImpl"));
Constant for the provider for JNDI sources.
/** Constant for the provider for JNDI sources. */
private static final BaseConfigurationBuilderProvider JNDI_PROVIDER = new BaseConfigurationBuilderProvider( BASIC_BUILDER, null, "org.apache.commons.configuration2.JNDIConfiguration", Collections.singletonList("org.apache.commons.configuration2.builder.JndiBuilderParametersImpl"));
Constant for the provider for system properties.
/** Constant for the provider for system properties. */
private static final BaseConfigurationBuilderProvider SYSTEM_PROVIDER = new BaseConfigurationBuilderProvider( BASIC_BUILDER, null, "org.apache.commons.configuration2.SystemConfiguration", Collections.singletonList("org.apache.commons.configuration2.builder.BasicBuilderParameters"));
Constant for the provider for ini files.
/** Constant for the provider for ini files. */
private static final BaseConfigurationBuilderProvider INI_PROVIDER = new BaseConfigurationBuilderProvider(FILE_BUILDER, RELOADING_BUILDER, "org.apache.commons.configuration2.INIConfiguration", Collections.singletonList(FILE_PARAMS));
Constant for the provider for environment properties.
/** Constant for the provider for environment properties. */
private static final BaseConfigurationBuilderProvider ENV_PROVIDER = new BaseConfigurationBuilderProvider( BASIC_BUILDER, null, "org.apache.commons.configuration2.EnvironmentConfiguration", Collections.singletonList("org.apache.commons.configuration2.builder.BasicBuilderParameters"));
Constant for the provider for plist files.
/** Constant for the provider for plist files. */
private static final BaseConfigurationBuilderProvider PLIST_PROVIDER = new FileExtensionConfigurationBuilderProvider( FILE_BUILDER, RELOADING_BUILDER, "org.apache.commons.configuration2.plist.XMLPropertyListConfiguration", "org.apache.commons.configuration2.plist.PropertyListConfiguration", EXT_XML, Collections.singletonList(FILE_PARAMS));
Constant for the provider for configuration definition files.
/** Constant for the provider for configuration definition files. */
private static final BaseConfigurationBuilderProvider COMBINED_PROVIDER = new CombinedConfigurationBuilderProvider();
Constant for the provider for multiple XML configurations.
/** Constant for the provider for multiple XML configurations. */
private static final MultiFileConfigurationBuilderProvider MULTI_XML_PROVIDER = new MultiFileConfigurationBuilderProvider( "org.apache.commons.configuration2.XMLConfiguration", "org.apache.commons.configuration2.builder.XMLBuilderParametersImpl");
An array with the names of the default tags.
/** An array with the names of the default tags. */
private static final String[] DEFAULT_TAGS = { "properties", "xml", "hierarchicalXml", "plist", "ini", "system", "env", "jndi", "configuration", "multiFile" };
An array with the providers for the default tags.
/** An array with the providers for the default tags. */
private static final ConfigurationBuilderProvider[] DEFAULT_PROVIDERS = { PROPERTIES_PROVIDER, XML_PROVIDER, XML_PROVIDER, PLIST_PROVIDER, INI_PROVIDER, SYSTEM_PROVIDER, ENV_PROVIDER, JNDI_PROVIDER, COMBINED_PROVIDER, MULTI_XML_PROVIDER };
A map with the default configuration builder providers.
/** A map with the default configuration builder providers. */
private static final Map<String, ConfigurationBuilderProvider> DEFAULT_PROVIDERS_MAP;
The builder for the definition configuration.
/** The builder for the definition configuration. */
private ConfigurationBuilder<? extends HierarchicalConfiguration<?>> definitionBuilder;
Stores temporarily the configuration with the builder definitions.
/** Stores temporarily the configuration with the builder definitions. */
private HierarchicalConfiguration<?> definitionConfiguration;
The object with data about configuration sources.
/** The object with data about configuration sources. */
private ConfigurationSourceData sourceData;
Stores the current parameters object.
/** Stores the current parameters object. */
private CombinedBuilderParametersImpl currentParameters;
The current XML parameters object.
/** The current XML parameters object. */
private XMLBuilderParametersImpl currentXMLParameters;
The configuration that is currently constructed.
/** The configuration that is currently constructed. */
private CombinedConfiguration currentConfiguration;
A ConfigurationInterpolator to be used as parent for all child configurations to enable cross-source interpolation.
/** * A {@code ConfigurationInterpolator} to be used as parent for all child * configurations to enable cross-source interpolation. */
private ConfigurationInterpolator parentInterpolator;
Creates a new instance of CombinedConfigurationBuilder. No parameters are set.
/** * Creates a new instance of {@code CombinedConfigurationBuilder}. No parameters * are set. */
public CombinedConfigurationBuilder() { super(CombinedConfiguration.class); }
Creates a new instance of CombinedConfigurationBuilder and sets the specified initialization parameters.
Params:
  • params – a map with initialization parameters
/** * * Creates a new instance of {@code CombinedConfigurationBuilder} and sets * the specified initialization parameters. * @param params a map with initialization parameters */
public CombinedConfigurationBuilder(final Map<String, Object> params) { super(CombinedConfiguration.class, params); }
Creates a new instance of CombinedConfigurationBuilder and sets the specified initialization parameters and the allowFailOnInit flag.
Params:
  • params – a map with initialization parameters
  • allowFailOnInit – the allowFailOnInit flag
/** * * Creates a new instance of {@code CombinedConfigurationBuilder} and sets * the specified initialization parameters and the <em>allowFailOnInit</em> flag. * @param params a map with initialization parameters * @param allowFailOnInit the <em>allowFailOnInit</em> flag */
public CombinedConfigurationBuilder(final Map<String, Object> params, final boolean allowFailOnInit) { super(CombinedConfiguration.class, params, allowFailOnInit); }
Returns the ConfigurationBuilder which creates the definition configuration.
Throws:
Returns:the builder for the definition configuration
/** * Returns the {@code ConfigurationBuilder} which creates the definition * configuration. * * @return the builder for the definition configuration * @throws ConfigurationException if an error occurs */
public synchronized ConfigurationBuilder<? extends HierarchicalConfiguration<?>> getDefinitionBuilder() throws ConfigurationException { if (definitionBuilder == null) { definitionBuilder = setupDefinitionBuilder(getParameters()); addDefinitionBuilderChangeListener(definitionBuilder); } return definitionBuilder; }
{@inheritDoc} This method is overridden to adapt the return type.
/** * {@inheritDoc} This method is overridden to adapt the return type. */
@Override public CombinedConfigurationBuilder configure(final BuilderParameters... params) { super.configure(params); return this; }

Returns the configuration builder with the given name. With this method a builder of a child configuration which was given a name in the configuration definition file can be accessed directly.

Important note: This method only returns a meaningful result after the result configuration has been created by calling getConfiguration(). If called before, always an exception is thrown.

Params:
  • name – the name of the builder in question
Throws:
  • ConfigurationException – if information about named builders is not yet available or no builder with this name exists
Returns:the child configuration builder with this name
/** * <p> * Returns the configuration builder with the given name. With this method a * builder of a child configuration which was given a name in the * configuration definition file can be accessed directly. * </p> * <p> * <strong>Important note:</strong> This method only returns a meaningful * result after the result configuration has been created by calling * {@code getConfiguration()}. If called before, always an exception is * thrown. * </p> * * @param name the name of the builder in question * @return the child configuration builder with this name * @throws ConfigurationException if information about named builders is not * yet available or no builder with this name exists */
public synchronized ConfigurationBuilder<? extends Configuration> getNamedBuilder( final String name) throws ConfigurationException { if (sourceData == null) { throw new ConfigurationException("Information about child builders" + " has not been setup yet! Call getConfiguration() first."); } final ConfigurationBuilder<? extends Configuration> builder = sourceData.getNamedBuilder(name); if (builder == null) { throw new ConfigurationException("Builder cannot be resolved: " + name); } return builder; }

Returns a set with the names of all child configuration builders. A tag defining a configuration source in the configuration definition file can have the config-name attribute. If this attribute is present, the corresponding builder is assigned this name and can be directly accessed through the getNamedBuilder(String) method. This method returns a collection with all available builder names.

Important note: This method only returns a meaningful result after the result configuration has been created by calling getConfiguration(). If called before, always an empty set is returned.

Returns:a set with the names of all builders
/** * <p> * Returns a set with the names of all child configuration builders. A tag * defining a configuration source in the configuration definition file can * have the {@code config-name} attribute. If this attribute is present, the * corresponding builder is assigned this name and can be directly accessed * through the {@link #getNamedBuilder(String)} method. This method returns * a collection with all available builder names. * </p> * <p> * <strong>Important note:</strong> This method only returns a meaningful * result after the result configuration has been created by calling * {@code getConfiguration()}. If called before, always an empty set is * returned. * </p> * * @return a set with the names of all builders */
public synchronized Set<String> builderNames() { if (sourceData == null) { return Collections.emptySet(); } return Collections.unmodifiableSet(sourceData.builderNames()); }
{@inheritDoc} This implementation resets some specific internal state of this builder.
/** * {@inheritDoc} This implementation resets some specific internal state of * this builder. */
@Override public synchronized void resetParameters() { super.resetParameters(); definitionBuilder = null; definitionConfiguration = null; currentParameters = null; currentXMLParameters = null; if (sourceData != null) { sourceData.cleanUp(); sourceData = null; } }
Obtains the ConfigurationBuilder object which provides access to the configuration containing the definition of the combined configuration to create. If a definition builder is defined in the parameters, it is used. Otherwise, we check whether the combined builder parameters object contains a parameters object for the definition builder. If this is the case, a builder for an XMLConfiguration is created and configured with this object. As a last resort, it is looked for a FileBasedBuilderParametersImpl object in the properties. If found, also a XML configuration builder is created which loads this file. Note: This method is called from a synchronized block.
Params:
  • params – the current parameters for this builder
Throws:
Returns:the builder for the definition configuration
/** * Obtains the {@code ConfigurationBuilder} object which provides access to * the configuration containing the definition of the combined configuration * to create. If a definition builder is defined in the parameters, it is * used. Otherwise, we check whether the combined builder parameters object * contains a parameters object for the definition builder. If this is the * case, a builder for an {@code XMLConfiguration} is created and configured * with this object. As a last resort, it is looked for a * {@link FileBasedBuilderParametersImpl} object in the properties. If * found, also a XML configuration builder is created which loads this file. * Note: This method is called from a synchronized block. * * @param params the current parameters for this builder * @return the builder for the definition configuration * @throws ConfigurationException if an error occurs */
protected ConfigurationBuilder<? extends HierarchicalConfiguration<?>> setupDefinitionBuilder( final Map<String, Object> params) throws ConfigurationException { final CombinedBuilderParametersImpl cbParams = CombinedBuilderParametersImpl.fromParameters(params); if (cbParams != null) { final ConfigurationBuilder<? extends HierarchicalConfiguration<?>> defBuilder = cbParams.getDefinitionBuilder(); if (defBuilder != null) { return defBuilder; } if (cbParams.getDefinitionBuilderParameters() != null) { return createXMLDefinitionBuilder(cbParams .getDefinitionBuilderParameters()); } } final BuilderParameters fileParams = FileBasedBuilderParametersImpl.fromParameters(params); if (fileParams != null) { return createXMLDefinitionBuilder(fileParams); } throw new ConfigurationException( "No builder for configuration definition specified!"); }
Creates a default builder for the definition configuration and initializes it with a parameters object. This method is called if no definition builder is defined in this builder's parameters. This implementation creates a default file-based builder which produces an XMLConfiguration; it expects a corresponding file specification. Note: This method is called in a synchronized block.
Params:
  • builderParams – the parameters object for the builder
Returns:the standard builder for the definition configuration
/** * Creates a default builder for the definition configuration and * initializes it with a parameters object. This method is called if no * definition builder is defined in this builder's parameters. This * implementation creates a default file-based builder which produces an * {@code XMLConfiguration}; it expects a corresponding file specification. * Note: This method is called in a synchronized block. * * @param builderParams the parameters object for the builder * @return the standard builder for the definition configuration */
protected ConfigurationBuilder<? extends HierarchicalConfiguration<?>> createXMLDefinitionBuilder( final BuilderParameters builderParams) { return new FileBasedConfigurationBuilder<>( XMLConfiguration.class).configure(builderParams); }
Returns the configuration containing the definition of the combined configuration to be created. This method only returns a defined result during construction of the result configuration. The definition configuration is obtained from the definition builder at first access and then stored temporarily to ensure that during result construction always the same configuration instance is used. (Otherwise, it would be possible that the definition builder returns a different instance when queried multiple times.)
Throws:
Returns:the definition configuration
/** * Returns the configuration containing the definition of the combined * configuration to be created. This method only returns a defined result * during construction of the result configuration. The definition * configuration is obtained from the definition builder at first access and * then stored temporarily to ensure that during result construction always * the same configuration instance is used. (Otherwise, it would be possible * that the definition builder returns a different instance when queried * multiple times.) * * @return the definition configuration * @throws ConfigurationException if an error occurs */
protected HierarchicalConfiguration<?> getDefinitionConfiguration() throws ConfigurationException { if (definitionConfiguration == null) { definitionConfiguration = getDefinitionBuilder().getConfiguration(); } return definitionConfiguration; }
Returns a collection with the builders for all child configuration sources. This method can be used by derived classes providing additional functionality on top of the declared configuration sources. It only returns a defined value during construction of the result configuration instance.
Returns:a collection with the builders for child configuration sources
/** * Returns a collection with the builders for all child configuration * sources. This method can be used by derived classes providing additional * functionality on top of the declared configuration sources. It only * returns a defined value during construction of the result configuration * instance. * * @return a collection with the builders for child configuration sources */
protected synchronized Collection<ConfigurationBuilder<? extends Configuration>> getChildBuilders() { return sourceData.getChildBuilders(); }
{@inheritDoc} This implementation evaluates the result property of the definition configuration. It creates a combined bean declaration with both the properties specified in the definition file and the properties defined as initialization parameters.
/** * {@inheritDoc} This implementation evaluates the {@code result} property * of the definition configuration. It creates a combined bean declaration * with both the properties specified in the definition file and the * properties defined as initialization parameters. */
@Override protected BeanDeclaration createResultDeclaration(final Map<String, Object> params) throws ConfigurationException { final BeanDeclaration paramsDecl = super.createResultDeclaration(params); final XMLBeanDeclaration resultDecl = new XMLBeanDeclaration(getDefinitionConfiguration(), KEY_RESULT, true, CombinedConfiguration.class.getName()); return new CombinedBeanDeclaration(resultDecl, paramsDecl); }
{@inheritDoc} This implementation processes the definition configuration in order to
  • initialize the resulting CombinedConfiguration
  • determine the builders for all configuration sources
  • populate the resulting CombinedConfiguration
/** * {@inheritDoc} This implementation processes the definition configuration * in order to * <ul> * <li>initialize the resulting {@code CombinedConfiguration}</li> * <li>determine the builders for all configuration sources</li> * <li>populate the resulting {@code CombinedConfiguration}</li> * </ul> */
@Override protected void initResultInstance(final CombinedConfiguration result) throws ConfigurationException { super.initResultInstance(result); currentConfiguration = result; final HierarchicalConfiguration<?> config = getDefinitionConfiguration(); if (config.getMaxIndex(KEY_COMBINER) < 0) { // No combiner defined => set default result.setNodeCombiner(new OverrideCombiner()); } setUpCurrentParameters(); initNodeCombinerListNodes(result, config, KEY_OVERRIDE_LIST); registerConfiguredProviders(config); setUpCurrentXMLParameters(); currentXMLParameters.setFileSystem(initFileSystem(config)); initSystemProperties(config, getBasePath()); registerConfiguredLookups(config, result); configureEntityResolver(config, currentXMLParameters); setUpParentInterpolator(currentConfiguration, config); final ConfigurationSourceData data = getSourceData(); final boolean createBuilders = data.getChildBuilders().isEmpty(); final List<ConfigurationBuilder<? extends Configuration>> overrideBuilders = data.createAndAddConfigurations(result, data.getOverrideSources(), data.overrideBuilders); if (createBuilders) { data.overrideBuilders.addAll(overrideBuilders); } if (!data.getUnionSources().isEmpty()) { final CombinedConfiguration addConfig = createAdditionalsConfiguration(result); result.addConfiguration(addConfig, ADDITIONAL_NAME); initNodeCombinerListNodes(addConfig, config, KEY_ADDITIONAL_LIST); final List<ConfigurationBuilder<? extends Configuration>> unionBuilders = data.createAndAddConfigurations(addConfig, data.unionDeclarations, data.unionBuilders); if (createBuilders) { data.unionBuilders.addAll(unionBuilders); } } result.isEmpty(); // this sets up the node structure currentConfiguration = null; }
Creates the CombinedConfiguration for the configuration sources in the <additional> section. This method is called when the builder constructs the final configuration. It creates a new CombinedConfiguration and initializes some properties from the result configuration.
Params:
  • resultConfig – the result configuration (this is the configuration that will be returned by the builder)
Returns:the CombinedConfiguration for the additional configuration sources
Since:1.7
/** * Creates the {@code CombinedConfiguration} for the configuration * sources in the <code>&lt;additional&gt;</code> section. This method is * called when the builder constructs the final configuration. It creates a * new {@code CombinedConfiguration} and initializes some properties * from the result configuration. * * @param resultConfig the result configuration (this is the configuration * that will be returned by the builder) * @return the {@code CombinedConfiguration} for the additional * configuration sources * @since 1.7 */
protected CombinedConfiguration createAdditionalsConfiguration( final CombinedConfiguration resultConfig) { final CombinedConfiguration addConfig = new CombinedConfiguration(new UnionCombiner()); addConfig.setListDelimiterHandler(resultConfig.getListDelimiterHandler()); return addConfig; }
Processes custom Lookup objects that might be declared in the definition configuration. Each Lookup object is registered at the definition configuration and at the result configuration. It is also added to all child configurations added to the resulting combined configuration.
Params:
  • defConfig – the definition configuration
  • resultConfig – the resulting configuration
Throws:
/** * Processes custom {@link Lookup} objects that might be declared in the * definition configuration. Each {@code Lookup} object is registered at the * definition configuration and at the result configuration. It is also * added to all child configurations added to the resulting combined * configuration. * * @param defConfig the definition configuration * @param resultConfig the resulting configuration * @throws ConfigurationException if an error occurs */
protected void registerConfiguredLookups( final HierarchicalConfiguration<?> defConfig, final Configuration resultConfig) throws ConfigurationException { final Map<String, Lookup> lookups = new HashMap<>(); final List<? extends HierarchicalConfiguration<?>> nodes = defConfig.configurationsAt(KEY_CONFIGURATION_LOOKUPS); for (final HierarchicalConfiguration<?> config : nodes) { final XMLBeanDeclaration decl = new XMLBeanDeclaration(config); final String key = config.getString(KEY_LOOKUP_KEY); final Lookup lookup = (Lookup) fetchBeanHelper().createBean(decl); lookups.put(key, lookup); } if (!lookups.isEmpty()) { final ConfigurationInterpolator defCI = defConfig.getInterpolator(); if (defCI != null) { defCI.registerLookups(lookups); } resultConfig.getInterpolator().registerLookups(lookups); } }
Creates and initializes a default FileSystem if the definition configuration contains a corresponding declaration. The file system returned by this method is used as default for all file-based child configuration sources.
Params:
  • config – the definition configuration
Throws:
Returns:the default FileSystem (may be null)
/** * Creates and initializes a default {@code FileSystem} if the definition * configuration contains a corresponding declaration. The file system * returned by this method is used as default for all file-based child * configuration sources. * * @param config the definition configuration * @return the default {@code FileSystem} (may be <b>null</b>) * @throws ConfigurationException if an error occurs */
protected FileSystem initFileSystem(final HierarchicalConfiguration<?> config) throws ConfigurationException { if (config.getMaxIndex(FILE_SYSTEM) == 0) { final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, FILE_SYSTEM); return (FileSystem) fetchBeanHelper().createBean(decl); } return null; }
Handles a file with system properties that may be defined in the definition configuration. If such property file is configured, all of its properties are added to the system properties.
Params:
  • config – the definition configuration
  • basePath – the base path defined for this builder (may be null)
Throws:
/** * Handles a file with system properties that may be defined in the * definition configuration. If such property file is configured, all of its * properties are added to the system properties. * * @param config the definition configuration * @param basePath the base path defined for this builder (may be * <b>null</b>) * @throws ConfigurationException if an error occurs. */
protected void initSystemProperties(final HierarchicalConfiguration<?> config, final String basePath) throws ConfigurationException { final String fileName = config.getString(KEY_SYSTEM_PROPS); if (fileName != null) { try { SystemConfiguration.setSystemProperties(basePath, fileName); } catch (final Exception ex) { throw new ConfigurationException( "Error setting system properties from " + fileName, ex); } } }
Creates and initializes a default EntityResolver if the definition configuration contains a corresponding declaration.
Params:
  • config – the definition configuration
  • xmlParams – the (already partly initialized) object with XML parameters; here the new resolver is to be stored
Throws:
/** * Creates and initializes a default {@code EntityResolver} if the * definition configuration contains a corresponding declaration. * * @param config the definition configuration * @param xmlParams the (already partly initialized) object with XML * parameters; here the new resolver is to be stored * @throws ConfigurationException if an error occurs */
protected void configureEntityResolver(final HierarchicalConfiguration<?> config, final XMLBuilderParametersImpl xmlParams) throws ConfigurationException { if (config.getMaxIndex(KEY_ENTITY_RESOLVER) == 0) { final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, KEY_ENTITY_RESOLVER, true); final EntityResolver resolver = (EntityResolver) fetchBeanHelper().createBean(decl, CatalogResolver.class); final FileSystem fileSystem = xmlParams.getFileHandler().getFileSystem(); if (fileSystem != null) { BeanHelper.setProperty(resolver, "fileSystem", fileSystem); } final String basePath = xmlParams.getFileHandler().getBasePath(); if (basePath != null) { BeanHelper.setProperty(resolver, "baseDir", basePath); } final ConfigurationInterpolator ci = new ConfigurationInterpolator(); ci.registerLookups(fetchPrefixLookups()); BeanHelper.setProperty(resolver, "interpolator", ci); xmlParams.setEntityResolver(resolver); } }
Returns the ConfigurationBuilderProvider for the given tag. This method is called during creation of the result configuration. (It is not allowed to call it at another point of time; result is then unpredictable!) It supports all default providers and custom providers added through the parameters object as well.
Params:
  • tagName – the name of the tag
Returns:the provider that was registered for this tag or null if there is none
/** * Returns the {@code ConfigurationBuilderProvider} for the given tag. This * method is called during creation of the result configuration. (It is not * allowed to call it at another point of time; result is then * unpredictable!) It supports all default providers and custom providers * added through the parameters object as well. * * @param tagName the name of the tag * @return the provider that was registered for this tag or <b>null</b> if * there is none */
protected ConfigurationBuilderProvider providerForTag(final String tagName) { return currentParameters.providerForTag(tagName); }
Initializes a parameters object for a child builder. This combined configuration builder has a bunch of properties which may be inherited by child configurations, e.g. the base path, the file system, etc. While processing the builders for child configurations, this method is called for each parameters object for a child builder. It initializes some properties of the passed in parameters objects which are derived from this parent builder.
Params:
  • params – the parameters object to be initialized
/** * Initializes a parameters object for a child builder. This combined * configuration builder has a bunch of properties which may be inherited by * child configurations, e.g. the base path, the file system, etc. While * processing the builders for child configurations, this method is called * for each parameters object for a child builder. It initializes some * properties of the passed in parameters objects which are derived from * this parent builder. * * @param params the parameters object to be initialized */
protected void initChildBuilderParameters(final BuilderParameters params) { initDefaultChildParameters(params); if (params instanceof BasicBuilderParameters) { initChildBasicParameters((BasicBuilderParameters) params); } if (params instanceof XMLBuilderProperties<?>) { initChildXMLParameters((XMLBuilderProperties<?>) params); } if (params instanceof FileBasedBuilderProperties<?>) { initChildFileBasedParameters((FileBasedBuilderProperties<?>) params); } if (params instanceof CombinedBuilderParametersImpl) { initChildCombinedParameters((CombinedBuilderParametersImpl) params); } }
Initializes the event listeners of the specified builder from this object. This method is used to inherit all listeners from a parent builder.
Params:
  • dest – the destination builder object which is to be initialized
/** * Initializes the event listeners of the specified builder from this * object. This method is used to inherit all listeners from a parent * builder. * * @param dest the destination builder object which is to be initialized */
void initChildEventListeners( final BasicConfigurationBuilder<? extends Configuration> dest) { copyEventListeners(dest); }
Returns the configuration object that is currently constructed. This method can be called during construction of the result configuration. It is intended for internal usage, e.g. some specialized builder providers need access to this configuration to perform advanced initialization.
Returns:the configuration that us currently under construction
/** * Returns the configuration object that is currently constructed. This * method can be called during construction of the result configuration. It * is intended for internal usage, e.g. some specialized builder providers * need access to this configuration to perform advanced initialization. * * @return the configuration that us currently under construction */
CombinedConfiguration getConfigurationUnderConstruction() { return currentConfiguration; }
Initializes a bean using the current BeanHelper. This is needed by builder providers when the configuration objects for sub builders are constructed.
Params:
  • bean – the bean to be initialized
  • decl – the BeanDeclaration
/** * Initializes a bean using the current {@code BeanHelper}. This is needed * by builder providers when the configuration objects for sub builders are * constructed. * * @param bean the bean to be initialized * @param decl the {@code BeanDeclaration} */
void initBean(final Object bean, final BeanDeclaration decl) { fetchBeanHelper().initBean(bean, decl); }
Initializes the current parameters object. This object has either been passed at builder configuration time or it is newly created. In any case, it is manipulated during result creation.
/** * Initializes the current parameters object. This object has either been * passed at builder configuration time or it is newly created. In any * case, it is manipulated during result creation. */
private void setUpCurrentParameters() { currentParameters = CombinedBuilderParametersImpl.fromParameters(getParameters(), true); currentParameters.registerMissingProviders(DEFAULT_PROVIDERS_MAP); }
Sets up an XML parameters object which is used to store properties related to XML and file-based configurations during creation of the result configuration. The properties stored in this object can be inherited to child configurations.
Throws:
  • ConfigurationException – if an error occurs
/** * Sets up an XML parameters object which is used to store properties * related to XML and file-based configurations during creation of the * result configuration. The properties stored in this object can be * inherited to child configurations. * * @throws ConfigurationException if an error occurs */
private void setUpCurrentXMLParameters() throws ConfigurationException { currentXMLParameters = new XMLBuilderParametersImpl(); initDefaultBasePath(); }
Sets up a parent ConfigurationInterpolator object. This object has a default Lookup querying the resulting combined configuration. Thus interpolation works globally across all configuration sources.
Params:
  • resultConfig – the result configuration
  • defConfig – the definition configuration
/** * Sets up a parent {@code ConfigurationInterpolator} object. This object * has a default {@link Lookup} querying the resulting combined * configuration. Thus interpolation works globally across all configuration * sources. * * @param resultConfig the result configuration * @param defConfig the definition configuration */
private void setUpParentInterpolator(final Configuration resultConfig, final Configuration defConfig) { parentInterpolator = new ConfigurationInterpolator(); parentInterpolator.addDefaultLookup(new ConfigurationLookup( resultConfig)); final ConfigurationInterpolator defInterpolator = defConfig.getInterpolator(); if (defInterpolator != null) { defInterpolator.setParentInterpolator(parentInterpolator); } }
Initializes the default base path for all file-based child configuration sources. The base path can be explicitly defined in the parameters of this builder. Otherwise, if the definition builder is a file-based builder, it is obtained from there.
Throws:
  • ConfigurationException – if an error occurs
/** * Initializes the default base path for all file-based child configuration * sources. The base path can be explicitly defined in the parameters of * this builder. Otherwise, if the definition builder is a file-based * builder, it is obtained from there. * * @throws ConfigurationException if an error occurs */
private void initDefaultBasePath() throws ConfigurationException { assert currentParameters != null : "Current parameters undefined!"; if (currentParameters.getBasePath() != null) { currentXMLParameters.setBasePath(currentParameters.getBasePath()); } else { final ConfigurationBuilder<? extends HierarchicalConfiguration<?>> defBuilder = getDefinitionBuilder(); if (defBuilder instanceof FileBasedConfigurationBuilder) { @SuppressWarnings("rawtypes") final FileBasedConfigurationBuilder fileBuilder = (FileBasedConfigurationBuilder) defBuilder; final URL url = fileBuilder.getFileHandler().getURL(); currentXMLParameters.setBasePath(url != null ? url .toExternalForm() : fileBuilder.getFileHandler() .getBasePath()); } } }
Executes the DefaultParametersManager stored in the current parameters on the passed in parameters object. If default handlers have been registered for this type of parameters, an initialization is now performed. This method is called before the parameters object is initialized from the configuration definition file. So default values can be overridden later with concrete property definitions.
Params:
  • params – the parameters to be initialized
Throws:
/** * Executes the {@link org.apache.commons.configuration2.builder.DefaultParametersManager * DefaultParametersManager} stored in the current * parameters on the passed in parameters object. If default handlers have been * registered for this type of parameters, an initialization is now * performed. This method is called before the parameters object is * initialized from the configuration definition file. So default values * can be overridden later with concrete property definitions. * * @param params the parameters to be initialized * @throws org.apache.commons.configuration2.ex.ConfigurationRuntimeException if an error * occurs when copying properties */
private void initDefaultChildParameters(final BuilderParameters params) { currentParameters.getChildDefaultParametersManager() .initializeParameters(params); }
Initializes basic builder parameters for a child configuration with default settings set for this builder. This implementation ensures that all Lookup objects are propagated to child configurations and interpolation is setup correctly.
Params:
  • params – the parameters object
/** * Initializes basic builder parameters for a child configuration with * default settings set for this builder. This implementation ensures that * all {@code Lookup} objects are propagated to child configurations and * interpolation is setup correctly. * * @param params the parameters object */
private void initChildBasicParameters(final BasicBuilderParameters params) { params.setPrefixLookups(fetchPrefixLookups()); params.setParentInterpolator(parentInterpolator); if (currentParameters.isInheritSettings()) { params.inheritFrom(getParameters()); } }
Initializes a parameters object for a file-based configuration with properties already set for this parent builder. This method handles properties like a default file system or a base path.
Params:
  • params – the parameters object
/** * Initializes a parameters object for a file-based configuration with * properties already set for this parent builder. This method handles * properties like a default file system or a base path. * * @param params the parameters object */
private void initChildFileBasedParameters( final FileBasedBuilderProperties<?> params) { params.setBasePath(getBasePath()); params.setFileSystem(currentXMLParameters.getFileHandler() .getFileSystem()); }
Initializes a parameters object for an XML configuration with properties already set for this parent builder.
Params:
  • params – the parameters object
/** * Initializes a parameters object for an XML configuration with properties * already set for this parent builder. * * @param params the parameters object */
private void initChildXMLParameters(final XMLBuilderProperties<?> params) { params.setEntityResolver(currentXMLParameters.getEntityResolver()); }
Initializes a parameters object for a combined configuration builder with properties already set for this parent builder. This implementation deals only with a subset of properties. Other properties are already handled by the specialized builder provider.
Params:
  • params – the parameters object
/** * Initializes a parameters object for a combined configuration builder with * properties already set for this parent builder. This implementation deals * only with a subset of properties. Other properties are already handled by * the specialized builder provider. * * @param params the parameters object */
private void initChildCombinedParameters( final CombinedBuilderParametersImpl params) { params.registerMissingProviders(currentParameters); params.setBasePath(getBasePath()); }
Obtains the data object for the configuration sources and the corresponding builders. This object is created on first access and reset when the definition builder sends a change event. This method is called in a synchronized block.
Throws:
Returns:the object with information about configuration sources
/** * Obtains the data object for the configuration sources and the * corresponding builders. This object is created on first access and reset * when the definition builder sends a change event. This method is called * in a synchronized block. * * @return the object with information about configuration sources * @throws ConfigurationException if an error occurs */
private ConfigurationSourceData getSourceData() throws ConfigurationException { if (sourceData == null) { if (currentParameters == null) { setUpCurrentParameters(); setUpCurrentXMLParameters(); } sourceData = createSourceData(); } return sourceData; }
Creates the data object for configuration sources and the corresponding builders.
Throws:
Returns:the newly created data object
/** * Creates the data object for configuration sources and the corresponding * builders. * * @return the newly created data object * @throws ConfigurationException if an error occurs */
private ConfigurationSourceData createSourceData() throws ConfigurationException { final ConfigurationSourceData result = new ConfigurationSourceData(); result.initFromDefinitionConfiguration(getDefinitionConfiguration()); return result; }
Returns the current base path of this configuration builder. This is used for instance by all file-based child configurations.
Returns:the base path
/** * Returns the current base path of this configuration builder. This is used * for instance by all file-based child configurations. * * @return the base path */
private String getBasePath() { return currentXMLParameters.getFileHandler().getBasePath(); }
Registers providers defined in the configuration.
Params:
  • defConfig – the definition configuration
Throws:
/** * Registers providers defined in the configuration. * * @param defConfig the definition configuration * @throws ConfigurationException if an error occurs */
private void registerConfiguredProviders(final HierarchicalConfiguration<?> defConfig) throws ConfigurationException { final List<? extends HierarchicalConfiguration<?>> nodes = defConfig.configurationsAt(KEY_CONFIGURATION_PROVIDERS); for (final HierarchicalConfiguration<?> config : nodes) { final XMLBeanDeclaration decl = new XMLBeanDeclaration(config); final String key = config.getString(KEY_PROVIDER_KEY); currentParameters.registerProvider(key, (ConfigurationBuilderProvider) fetchBeanHelper().createBean(decl)); } }
Adds a listener at the given definition builder which resets this builder when a reset of the definition builder happens. This way it is ensured that this builder produces a new combined configuration when its definition configuration changes.
Params:
  • defBuilder – the definition builder
/** * Adds a listener at the given definition builder which resets this builder * when a reset of the definition builder happens. This way it is ensured * that this builder produces a new combined configuration when its * definition configuration changes. * * @param defBuilder the definition builder */
private void addDefinitionBuilderChangeListener( final ConfigurationBuilder<? extends HierarchicalConfiguration<?>> defBuilder) { defBuilder.addEventListener(ConfigurationBuilderEvent.RESET, event -> { synchronized (CombinedConfigurationBuilder.this) { reset(); definitionBuilder = defBuilder; } }); }
Returns a map with the current prefix lookup objects. This map is obtained from the ConfigurationInterpolator of the configuration under construction.
Returns:the map with current prefix lookups (may be null)
/** * Returns a map with the current prefix lookup objects. This map is * obtained from the {@code ConfigurationInterpolator} of the configuration * under construction. * * @return the map with current prefix lookups (may be <b>null</b>) */
private Map<String, ? extends Lookup> fetchPrefixLookups() { final CombinedConfiguration cc = getConfigurationUnderConstruction(); return cc != null ? cc.getInterpolator().getLookups() : null; }
Creates ConfigurationDeclaration objects for the specified configurations.
Params:
  • configs – the list with configurations
Returns:a collection with corresponding declarations
/** * Creates {@code ConfigurationDeclaration} objects for the specified * configurations. * * @param configs the list with configurations * @return a collection with corresponding declarations */
private Collection<ConfigurationDeclaration> createDeclarations( final Collection<? extends HierarchicalConfiguration<?>> configs) { final Collection<ConfigurationDeclaration> declarations = new ArrayList<>(configs.size()); for (final HierarchicalConfiguration<?> c : configs) { declarations.add(new ConfigurationDeclaration(this, c)); } return declarations; }
Initializes the list nodes of the node combiner for the given combined configuration. This information can be set in the header section of the configuration definition file for both the override and the union combiners.
Params:
  • cc – the combined configuration to initialize
  • defConfig – the definition configuration
  • key – the key for the list nodes
/** * Initializes the list nodes of the node combiner for the given combined * configuration. This information can be set in the header section of the * configuration definition file for both the override and the union * combiners. * * @param cc the combined configuration to initialize * @param defConfig the definition configuration * @param key the key for the list nodes */
private static void initNodeCombinerListNodes(final CombinedConfiguration cc, final HierarchicalConfiguration<?> defConfig, final String key) { final List<Object> listNodes = defConfig.getList(key); for (final Object listNode : listNodes) { cc.getNodeCombiner().addListNode((String) listNode); } }
Creates the map with the default configuration builder providers.
Returns:the map with default providers
/** * Creates the map with the default configuration builder providers. * * @return the map with default providers */
private static Map<String, ConfigurationBuilderProvider> createDefaultProviders() { final Map<String, ConfigurationBuilderProvider> providers = new HashMap<>(); for (int i = 0; i < DEFAULT_TAGS.length; i++) { providers.put(DEFAULT_TAGS[i], DEFAULT_PROVIDERS[i]); } return providers; } static { DEFAULT_PROVIDERS_MAP = createDefaultProviders(); }
A data class for storing information about all configuration sources defined for a combined builder.
/** * A data class for storing information about all configuration sources * defined for a combined builder. */
private class ConfigurationSourceData {
A list with data for all builders for override configurations.
/** A list with data for all builders for override configurations. */
private final List<ConfigurationDeclaration> overrideDeclarations;
A list with data for all builders for union configurations.
/** A list with data for all builders for union configurations. */
private final List<ConfigurationDeclaration> unionDeclarations;
A list with the builders for override configurations.
/** A list with the builders for override configurations. */
private final List<ConfigurationBuilder<? extends Configuration>> overrideBuilders;
A list with the builders for union configurations.
/** A list with the builders for union configurations. */
private final List<ConfigurationBuilder<? extends Configuration>> unionBuilders;
A map for direct access to a builder by its name.
/** A map for direct access to a builder by its name. */
private final Map<String, ConfigurationBuilder<? extends Configuration>> namedBuilders;
A collection with all child builders.
/** A collection with all child builders. */
private final Collection<ConfigurationBuilder<? extends Configuration>> allBuilders;
A listener for reacting on changes of sub builders.
/** A listener for reacting on changes of sub builders. */
private final EventListener<ConfigurationBuilderEvent> changeListener;
Creates a new instance of ConfigurationSourceData.
/** * Creates a new instance of {@code ConfigurationSourceData}. */
public ConfigurationSourceData() { overrideDeclarations = new ArrayList<>(); unionDeclarations = new ArrayList<>(); overrideBuilders = new ArrayList<>(); unionBuilders = new ArrayList<>(); namedBuilders = new HashMap<>(); allBuilders = new LinkedList<>(); changeListener = createBuilderChangeListener(); }
Initializes this object from the specified definition configuration.
Params:
  • config – the definition configuration
Throws:
/** * Initializes this object from the specified definition configuration. * * @param config the definition configuration * @throws ConfigurationException if an error occurs */
public void initFromDefinitionConfiguration( final HierarchicalConfiguration<?> config) throws ConfigurationException { overrideDeclarations.addAll(createDeclarations(fetchTopLevelOverrideConfigs(config))); overrideDeclarations.addAll(createDeclarations(config.childConfigurationsAt(KEY_OVERRIDE))); unionDeclarations.addAll(createDeclarations(config.childConfigurationsAt(KEY_UNION))); }
Processes the declaration of configuration builder providers, creates the corresponding builder if necessary, obtains configurations, and adds them to the specified result configuration.
Params:
  • ccResult – the result configuration
  • srcDecl – the collection with the declarations of configuration sources to process
Throws:
Returns:a list with configuration builders
/** * Processes the declaration of configuration builder providers, creates * the corresponding builder if necessary, obtains configurations, and * adds them to the specified result configuration. * * @param ccResult the result configuration * @param srcDecl the collection with the declarations of configuration * sources to process * @return a list with configuration builders * @throws ConfigurationException if an error occurs */
public List<ConfigurationBuilder<? extends Configuration>> createAndAddConfigurations( final CombinedConfiguration ccResult, final List<ConfigurationDeclaration> srcDecl, final List<ConfigurationBuilder<? extends Configuration>> builders) throws ConfigurationException { final boolean createBuilders = builders.isEmpty(); List<ConfigurationBuilder<? extends Configuration>> newBuilders; if (createBuilders) { newBuilders = new ArrayList<>(srcDecl.size()); } else { newBuilders = builders; } for (int i = 0; i < srcDecl.size(); i++) { ConfigurationBuilder<? extends Configuration> b; if (createBuilders) { b = createConfigurationBuilder(srcDecl.get(i)); newBuilders.add(b); } else { b = builders.get(i); } addChildConfiguration(ccResult, srcDecl.get(i), b); } return newBuilders; }
Frees resources used by this object and performs clean up. This method is called when the owning builder is reset.
/** * Frees resources used by this object and performs clean up. This * method is called when the owning builder is reset. */
public void cleanUp() { for (final ConfigurationBuilder<?> b : getChildBuilders()) { b.removeEventListener(ConfigurationBuilderEvent.RESET, changeListener); } namedBuilders.clear(); }
Returns a collection containing the builders for all child configuration sources.
Returns:the child configuration builders
/** * Returns a collection containing the builders for all child * configuration sources. * * @return the child configuration builders */
public Collection<ConfigurationBuilder<? extends Configuration>> getChildBuilders() { return allBuilders; }
Returns a collection with all configuration source declarations defined in the override section.
Returns:the override configuration builders
/** * Returns a collection with all configuration source declarations * defined in the override section. * * @return the override configuration builders */
public List<ConfigurationDeclaration> getOverrideSources() { return overrideDeclarations; }
Returns a collection with all configuration source declarations defined in the union section.
Returns:the union configuration builders
/** * Returns a collection with all configuration source declarations * defined in the union section. * * @return the union configuration builders */
public List<ConfigurationDeclaration> getUnionSources() { return unionDeclarations; }
Returns the ConfigurationBuilder with the given name. If no such builder is defined in the definition configuration, result is null.
Params:
  • name – the name of the builder in question
Returns:the builder with this name or null
/** * Returns the {@code ConfigurationBuilder} with the given name. If no * such builder is defined in the definition configuration, result is * <b>null</b>. * * @param name the name of the builder in question * @return the builder with this name or <b>null</b> */
public ConfigurationBuilder<? extends Configuration> getNamedBuilder( final String name) { return namedBuilders.get(name); }
Returns a set with the names of all known named builders.
Returns:the names of the available sub builders
/** * Returns a set with the names of all known named builders. * * @return the names of the available sub builders */
public Set<String> builderNames() { return namedBuilders.keySet(); }
Creates a configuration builder based on a source declaration in the definition configuration.
Params:
  • decl – the current ConfigurationDeclaration
Throws:
Returns:the newly created builder
/** * Creates a configuration builder based on a source declaration in the * definition configuration. * * @param decl the current {@code ConfigurationDeclaration} * @return the newly created builder * @throws ConfigurationException if an error occurs */
private ConfigurationBuilder<? extends Configuration> createConfigurationBuilder( final ConfigurationDeclaration decl) throws ConfigurationException { final ConfigurationBuilderProvider provider = providerForTag(decl.getConfiguration().getRootElementName()); if (provider == null) { throw new ConfigurationException( "Unsupported configuration source: " + decl.getConfiguration().getRootElementName()); } final ConfigurationBuilder<? extends Configuration> builder = provider.getConfigurationBuilder(decl); if (decl.getName() != null) { namedBuilders.put(decl.getName(), builder); } allBuilders.add(builder); builder.addEventListener(ConfigurationBuilderEvent.RESET, changeListener); return builder; }
Creates a new configuration using the specified builder and adds it to the resulting combined configuration.
Params:
  • ccResult – the resulting combined configuration
  • decl – the current ConfigurationDeclaration
  • builder – the configuration builder
Throws:
/** * Creates a new configuration using the specified builder and adds it * to the resulting combined configuration. * * @param ccResult the resulting combined configuration * @param decl the current {@code ConfigurationDeclaration} * @param builder the configuration builder * @throws ConfigurationException if an error occurs */
private void addChildConfiguration(final CombinedConfiguration ccResult, final ConfigurationDeclaration decl, final ConfigurationBuilder<? extends Configuration> builder) throws ConfigurationException { try { ccResult.addConfiguration( builder.getConfiguration(), decl.getName(), decl.getAt()); } catch (final ConfigurationException cex) { // ignore exceptions for optional configurations if (!decl.isOptional()) { throw cex; } } }
Creates a listener for builder change events. This listener is registered at all builders for child configurations.
/** * Creates a listener for builder change events. This listener is * registered at all builders for child configurations. */
private EventListener<ConfigurationBuilderEvent> createBuilderChangeListener() { return event -> resetResult(); }
Finds the override configurations that are defined as top level elements in the configuration definition file. This method fetches the child elements of the root node and removes the nodes that represent other configuration sections. The remaining nodes are treated as definitions for override configurations.
Params:
  • config – the definition configuration
Returns:a list with sub configurations for the top level override configurations
/** * Finds the override configurations that are defined as top level * elements in the configuration definition file. This method fetches * the child elements of the root node and removes the nodes that * represent other configuration sections. The remaining nodes are * treated as definitions for override configurations. * * @param config the definition configuration * @return a list with sub configurations for the top level override * configurations */
private List<? extends HierarchicalConfiguration<?>> fetchTopLevelOverrideConfigs( final HierarchicalConfiguration<?> config) { final List<? extends HierarchicalConfiguration<?>> configs = config.childConfigurationsAt(null); for (final Iterator<? extends HierarchicalConfiguration<?>> it = configs.iterator(); it.hasNext();) { final String nodeName = it.next().getRootElementName(); for (final String element : CONFIG_SECTIONS) { if (element.equals(nodeName)) { it.remove(); break; } } } return configs; } } }