Package org.apache.commons.configuration2.tree

# Class TrackedNodeModel

java.lang.Object
org.apache.commons.configuration2.tree.TrackedNodeModel

All Implemented Interfaces:
  `NodeModel<ImmutableNode>`

public class TrackedNodeModel extends Object implements NodeModel<ImmutableNode>

A specialized `NodeModel` implementation that uses a tracked node managed by an `InMemoryNodeModel` object as root node.

Models of this type are useful when working on specific sub trees of a nodes structure. This is the case for instance for a `SubnodeConfiguration`.

An instance of this class is constructed with an `InMemoryNodeModelSupport` object providing a reference to the underlying `InMemoryNodeModel` and the `NodeSelector` pointing to the tracked node acting as this model's root node. The `NodeModel` operations are implemented by delegating to the wrapped `InMemoryNodeModel` object specifying the selector to the tracked node as target root node for the update transaction. Note that the tracked node can become detached at any time. This situation is handled transparently by the implementation of `InMemoryNodeModel`. The reason for using an `InMemoryNodeModelSupport` object rather than an `InMemoryNodeModel` directly is that this additional layer of indirection can be used for performing special initializations on the model before it is returned to the `TrackedNodeModel` object. This is needed by some dynamic configuration implementations, e.g. by `CombinedConfiguration`.

If the tracked node acting as root node is exclusively used by this model, it should be released when this model is no longer needed. This can be done manually by calling the `close()` method. It is also possible to pass a value of true to the `untrackOnFinalize` argument of the constructor. This causes `close()` to be called automatically if this object gets claimed by the garbage collector.

As `InMemoryNodeModel`, this class is thread-safe.

