T - the type of the nodes managed by this hierarchical configurationpublic abstract class AbstractHierarchicalConfiguration<T> extends AbstractConfiguration implements Cloneable, NodeKeyResolver<T>, HierarchicalConfiguration<T>
A specialized configuration class that extends its base class by the ability of keeping more structure in the stored properties.
 There are some sources of configuration data that cannot be stored very well
 in a BaseConfiguration object because then their structure is lost.
 This is for instance true for XML documents. This class can deal with such
 structured configuration sources by storing the properties in a tree-like
 organization. The exact storage structure of the underlying data does not
 matter for the configuration instance; it uses a NodeModel object for
 accessing it.
 
The hierarchical organization allows for a more sophisticated access to single properties. As an example consider the following XML document:
 <database>
   <tables>
     <table>
       <name>users</name>
       <fields>
         <field>
           <name>lid</name>
           <type>long</name>
         </field>
         <field>
           <name>usrName</name>
           <type>java.lang.String</type>
         </field>
        ...
       </fields>
     </table>
     <table>
       <name>documents</name>
       <fields>
         <field>
           <name>docid</name>
           <type>long</type>
         </field>
         ...
       </fields>
     </table>
     ...
   </tables>
 </database>
 
 If this document is parsed and stored in a hierarchical configuration object (which can be done by one of the sub classes), there are enhanced possibilities of accessing properties. Per default, the keys for querying information can contain indices that select a specific element if there are multiple hits.
 For instance the key tables.table(0).name can be used to find out the
 name of the first table. In opposite tables.table.name would return a
 collection with the names of all available tables. Similarly the key
 tables.table(1).fields.field.name returns a collection with the names
 of all fields of the second table. If another index is added after the
 field element, a single field can be accessed:
 tables.table(1).fields.field(0).name.
 
 There is a getMaxIndex() method that returns the maximum allowed
 index that can be added to a given property key. This method can be used to
 iterate over all values defined for a certain property.
 
 Since the 1.3 release of Commons Configuration hierarchical
 configurations support an expression engine. This expression engine
 is responsible for evaluating the passed in configuration keys and map them
 to the stored properties. The examples above are valid for the default
 expression engine, which is used when a new
 AbstractHierarchicalConfiguration instance is created. With the
 setExpressionEngine() method a different expression engine can be
 set. For instance with
 XPathExpressionEngine
 there is an expression engine available that supports configuration keys in
 XPATH syntax.
 
 In addition to the events common for all configuration classes, hierarchical
 configurations support some more events that correspond to some specific
 methods and features. For those events specific event type constants in
 ConfigurationEvent exist:
 
addNodes() method was called; the event object contains the
 key, to which the nodes were added, and a collection with the new nodes as
 value.clearTree() method was called; the event object stores the
 key of the removed sub tree.SubnodeConfiguration that was created from this configuration
 has been changed. The value property of the event object contains the
 original event object as it was sent by the subnode configuration.
 Whether an AbstractHierarchicalConfiguration object is thread-safe or
 not depends on the underlying NodeModel and the
 Synchronizer
 it is associated with. Some NodeModel implementations are inherently
 thread-safe; they do not require a special Synchronizer. (Per
 default, a dummy Synchronizer is used which is not thread-safe!) The
 methods for querying or updating configuration data invoke this
 Synchronizer accordingly. When accessing the configuration's root
 node directly, the client application is responsible for proper
 synchronization. This is achieved by calling the methods
 lock(),
 and unlock() with a proper
 LockMode argument.
 In any case, it is recommended to not access the
 root node directly, but to use corresponding methods for querying or updating
 configuration data instead. Direct manipulations of a configuration's node
 structure circumvent many internal mechanisms and thus can cause undesired
 effects. For concrete subclasses dealing with specific node structures, this
 situation may be different.
 
| Modifier | Constructor and Description | 
|---|---|
protected  | 
AbstractHierarchicalConfiguration(NodeModel<T> nodeModel)
Creates a new instance of  
AbstractHierarchicalConfiguration and
 sets the NodeModel to be used. | 
| Modifier and Type | Method and Description | 
|---|---|
void | 
addNodes(String key,
        Collection<? extends T> nodes)
