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.tree;
018
019import java.util.Collection;
020
021/**
022 * <p>
023 * Definition of an interface describing a model based on a nodes structure.
024 * </p>
025 * <p>
026 * This interface can be used for dealing with hierarchical, tree-like data. It
027 * defines basic operations for manipulating the tree structure which use keys
028 * to select the nodes affected.
029 * </p>
030 * <p>
031 * The idea behind this interface is that concrete implementations can be used
032 * by hierarchical configurations. This makes it possible to integrate various
033 * hierarchical structures with the API of a hierarchical configuration, e.g.
034 * configuration nodes stored in memory, JNDI contexts, or other structures. The
035 * configuration object interacts with the underlying data structure via this
036 * interface. For more complex operations access to an {@link ExpressionEngine}
037 * may be required in order to interpret the passed in keys. For these purposes
038 * a {@link NodeKeyResolver} has to be provided which knows how to deal with
039 * keys.
040 * </p>
041 *
042 * @version $Id: NodeModel.java 1624601 2014-09-12 18:04:36Z oheger $
043 * @since 2.0
044 * @param <T> the type of the nodes managed by this model
045 */
046public interface NodeModel<T>
047{
048    /**
049     * Sets a new root node for this model. The whole structure is replaced by
050     * the new node and its children.
051     *
052     * @param newRoot the new root node to be set (can be <b>null</b>, then an
053     *        empty root node is set)
054     */
055    void setRootNode(T newRoot);
056
057    /**
058     * Returns a {@code NodeHandler} for dealing with the nodes managed by this
059     * model.
060     *
061     * @return the {@code NodeHandler}
062     */
063    NodeHandler<T> getNodeHandler();
064
065    /**
066     * Adds a new property to this node model consisting of an arbitrary number
067     * of values. The key for the add operation is provided. For each value a
068     * new node has to be added. The passed in resolver is queried for a
069     * {@link NodeAddData} object defining the add operation to be performed.
070     *
071     * @param key the key
072     * @param values the values to be added at the position defined by the key
073     * @param resolver the {@code NodeKeyResolver}
074     */
075    void addProperty(String key, Iterable<?> values, NodeKeyResolver<T> resolver);
076
077    /**
078     * Adds a collection of new nodes to this model. This operation corresponds
079     * to the {@code addNodes()} method of the {@code HierarchicalConfiguration}
080     * interface. The new nodes are either added to an existing node (if the
081     * passed in key selects exactly one node) or to a newly created node. The
082     * passed in {@code NodeKeyResolver} is used to interpret the given key.
083     *
084     * @param key the key
085     * @param nodes the collection of nodes to be added (may be <b>null</b>)
086     * @param resolver the {@code NodeKeyResolver}
087     * @throws IllegalArgumentException if the key references an attribute (of
088     *         course, it is not possible to add something to an attribute)
089     */
090    void addNodes(String key, Collection<? extends T> nodes,
091            NodeKeyResolver<T> resolver);
092
093    /**
094     * Changes the value of a property. This is a more complex operation as it
095     * might involve adding, updating, or deleting nodes and attributes from the
096     * model. The object representing the new value is passed to the
097     * {@code NodeKeyResolver} which will produce a corresponding
098     * {@link NodeUpdateData} object. Based on the content of this object,
099     * update operations are performed.
100     *
101     * @param key the key
102     * @param value the new value for this property (to be evaluated by the
103     *        {@code NodeKeyResolver})
104     * @param resolver the {@code NodeKeyResolver}
105     */
106    void setProperty(String key, Object value, NodeKeyResolver<T> resolver);
107
108    /**
109     * Removes the sub trees defined by the given key from this model. All nodes
110     * selected by this key are retrieved from the specified
111     * {@code NodeKeyResolver} and removed from the model.
112     *
113     * @param key the key selecting the properties to be removed
114     * @param resolver the {@code NodeKeyResolver}
115     * @return an object with information about the data removed
116     */
117    Object clearTree(String key, NodeKeyResolver<T> resolver);
118
119    /**
120     * Clears the value of a property. This method is similar to
121     * {@link #clearTree(String, NodeKeyResolver)}: However, the nodes
122     * referenced by the passed in key are not removed completely, but only
123     * their value is set to <b>null</b>.
124     *
125     * @param key the key selecting the properties to be cleared
126     * @param resolver the {@code NodeKeyResolver}
127     */
128    void clearProperty(String key, NodeKeyResolver<T> resolver);
129
130    /**
131     * Removes all data from this model.
132     *
133     * @param resolver the {@code NodeKeyResolver}
134     */
135    void clear(NodeKeyResolver<T> resolver);
136
137    /**
138     * Returns a representation of the data stored in this model in form of a
139     * nodes hierarchy of {@code ImmutableNode} objects. A concrete model
140     * implementation can use an arbitrary means to store its data. When a
141     * model's data is to be used together with other functionality of the
142     * <em>Configuration</em> library (e.g. when combining multiple
143     * configuration sources) it has to be transformed into a common format.
144     * This is done by this method. {@code ImmutableNode} is a generic
145     * representation of a hierarchical structure. Thus, it should be possible
146     * to generate a corresponding structure from arbitrary model data.
147     *
148     * @return the root node of an in-memory hierarchy representing the data
149     *         stored in this model
150     */
151    ImmutableNode getInMemoryRepresentation();
152}