1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.configuration2.tree;
18
19 import java.util.Collection;
20
21 /**
22 * <p>
23 * Definition of an interface describing a model based on a nodes structure.
24 * </p>
25 * <p>
26 * This interface can be used for dealing with hierarchical, tree-like data. It defines basic operations for
27 * manipulating the tree structure which use keys to select the nodes affected.
28 * </p>
29 * <p>
30 * The idea behind this interface is that concrete implementations can be used by hierarchical configurations. This
31 * makes it possible to integrate various hierarchical structures with the API of a hierarchical configuration, for example
32 * configuration nodes stored in memory, JNDI contexts, or other structures. The configuration object interacts with the
33 * underlying data structure via this interface. For more complex operations access to an {@link ExpressionEngine} may
34 * be required in order to interpret the passed in keys. For these purposes a {@link NodeKeyResolver} has to be provided
35 * which knows how to deal with keys.
36 * </p>
37 *
38 * @param <T> the type of the nodes managed by this model
39 * @since 2.0
40 */
41 public interface NodeModel<T> {
42 /**
43 * Adds a collection of new nodes to this model. This operation corresponds to the {@code addNodes()} method of the
44 * {@code HierarchicalConfiguration} interface. The new nodes are either added to an existing node (if the passed in key
45 * selects exactly one node) or to a newly created node. The passed in {@code NodeKeyResolver} is used to interpret the
46 * given key.
47 *
48 * @param key the key
49 * @param nodes the collection of nodes to be added (may be <strong>null</strong>)
50 * @param resolver the {@code NodeKeyResolver}
51 * @throws IllegalArgumentException if the key references an attribute (of course, it is not possible to add something
52 * to an attribute)
53 */
54 void addNodes(String key, Collection<? extends T> nodes, NodeKeyResolver<T> resolver);
55
56 /**
57 * Adds a new property to this node model consisting of an arbitrary number of values. The key for the add operation is
58 * provided. For each value a new node has to be added. The passed in resolver is queried for a {@link NodeAddData}
59 * object defining the add operation to be performed.
60 *
61 * @param key the key
62 * @param values the values to be added at the position defined by the key
63 * @param resolver the {@code NodeKeyResolver}
64 */
65 void addProperty(String key, Iterable<?> values, NodeKeyResolver<T> resolver);
66
67 /**
68 * Removes all data from this model.
69 *
70 * @param resolver the {@code NodeKeyResolver}
71 */
72 void clear(NodeKeyResolver<T> resolver);
73
74 /**
75 * Clears the value of a property. This method is similar to {@link #clearTree(String, NodeKeyResolver)}: However, the
76 * nodes referenced by the passed in key are not removed completely, but only their value is set to <strong>null</strong>.
77 *
78 * @param key the key selecting the properties to be cleared
79 * @param resolver the {@code NodeKeyResolver}
80 */
81 void clearProperty(String key, NodeKeyResolver<T> resolver);
82
83 /**
84 * Removes the sub trees defined by the given key from this model. All nodes selected by this key are retrieved from the
85 * specified {@code NodeKeyResolver} and removed from the model.
86 *
87 * @param key the key selecting the properties to be removed
88 * @param resolver the {@code NodeKeyResolver}
89 * @return an object with information about the data removed
90 */
91 Object clearTree(String key, NodeKeyResolver<T> resolver);
92
93 /**
94 * Gets a representation of the data stored in this model in form of a nodes hierarchy of {@code ImmutableNode}
95 * objects. A concrete model implementation can use an arbitrary means to store its data. When a model's data is to be
96 * used together with other functionality of the <em>Configuration</em> library (for example when combining multiple
97 * configuration sources) it has to be transformed into a common format. This is done by this method.
98 * {@code ImmutableNode} is a generic representation of a hierarchical structure. Thus, it should be possible to
99 * generate a corresponding structure from arbitrary model data.
100 *
101 * @return the root node of an in-memory hierarchy representing the data stored in this model
102 */
103 ImmutableNode getInMemoryRepresentation();
104
105 /**
106 * Gets a {@code NodeHandler} for dealing with the nodes managed by this model.
107 *
108 * @return the {@code NodeHandler}
109 */
110 NodeHandler<T> getNodeHandler();
111
112 /**
113 * Changes the value of a property. This is a more complex operation as it might involve adding, updating, or deleting
114 * nodes and attributes from the model. The object representing the new value is passed to the {@code NodeKeyResolver}
115 * which will produce a corresponding {@link NodeUpdateData} object. Based on the content of this object, update
116 * operations are performed.
117 *
118 * @param key the key
119 * @param value the new value for this property (to be evaluated by the {@code NodeKeyResolver})
120 * @param resolver the {@code NodeKeyResolver}
121 */
122 void setProperty(String key, Object value, NodeKeyResolver<T> resolver);
123
124 /**
125 * Sets a new root node for this model. The whole structure is replaced by the new node and its children.
126 *
127 * @param newRoot the new root node to be set (can be <strong>null</strong>, then an empty root node is set)
128 */
129 void setRootNode(T newRoot);
130 }