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 /**
44 * Adds a collection of new nodes to this model. This operation corresponds to the {@code addNodes()} method of the
45 * {@code HierarchicalConfiguration} interface. The new nodes are either added to an existing node (if the passed in key
46 * selects exactly one node) or to a newly created node. The passed in {@code NodeKeyResolver} is used to interpret the
47 * given key.
48 *
49 * @param key the key
50 * @param nodes the collection of nodes to be added (may be <strong>null</strong>)
51 * @param resolver the {@code NodeKeyResolver}
52 * @throws IllegalArgumentException if the key references an attribute (of course, it is not possible to add something
53 * to an attribute)
54 */
55 void addNodes(String key, Collection<? extends T> nodes, NodeKeyResolver<T> resolver);
56
57 /**
58 * Adds a new property to this node model consisting of an arbitrary number of values. The key for the add operation is
59 * provided. For each value a new node has to be added. The passed in resolver is queried for a {@link NodeAddData}
60 * object defining the add operation to be performed.
61 *
62 * @param key the key
63 * @param values the values to be added at the position defined by the key
64 * @param resolver the {@code NodeKeyResolver}
65 */
66 void addProperty(String key, Iterable<?> values, NodeKeyResolver<T> resolver);
67
68 /**
69 * Removes all data from this model.
70 *
71 * @param resolver the {@code NodeKeyResolver}
72 */
73 void clear(NodeKeyResolver<T> resolver);
74
75 /**
76 * Clears the value of a property. This method is similar to {@link #clearTree(String, NodeKeyResolver)}: However, the
77 * nodes referenced by the passed in key are not removed completely, but only their value is set to <strong>null</strong>.
78 *
79 * @param key the key selecting the properties to be cleared
80 * @param resolver the {@code NodeKeyResolver}
81 */
82 void clearProperty(String key, NodeKeyResolver<T> resolver);
83
84 /**
85 * Removes the sub trees defined by the given key from this model. All nodes selected by this key are retrieved from the
86 * specified {@code NodeKeyResolver} and removed from the model.
87 *
88 * @param key the key selecting the properties to be removed
89 * @param resolver the {@code NodeKeyResolver}
90 * @return an object with information about the data removed
91 */
92 Object clearTree(String key, NodeKeyResolver<T> resolver);
93
94 /**
95 * Gets a representation of the data stored in this model in form of a nodes hierarchy of {@code ImmutableNode}
96 * objects. A concrete model implementation can use an arbitrary means to store its data. When a model's data is to be
97 * used together with other functionality of the <em>Configuration</em> library (for example when combining multiple
98 * configuration sources) it has to be transformed into a common format. This is done by this method.
99 * {@code ImmutableNode} is a generic representation of a hierarchical structure. Thus, it should be possible to
100 * generate a corresponding structure from arbitrary model data.
101 *
102 * @return the root node of an in-memory hierarchy representing the data stored in this model
103 */
104 ImmutableNode getInMemoryRepresentation();
105
106 /**
107 * Gets a {@code NodeHandler} for dealing with the nodes managed by this model.
108 *
109 * @return the {@code NodeHandler}
110 */
111 NodeHandler<T> getNodeHandler();
112
113 /**
114 * Changes the value of a property. This is a more complex operation as it might involve adding, updating, or deleting
115 * nodes and attributes from the model. The object representing the new value is passed to the {@code NodeKeyResolver}
116 * which will produce a corresponding {@link NodeUpdateData} object. Based on the content of this object, update
117 * operations are performed.
118 *
119 * @param key the key
120 * @param value the new value for this property (to be evaluated by the {@code NodeKeyResolver})
121 * @param resolver the {@code NodeKeyResolver}
122 */
123 void setProperty(String key, Object value, NodeKeyResolver<T> resolver);
124
125 /**
126 * Sets a new root node for this model. The whole structure is replaced by the new node and its children.
127 *
128 * @param newRoot the new root node to be set (can be <strong>null</strong>, then an empty root node is set)
129 */
130 void setRootNode(T newRoot);
131 }