Class BaseHierarchicalConfiguration

All Implemented Interfaces:
Cloneable, Configuration, EventSource, HierarchicalConfiguration<ImmutableNode>, ImmutableConfiguration, ImmutableHierarchicalConfiguration, SynchronizerSupport, InMemoryNodeModelSupport, NodeKeyResolver<ImmutableNode>, NodeModelSupport<ImmutableNode>
Direct Known Subclasses:
AbstractYAMLBasedConfiguration, CombinedConfiguration, INIConfiguration, PatternSubtreeConfigurationWrapper, PropertyListConfiguration, SubnodeConfiguration, XMLConfiguration, XMLPropertyListConfiguration

public class BaseHierarchicalConfiguration extends AbstractHierarchicalConfiguration<ImmutableNode> implements InMemoryNodeModelSupport

A specialized hierarchical configuration implementation that is based on a structure of ImmutableNode objects.

  • Field Details

  • Constructor Details

    • BaseHierarchicalConfiguration

      public BaseHierarchicalConfiguration()
      Creates a new instance of BaseHierarchicalConfiguration.
    • BaseHierarchicalConfiguration

      public BaseHierarchicalConfiguration(HierarchicalConfiguration<ImmutableNode> c)
      Creates a new instance of BaseHierarchicalConfiguration and copies all data contained in the specified configuration into the new one.
      Parameters:
      c - the configuration that is to be copied (if null, this constructor will behave like the standard constructor)
      Since:
      1.4
    • BaseHierarchicalConfiguration

      protected BaseHierarchicalConfiguration(NodeModel<ImmutableNode> model)
      Creates a new instance of BaseHierarchicalConfiguration and initializes it with the given NodeModel.
      Parameters:
      model - the NodeModel
  • Method Details

    • createNodeModel

      private static NodeModel<ImmutableNode> createNodeModel(HierarchicalConfiguration<ImmutableNode> c)
      Creates the NodeModel for this configuration based on a passed in source configuration. This implementation creates an InMemoryNodeModel. If the passed in source configuration is defined, its root node also becomes the root node of this configuration. Otherwise, a new, empty root node is used.
      Parameters:
      c - the configuration that is to be copied
      Returns:
      the NodeModel for the new configuration
    • obtainRootNode

      private static ImmutableNode obtainRootNode(HierarchicalConfiguration<ImmutableNode> c)
      Obtains the root node from a configuration whose data is to be copied. It has to be ensured that the synchronizer is called correctly.
      Parameters:
      c - the configuration that is to be copied
      Returns:
      the root node of this configuration
    • toImmutable

      private static List<ImmutableHierarchicalConfiguration> toImmutable(List<? extends HierarchicalConfiguration<?>> subs)
      Creates a list with immutable configurations from the given input list.
      Parameters:
      subs - a list with mutable configurations
      Returns:
      a list with corresponding immutable configurations
    • childConfigurationsAt

      public List<HierarchicalConfiguration<ImmutableNode>> childConfigurationsAt(String key)
      Returns a list with sub configurations for all child nodes of the node selected by the given key. This method works like ImmutableHierarchicalConfiguration.immutableChildConfigurationsAt(String), but returns a list with mutable configuration objects. The configuration objects returned are not connected to the parent configuration. This implementation resolves the node(s) selected by the given key. If not a single node is selected, an empty list is returned. Otherwise, sub configurations for each child of the node are created.
      Specified by:
      childConfigurationsAt in interface HierarchicalConfiguration<ImmutableNode>
      Parameters:
      key - the key for selecting the desired parent node
      Returns:
      a collection with HierarchicalConfiguration objects for all child nodes of the selected parent node
    • childConfigurationsAt

      public List<HierarchicalConfiguration<ImmutableNode>> childConfigurationsAt(String key, boolean supportUpdates)
      Returns a list with sub configurations for all child nodes of the node selected by the given key allowing the caller to specify the supportUpdates flag. This method works like childConfigurationsAt(String); however, depending on the value of the supportUpdates flag, connected sub configurations may be created.
      Specified by:
      childConfigurationsAt in interface HierarchicalConfiguration<ImmutableNode>
      Parameters:
      key - the key for selecting the desired parent node
      supportUpdates - a flag whether the returned sub configuration should be directly connected to its parent
      Returns:
      a collection with HierarchicalConfiguration objects for all child nodes of the selected parent node
    • 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.
      Specified by:
      cloneNodeModel in class AbstractHierarchicalConfiguration<ImmutableNode>
      Returns:
      the clone of the NodeModel
    • configurationAt

      public HierarchicalConfiguration<ImmutableNode> configurationAt(String key)
      Returns a hierarchical subnode configuration for the node specified by the given key. This is a short form for configurationAt(key, <b>false</b>). This is a short form for configurationAt(key, <b>false</b>).
      Specified by:
      configurationAt in interface HierarchicalConfiguration<ImmutableNode>
      Parameters:
      key - the key that selects the sub tree
      Returns:
      a hierarchical configuration that contains this sub tree
      Throws:
      ConfigurationRuntimeException - if the key does not select a single node
      See Also:
    • configurationAt

      public HierarchicalConfiguration<ImmutableNode> configurationAt(String key, boolean supportUpdates)

      Returns a hierarchical sub configuration object that wraps the configuration node specified by the given key. This method provides an easy means of accessing sub trees of a hierarchical configuration. In the returned configuration the sub tree can directly be accessed, it becomes the root node of this configuration. Because of this the passed in key must select exactly one configuration node; otherwise an IllegalArgumentException will be thrown.

      The difference between this method and the Configuration.subset(String) method is that subset() supports arbitrary subsets of configuration nodes while configurationAt() only returns a single sub tree. Please refer to the documentation of the SubnodeConfiguration class to obtain further information about sub configurations and when they should be used.

      With the supportUpdate flag the behavior of the returned sub configuration regarding updates of its parent configuration can be determined. If set to false, the configurations return on independent nodes structures. So changes made on one configuration cannot be seen by the other one. A value of true in contrast creates a direct connection between both configurations - they are then using the same underlying data structures as much as possible. There are however changes which break this connection; for instance, if the sub tree the sub configuration belongs to is completely removed from the parent configuration. If such a change happens, the sub configuration becomes detached from its parent. It can still be used in a normal way, but changes on it are not reflected by the parent and vice verse. Also, it is not possible to reattach a once detached sub configuration.

      The result of this implementation depends on the supportUpdates flag: If it is false, a plain BaseHierarchicalConfiguration is returned using the selected node as root node. This is suitable for read-only access to properties. Because the configuration returned in this case is not connected to the parent configuration, updates on properties made by one configuration are not reflected by the other one. A value of true for this parameter causes a tracked node to be created, and result is a SubnodeConfiguration based on this tracked node. This configuration is really connected to its parent, so that updated properties are visible on both.
      Specified by:
      configurationAt in interface HierarchicalConfiguration<ImmutableNode>
      Parameters:
      key - the key that selects the sub tree
      supportUpdates - a flag whether the returned sub configuration should be directly connected to its parent
      Returns:
      a hierarchical configuration that contains this sub tree
      Throws:
      ConfigurationRuntimeException - if the key does not select a single node
      See Also:
    • configurationsAt

      public List<HierarchicalConfiguration<ImmutableNode>> configurationsAt(String key)
      Returns a list of sub configurations for all configuration nodes selected by the given key. This method will evaluate the passed in key (using the current ExpressionEngine) and then create a sub configuration for each returned node (like HierarchicalConfiguration.configurationAt(String) ). This is especially useful when dealing with list-like structures. As an example consider the configuration that contains data about database tables and their fields. If you need access to all fields of a certain table, you can simply do
       List fields = config.configurationsAt("tables.table(0).fields.field");
       for(Iterator it = fields.iterator(); it.hasNext();)
       {
           BaseHierarchicalConfiguration sub = (BaseHierarchicalConfiguration) it.next();
           // now the children and attributes of the field node can be
           // directly accessed
           String fieldName = sub.getString("name");
           String fieldType = sub.getString("type");
           ...
       
      The configuration objects returned are not connected to the parent configuration. This implementation creates sub configurations in the same way as described for configurationAt(String).
      Specified by:
      configurationsAt in interface HierarchicalConfiguration<ImmutableNode>
      Parameters:
      key - the key for selecting the desired nodes
      Returns:
      a list with hierarchical configuration objects; each configuration represents one of the nodes selected by the passed in key
    • configurationsAt

      public List<HierarchicalConfiguration<ImmutableNode>> configurationsAt(String key, boolean supportUpdates)
      Returns a list of sub configurations for all configuration nodes selected by the given key allowing the caller to specify the supportUpdates flag. This method works like HierarchicalConfiguration.configurationsAt(String), but with the additional boolean parameter it can be specified whether the returned configurations react on updates of the parent configuration. This implementation creates tracked nodes for the specified key. Then sub configurations for these nodes are created and returned.
      Specified by:
      configurationsAt in interface HierarchicalConfiguration<ImmutableNode>
      Parameters:
      key - the key for selecting the desired nodes
      supportUpdates - a flag whether the returned sub configuration should be directly connected to its parent
      Returns:
      a list with hierarchical configuration objects; each configuration represents one of the nodes selected by the passed in key
      See Also:
    • createChangeListener

      private EventListener<ConfigurationEvent> createChangeListener()
      Creates a listener which reacts on all changes on this configuration or one of its SubnodeConfiguration instances. If such a change is detected, some updates have to be performed.
      Returns:
      the newly created change listener
    • createConnectedSubConfiguration

      private BaseHierarchicalConfiguration createConnectedSubConfiguration(String key)
      Creates a sub configuration from the specified key which is connected to this configuration. This implementation creates a SubnodeConfiguration with a tracked node identified by the passed in key.
      Parameters:
      key - the key of the sub configuration
      Returns:
      the new sub configuration
    • createConnectedSubConfigurations

      private List<HierarchicalConfiguration<ImmutableNode>> createConnectedSubConfigurations(InMemoryNodeModelSupport parentModelSupport, Collection<NodeSelector> selectors)
      Creates a list of connected sub configurations based on a passed in list of node selectors.
      Parameters:
      parentModelSupport - the parent node model support object
      selectors - the list of NodeSelector objects
      Returns:
      the list with sub configurations
    • createIndependentSubConfiguration

      private BaseHierarchicalConfiguration createIndependentSubConfiguration(String key)
      Creates a sub configuration from the specified key which is independent on this configuration. This means that the sub configuration operates on a separate node model (although the nodes are initially shared).
      Parameters:
      key - the key of the sub configuration
      Returns:
      the new sub configuration
    • createIndependentSubConfigurationForNode

      private BaseHierarchicalConfiguration createIndependentSubConfigurationForNode(ImmutableNode node)
      Returns an initialized sub configuration for this configuration that is based on another BaseHierarchicalConfiguration. Thus, it is independent from this configuration.
      Parameters:
      node - the root node for the sub configuration
      Returns:
      the initialized sub configuration
    • createSubConfigurationForTrackedNode

      protected SubnodeConfiguration createSubConfigurationForTrackedNode(NodeSelector selector, InMemoryNodeModelSupport parentModelSupport)
      Creates a connected sub configuration based on a selector for a tracked node.
      Parameters:
      selector - the NodeSelector
      parentModelSupport - the InMemoryNodeModelSupport object for the parent node model
      Returns:
      the newly created sub configuration
      Since:
      2.0
    • createSubsetRootNode

      private ImmutableNode createSubsetRootNode(Collection<QueryResult<ImmutableNode>> results)
      Creates a root node for a subset configuration based on the passed in query results. This method creates a new root node and adds the children and attributes of all result nodes to it. If only a single node value is defined, it is assigned as value of the new root node.
      Parameters:
      results - the collection of query results
      Returns:
      the root node for the subset configuration
    • fetchFilteredNodeResults

      private List<ImmutableNode> fetchFilteredNodeResults(String key)
      Executes a query on the specified key and filters it for node results.
      Parameters:
      key - the key
      Returns:
      the filtered list with result nodes
    • 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.
      Specified by:
      getNodeModel in interface InMemoryNodeModelSupport
      Specified by:
      getNodeModel in interface NodeModelSupport<ImmutableNode>
      Overrides:
      getNodeModel in class AbstractHierarchicalConfiguration<ImmutableNode>
      Returns:
      the NodeModel
    • 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.
      Parameters:
      key - the key of the sub configuration
      Returns:
      a NodeSelector for initializing a sub configuration
      Since:
      2.0
    • 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.
      Returns:
      the parent model for a new sub configuration
    • immutableChildConfigurationsAt

      public List<ImmutableHierarchicalConfiguration> immutableChildConfigurationsAt(String key)
      Returns a list of immutable configurations for all direct child elements of the node selected by the given key. With this method it is possible to inspect the content of a hierarchical structure; all children of a given node can be queried without having to know their exact names. If the passed in key does not point to a single node, an empty list is returned. This is also the result if the node referred to by the key does not have child elements. This implementation first delegates to childConfigurationsAt() to create a list of mutable child configurations. Then a list with immutable wrapper configurations is created.
      Specified by:
      immutableChildConfigurationsAt in interface ImmutableHierarchicalConfiguration
      Parameters:
      key - the key for selecting the desired parent node
      Returns:
      a collection with immutable configurations for all child nodes of the selected parent node
    • immutableConfigurationAt

      public ImmutableHierarchicalConfiguration immutableConfigurationAt(String key)
      Returns an immutable hierarchical configuration for the node specified by the given key. This is a short form for immutableConfigurationAt(key, <b>false</b>). This implementation creates a SubnodeConfiguration by delegating to configurationAt(). Then an immutable wrapper is created and returned.
      Specified by:
      immutableConfigurationAt in interface ImmutableHierarchicalConfiguration
      Parameters:
      key - the key that selects the sub tree
      Returns:
      a hierarchical configuration that contains this sub tree
      Throws:
      ConfigurationRuntimeException - if the key does not select a single node
    • immutableConfigurationAt

      public ImmutableHierarchicalConfiguration immutableConfigurationAt(String key, boolean supportUpdates)

      Returns an immutable hierarchical configuration object that wraps the configuration node specified by the given key. This method provides an easy means of accessing sub trees of a hierarchical configuration. In the returned configuration the sub tree can directly be accessed, it becomes the root node of this configuration. Because of this the passed in key must select exactly one configuration node; otherwise an IllegalArgumentException will be thrown.

      The difference between this method and the ImmutableConfiguration.immutableSubset(String) method is that immutableSubset() supports arbitrary subsets of configuration nodes while immutableConfigurationAt() only returns a single sub tree. Please refer to the documentation of the SubnodeConfiguration class to obtain further information about subnode configurations and when they should be used.

      This implementation creates a SubnodeConfiguration by delegating to configurationAt(). Then an immutable wrapper is created and returned.
      Specified by:
      immutableConfigurationAt in interface ImmutableHierarchicalConfiguration
      Parameters:
      key - the key that selects the sub tree
      supportUpdates - a flag whether the returned subnode configuration should be able to handle updates of its parent
      Returns:
      a hierarchical configuration that contains this sub tree
    • immutableConfigurationsAt

      public List<ImmutableHierarchicalConfiguration> immutableConfigurationsAt(String key)
      Returns a list of immutable configurations for all configuration nodes selected by the given key. This method will evaluate the passed in key (using the current ExpressionEngine) and then create an immutable subnode configuration for each returned node (like ImmutableHierarchicalConfiguration.immutableConfigurationAt(String)}). This is especially useful when dealing with list-like structures. As an example consider the configuration that contains data about database tables and their fields. If you need access to all fields of a certain table, you can simply do
       List<ImmutableHierarchicalConfiguration> fields =
         config.immutableConfigurationsAt("tables.table(0).fields.field");
       for(Iterator<ImmutableHierarchicalConfiguration> it = fields.iterator();
         it.hasNext();)
       {
           ImmutableHierarchicalConfiguration sub = it.next();
           // now the children and attributes of the field node can be
           // directly accessed
           String fieldName = sub.getString("name");
           String fieldType = sub.getString("type");
           ...
       
      This implementation first delegates to configurationsAt() to create a list of SubnodeConfiguration objects. Then for each element of this list an unmodifiable wrapper is created.
      Specified by:
      immutableConfigurationsAt in interface ImmutableHierarchicalConfiguration
      Parameters:
      key - the key for selecting the desired nodes
      Returns:
      a list with immutable hierarchical configuration objects; each configuration represents one of the nodes selected by the passed in key
    • initSubConfiguration

      private void initSubConfiguration(BaseHierarchicalConfiguration sub)
      Initializes properties of a sub configuration. A sub configuration inherits some settings from its parent, e.g. the expression engine or the synchronizer. The corresponding values are copied by this method.
      Parameters:
      sub - the sub configuration to be initialized
    • initSubConfigurationForThisParent

      protected void initSubConfigurationForThisParent(SubnodeConfiguration subConfig)
      Initializes a SubnodeConfiguration object. This method should be called for each sub configuration created for this configuration. It ensures that the sub configuration is correctly connected to its parent instance and that update events are correctly propagated.
      Parameters:
      subConfig - the sub configuration to be initialized
      Since:
      2.0
    • interpolatedConfiguration

      public Configuration interpolatedConfiguration()
      Returns a configuration with the same content as this configuration, but with all variables replaced by their actual values. This implementation is specific for hierarchical configurations. It clones the current configuration and runs a specialized visitor on the clone, which performs interpolation on the single configuration nodes.
      Overrides:
      interpolatedConfiguration in class AbstractConfiguration
      Returns:
      a configuration with all variables interpolated
      Since:
      1.5
    • subnodeConfigurationChanged

      protected void subnodeConfigurationChanged(ConfigurationEvent event)
      This method is always called when a subnode configuration created from this configuration has been modified. This implementation transforms the received event into an event of type SUBNODE_CHANGED and notifies the registered listeners.
      Parameters:
      event - the event describing the change
      Since:
      1.5
    • subset

      public Configuration subset(String prefix)
      Creates a new Configuration object containing all keys that start with the specified prefix. This implementation will return a BaseHierarchicalConfiguration object so that the structure of the keys will be saved. The nodes selected by the prefix (it is possible that multiple nodes are selected) are mapped to the root node of the returned configuration, i.e. their children and attributes will become children and attributes of the new root node. However, a value of the root node is only set if exactly one of the selected nodes contain a value (if multiple nodes have a value, there is simply no way to decide how these values are merged together). Note that the returned Configuration object is not connected to its source configuration: updates on the source configuration are not reflected in the subset and vice versa. The returned configuration uses the same Synchronizer as this configuration.
      Specified by:
      subset in interface Configuration
      Overrides:
      subset in class AbstractConfiguration
      Parameters:
      prefix - the prefix of the keys for the subset
      Returns:
      a new configuration object representing the selected subset
      See Also: