You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by oh...@apache.org on 2014/03/01 21:06:25 UTC
svn commit: r1573214 - in
/commons/proper/configuration/branches/immutableNodes/src:
main/java/org/apache/commons/configuration/tree/
test/java/org/apache/commons/configuration/tree/
Author: oheger
Date: Sat Mar 1 20:06:24 2014
New Revision: 1573214
URL: http://svn.apache.org/r1573214
Log:
Extracted NodeModel interface from InMemoryNodeModel.
This is a generic interface allowing hierarchical configuration objects to
interact with arbitrary hierarchical nodes structures.
Added:
commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/NodeModel.java
Modified:
commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/ImmutableNode.java
commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/InMemoryNodeModel.java
commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/ModelTransaction.java
commons/proper/configuration/branches/immutableNodes/src/test/java/org/apache/commons/configuration/tree/TestInMemoryNodeModel.java
Modified: commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/ImmutableNode.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/ImmutableNode.java?rev=1573214&r1=1573213&r2=1573214&view=diff
==============================================================================
--- commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/ImmutableNode.java (original)
+++ commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/ImmutableNode.java Sat Mar 1 20:06:24 2014
@@ -438,10 +438,11 @@ public class ImmutableNode
* {@link #addChild(ImmutableNode)}, but it allows setting a number of
* child nodes at once.
*
+ *
* @param children a collection with the child nodes to be added
* @return a reference to this object for method chaining
*/
- public Builder addChildren(Collection<ImmutableNode> children)
+ public Builder addChildren(Collection<? extends ImmutableNode> children)
{
if (children != null)
{
@@ -593,11 +594,12 @@ public class ImmutableNode
/**
* Filters null entries from the passed in collection with child nodes.
*
+ *
* @param children the collection to be filtered
* @return the collection with null entries removed
*/
private static Collection<? extends ImmutableNode> filterNull(
- Collection<ImmutableNode> children)
+ Collection<? extends ImmutableNode> children)
{
List<ImmutableNode> result =
new ArrayList<ImmutableNode>(children.size());
Modified: commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/InMemoryNodeModel.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/InMemoryNodeModel.java?rev=1573214&r1=1573213&r2=1573214&view=diff
==============================================================================
--- commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/InMemoryNodeModel.java (original)
+++ commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/InMemoryNodeModel.java Sat Mar 1 20:06:24 2014
@@ -34,11 +34,23 @@ import org.apache.commons.lang3.StringUt
* A specialized node model implementation which operates on
* {@link ImmutableNode} structures.
* </p>
+ * <p>
+ * This {@code NodeModel} implementation keeps all its data as a tree of
+ * {@link ImmutableNode} objects in memory. The managed structure can be
+ * manipulated in a thread-safe, non-blocking way. This is achieved by using
+ * atomic variables: The root of the tree is stored in an atomic reference
+ * variable. Each update operation causes a new structure to be constructed
+ * (which reuses as much from the original structure as possible). The old root
+ * node is then replaced by the new one using an atomic compare-and-set
+ * operation. If this fails, the manipulation has to be done anew on the updated
+ * structure.
+ * </p>
*
* @version $Id$
* @since 2.0
*/
-public class InMemoryNodeModel implements NodeHandler<ImmutableNode>
+public class InMemoryNodeModel implements NodeHandler<ImmutableNode>,
+ NodeModel<ImmutableNode>
{
/** Stores information about the current nodes structure. */
private final AtomicReference<TreeData> structure;
@@ -66,21 +78,15 @@ public class InMemoryNodeModel implement
createTreeData(initialRootNode(root)));
}
- /**
- * Returns the root node of this model.
- *
- * @return the root node
- */
public ImmutableNode getRootNode()
{
return getTreeData().getRoot();
}
/**
- * Returns a {@code NodeHandler} for dealing with the nodes managed by this
- * model.
- *
- * @return the {@code NodeHandler}
+ * {@inheritDoc} {@code InMemoryNodeModel} implements the
+ * {@code NodeHandler} interface itself. So this implementation just returns
+ * the <strong>this</strong> reference.
*/
public NodeHandler<ImmutableNode> getNodeHandler()
{
@@ -181,15 +187,6 @@ public class InMemoryNodeModel implement
return checkIfNodeDefined(node);
}
- /**
- * Adds a new property to this node model consisting of an arbitrary number
- * of values. The key for the add operation is provided. For each value a
- * new node has to be added.
- *
- * @param key the key
- * @param values the values to be added at the position defined by the key
- * @param resolver the {@code NodeKeyResolver}
- */
public void addProperty(final String key, final Iterable<?> values,
final NodeKeyResolver resolver)
{
@@ -204,20 +201,8 @@ public class InMemoryNodeModel implement
}
}
- /**
- * Adds a collection of new nodes to this model. This operation corresponds
- * to the {@code addNodes()} method of the {@code Configuration} interface.
- * The new nodes are either added to an existing node (if the passed in key
- * selects exactly one node) or to a newly created node.
- *
- * @param key the key
- * @param nodes the collection of nodes to be added (may be <b>null</b>)
- * @param resolver the {@code NodeKeyResolver}
- * @throws IllegalArgumentException if the key references an attribute (of
- * course, it is not possible to add something to an attribute)
- */
public void addNodes(final String key,
- final Collection<ImmutableNode> nodes,
+ final Collection<? extends ImmutableNode> nodes,
final NodeKeyResolver resolver)
{
if (nodes != null && !nodes.isEmpty())
@@ -257,19 +242,6 @@ public class InMemoryNodeModel implement
}
}
- /**
- * Changes the value of a property. This is a more complex operation as it
- * might involve adding, updating, or deleting nodes and attributes from the
- * model. The object representing the new value is passed to the
- * {@code NodeKeyResolver} which will produce a corresponding
- * {@link NodeUpdateData} object. Based on the content of this object,
- * update operations are performed.
- *
- * @param key the key
- * @param value the new value for this property (to be evaluated by the
- * {@code NodeKeyResolver})
- * @param resolver the {@code NodeKeyResolver}
- */
public void setProperty(final String key, final Object value,
final NodeKeyResolver resolver)
{
@@ -300,12 +272,9 @@ public class InMemoryNodeModel implement
}
/**
- * Removes the sub trees defined by the given key from this model. All nodes
- * selected by this key are retrieved and removed from the model. If this
- * causes other nodes to become undefined, they are removed, too.
- *
- * @param key the key selecting the properties to be removed
- * @param resolver the {@code NodeKeyResolver}
+ * {@inheritDoc} This implementation checks whether nodes become undefined
+ * after subtrees have been removed. If this is the case, such nodes are
+ * removed, too.
*/
public void clearTree(final String key, final NodeKeyResolver resolver)
{
@@ -342,14 +311,8 @@ public class InMemoryNodeModel implement
}
/**
- * Clears the value of a property. This method is similar to
- * {@link #clearTree(String, NodeKeyResolver)}: However, the nodes
- * referenced by the passed in key are not removed completely, but only
- * their value is set to <b>null</b>. (If this operation leaves the affected
- * node in an undefined state, it is indeed removed.)
- *
- * @param key the key selecting the properties to be cleared
- * @param resolver the {@code NodeKeyResolver}
+ * {@inheritDoc} If this operation leaves an affected node in an undefined
+ * state, it is removed from the model.
*/
public void clearProperty(final String key, final NodeKeyResolver resolver)
{
@@ -365,7 +328,7 @@ public class InMemoryNodeModel implement
}
/**
- * Removes all data from this model. A new empty root node is created with
+ * {@inheritDoc} A new empty root node is created with
* the same name as the current root node. Implementation note: Because this
* is a hard reset the usual dance for dealing with concurrent updates is
* not required here.
@@ -381,16 +344,14 @@ public class InMemoryNodeModel implement
}
/**
- * Sets a new root node for this model. The whole structure is replaced by
- * the new node and its children. Care has to be taken when this method is
- * used and the model is accessed by multiple threads. It is not
- * deterministic which concurrent operations see the old root and which see
- * the new root node.
+ * {@inheritDoc} Care has to be taken when this method is used and the model
+ * is accessed by multiple threads. It is not deterministic which concurrent
+ * operations see the old root and which see the new root node.
*
* @param newRoot the new root node to be set (can be <b>null</b>, then an
* empty root node is set)
*/
- public void setRoot(ImmutableNode newRoot)
+ public void setRootNode(ImmutableNode newRoot)
{
structure.set(createTreeData(initialRootNode(newRoot)));
}
Modified: commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/ModelTransaction.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/ModelTransaction.java?rev=1573214&r1=1573213&r2=1573214&view=diff
==============================================================================
--- commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/ModelTransaction.java (original)
+++ commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/ModelTransaction.java Sat Mar 1 20:06:24 2014
@@ -131,7 +131,7 @@ class ModelTransaction
* @param newNodes the collection of new child nodes
*/
public void addAddNodesOperation(ImmutableNode parent,
- Collection<ImmutableNode> newNodes)
+ Collection<? extends ImmutableNode> newNodes)
{
ChildrenUpdateOperation op = new ChildrenUpdateOperation();
op.addNewNodes(newNodes);
@@ -586,7 +586,7 @@ class ModelTransaction
*
* @param nodes the collection with new nodes
*/
- public void addNewNodes(Collection<ImmutableNode> nodes)
+ public void addNewNodes(Collection<? extends ImmutableNode> nodes)
{
newNodes = concatenate(newNodes, nodes);
}
Added: commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/NodeModel.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/NodeModel.java?rev=1573214&view=auto
==============================================================================
--- commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/NodeModel.java (added)
+++ commons/proper/configuration/branches/immutableNodes/src/main/java/org/apache/commons/configuration/tree/NodeModel.java Sat Mar 1 20:06:24 2014
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.configuration.tree;
+
+import java.util.Collection;
+
+/**
+ * <p>
+ * Definition of an interface describing a model based on a nodes structure.
+ * </p>
+ * <p>
+ * This interface can be used for dealing with hierarchical, tree-like data. It
+ * defines basic operations for manipulating the tree structure which use keys
+ * to select the nodes affected.
+ * </p>
+ * <p>
+ * The idea behind this interface is that concrete implementations can be used
+ * by hierarchical configurations. This makes it possible to integrate various
+ * hierarchical structures with the API of a hierarchical configuration, e.g.
+ * configuration nodes stored in memory, JNDI contexts, or other structures. The
+ * configuration object interacts with the underlying data structure via this
+ * interface. For more complex operations access to an {@link ExpressionEngine}
+ * may be required in order to interpret the passed in keys. For these purposes
+ * a {@link NodeKeyResolver} has to be provided which knows how to deal with
+ * keys.
+ * </p>
+ *
+ * @version $Id$
+ * @since 2.0
+ * @param <T> the type of the nodes managed by this model
+ */
+public interface NodeModel<T>
+{
+ /**
+ * Returns the root node of this model.
+ *
+ * @return the root node
+ */
+ T getRootNode();
+
+ /**
+ * Sets a new root node for this model. The whole structure is replaced by
+ * the new node and its children.
+ *
+ * @param newRoot the new root node to be set (can be <b>null</b>, then an
+ * empty root node is set)
+ */
+ void setRootNode(T newRoot);
+
+ /**
+ * Returns a {@code NodeHandler} for dealing with the nodes managed by this
+ * model.
+ *
+ * @return the {@code NodeHandler}
+ */
+ NodeHandler<T> getNodeHandler();
+
+ /**
+ * Adds a new property to this node model consisting of an arbitrary number
+ * of values. The key for the add operation is provided. For each value a
+ * new node has to be added. The passed in resolver is queried for a
+ * {@link NodeAddData} object defining the add operation to be performed.
+ *
+ * @param key the key
+ * @param values the values to be added at the position defined by the key
+ * @param resolver the {@code NodeKeyResolver}
+ */
+ void addProperty(String key, Iterable<?> values, NodeKeyResolver resolver);
+
+ /**
+ * Adds a collection of new nodes to this model. This operation corresponds
+ * to the {@code addNodes()} method of the {@code HierarchicalConfiguration}
+ * interface. The new nodes are either added to an existing node (if the
+ * passed in key selects exactly one node) or to a newly created node. The
+ * passed in {@code NodeKeyResolver} is used to interpret the given key.
+ *
+ * @param key the key
+ * @param nodes the collection of nodes to be added (may be <b>null</b>)
+ * @param resolver the {@code NodeKeyResolver}
+ * @throws IllegalArgumentException if the key references an attribute (of
+ * course, it is not possible to add something to an attribute)
+ */
+ void addNodes(String key, Collection<? extends T> nodes,
+ NodeKeyResolver resolver);
+
+ /**
+ * Changes the value of a property. This is a more complex operation as it
+ * might involve adding, updating, or deleting nodes and attributes from the
+ * model. The object representing the new value is passed to the
+ * {@code NodeKeyResolver} which will produce a corresponding
+ * {@link NodeUpdateData} object. Based on the content of this object,
+ * update operations are performed.
+ *
+ * @param key the key
+ * @param value the new value for this property (to be evaluated by the
+ * {@code NodeKeyResolver})
+ * @param resolver the {@code NodeKeyResolver}
+ */
+ void setProperty(String key, Object value, NodeKeyResolver resolver);
+
+ /**
+ * Removes the sub trees defined by the given key from this model. All nodes
+ * selected by this key are retrieved from the specified
+ * {@code NodeKeyResolver} and removed from the model.
+ *
+ * @param key the key selecting the properties to be removed
+ * @param resolver the {@code NodeKeyResolver}
+ */
+ void clearTree(String key, NodeKeyResolver resolver);
+
+ /**
+ * Clears the value of a property. This method is similar to
+ * {@link #clearTree(String, NodeKeyResolver)}: However, the nodes
+ * referenced by the passed in key are not removed completely, but only
+ * their value is set to <b>null</b>.
+ *
+ * @param key the key selecting the properties to be cleared
+ * @param resolver the {@code NodeKeyResolver}
+ */
+ void clearProperty(String key, NodeKeyResolver resolver);
+
+ /**
+ * Removes all data from this model.
+ */
+ void clear();
+}
Modified: commons/proper/configuration/branches/immutableNodes/src/test/java/org/apache/commons/configuration/tree/TestInMemoryNodeModel.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/immutableNodes/src/test/java/org/apache/commons/configuration/tree/TestInMemoryNodeModel.java?rev=1573214&r1=1573213&r2=1573214&view=diff
==============================================================================
--- commons/proper/configuration/branches/immutableNodes/src/test/java/org/apache/commons/configuration/tree/TestInMemoryNodeModel.java (original)
+++ commons/proper/configuration/branches/immutableNodes/src/test/java/org/apache/commons/configuration/tree/TestInMemoryNodeModel.java Sat Mar 1 20:06:24 2014
@@ -1233,7 +1233,7 @@ public class TestInMemoryNodeModel
{
InMemoryNodeModel model =
new InMemoryNodeModel(NodeStructureHelper.ROOT_PERSONAE_TREE);
- model.setRoot(NodeStructureHelper.ROOT_AUTHORS_TREE);
+ model.setRootNode(NodeStructureHelper.ROOT_AUTHORS_TREE);
assertSame("Root node not changed",
NodeStructureHelper.ROOT_AUTHORS_TREE, model.getRootNode());
ImmutableNode node = nodeForKey(model, "Homer/Ilias");
@@ -1249,7 +1249,7 @@ public class TestInMemoryNodeModel
{
InMemoryNodeModel model =
new InMemoryNodeModel(NodeStructureHelper.ROOT_PERSONAE_TREE);
- model.setRoot(null);
+ model.setRootNode(null);
ImmutableNode rootNode = model.getRootNode();
assertTrue("Got children", rootNode.getChildren().isEmpty());
}