Since:
  2.0

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `TrackedNodeModel(InMemoryNodeModelSupport modelSupport, NodeSelector sel, boolean untrackOnFinalize)`
  Creates a new instance of `TrackedNodeModel` and initializes it with the given underlying model and the selector to the root node.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `addNodes(String key, Collection<? extends ImmutableNode> nodes, NodeKeyResolver<ImmutableNode> resolver)`
  Adds a collection of new nodes to this model.
  `void`
  `addProperty(String key, Iterable<?> values, NodeKeyResolver<ImmutableNode> resolver)`
  Adds a new property to this node model consisting of an arbitrary number of values.
  `void`
  `clear(NodeKeyResolver<ImmutableNode> resolver)`
  Removes all data from this model.
  `void`
  `clearProperty(String key, NodeKeyResolver<ImmutableNode> resolver)`
  Clears the value of a property.
  `List<QueryResult<ImmutableNode>>`
  `clearTree(String key, NodeKeyResolver<ImmutableNode> resolver)`
  Removes the sub trees defined by the given key from this model.
  `void`
  `close()`
  Closes this model.
  `protected void`
  `finalize()`
  This implementation calls `close()` if the `untrackOnFinalize` flag was set when this instance was constructed.
  `ImmutableNode`
  `getInMemoryRepresentation()`
  Gets a representation of the data stored in this model in form of a nodes hierarchy of `ImmutableNode` objects.
  `NodeHandler<ImmutableNode>`
  `getNodeHandler()`
  Gets a `NodeHandler` for dealing with the nodes managed by this model.
  `InMemoryNodeModel`
  `getParentModel()`
  Gets the parent model.
  `InMemoryNodeModelSupport`
  `getParentModelSupport()`
  Gets the `InMemoryNodeModelSupport` object which is used to gain access to the underlying node model.
  `NodeSelector`
  `getSelector()`
  Gets the `NodeSelector` pointing to the tracked node managed by this model.
  `boolean`
  `isReleaseTrackedNodeOnFinalize()`
  Returns the flag whether the managed tracked node is to be released when this object gets finalized.
  `void`
  `setProperty(String key, Object value, NodeKeyResolver<ImmutableNode> resolver)`
  Changes the value of a property.
  `void`
  `setRootNode(ImmutableNode newRoot)`
  Sets a new root node for this model.

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

  `clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Constructor Details

  - ### TrackedNodeModel

    public TrackedNodeModel(InMemoryNodeModelSupport modelSupport, NodeSelector sel, boolean untrackOnFinalize)
    Creates a new instance of `TrackedNodeModel` and initializes it with the given underlying model and the selector to the root node. The boolean argument controls whether the associated tracked node should be released when this object gets finalized. This allows the underlying model to free some resources. If used as model within a `SubnodeConfiguration`, there is typically no way to discard the model explicitly. Therefore, it makes sense to do this automatically on finalization.
    Parameters:
      `modelSupport` - the underlying `InMemoryNodeModelSupport` (must not be null)
      `sel` - the selector to the root node of this model (must not be null)
      `untrackOnFinalize` - a flag whether the tracked node should be released on finalization
    Throws:
      `IllegalArgumentException` - if a required parameter is missing

- ## Method Details

  - ### getParentModelSupport

    public InMemoryNodeModelSupport getParentModelSupport()
    Gets the `InMemoryNodeModelSupport` object which is used to gain access to the underlying node model.
    Returns:
      the associated `InMemoryNodeModelSupport` object

  - ### getParentModel

    public InMemoryNodeModel getParentModel()
    Gets the parent model. Operations on this model are delegated to this parent model specifying the selector to the tracked node.
    Returns:
      the parent model

  - ### getSelector

    public NodeSelector getSelector()
    Gets the `NodeSelector` pointing to the tracked node managed by this model.
    Returns:
      the tracked node selector

  - ### isReleaseTrackedNodeOnFinalize

    public boolean isReleaseTrackedNodeOnFinalize()
    Returns the flag whether the managed tracked node is to be released when this object gets finalized. This method returns the value of the corresponding flag passed to the constructor. If result is true, the underlying model is asked to untrack the managed node when this object is claimed by the GC.
    Returns:
      a flag whether the managed tracked node should be released when this object dies
    See Also:
      - `InMemoryNodeModel.untrackNode(NodeSelector)`

  - ### setRootNode

    public void setRootNode(ImmutableNode newRoot)
    Description copied from interface: `NodeModel`
    Sets a new root node for this model. The whole structure is replaced by the new node and its children.
    Specified by:
      `setRootNode` in interface `NodeModel<ImmutableNode>`
    Parameters:
      `newRoot` - the new root node to be set (can be null, then an empty root node is set)

  - ### getNodeHandler

    public NodeHandler<ImmutableNode> getNodeHandler()
    Description copied from interface: `NodeModel`
    Gets a `NodeHandler` for dealing with the nodes managed by this model.
    Specified by:
      `getNodeHandler` in interface `NodeModel<ImmutableNode>`
    Returns:
      the `NodeHandler`

  - ### addProperty

    public void addProperty(String key, Iterable<?> values, NodeKeyResolver<ImmutableNode> resolver)
    Description copied from interface: `NodeModel`
    Adds a new property to this node model consisting of an arbitrary number of values. The key for the add operation is provided. For each value a new node has to be added. The passed in resolver is queried for a `NodeAddData` object defining the add operation to be performed.
    Specified by:
      `addProperty` in interface `NodeModel<ImmutableNode>`
    Parameters:
      `key` - the key
      `values` - the values to be added at the position defined by the key
      `resolver` - the `NodeKeyResolver`

  - ### addNodes

    public void addNodes(String key, Collection<? extends ImmutableNode> nodes, NodeKeyResolver<ImmutableNode> resolver)
    Description copied from interface: `NodeModel`
    Adds a collection of new nodes to this model. This operation corresponds to the `addNodes()` method of the `HierarchicalConfiguration` interface. The new nodes are either added to an existing node (if the passed in key selects exactly one node) or to a newly created node. The passed in `NodeKeyResolver` is used to interpret the given key.
    Specified by:
      `addNodes` in interface `NodeModel<ImmutableNode>`
    Parameters:
      `key` - the key
      `nodes` - the collection of nodes to be added (may be null)
      `resolver` - the `NodeKeyResolver`

  - ### setProperty

    public void setProperty(String key, Object value, NodeKeyResolver<ImmutableNode> resolver)
    Description copied from interface: `NodeModel`
    Changes the value of a property. This is a more complex operation as it might involve adding, updating, or deleting nodes and attributes from the model. The object representing the new value is passed to the `NodeKeyResolver` which will produce a corresponding `NodeUpdateData` object. Based on the content of this object, update operations are performed.
    Specified by:
      `setProperty` in interface `NodeModel<ImmutableNode>`
    Parameters:
      `key` - the key
      `value` - the new value for this property (to be evaluated by the `NodeKeyResolver`)
      `resolver` - the `NodeKeyResolver`

  - ### clearTree

    public List<QueryResult<ImmutableNode>> clearTree(String key, NodeKeyResolver<ImmutableNode> resolver)
    Description copied from interface: `NodeModel`
    Removes the sub trees defined by the given key from this model. All nodes selected by this key are retrieved from the specified `NodeKeyResolver` and removed from the model.
    Specified by:
      `clearTree` in interface `NodeModel<ImmutableNode>`
    Parameters:
      `key` - the key selecting the properties to be removed
      `resolver` - the `NodeKeyResolver`
    Returns:
      an object with information about the data removed

  - ### clearProperty

    public void clearProperty(String key, NodeKeyResolver<ImmutableNode> resolver)
    Description copied from interface: `NodeModel`
    Clears the value of a property. This method is similar to `NodeModel.clearTree(String, NodeKeyResolver)`: However, the nodes referenced by the passed in key are not removed completely, but only their value is set to null.
    Specified by:
      `clearProperty` in interface `NodeModel<ImmutableNode>`
    Parameters:
      `key` - the key selecting the properties to be cleared
      `resolver` - the `NodeKeyResolver`

  - ### clear

    public void clear(NodeKeyResolver<ImmutableNode> resolver)
    Removes all data from this model. This implementation clears the sub tree spanned by the associate tracked node. This has the side effect that this in any case becomes detached.
    Specified by:
      `clear` in interface `NodeModel<ImmutableNode>`
    Parameters:
      `resolver` - the `NodeKeyResolver`.

  - ### getInMemoryRepresentation

    public ImmutableNode getInMemoryRepresentation()
    Gets a representation of the data stored in this model in form of a nodes hierarchy of `ImmutableNode` objects. A concrete model implementation can use an arbitrary means to store its data. When a model's data is to be used together with other functionality of the Configuration library (e.g. when combining multiple configuration sources) it has to be transformed into a common format. This is done by this method. `ImmutableNode` is a generic representation of a hierarchical structure. Thus, it should be possible to generate a corresponding structure from arbitrary model data. This implementation returns the tracked node instance acting as root node of this model.
    Specified by:
      `getInMemoryRepresentation` in interface `NodeModel<ImmutableNode>`
    Returns:
      the root node of an in-memory hierarchy representing the data stored in this model

  - ### close

    public void close()
    Closes this model. This causes the tracked node this model is based upon to be released (i.e. `InMemoryNodeModel.untrackNode(NodeSelector)` is called). This method should be called when this model is no longer needed. This implementation is idempotent; it is safe to call `close()` multiple times - only the first invocation has an effect. After this method has been called this model can no longer be used because there is no guarantee that the node can still be accessed from the parent model.

  - ### finalize

    protected void finalize() throws Throwable
    This implementation calls `close()` if the `untrackOnFinalize` flag was set when this instance was constructed. While this is not 100 percent reliable, it is better than keeping the tracked node hanging around. Note that it is not a problem if `close()` already had been invoked manually because this method is idempotent.
    Overrides:
      `finalize` in class `Object`
    Throws:
      `Throwable`
    See Also:
      - `close()`