Adds a collection of nodes at the specified position of the configuration
 tree. 
 | 
protected void | 
addNodesInternal(String key,
                Collection<? extends T> nodes)
Actually adds a collection of new nodes to this configuration. 
 | 
protected void | 
addPropertyDirect(String key,
                 Object value)
Adds a key/value pair to the Configuration. 
 | 
protected void | 
addPropertyInternal(String key,
                   Object obj)
Adds the property with the specified key. 
 | 
protected void | 
clearInternal()
Clears this configuration. 
 | 
protected void | 
clearPropertyDirect(String key)
Removes the property with the given key. 
 | 
void | 
clearTree(String key)
Removes all values of the property with the given name and of keys that
 start with this name. 
 | 
protected Object | 
clearTreeInternal(String key)
Actually clears the tree of elements referenced by the given key. 
 | 
Object | 
clone()
Creates a copy of this object. 
 | 
protected abstract NodeModel<T> | 
cloneNodeModel()
Creates a clone of the node model. 
 | 
protected boolean | 
containsKeyInternal(String key)
Checks if the specified key is contained in this configuration. 
 | 
protected List<QueryResult<T>> | 
fetchNodeList(String key)
Helper method for resolving the specified key. 
 | 
ExpressionEngine | 
getExpressionEngine()
Returns the expression engine used by this configuration. 
 | 
protected Iterator<String> | 
getKeysInternal()
Returns an iterator with all keys defined in this configuration. 
 | 
protected Iterator<String> | 
getKeysInternal(String prefix)
Returns an iterator with all keys defined in this configuration that
 start with the given prefix. 
 | 
int | 
getMaxIndex(String key)
Returns the maximum defined index for the given key. 
 | 
protected int | 
getMaxIndexInternal(String key)
Actually retrieves the maximum defined index for the given key. 
 | 
protected NodeModel<T> | 
getModel()
Returns the  
NodeModel used by this configuration. | 
NodeModel<T> | 
getNodeModel()
Returns the  
NodeModel supported by this object. | 
protected Object | 
getPropertyInternal(String key)
Fetches the specified property. 
 | 
String | 
getRootElementName()
Returns the name of the root element of this configuration. 
 | 
protected String | 
getRootElementNameInternal()
Actually obtains the name of the root element. 
 | 
protected boolean | 
isEmptyInternal()
Checks if this configuration is empty. 
 | 
protected boolean | 
nodeDefined(T node)
Checks if the specified node is defined. 
 | 
String | 
nodeKey(T node,
       Map<T,String> cache,
       NodeHandler<T> handler)
Generates a unique key for the specified node. 
 | 
NodeAddData<T> | 
resolveAddKey(T root,
             String key,
             NodeHandler<T> handler)
Resolves a key of an add operation. 
 | 
List<QueryResult<T>> | 
resolveKey(T root,
          String key,
          NodeHandler<T> handler)
Performs a query for the specified key on the given root node. 
 | 
List<T> | 
resolveNodeKey(T root,
              String key,
              NodeHandler<T> handler)
Performs a query for the specified key on the given root node returning
 only node results. 
 | 
NodeUpdateData<T> | 
resolveUpdateKey(T root,
                String key,
                Object newValue,
                NodeHandler<T> handler)
Resolves a key for an update operation. 
 | 
void | 
setExpressionEngine(ExpressionEngine expressionEngine)
Sets the expression engine to be used by this configuration. 
 | 
protected void | 
setPropertyInternal(String key,
                   Object value)
Sets the value of the specified property. 
 | 
protected int | 
sizeInternal()
Actually calculates the size of this configuration. 
 | 
