Package org.apache.commons.configuration2

# Class SubnodeConfiguration

java.lang.Object
org.apache.commons.configuration2.event.BaseEventSource
org.apache.commons.configuration2.AbstractConfiguration
org.apache.commons.configuration2.AbstractHierarchicalConfiguration<ImmutableNode>
org.apache.commons.configuration2.BaseHierarchicalConfiguration
org.apache.commons.configuration2.SubnodeConfiguration

All Implemented Interfaces:
  `Cloneable`, `Configuration`, `EventSource`, `HierarchicalConfiguration<ImmutableNode>`, `ImmutableConfiguration`, `ImmutableHierarchicalConfiguration`, `SynchronizerSupport`, `InMemoryNodeModelSupport`, `NodeKeyResolver<ImmutableNode>`, `NodeModelSupport<ImmutableNode>`

public class SubnodeConfiguration extends BaseHierarchicalConfiguration

A specialized hierarchical configuration class with a node model that uses a tracked node of another node model as its root node.

Configurations of this type are initialized with a special `NodeModel` operating on a specific tracked node of the parent configuration and the corresponding `NodeSelector`. 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.

By making use of a tracked node as root node, a `SubnodeConfiguration` and its parent configuration initially operate on the same hierarchy of configuration nodes. So if modifications are performed at the subnode configuration, these changes are immediately visible in the parent configuration. Analogously will updates of the parent configuration affect the `SubnodeConfiguration` if the sub tree spanned by the `SubnodeConfiguration`'s root node is involved.

Note that by making use of a `NodeSelector` the `SubnodeConfiguration` is not associated with a physical node instance, but the selection criteria stored in the selector are evaluated after each change of the nodes structure. As an example consider that the selector uses a key with an index into a list element, say index 2. Now if an update occurs on the underlying nodes structure which removes the first element in this list structure, the `SubnodeConfiguration` still references the element with index 2 which is now another one.

There are also possible changes of the underlying nodes structure which completely detach the `SubnodeConfiguration` from its parent configuration. For instance, the key referenced by the `SubnodeConfiguration` could be removed in the parent configuration. If this happens, the `SubnodeConfiguration` stays functional; however, it now operates on a separate node model than its parent configuration. Changes made by one configuration are no longer visible for the other one (as the node models have no longer overlapping nodes, there is no way to have a synchronization here).

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, and change its expression engine without affecting the parent configuration.

Because the `SubnodeConfiguration` operates on the same nodes structure as its parent it uses the same `Synchronizer` instance per default. This means that locks held on one `SubnodeConfiguration` also impact the parent configuration and all of its other `SubnodeConfiguration` objects. You should not change this without a good reason! Otherwise, there is the risk of data corruption when multiple threads access these configuration concurrently.

