public class CombinedConfiguration extends HierarchicalConfiguration implements ConfigurationListener, Cloneable
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
object can be set. This makes it possible to specify different algorithms for
the combination process.
NodeCombiner
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
and the involved
properties, the results may be different than expected. Some examples may
illustrate this:
NodeCombiner
CombinedConfiguration
cc containing
two child configurations with the following content:
gui.background = blue gui.position = (10, 10, 400, 200)
gui.background = black gui.foreground = white home.dir = /data
NodeCombiner
a
OverrideCombiner
is used. This combiner will ensure that defined user settings take precedence
over the default values. If the resulting CombinedConfiguration
is queried for the background color, blue
will be returned
because this value is defined in user.properties
. Now
consider what happens if the key gui.background
is removed
from the CombinedConfiguration
:
cc.clearProperty("gui.background");Will a
cc.containsKey("gui.background")
now return false?
No, it won't! The clearProperty()
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 the CombinedConfiguration
to be re-constructed. This
time the OverrideCombiner
cannot find a
gui.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
statement
addProperty("database.user", "scott");would cause such a hanging property. If now one of the child configurations is changed and the
CombinedConfiguration
is re-constructed,
this property will disappear! (Add operations are not problematic if they
result in a child configuration being updated. For instance an
addProperty("home.url", "localhost");
will alter the second
child configuration - because the prefix home is here already
present; when the CombinedConfiguration
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.
HierarchicalConfiguration.BuilderVisitor, HierarchicalConfiguration.Node, HierarchicalConfiguration.NodeVisitor
Modifier and Type | Field and Description |
---|---|
static int |
EVENT_COMBINED_INVALIDATE
Constant for the invalidate event that is fired when the internal node
structure becomes invalid.
|
EVENT_ADD_NODES, EVENT_CLEAR_TREE, EVENT_SUBNODE_CHANGED
END_TOKEN, EVENT_ADD_PROPERTY, EVENT_CLEAR, EVENT_CLEAR_PROPERTY, EVENT_READ_PROPERTY, EVENT_SET_PROPERTY, START_TOKEN
Constructor and Description |
---|
CombinedConfiguration()
Creates a new instance of
CombinedConfiguration that uses
a union combiner. |
CombinedConfiguration(NodeCombiner comb)
Creates a new instance of
CombinedConfiguration and
initializes the combiner to be used. |
Modifier and Type | Method and Description |
---|---|
void |
addConfiguration(AbstractConfiguration config)
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.
|
Object |
clone()
Returns a copy of this object.
|
void |
configurationChanged(ConfigurationEvent event)
Event listener call back for configuration update events.
|
protected List |
fetchNodeList(String key)
Evaluates the passed in property key and returns a list with the matching
configuration nodes.
|
Configuration |
getConfiguration(int index)
Returns the configuration at the specified index.
|
Configuration |
getConfiguration(String name)
Returns the configuration with the given name.
|
Set |
getConfigurationNames()
Returns a set with the names of all configurations contained in this
combined configuration.
|
ExpressionEngine |
getConversionExpressionEngine()
Returns the
ExpressionEngine for converting flat child
configurations to hierarchical ones. |
NodeCombiner |
getNodeCombiner()
Returns the node combiner that is used for creating the combined node
structure.
|
int |
getNumberOfConfigurations()
Returns the number of configurations that are contained in this combined
configuration.
|
ConfigurationNode |
getRootNode()
Returns the configuration root node of this combined configuration.
|
Configuration |
getSource(String key)
Returns the configuration source, in which the specified key is defined.
|
void |
invalidate()
Invalidates this combined configuration.
|
boolean |
isForceReloadCheck()
Returns a flag whether an enhanced reload check must be performed.
|
protected void |
performReloadCheck()
Triggers the contained configurations to perform a reload check if
necessary.
|
boolean |
removeConfiguration(Configuration config)
Removes the specified configuration from this combined configuration.
|
Configuration |
removeConfiguration(String name)
Removes the configuration with the specified name.
|
Configuration |
removeConfigurationAt(int index)
Removes the configuration at the specified index.
|
void |
setConversionExpressionEngine(ExpressionEngine conversionExpressionEngine)
Sets the
ExpressionEngine for converting flat child
configurations to hierarchical ones. |
void |
setForceReloadCheck(boolean forceReloadCheck)
Sets the force reload check flag.
|
void |
setNodeCombiner(NodeCombiner nodeCombiner)
Sets the node combiner.
|
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
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, isThrowExceptionOnMissing, resolveContainerStore, setDefaultListDelimiter, setDelimiter, setDelimiterParsingDisabled, setListDelimiter, setLogger, setThrowExceptionOnMissing
addConfigurationListener, addErrorListener, clearConfigurationListeners, clearErrorListeners, createErrorEvent, createEvent, fireError, fireEvent, getConfigurationListeners, getErrorListeners, isDetailEvents, removeConfigurationListener, removeErrorListener, setDetailEvents
public static final int EVENT_COMBINED_INVALIDATE
public CombinedConfiguration(NodeCombiner comb)
CombinedConfiguration
and
initializes the combiner to be used.comb
- the node combiner (can be null, then a union combiner
is used as default)public CombinedConfiguration()
CombinedConfiguration
that uses
a union combiner.UnionCombiner
public NodeCombiner getNodeCombiner()
public void setNodeCombiner(NodeCombiner nodeCombiner)
IllegalArgumentException
exception is thrown. Changing the
node combiner causes an invalidation of this combined configuration, so
that the new combiner immediately takes effect.nodeCombiner
- the node combinerpublic boolean isForceReloadCheck()
public void setForceReloadCheck(boolean forceReloadCheck)
forceReloadCheck
- the value of the flagpublic ExpressionEngine getConversionExpressionEngine()
ExpressionEngine
for converting flat child
configurations to hierarchical ones.public void setConversionExpressionEngine(ExpressionEngine conversionExpressionEngine)
ExpressionEngine
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.conversionExpressionEngine
- the conversion expression engineConfigurationUtils.convertToHierarchical(Configuration, ExpressionEngine)
public void addConfiguration(AbstractConfiguration config, String name, String at)
ConfigurationRuntimeException
will
be thrown. With the optional at
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.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)public void addConfiguration(AbstractConfiguration config, String name)
config
- the configuration to add (must not be null)name
- the name of this configuration (can be null)public void addConfiguration(AbstractConfiguration config)
config
- the configuration to add (must not be null)public int getNumberOfConfigurations()
public Configuration getConfiguration(int index)
index
- the indexpublic Configuration getConfiguration(String name)
name
- the name of the configurationpublic boolean removeConfiguration(Configuration config)
config
- the configuration to be removedpublic Configuration removeConfigurationAt(int index)
index
- the indexpublic Configuration removeConfiguration(String name)
name
- the name of the configuration to be removedpublic Set getConfigurationNames()
public void invalidate()
EVENT_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).public void configurationChanged(ConfigurationEvent event)
configurationChanged
in interface ConfigurationListener
event
- the update eventpublic ConfigurationNode getRootNode()
getRootNode
in class HierarchicalConfiguration
public void clear()
clear
in interface Configuration
clear
in class AbstractConfiguration
public Object clone()
clone
in class HierarchicalConfiguration
public Configuration getSource(String key)
IllegalArgumentException
is
thrown (in this case no unique source can be determined).key
- the key of a configuration propertyIllegalArgumentException
- if the key maps to multiple properties
and the source cannot be determined, or if the key is nullprotected List fetchNodeList(String key)
performReloadCheck()
is invoked.fetchNodeList
in class HierarchicalConfiguration
key
- the property keyprotected void performReloadCheck()
forceReloadCheck
property
is set to true.setForceReloadCheck(boolean)
Copyright © 2018 JBoss by Red Hat. All rights reserved.