Class CombinedConfiguration
- All Implemented Interfaces:
Serializable
,Cloneable
,Configuration
,ConfigurationListener
,Reloadable
- Direct Known Subclasses:
DynamicCombinedConfiguration
A hierarchical composite configuration class.
This class maintains a list of configuration objects, which can be added
using the divers addConfiguration()
methods. After that the
configurations can be accessed either by name (if one was provided when the
configuration was added) or by index. For the whole set of managed
configurations a logical node structure is constructed. For this purpose a
NodeCombiner
object can be set. This makes it possible to specify different algorithms for
the combination process.
The big advantage of this class is that it creates a truly hierarchical structure of all the properties stored in the contained configurations - even if some of them are no hierarchical configurations per se. So all enhanced features provided by a hierarchical configuration (e.g. choosing an expression engine) are applicable.
The class works by registering itself as an event listener at all added
configurations. So it gets notified whenever one of these configurations is
changed and can invalidate its internal node structure. The next time a
property is accessed the node structure will be re-constructed using the
current state of the managed configurations. Note that, depending on the used
NodeCombiner
, this may be a complex operation.
Because of the way a CombinedConfiguration
is working it has
more or less view character: it provides a logic view on the configurations
it contains. In this constellation not all methods defined for hierarchical
configurations - especially methods that update the stored properties - can
be implemented in a consistent manner. Using such methods (like
addProperty()
, or clearProperty()
on a
CombinedConfiguration
is not strictly forbidden, however,
depending on the current NodeCombiner
and the involved
properties, the results may be different than expected. Some examples may
illustrate this:
- Imagine a
CombinedConfiguration
cc containing two child configurations with the following content:- user.properties
-
gui.background = blue gui.position = (10, 10, 400, 200)
- default.properties
-
gui.background = black gui.foreground = white home.dir = /data
NodeCombiner
aOverrideCombiner
is used. This combiner will ensure that defined user settings take precedence over the default values. If the resultingCombinedConfiguration
is queried for the background color,blue
will be returned because this value is defined inuser.properties
. Now consider what happens if the keygui.background
is removed from theCombinedConfiguration
:cc.clearProperty("gui.background");
Will acc.containsKey("gui.background")
now return false? No, it won't! TheclearProperty()
operation is executed on the node set of the combined configuration, which was constructed from the nodes of the two child configurations. It causes the value of the background node to be cleared, which is also part of the first child configuration. This modification of one of its child configurations causes theCombinedConfiguration
to be re-constructed. This time theOverrideCombiner
cannot find agui.background
property in the first child configuration, but it finds one in the second, and adds it to the resulting combined configuration. So the property is still present (with a different value now). addProperty()
can also be problematic: Most node combiners use special view nodes for linking parts of the original configurations' data together. If new properties are added to such a special node, they do not belong to any of the managed configurations and thus hang in the air. Using the same configurations as in the last example, the statementaddProperty("database.user", "scott");
would cause such a hanging property. If now one of the child configurations is changed and theCombinedConfiguration
is re-constructed, this property will disappear! (Add operations are not problematic if they result in a child configuration being updated. For instance anaddProperty("home.url", "localhost");
will alter the second child configuration - because the prefix home is here already present; when theCombinedConfiguration
is re-constructed, this change is taken into account.)
Whenever the node structure of a CombinedConfiguration
becomes
invalid (either because one of the contained configurations was modified or
because the invalidate()
method was directly called) an event
is generated. So this can be detected by interested event listeners. This
also makes it possible to add a combined configuration into another one.
Implementation note: Adding and removing configurations to and from a combined configuration is not thread-safe. If a combined configuration is manipulated by multiple threads, the developer has to take care about properly synchronization.
- Since:
- 1.3
- Version:
- $Id: CombinedConfiguration.java 1234985 2012-01-23 21:09:09Z oheger $
- Author:
- Commons Configuration team
- See Also:
-
Nested Class Summary
Nested classes/interfaces inherited from class org.apache.commons.configuration.HierarchicalConfiguration
HierarchicalConfiguration.BuilderVisitor, HierarchicalConfiguration.Node, HierarchicalConfiguration.NodeVisitor
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final int
Constant for the invalidate event that is fired when the internal node structure becomes invalid.Fields inherited from class org.apache.commons.configuration.HierarchicalConfiguration
EVENT_ADD_NODES, EVENT_CLEAR_TREE, EVENT_SUBNODE_CHANGED
Fields inherited from class org.apache.commons.configuration.AbstractConfiguration
END_TOKEN, EVENT_ADD_PROPERTY, EVENT_CLEAR, EVENT_CLEAR_PROPERTY, EVENT_READ_PROPERTY, EVENT_SET_PROPERTY, START_TOKEN
-
Constructor Summary
ConstructorsConstructorDescriptionCreates a new instance ofCombinedConfiguration
that uses a union combiner.CombinedConfiguration
(Lock lock) Creates a new instance ofCombinedConfiguration
and initializes the combiner to be used.CombinedConfiguration
(NodeCombiner comb, Lock lock) -
Method Summary
Modifier and TypeMethodDescriptionvoid
Adds a new configuration to this combined configuration.void
addConfiguration
(AbstractConfiguration config, String name) Adds a new configuration to this combined configuration with an optional name.void
addConfiguration
(AbstractConfiguration config, String name, String at) Adds a new configuration to this combined configuration.void
clear()
Clears this configuration.clone()
Returns a copy of this object.void
Event listener call back for configuration update events.protected List<ConfigurationNode>
fetchNodeList
(String key) Evaluates the passed in property key and returns a list with the matching configuration nodes.getConfiguration
(int index) Returns the configuration at the specified index.getConfiguration
(String name) Returns the configuration with the given name.Returns a List of the names of all the configurations that have been added in the order they were added.Returns a set with the names of all configurations contained in this combined configuration.Returns a List of all the configurations that have been added.Returns theExpressionEngine
for converting flat child configurations to hierarchical ones.Returns the node combiner that is used for creating the combined node structure.int
Returns the number of configurations that are contained in this combined configuration.Returns the configuration root node of this combined configuration.Returns the configuration source, in which the specified key is defined.void
Invalidates this combined configuration.boolean
Returns a flag whether an enhanced reload check must be performed.boolean
Retrieves the value of the ignoreReloadExceptions flag.protected void
Triggers the contained configurations to perform a reload check if necessary.removeConfiguration
(String name) Removes the configuration with the specified name.boolean
removeConfiguration
(Configuration config) Removes the specified configuration from this combined configuration.removeConfigurationAt
(int index) Removes the configuration at the specified index.void
setConversionExpressionEngine
(ExpressionEngine conversionExpressionEngine) Sets theExpressionEngine
for converting flat child configurations to hierarchical ones.void
setForceReloadCheck
(boolean forceReloadCheck) Sets the force reload check flag.void
setIgnoreReloadExceptions
(boolean ignoreReloadExceptions) If set to true then exceptions that occur during reloading will be ignored.void
setNodeCombiner
(NodeCombiner nodeCombiner) Sets the node combiner.Methods inherited from class org.apache.commons.configuration.HierarchicalReloadableConfiguration
getReloadLock
Methods inherited from class org.apache.commons.configuration.HierarchicalConfiguration
addNodes, addPropertyDirect, clearNode, clearNode, clearProperty, clearReferences, clearTree, configurationAt, configurationAt, configurationsAt, containsKey, createAddPath, createNode, createSubnodeConfiguration, createSubnodeConfiguration, fetchAddNode, findLastPathNode, findPropertyNodes, getDefaultExpressionEngine, getExpressionEngine, getKeys, getKeys, getMaxIndex, getProperty, getRoot, interpolatedConfiguration, isEmpty, nodeDefined, nodeDefined, removeNode, removeNode, setDefaultExpressionEngine, setExpressionEngine, setProperty, setRoot, setRootNode, subnodeConfigurationChanged, subset
Methods inherited from class org.apache.commons.configuration.AbstractConfiguration
addErrorLogListener, addProperty, append, clearPropertyDirect, copy, createInterpolator, getBigDecimal, getBigDecimal, getBigInteger, getBigInteger, getBoolean, getBoolean, getBoolean, getByte, getByte, getByte, getDefaultListDelimiter, getDelimiter, getDouble, getDouble, getDouble, getFloat, getFloat, getFloat, getInt, getInt, getInteger, getInterpolator, getList, getList, getListDelimiter, getLogger, getLong, getLong, getLong, getProperties, getProperties, getShort, getShort, getShort, getString, getString, getStringArray, getSubstitutor, interpolate, interpolate, interpolateHelper, isDelimiterParsingDisabled, isScalarValue, isThrowExceptionOnMissing, resolveContainerStore, setDefaultListDelimiter, setDelimiter, setDelimiterParsingDisabled, setListDelimiter, setLogger, setThrowExceptionOnMissing
Methods inherited from class org.apache.commons.configuration.event.EventSource
addConfigurationListener, addErrorListener, clearConfigurationListeners, clearErrorListeners, createErrorEvent, createEvent, fireError, fireEvent, getConfigurationListeners, getErrorListeners, isDetailEvents, removeConfigurationListener, removeErrorListener, setDetailEvents
-
Field Details
-
EVENT_COMBINED_INVALIDATE
Constant for the invalidate event that is fired when the internal node structure becomes invalid.- See Also:
-
-
Constructor Details
-
CombinedConfiguration
Creates a new instance ofCombinedConfiguration
and initializes the combiner to be used.- Parameters:
comb
- the node combiner (can be null, then a union combiner is used as default)
-
CombinedConfiguration
-
CombinedConfiguration
-
CombinedConfiguration
public CombinedConfiguration()Creates a new instance ofCombinedConfiguration
that uses a union combiner.- See Also:
-
-
Method Details
-
getNodeCombiner
Returns the node combiner that is used for creating the combined node structure.- Returns:
- the node combiner
-
setNodeCombiner
Sets the node combiner. This object will be used when the combined node structure is to be constructed. It must not be null, otherwise anIllegalArgumentException
exception is thrown. Changing the node combiner causes an invalidation of this combined configuration, so that the new combiner immediately takes effect.- Parameters:
nodeCombiner
- the node combiner
-
isForceReloadCheck
Returns a flag whether an enhanced reload check must be performed.- Returns:
- the force reload check flag
- Since:
- 1.4
-
setForceReloadCheck
Sets the force reload check flag. If this flag is set, each property access on this configuration will cause a reload check on the contained configurations. This is a workaround for a problem with some reload implementations that only check if a reload is required when they are triggered. Per default this mode is disabled. If the force reload check flag is set to true, accessing properties will be less efficient, but reloads on contained configurations will be detected.- Parameters:
forceReloadCheck
- the value of the flag- Since:
- 1.4
-
getConversionExpressionEngine
Returns theExpressionEngine
for converting flat child configurations to hierarchical ones.- Returns:
- the conversion expression engine
- Since:
- 1.6
-
setConversionExpressionEngine
Sets theExpressionEngine
for converting flat child configurations to hierarchical ones. When constructing the root node for this combined configuration the properties of all child configurations must be combined to a single hierarchical node structure. In this process, non hierarchical configurations are converted to hierarchical ones first. This can be problematic if a child configuration contains keys that are no compatible with the default expression engine used by hierarchical configurations. Therefore it is possible to specify a specific expression engine to be used for this purpose.- Parameters:
conversionExpressionEngine
- the conversion expression engine- Since:
- 1.6
- See Also:
-
isIgnoreReloadExceptions
Retrieves the value of the ignoreReloadExceptions flag.- Returns:
- true if exceptions are ignored, false otherwise.
-
setIgnoreReloadExceptions
If set to true then exceptions that occur during reloading will be ignored. If false then the exceptions will be allowed to be thrown back to the caller.- Parameters:
ignoreReloadExceptions
- true if exceptions should be ignored.
-
addConfiguration
Adds a new configuration to this combined configuration. It is possible (but not mandatory) to give the new configuration a name. This name must be unique, otherwise aConfigurationRuntimeException
will be thrown. With the optionalat
argument you can specify where in the resulting node structure the content of the added configuration should appear. This is a string that uses dots as property delimiters (independent on the current expression engine). For instance if you pass in the string"database.tables"
, all properties of the added configuration will occur in this branch.- Parameters:
config
- the configuration to add (must not be null)name
- the name of this configuration (can be null)at
- the position of this configuration in the combined tree (can be null)
-
addConfiguration
Adds a new configuration to this combined configuration with an optional name. The new configuration's properties will be added under the root of the combined node structure.- Parameters:
config
- the configuration to add (must not be null)name
- the name of this configuration (can be null)
-
addConfiguration
Adds a new configuration to this combined configuration. The new configuration is not given a name. Its properties will be added under the root of the combined node structure.- Parameters:
config
- the configuration to add (must not be null)
-
getNumberOfConfigurations
Returns the number of configurations that are contained in this combined configuration.- Returns:
- the number of contained configurations
-
getConfiguration
Returns the configuration at the specified index. The contained configurations are numbered in the order they were added to this combined configuration. The index of the first configuration is 0.- Parameters:
index
- the index- Returns:
- the configuration at this index
-
getConfiguration
Returns the configuration with the given name. This can be null if no such configuration exists.- Parameters:
name
- the name of the configuration- Returns:
- the configuration with this name
-
getConfigurations
Returns a List of all the configurations that have been added.- Returns:
- A List of all the configurations.
- Since:
- 1.7
-
getConfigurationNameList
Returns a List of the names of all the configurations that have been added in the order they were added. A NULL value will be present in the list for each configuration that was added without a name.- Returns:
- A List of all the configuration names.
- Since:
- 1.7
-
removeConfiguration
Removes the specified configuration from this combined configuration.- Parameters:
config
- the configuration to be removed- Returns:
- a flag whether this configuration was found and could be removed
-
removeConfigurationAt
Removes the configuration at the specified index.- Parameters:
index
- the index- Returns:
- the removed configuration
-
removeConfiguration
Removes the configuration with the specified name.- Parameters:
name
- the name of the configuration to be removed- Returns:
- the removed configuration (null if this configuration was not found)
-
getConfigurationNames
Returns a set with the names of all configurations contained in this combined configuration. Of course here are only these configurations listed, for which a name was specified when they were added.- Returns:
- a set with the names of the contained configurations (never null)
-
invalidate
Invalidates this combined configuration. This means that the next time a property is accessed the combined node structure must be re-constructed. Invalidation of a combined configuration also means that an event of typeEVENT_COMBINED_INVALIDATE
is fired. Note that while other events most times appear twice (once before and once after an update), this event is only fired once (after update). -
configurationChanged
Event listener call back for configuration update events. This method is called whenever one of the contained configurations was modified. It invalidates this combined configuration.- Specified by:
configurationChanged
in interfaceConfigurationListener
- Parameters:
event
- the update event
-
getRootNode
Returns the configuration root node of this combined configuration. This method will construct a combined node structure using the current node combiner if necessary.- Overrides:
getRootNode
in classHierarchicalConfiguration
- Returns:
- the combined root node
-
clear
Clears this configuration. All contained configurations will be removed.- Specified by:
clear
in interfaceConfiguration
- Overrides:
clear
in classHierarchicalConfiguration
-
clone
Returns a copy of this object. This implementation performs a deep clone, i.e. all contained configurations will be cloned, too. For this to work, all contained configurations must be cloneable. Registered event listeners won't be cloned. The clone will use the same node combiner than the original.- Overrides:
clone
in classHierarchicalConfiguration
- Returns:
- the copied object
-
getSource
Returns the configuration source, in which the specified key is defined. This method will determine the configuration node that is identified by the given key. The following constellations are possible:- If no node object is found for this key, null is returned.
- If the key maps to multiple nodes belonging to different
configuration sources, a
IllegalArgumentException
is thrown (in this case no unique source can be determined). - If exactly one node is found for the key, the (child) configuration object, to which the node belongs is determined and returned.
- For keys that have been added directly to this combined configuration and that do not belong to the namespaces defined by existing child configurations this configuration will be returned.
- Parameters:
key
- the key of a configuration property- Returns:
- the configuration, to which this property belongs or null if the key cannot be resolved
- Throws:
IllegalArgumentException
- if the key maps to multiple properties and the source cannot be determined, or if the key is null- Since:
- 1.5
-
fetchNodeList
Evaluates the passed in property key and returns a list with the matching configuration nodes. This implementation also evaluates the force reload check flag. If it is set,performReloadCheck()
is invoked.- Overrides:
fetchNodeList
in classHierarchicalConfiguration
- Parameters:
key
- the property key- Returns:
- a list with the matching configuration nodes
-
performReloadCheck
Triggers the contained configurations to perform a reload check if necessary. This method is called when a property of this combined configuration is accessed and theforceReloadCheck
property is set to true.- Since:
- 1.6
- See Also:
-