String | 
toString()  | 
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, getEncodedString, getEncodedString, getFloat, getFloat, getFloat, getInt, getInt, getInteger, getInterpolator, getKeys, getKeys, getList, getList, getList, getList, getListDelimiterHandler, getLogger, getLong, getLong, getLong, getProperties, getProperties, getProperty, getShort, getShort, getShort, getString, getString, getStringArray, getSynchronizer, immutableSubset, initLogger, installInterpolator, interpolate, interpolate, interpolatedConfiguration, isEmpty, isScalarValue, isThrowExceptionOnMissing, lock, setConfigurationDecoder, setConversionHandler, setDefaultLookups, setInterpolator, setListDelimiterHandler, setLogger, setParentInterpolator, setPrefixLookups, setProperty, setSynchronizer, setThrowExceptionOnMissing, size, subset, unlockaddEventListener, clearErrorListeners, clearEventListeners, copyEventListeners, createErrorEvent, createEvent, fireError, fireEvent, getEventListenerRegistrations, getEventListeners, isDetailEvents, removeEventListener, setDetailEventsequals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitchildConfigurationsAt, childConfigurationsAt, configurationAt, configurationAt, configurationsAt, configurationsAtaddProperty, clear, clearProperty, getInterpolator, installInterpolator, setInterpolator, setProperty, subsetgetSynchronizer, lock, setSynchronizer, unlockimmutableChildConfigurationsAt, immutableConfigurationAt, immutableConfigurationAt, immutableConfigurationsAtcontainsKey, get, get, getArray, getArray, getBigDecimal, getBigDecimal, getBigInteger, getBigInteger, getBoolean, getBoolean, getBoolean, getByte, getByte, getByte, getCollection, getCollection, getDouble, getDouble, getDouble, getEncodedString, getEncodedString, getFloat, getFloat, getFloat, getInt, getInt, getInteger, getKeys, getKeys, getList, getList, getList, getList, getLong, getLong, getLong, getProperties, getProperty, getShort, getShort, getShort, getString, getString, getStringArray, immutableSubset, isEmpty, sizepublic final String getRootElementName()
immutableConfigurationsAt() method. The exact
 meaning of the string returned by this method is specific to a concrete
 implementation. For instance, an XML configuration might return the name
 of the document element. This implementation handles synchronization and delegates
 to getRootElementNameInternal().getRootElementName in interface ImmutableHierarchicalConfigurationprotected String getRootElementNameInternal()
getRootElementName(). It just returns the name of the root node.
 Subclasses that treat the root element name differently can override this
 method.public NodeModel<T> getNodeModel()
NodeModel supported by this object. This implementation returns the configuration's
 NodeModel. It is guarded by the current Synchronizer.getNodeModel in interface NodeModelSupport<T>NodeModelpublic ExpressionEngine getExpressionEngine()
getExpressionEngine in interface ImmutableHierarchicalConfigurationpublic void setExpressionEngine(ExpressionEngine expressionEngine)
setExpressionEngine in interface HierarchicalConfiguration<T>expressionEngine - the new expression engine; can be null,
 then the default expression engine will be usedprotected Object getPropertyInternal(String key)
getPropertyInternal in class AbstractConfigurationkey - the key to be looked upprotected void addPropertyInternal(String key, Object obj)
ExpressionEngine, so the passed in key
 must match the requirements of this implementation.addPropertyInternal in class AbstractConfigurationkey - the key of the new propertyobj - the value of the new propertyprotected void addPropertyDirect(String key, Object value)
addProperty() for hierarchical configurations because all values
 to be added for the property have to be passed to the model in a single
 step. However, to allow derived classes to add an arbitrary value as an
 object, a special implementation is provided here. The passed in object
 is not parsed as a list, but passed directly as only value to the model.addPropertyDirect in class AbstractConfigurationkey - key to use for mappingvalue - object to storepublic final void addNodes(String key, Collection<? extends T> nodes)
addProperty(), but
 instead of a single property a whole collection of nodes can be added -
 and thus complete configuration sub trees. E.g. with this method it is
 possible to add parts of another BaseHierarchicalConfiguration
 object to this object. If the passed in key refers to
 an existing and unique node, the new nodes are added to this node.
 Otherwise a new node will be created at the specified position in the
 hierarchy. Implementation node: This method performs some book-keeping
 and then delegates to addNodesInternal().addNodes in interface HierarchicalConfiguration<T>key - the key where the nodes are to be added; can be null,
 then they are added to the root nodenodes - a collection with the Node objects to be
 addedprotected void addNodesInternal(String key, Collection<? extends T> nodes)
addNodes(). It can be overridden by
 subclasses that need to adapt this operation.key - the key where the nodes are to be added; can be null,
        then they are added to the root nodenodes - a collection with the Node objects to be addedprotected boolean isEmptyInternal()
