A hierarchical composite configuration class.
This class maintains a list of configuration objects, which can be added using the diverse {@code addConfiguration()} methods. After that theconfigurations 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 {@link org.apache.commons.configuration2.tree.NodeCombiner 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 {@code NodeCombiner}, this may be a complex operation.
Because of the way a {@code CombinedConfiguration} is working it has more orless 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 {@code addProperty()}, or {@code clearProperty()} on a{@code CombinedConfiguration} is not strictly forbidden, however, dependingon the current {@link NodeCombiner} and the involved properties, the resultsmay be different than expected. Some examples may illustrate this:
Because of such problems it is recommended to perform updates only on the managed child configurations.
Whenever the node structure of a {@code CombinedConfiguration} becomesinvalid (either because one of the contained configurations was modified or because the {@code invalidate()} method was directly called) an event isgenerated. So this can be detected by interested event listeners. This also makes it possible to add a combined configuration into another one.
Notes about thread-safety: This configuration implementation uses a {@code Synchronizer} object to protect instances against concurrent access.The concrete {@code Synchronizer} implementation used determines whether aninstance of this class is thread-safe or not. In contrast to other implementations derived from {@link BaseHierarchicalConfiguration}, thread-safety is an issue here because the nodes structure used by this configuration has to be constructed dynamically when a child configuration is changed. Therefore, when multiple threads are involved which also manipulate one of the child configurations, a proper {@code Synchronizer} object shouldbe set. Note that the {@code Synchronizer} objects used by the childconfigurations do not really matter. Because immutable in-memory nodes structures are used for them there is no danger that updates on child configurations could interfere with read operations on the combined configuration.
@since 1.3
@version $Id: CombinedConfiguration.java 1624601 2014-09-12 18:04:36Z oheger $