From its purpose this class is quite similar to `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.

It is strongly recommended to create `SubnodeConfiguration` instances only through the `configurationAt()` methods of a hierarchical configuration. These methods ensure that all necessary initializations are done. Creating instances manually without doing proper initialization may break some of the functionality provided by this class.

Since:
  1.3

- ## Nested Class Summary

  ## Nested classes/interfaces inherited from class org.apache.commons.configuration2.BaseHierarchicalConfiguration

  `BaseHierarchicalConfiguration.BuilderVisitor`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `SubnodeConfiguration(BaseHierarchicalConfiguration parent, TrackedNodeModel model)`
  Creates a new instance of `SubnodeConfiguration` and initializes it with all relevant properties.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `protected NodeModel<ImmutableNode>`
  `cloneNodeModel()`
  Creates a clone of the node model.
  `void`
  `close()`
  Closes this sub configuration.
  `protected SubnodeConfiguration`
  `createSubConfigurationForTrackedNode(NodeSelector selector, InMemoryNodeModelSupport parentModelSupport)`
  Creates a connected sub configuration based on a selector for a tracked node.
  `InMemoryNodeModel`
  `getNodeModel()`
  Gets the `NodeModel` supported by this object.
  `BaseHierarchicalConfiguration`
  `getParent()`
  Gets the parent configuration of this subnode configuration.
  `InMemoryNodeModel`
  `getRootNodeModel()`
  Gets the node model of the root configuration.
  `NodeSelector`
  `getRootSelector()`
  Gets the selector to the root node of this configuration.
  `protected NodeSelector`
  `getSubConfigurationNodeSelector(String key)`
  Gets the `NodeSelector` to be used for a sub configuration based on the passed in key.
  `protected InMemoryNodeModel`
  `getSubConfigurationParentModel()`
  Gets the `InMemoryNodeModel` to be used as parent model for a new sub configuration.

  ### Methods inherited from class org.apache.commons.configuration2.BaseHierarchicalConfiguration

  `childConfigurationsAt, childConfigurationsAt, configurationAt, configurationAt, configurationsAt, configurationsAt, immutableChildConfigurationsAt, immutableConfigurationAt, immutableConfigurationAt, immutableConfigurationsAt, initSubConfigurationForThisParent, interpolatedConfiguration, subnodeConfigurationChanged, subset`

  ### Methods inherited from class org.apache.commons.configuration2.AbstractHierarchicalConfiguration

  `addNodes, addNodesInternal, addPropertyDirect, addPropertyInternal, clearInternal, clearPropertyDirect, clearTree, clearTreeInternal, clone, containsKeyInternal, fetchNodeList, getExpressionEngine, getKeysInternal, getKeysInternal, getMaxIndex, getMaxIndexInternal, getModel, getPropertyInternal, getRootElementName, getRootElementNameInternal, isEmptyInternal, nodeDefined, nodeKey, resolveAddKey, resolveKey, resolveNodeKey, resolveUpdateKey, setExpressionEngine, setPropertyInternal, sizeInternal, toString`

  ### Methods inherited from class org.apache.commons.configuration2.AbstractConfiguration

  `addErrorLogListener, addProperty, append, beginRead, beginWrite, clear, clearProperty, cloneInterpolator, containsKey, copy, endRead, endWrite, get, get, getArray, getArray, getBigDecimal, getBigDecimal, getBigInteger, getBigInteger, getBoolean, getBoolean, getBoolean, getByte, getByte, getByte, getCollection, getCollection, getConfigurationDecoder, getConversionHandler, getDouble, getDouble, getDouble, getDuration, getDuration, getEncodedString, getEncodedString, getFloat, getFloat, getFloat, getInt, getInt, getInteger, getInterpolator, getKeys, getKeys, getKeys, getKeysInternal, getList, getList, getList, getList, getListDelimiterHandler, getLogger, getLong, getLong, getLong, getProperties, getProperties, getProperty, getShort, getShort, getShort, getString, getString, getStringArray, getSynchronizer, immutableSubset, initLogger, installInterpolator, interpolate, interpolate, isEmpty, isScalarValue, isThrowExceptionOnMissing, lock, setConfigurationDecoder, setConversionHandler, setDefaultLookups, setInterpolator, setListDelimiterHandler, setLogger, setParentInterpolator, setPrefixLookups, setProperty, setSynchronizer, setThrowExceptionOnMissing, size, unlock`

  ### Methods inherited from class org.apache.commons.configuration2.event.BaseEventSource

  `addEventListener, clearErrorListeners, clearEventListeners, copyEventListeners, createErrorEvent, createEvent, fireError, fireEvent, getEventListenerRegistrations, getEventListeners, isDetailEvents, removeEventListener, setDetailEvents`

  ### Methods inherited from class java.lang.Object

  `equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

  ### Methods inherited from interface org.apache.commons.configuration2.Configuration

  `addProperty, clear, clearProperty, getInterpolator, installInterpolator, setInterpolator, setProperty`

  ### Methods inherited from interface org.apache.commons.configuration2.ImmutableConfiguration

  `containsKey, get, get, getArray, getArray, getBigDecimal, getBigDecimal, getBigInteger, getBigInteger, getBoolean, getBoolean, getBoolean, getByte, getByte, getByte, getCollection, getCollection, getDouble, getDouble, getDouble, getDuration, getDuration, getEncodedString, getEncodedString, getEnum, getEnum, getFloat, getFloat, getFloat, getInt, getInt, getInteger, getKeys, getKeys, getKeys, getList, getList, getList, getList, getLong, getLong, getLong, getProperties, getProperty, getShort, getShort, getShort, getString, getString, getStringArray, immutableSubset, isEmpty, size`

  ### Methods inherited from interface org.apache.commons.configuration2.sync.SynchronizerSupport

  `getSynchronizer, lock, setSynchronizer, unlock`

- ## Constructor Details

  - ### SubnodeConfiguration

    public SubnodeConfiguration(BaseHierarchicalConfiguration parent, TrackedNodeModel model)
    Creates a new instance of `SubnodeConfiguration` and initializes it with all relevant properties.
    Parameters:
      `parent` - the parent configuration
      `model` - the `TrackedNodeModel` to be used for this configuration
    Throws:
      `IllegalArgumentException` - if a required argument is missing

