A specialized hierarchical configuration class that wraps a single node of its parent configuration.
Configurations of this type are initialized with a parent configuration and a configuration node of this configuration. This node becomes the root node of the subnode configuration. All property accessor methods are evaluated relative to this root node. A good use case for a SubnodeConfiguration
is when multiple properties from a specific sub tree of the whole configuration need to be accessed. Then a SubnodeConfiguration
can be created with the parent node of the affected sub tree as root node. This allows for simpler property keys and is also more efficient.
A subnode configuration and its parent configuration operate on the same hierarchy of configuration nodes. So if modifications are performed at the subnode configuration, these changes are immideately visible in the parent configuration. Analogously will updates of the parent configuration affect the subnode configuration if the sub tree spanned by the subnode configuration's root node is involved.
There are however changes at the parent configuration, which cause the subnode configuration to become detached. An example for such a change is a reload operation of a file-based configuration, which replaces all nodes of the parent configuration. The subnode configuration per default still references the old nodes. Another example are list structures: a subnode configuration can be created to point on the ith element of the list. Now list elements can be added or removed, so that the list elements' indices change. In such a scenario the subnode configuration would always point to the same list element, regardless of its current index.
To solve these problems and make a subnode configuration aware of such structural changes of its parent, it is possible to associate a subnode configuration with a configuration key. This can be done by calling the setSubnodeKey()
method. If here a key is set, the subnode configuration will evaluate it on each access, thus ensuring that it is always in sync with its parent. In this mode the subnode configuration really behaves like a live-view on its parent. The price for this is a decreased performance because now an additional evaluation has to be performed on each property access. So this mode should only be used if necessary; if for instance a subnode configuration is only used for a temporary convenient access to a complex configuration, there is no need to make it aware for structural changes of its parent. If a subnode configuration is created using the {@link HierarchicalConfiguration#configurationAt(String,boolean) configurationAt()}
method of HierarchicalConfiguration
(which should be the preferred way), with an additional boolean parameter it can be specified whether the resulting subnode configuration should be aware of structural changes or not. Then the configuration key will be automatically set.
Note: At the moment support for creating a subnode configuration that is aware of structural changes of its parent from another subnode configuration (a "sub subnode configuration") is limited. This only works if
- the subnode configuration that serves as the parent for the new subnode configuration is itself associated with a configuration key and
- the key passed in to create the new subnode configuration is not too complex (if configuration keys are used that contain indices, a corresponding key that is valid from the parent configuration's point of view cannot be constructed).
When a subnode configuration is created, it inherits the settings of its parent configuration, e.g. some flags like the throwExceptionOnMissing
flag or the settings for handling list delimiters) or the expression engine. If these settings are changed later in either the subnode or the parent configuration, the changes are not visible for each other. So you could create a subnode configuration, change its expression engine without affecting the parent configuration.
From its purpose this class is quite similar to {@link SubsetConfiguration}
. The difference is that a subset configuration of a hierarchical configuration may combine multiple configuration nodes from different sub trees of the configuration, while all nodes in a subnode configuration belong to the same sub tree. If an application can live with this limitation, it is recommended to use this class instead of SubsetConfiguration
because creating a subset configuration is more expensive than creating a subnode configuration.
@since 1.3
@author Oliver Heger
@version $Id: SubnodeConfiguration.java 531254 2007-04-22 18:54:57Z oheger $