isEmptyInternal in class AbstractConfigurationprotected boolean containsKeyInternal(String key)
containsKeyInternal in class AbstractConfigurationkey - the key to be checkedprotected void setPropertyInternal(String key, Object value)
setPropertyInternal in class AbstractConfigurationkey - the key of the property to setvalue - the new value of this propertypublic List<QueryResult<T>> resolveKey(T root, String key, NodeHandler<T> handler)
query() method of an
 ExpressionEngine. This implementation delegates to the expression engine.resolveKey in interface NodeKeyResolver<T>root - the root nodekey - the key to be resolvedhandler - the NodeHandlerpublic List<T> resolveNodeKey(T root, String key, NodeHandler<T> handler)
resolveKey(), but filters only
 for results of type node. This implementation delegates to resolveKey() and
 then filters out attribute results.resolveNodeKey in interface NodeKeyResolver<T>root - the root nodekey - the key to be resolvedhandler - the NodeHandlerpublic NodeAddData<T> resolveAddKey(T root, String key, NodeHandler<T> handler)
NodeAddData
 object containing all information for actually performing the add
 operation at the specified key. This implementation delegates to the expression engine.resolveAddKey in interface NodeKeyResolver<T>root - the root nodekey - the key to be resolvedhandler - the NodeHandlerNodeAddData object to be used for the add operationpublic NodeUpdateData<T> resolveUpdateKey(T root, String key, Object newValue, NodeHandler<T> handler)
NodeUpdateData object containing all information for actually
 performing the update operation at the specified key using the provided
 new value object. This implementation executes a query for the given key and
 constructs a NodeUpdateData object based on the results. It
 determines which nodes need to be changed and whether new ones need to be
 added or existing ones need to be removed.resolveUpdateKey in interface NodeKeyResolver<T>root - the root nodekey - the key to be resolvednewValue - the new value for the key to be updated; this can be a
        single value or a container for multiple valueshandler - the NodeHandlerNodeUpdateData object to be used for this update
         operationpublic String nodeKey(T node, Map<T,String> cache, NodeHandler<T> handler)
nodeKey in interface NodeKeyResolver<T>node - the node in questioncache - a map serving as cachehandler - the NodeHandlerprotected void clearInternal()
clearInternal in class AbstractConfigurationpublic final void clearTree(String key)
clearTree("foo") would remove both properties.clearTree in interface HierarchicalConfiguration<T>key - the key of the property to be removedprotected Object clearTreeInternal(String key)
clearTree(). Subclasses that need to adapt
 this operation can override this method. This base implementation
 delegates to the node model.key - the key of the property to be removedprotected void clearPropertyDirect(String key)
clearPropertyDirect in class AbstractConfigurationkey - the key of the property to be removedprotected int sizeInternal()
size() with a read lock held. The base implementation provided
 here calculates the size based on the iterator returned by
 getKeys(). Sub classes which can determine the size in a more
 efficient way should override this method. This implementation is slightly more efficient than the
 default implementation. It does not iterate over the key set, but
 directly queries its size after it has been constructed. Note that
 constructing the key set is still an O(n) operation.sizeInternal in class AbstractConfigurationprotected Iterator<String> getKeysInternal()
getKeysInternal in class AbstractConfigurationprotected Iterator<String> getKeysInternal(String prefix)
getKeysInternal in class AbstractConfigurationprefix - the prefix of the keys to start withpublic final int getMaxIndex(String key)
getMaxIndex in interface ImmutableHierarchicalConfigurationkey - the key to be checkedprotected int getMaxIndexInternal(String key)
getMaxIndex(). Subclasses that need to adapt
 this operation have to override this method.key - the key to be checkedpublic Object clone()
clone in class BaseEventSourceprotected abstract NodeModel<T> cloneNodeModel()
clone().NodeModelprotected List<QueryResult<T>> fetchNodeList(String key)
key - the keyprotected boolean nodeDefined(T node)
node - the node to be checkedprotected NodeModel<T> getModel()
NodeModel used by this configuration. This method is
 intended for internal use only. Access to the model is granted without
 any synchronization. This is in contrast to the "official"
 getNodeModel() method which is guarded by the configuration's
 Synchronizer.Copyright © 2001–2020 The Apache Software Foundation. All rights reserved.