You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by oh...@apache.org on 2006/01/04 18:26:08 UTC

svn commit: r365950 - in /jakarta/commons/proper/configuration/trunk/src: java/org/apache/commons/configuration/tree/ test/org/apache/commons/configuration/tree/

Author: oheger
Date: Wed Jan  4 09:25:55 2006
New Revision: 365950

URL: http://svn.apache.org/viewcvs?rev=365950&view=rev
Log:
Added new ExpressionEngine interface with auxiliary class

Added:
    jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/ExpressionEngine.java   (with props)
    jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/NodeAddData.java   (with props)
    jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/TestNodeAddData.java   (with props)

Added: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/ExpressionEngine.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/ExpressionEngine.java?rev=365950&view=auto
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/ExpressionEngine.java (added)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/ExpressionEngine.java Wed Jan  4 09:25:55 2006
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.List;
+
+/**
+ * <p>
+ * Definition of an interface for evaluating keys for hierarchical
+ * configurations.
+ * </p>
+ * <p>
+ * An <em>expression engine</em> knows how to map a key for a configuration's
+ * property to a single or a set of configuration nodes. Thus it defines the way
+ * how properties are addressed in this configuration. Methods of a
+ * configuration that have to handle property key (e.g.
+ * <code>getProperty()</code> or <code>addProperty()</code> do not interpret
+ * the passed in keys on their own, but delegate this task to an associated
+ * expression engine. This expression engine will then find out, which
+ * configuration nodes are addressed by the key.
+ * </p>
+ * <p>
+ * Seperating the task of evaluating property keys from the configuration object
+ * has the advantage that many different expression languages (i.e. ways for
+ * querying or setting properties) can be supported. Just set a suitable
+ * implementation of this interface as the configuration's expression engine,
+ * and you can use the syntax provided by this implementation.
+ * </p>
+ *
+ * @since 1.3
+ * @author Oliver Heger
+ */
+public interface ExpressionEngine
+{
+    /**
+     * Finds the node(s) that is (are) matched by the specified key. This is the
+     * main method for interpreting property keys. An implementation must
+     * traverse the given root node and its children to find all nodes that are
+     * matched by the given key. If the key is not correct in the syntax
+     * provided by that implementation, it is free to throw a (runtime)
+     * exception indicating this error condition.
+     *
+     * @param root the root node of a hierarchy of configuration nodes
+     * @param key the key to be evaluated
+     * @return a list with the nodes that are matched by the key (should never
+     * be <b>null</b>)
+     */
+    List query(ConfigurationNode root, String key);
+
+    /**
+     * Returns the key for the specified node in the expression language
+     * supported by an implementation. This method is called whenever a property
+     * key for a node has to be constructed, e.g. by the
+     * <code>{@link org.apache.commons.configuration.Configuration#getKeys() getKeys()}</code>
+     * method.
+     *
+     * @param node the node, for which the key must be constructed
+     * @param parentKey the key of this node's parent (can be <b>null</b> for
+     * the root node)
+     * @return this node's key
+     */
+    String nodeKey(ConfigurationNode node, String parentKey);
+
+    /**
+     * Returns information needed for an add operation. This method gets called
+     * when new properties are to be added to a configuration. An implementation
+     * has to interpret the specified key, find the parent node for the new
+     * elements, and provide all information about new nodes to be added.
+     *
+     * @param root the root node
+     * @param key the key for the new property
+     * @return an object with all information needed for the add operation
+     */
+    NodeAddData prepareAdd(ConfigurationNode root, String key);
+}