- ## Method Details

  - ### getParent

    public BaseHierarchicalConfiguration getParent()
    Gets the parent configuration of this subnode configuration.
    Returns:
      the parent configuration

  - ### getRootSelector

    public NodeSelector getRootSelector()
    Gets the selector to the root node of this configuration.
    Returns:
      the `NodeSelector` to the root node

  - ### close

    public void close()
    Closes this sub configuration. This method closes the underlying `TrackedNodeModel`, thus causing the tracked node acting as root node to be released. Per default, this happens automatically when the model is claimed by the garbage collector. By calling this method explicitly, it can be indicated that this configuration is no longer used and that resources used by it can be freed immediately.

  - ### getNodeModel

    public InMemoryNodeModel getNodeModel()
    Gets the `NodeModel` supported by this object. This implementation returns the configuration's `NodeModel`. It is guarded by the current `Synchronizer`. This implementation returns the `InMemoryNodeModel` used by this configuration. This implementation returns a newly created node model with the correct root node set. Note that this model is not used for property access, but only made available to clients that need to operate on the node structure of this `SubnodeConfiguration`. Be aware that the implementation of this method is not very efficient.
    Specified by:
      `getNodeModel` in interface `InMemoryNodeModelSupport`
    Specified by:
      `getNodeModel` in interface `NodeModelSupport<ImmutableNode>`
    Overrides:
      `getNodeModel` in class `BaseHierarchicalConfiguration`
    Returns:
      the `NodeModel`

  - ### getRootNodeModel

    public InMemoryNodeModel getRootNodeModel()
    Gets the node model of the root configuration. `SubnodeConfiguration` instances created from a hierarchical configuration operate on the same node model, using different nodes as their local root nodes. With this method the top-level node model can be obtained. It works even in constellations where a `SubnodeConfiguration` has been created from another `SubnodeConfiguration`.
    Returns:
      the root node model
    Since:
      2.2

  - ### cloneNodeModel

    protected NodeModel<ImmutableNode> cloneNodeModel()
    Creates a clone of the node model. This method is called by `clone()`. This implementation creates a new instance of `InMemoryNodeModel`, initialized with this configuration's root node. This has the effect that although the same nodes are used, the original and copied configurations are independent on each other. This implementation returns a copy of the current node model with the same settings. However, it has to be ensured that the track count for the node selector is increased.
    Overrides:
      `cloneNodeModel` in class `BaseHierarchicalConfiguration`
    Returns:
      the node model for the clone

  - ### getSubConfigurationNodeSelector

    protected NodeSelector getSubConfigurationNodeSelector(String key)
    Gets the `NodeSelector` to be used for a sub configuration based on the passed in key. This method is called whenever a sub configuration is to be created. This base implementation returns a new `NodeSelector` initialized with the passed in key. Sub classes may override this method if they have a different strategy for creating a selector. This implementation returns a sub selector of the selector of this configuration.
    Overrides:
      `getSubConfigurationNodeSelector` in class `BaseHierarchicalConfiguration`
    Parameters:
      `key` - the key of the sub configuration
    Returns:
      a `NodeSelector` for initializing a sub configuration

  - ### getSubConfigurationParentModel

    protected InMemoryNodeModel getSubConfigurationParentModel()
    Gets the `InMemoryNodeModel` to be used as parent model for a new sub configuration. This method is called whenever a sub configuration is to be created. This base implementation returns the model of this configuration. Sub classes with different requirements for the parent models of sub configurations have to override it. This implementation returns the parent model of the `TrackedNodeModel` used by this configuration.
    Overrides:
      `getSubConfigurationParentModel` in class `BaseHierarchicalConfiguration`
    Returns:
      the parent model for a new sub configuration

  - ### createSubConfigurationForTrackedNode

    protected SubnodeConfiguration createSubConfigurationForTrackedNode(NodeSelector selector, InMemoryNodeModelSupport parentModelSupport)
    Creates a connected sub configuration based on a selector for a tracked node. This implementation makes sure that the correct node model (the one of the parent) is used for the new sub configuration.
    Overrides:
      `createSubConfigurationForTrackedNode` in class `BaseHierarchicalConfiguration`
    Parameters:
      `selector` - the `NodeSelector`
      `parentModelSupport` - the `InMemoryNodeModelSupport` object for the parent node model
    Returns:
      the newly created sub configuration