001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.configuration2;
018
019import java.util.List;
020
021import org.apache.commons.configuration2.tree.ExpressionEngine;
022
023/**
024 * <p>
025 * An interface for immutable hierarchical configurations.
026 * </p>
027 * <p>
028 * There are some sources of configuration data that cannot be stored very well
029 * in a flat configuration object (like {@link BaseConfiguration}) because then
030 * their structure is lost. A prominent example are XML documents.
031 * </p>
032 * <p>
033 * This interface extends the basic {@link ImmutableConfiguration} interface by
034 * structured access to configuration properties. An {@link ExpressionEngine} is
035 * used to evaluate complex property keys and to map them to nodes of a
036 * tree-like structure.
037 * </p>
038 *
039 * @version $Id: ImmutableHierarchicalConfiguration.java 1679758 2015-05-16 17:35:56Z oheger $
040 * @since 2.0
041 */
042public interface ImmutableHierarchicalConfiguration extends ImmutableConfiguration
043{
044    /**
045     * Returns the expression engine used by this configuration. This method
046     * will never return <b>null</b>; if no specific expression engine was set,
047     * the default expression engine will be returned.
048     *
049     * @return the current expression engine
050     */
051    ExpressionEngine getExpressionEngine();
052
053    /**
054     * Returns the maximum defined index for the given key. This is useful if
055     * there are multiple values for this key. They can then be addressed
056     * separately by specifying indices from 0 to the return value of this
057     * method.
058     *
059     * @param key the key to be checked
060     * @return the maximum defined index for this key
061     */
062    int getMaxIndex(String key);
063
064    /**
065     * Returns the name of the root element of this configuration. This
066     * information may be of use in some cases, e.g. for sub configurations
067     * created using the {@code immutableConfigurationsAt()} method. The exact
068     * meaning of the string returned by this method is specific to a concrete
069     * implementation. For instance, an XML configuration might return the name
070     * of the document element.
071     *
072     * @return the name of the root element of this configuration
073     */
074    String getRootElementName();
075
076    /**
077     * <p>
078     * Returns an immutable hierarchical configuration object that wraps the
079     * configuration node specified by the given key. This method provides an
080     * easy means of accessing sub trees of a hierarchical configuration. In the
081     * returned configuration the sub tree can directly be accessed, it becomes
082     * the root node of this configuration. Because of this the passed in key
083     * must select exactly one configuration node; otherwise an
084     * {@code IllegalArgumentException} will be thrown.
085     * </p>
086     * <p>
087     * The difference between this method and the
088     * {@link #immutableSubset(String)} method is that
089     * {@code immutableSubset()} supports arbitrary subsets of configuration nodes
090     * while {@code immutableConfigurationAt()} only returns a single sub tree.
091     * Please refer to the documentation of the
092     * {@code SubnodeConfiguration} class to obtain further information
093     * about subnode configurations and when they should be used.
094     * </p>
095     *
096     * @param key the key that selects the sub tree
097     * @param supportUpdates a flag whether the returned subnode configuration
098     * should be able to handle updates of its parent
099     * @return a hierarchical configuration that contains this sub tree
100     */
101    ImmutableHierarchicalConfiguration immutableConfigurationAt(String key,
102            boolean supportUpdates);
103
104    /**
105     * Returns an immutable hierarchical configuration for the node specified by
106     * the given key. This is a short form for {@code immutableConfigurationAt(key,
107     * <b>false</b>)}.
108     *
109     * @param key the key that selects the sub tree
110     * @return a hierarchical configuration that contains this sub tree
111     */
112    ImmutableHierarchicalConfiguration immutableConfigurationAt(String key);
113
114    /**
115     * Returns a list of immutable configurations for all configuration nodes selected
116     * by the given key. This method will evaluate the passed in key (using the
117     * current {@code ExpressionEngine}) and then create an immutable subnode
118     * configuration for each returned node (like
119     * {@link #immutableConfigurationAt(String)}}). This is especially
120     * useful when dealing with list-like structures. As an example consider the
121     * configuration that contains data about database tables and their fields.
122     * If you need access to all fields of a certain table, you can simply do
123     *
124     * <pre>
125     * List&lt;ImmutableHierarchicalConfiguration&gt; fields =
126     *   config.immutableConfigurationsAt("tables.table(0).fields.field");
127     * for(Iterator&lt;ImmutableHierarchicalConfiguration&gt; it = fields.iterator();
128     *   it.hasNext();)
129     * {
130     *     ImmutableHierarchicalConfiguration sub = it.next();
131     *     // now the children and attributes of the field node can be
132     *     // directly accessed
133     *     String fieldName = sub.getString("name");
134     *     String fieldType = sub.getString("type");
135     *     ...
136     * </pre>
137     *
138     * @param key the key for selecting the desired nodes
139     * @return a list with immutable hierarchical configuration objects; each
140     * configuration represents one of the nodes selected by the passed in key
141     */
142    List<ImmutableHierarchicalConfiguration> immutableConfigurationsAt(String key);
143
144    /**
145     * Returns a list of immutable configurations for all direct child elements
146     * of the node selected by the given key. With this method it is possible to
147     * inspect the content of a hierarchical structure; all children of a given
148     * node can be queried without having to know their exact names. If the
149     * passed in key does not point to a single node, an empty list is returned.
150     * This is also the result if the node referred to by the key does not have
151     * child elements.
152     *
153     * @param key the key for selecting the desired parent node
154     * @return a collection with immutable configurations for all child nodes of
155     *         the selected parent node
156     */
157    List<ImmutableHierarchicalConfiguration> immutableChildConfigurationsAt(
158            String key);
159}