Propchange: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/ExpressionEngine.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/ExpressionEngine.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/ExpressionEngine.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/NodeAddData.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/NodeAddData.java?rev=365950&view=auto
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/NodeAddData.java (added)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/NodeAddData.java Wed Jan  4 09:25:55 2006
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * <p>
+ * A simple data class used by <code>{@link ExpressionEngine}</code> to store
+ * the results of the <code>prepareAdd()</code> operation.
+ * </p>
+ * <p>
+ * If a new property is to be added to a configuration, the affected
+ * <code>Configuration</code> object must know, where in its hierarchy of
+ * configuration nodes new elements have to be added. This information is
+ * obtained by an <code>ExpressionEngine</code> object that interprets the key
+ * of the new property. This expression engine will pack all information
+ * necessary for the configuration to perform the add operation in an instance
+ * of this class.
+ * </p>
+ * <p>
+ * Information managed by this class contains:
+ * <ul>
+ * <li>the configuration node, to which new elements must be added</li>
+ * <li>the name of the new node</li>
+ * <li>whether the new node is a child node or an attribute node</li>
+ * <li>if a whole branch is to be added at once, the names of all nodes between
+ * the parent node (the target of the add operation) and the new node</li>
+ * </ul>
+ * </p>
+ *
+ * @since 1.3
+ * @author Oliver Heger
+ */
+public class NodeAddData
+{
+    /** Stores the parent node of the add operation. */
+    private ConfigurationNode parent;
+
+    /**
+     * Stores a list with nodes that are on the path between the parent node and
+     * the new node.
+     */
+    private List pathNodes;
+
+    /** Stores the name of the new node. */
+    private String newNodeName;
+
+    /** Stores the attribute flag. */
+    private boolean attribute;
+
+    /**
+     * Creates a new, uninitialized instance of <code>NodeAddData</code>.
+     */
+    public NodeAddData()
+    {
+        this(null, null);
+    }
+
+    /**
+     * Creates a new instance of <code>NodeAddData</code> and sets the most
+     * important data fields.
+     *
+     * @param parent the parent node
+     * @param nodeName the name of the new node
+     */
+    public NodeAddData(ConfigurationNode parent, String nodeName)
+    {
+        setParent(parent);
+        setNewNodeName(nodeName);
+    }
+
+    /**
+     * Returns a flag if the new node to be added is an attribute.
+     *
+     * @return <b>true</b> for an attribute node, <b>false</b> for a child
+     * node
+     */
+    public boolean isAttribute()
+    {
+        return attribute;
+    }
+
+    /**
+     * Sets the attribute flag. This flag determines whether an attribute or a
+     * child node will be added.
+     *
+     * @param attribute the attribute flag
+     */
+    public void setAttribute(boolean attribute)
+    {
+        this.attribute = attribute;
+    }
+
+    /**
+     * Returns the name of the new node.
+     *
+     * @return the new node's name
+     */
+    public String getNewNodeName()
+    {
+        return newNodeName;
+    }
+
+    /**
+     * Sets the name of the new node. A node with this name will be added to the
+     * configuration's node hierarchy.
+     *
+     * @param newNodeName the name of the new node
+     */
+    public void setNewNodeName(String newNodeName)
+    {
+        this.newNodeName = newNodeName;
+    }
+
+    /**
+     * Returns the parent node.
+     *
+     * @return the parent node
+     */
+    public ConfigurationNode getParent()
+    {
+        return parent;
+    }
+
+    /**
+     * Sets the parent node. New nodes will be added to this node.
+     *
+     * @param parent the parent node
+     */
+    public void setParent(ConfigurationNode parent)
+    {
+        this.parent = parent;
+    }
+
+    /**
+     * Returns a list with further nodes that must be added. This is needed if a
+     * complete branch is to be added at once. For instance imagine that there
+     * exists only a node <code>database</code>. Now the key
+     * <code>database.connection.settings.username</code> (assuming the syntax
+     * of the default expression engine) is to be added. Then
+     * <code>username</code> is the name of the new node, but the nodes
+     * <code>connection</code> and <code>settings</code> must be added to
+     * the parent node first. In this example these names would be returned by
+     * this method.
+     *
+     * @return a list with the names of nodes that must be added as parents of
+     * the new node (never <b>null</b>)
+     */
+    public List getPathNodes()
+    {
+        return (pathNodes != null) ? Collections.unmodifiableList(pathNodes)
+                : Collections.EMPTY_LIST;
+    }
+
+    /**
+     * Adds the name of a path node. With this method an additional node to be
+     * added can be defined.
+     *
+     * @param nodeName the name of the node
+     * @see #getPathNodes()
+     */
+    public void addPathNode(String nodeName)
+    {
+        if (pathNodes == null)
+        {
+            pathNodes = new LinkedList();
+        }
+        pathNodes.add(nodeName);
+    }
+}

Propchange: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/NodeAddData.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/NodeAddData.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/tree/NodeAddData.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/TestNodeAddData.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/TestNodeAddData.java?rev=365950&view=auto
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/TestNodeAddData.java (added)
+++ jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/TestNodeAddData.java Wed Jan  4 09:25:55 2006
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.List;
+
+import junit.framework.TestCase;
+
+/**
+ * Test class for NodeAddData.
+ *
+ * @author Oliver Heger
+ */
+public class TestNodeAddData extends TestCase
+{
+    /** Constant for the default parent node used for testing. */
+    private static final ConfigurationNode TEST_PARENT = new DefaultConfigurationNode(
+            "parent");
+
+    /** Constant for the name of the new node. */
+    private static final String TEST_NODENAME = "testNewNode";
+
+    /** Constant for the name of a path node. */
+    private static final String PATH_NODE_NAME = "PATHNODE";
+
+    /** Constant for the number of path nodes to be added. */
+    private static final int PATH_NODE_COUNT = 10;
+
+    /** The object to be tested. */
+    NodeAddData addData;
+
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        addData = new NodeAddData(TEST_PARENT, TEST_NODENAME);
+    }
+
+    /**
+     * Tests the default values of an unitialized instance.
+     */
+    public void testUninitialized()
+    {
+        addData = new NodeAddData();
+        assertNull("A parent is set", addData.getParent());
+        assertNull("Node has a name", addData.getNewNodeName());
+        assertFalse("Attribute flag is set", addData.isAttribute());
+        assertTrue("Path nodes are not empty", addData.getPathNodes().isEmpty());
+    }
+
+    /**
+     * Tests the constructor that initializes the most important fields.
+     */
+    public void testInitialized()
+    {
+        assertSame("Wrong parent", TEST_PARENT, addData.getParent());
+        assertEquals("Wrong node name", TEST_NODENAME, addData.getNewNodeName());
+        assertFalse("Attribute flag is set", addData.isAttribute());
+        assertTrue("Path nodes are not empty", addData.getPathNodes().isEmpty());
+    }
+
+    /**
+     * Tests adding path nodes.
+     */
+    public void testAddPathNode()
+    {
+        for (int i = 0; i < PATH_NODE_COUNT; i++)
+        {
+            addData.addPathNode(PATH_NODE_NAME + i);
+        }
+
+        List nodes = addData.getPathNodes();
+        assertEquals("Incorrect number of path nodes", PATH_NODE_COUNT, nodes
+                .size());
+        for (int i = 0; i < PATH_NODE_COUNT; i++)
+        {
+            assertEquals("Wrong path node at position" + i, PATH_NODE_NAME + i,
+                    nodes.get(i));
+        }
+    }
+}

Propchange: jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/TestNodeAddData.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/TestNodeAddData.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/TestNodeAddData.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org