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 2008/07/11 21:04:47 UTC

svn commit: r676049 - in /commons/proper/configuration/branches/configuration2_experimental/src: main/java/org/apache/commons/configuration2/expr/ main/java/org/apache/commons/configuration2/expr/def/ main/java/org/apache/commons/configuration2/expr/xp...

Author: oheger
Date: Fri Jul 11 12:04:46 2008
New Revision: 676049

URL: http://svn.apache.org/viewvc?rev=676049&view=rev
Log:
CONFIGURATION-333: Added the uniqueNodeKey() method to the ExpressionEngine interface. DefaultExpressionEngine and XPathExpressionEngine were updated accordingly.

Modified:
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/ExpressionEngine.java
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/def/DefaultExpressionEngine.java
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/XPathExpressionEngine.java
    commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/def/TestDefaultExpressionEngine.java
    commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/xpath/TestXPathExpressionEngine.java

Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/ExpressionEngine.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/ExpressionEngine.java?rev=676049&r1=676048&r2=676049&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/ExpressionEngine.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/ExpressionEngine.java Fri Jul 11 12:04:46 2008
@@ -80,6 +80,24 @@
     <T> String nodeKey(T node, String parentKey, NodeHandler<T> handler);
 
     /**
+     * Constructs a unique key for the specified node in the expression language
+     * supported by an implementation. This method is similar to
+     * <code>nodeKey()</code>, but indices are used to identify the specified
+     * node exactly. So if a parent has multiple child nodes with the same name,
+     * this method will return a different key for each child (
+     * <code>nodeKey()</code> would return the same key for all).
+     *
+     * @param <T> the type of the nodes involved
+     * @param node the node, for which the key is to be constructed
+     * @param parentKey the key of this node's parent (can be <b>null</b> for
+     *        the root node)
+     * @param handler the node handler
+     * @return a unique key for this node
+     * @since 2.0
+     */
+    <T> String uniqueNodeKey(T node, String parentKey, NodeHandler<T> handler);
+
+    /**
      * Returns the key of an attribute of the specified node. This method is
      * analogous to <code>nodeKey()</code>, but deals with attributes.
      *

Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/def/DefaultExpressionEngine.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/def/DefaultExpressionEngine.java?rev=676049&r1=676048&r2=676049&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/def/DefaultExpressionEngine.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/def/DefaultExpressionEngine.java Fri Jul 11 12:04:46 2008
@@ -299,6 +299,7 @@
      *
      * @param node the node whose key is to be determined
      * @param parentKey the key of this node's parent
+     * @param handler the node handler
      * @return the key for the given node
      */
     public <T> String nodeKey(T node, String parentKey, NodeHandler<T> handler)
@@ -319,6 +320,35 @@
     }
 
     /**
+     * Determines a unique key of the passed in node. This implementation first
+     * fetches the default key using <code>nodeKey()</code>. Then it obtains the
+     * index of the node relative to its parent. If an index is defined, it is
+     * added.
+     *
+     * @param node the node whose key is to be determined
+     * @param parentKey the key of this node's parent
+     * @param handler the node handler
+     * @return the key for the given node
+     * @since 2.0
+     */
+    public <T> String uniqueNodeKey(T node, String parentKey,
+            NodeHandler<T> handler)
+    {
+        String key = nodeKey(node, parentKey, handler);
+
+        int index = handler.indexOfChild(node);
+        if (index >= 0)
+        {
+            DefaultConfigurationKey ckey = new DefaultConfigurationKey(this,
+                    key);
+            ckey.appendIndex(index);
+            key = ckey.toString();
+        }
+
+        return key;
+    }
+
+    /**
      * Determines the key of the specified attribute. This implementation
      * appends the name of the attribute to the parent key using the attribute
      * marker as separator.

Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/XPathExpressionEngine.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/XPathExpressionEngine.java?rev=676049&r1=676048&r2=676049&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/XPathExpressionEngine.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/XPathExpressionEngine.java Fri Jul 11 12:04:46 2008
@@ -127,6 +127,12 @@
     /** Constant for the delimiters for splitting node paths. */
     private static final String NODE_PATH_DELIMITERS = PATH_DELIMITER + ATTR_DELIMITER;
 
+    /** Constant for the index start character.*/
+    private static final char INDEX_START = '[';
+
+    /** Constant for the index end character.*/
+    private static final char INDEX_END = ']';
+
     /**
      * Executes a query. The passed in property key is directly passed to a
      * JXPath context.
@@ -215,6 +221,34 @@
     }
 
     /**
+     * Returns a unique key for the given node based on the parent's key. This
+     * implementation first creates a default key for the passed in node using
+     * <code>nodeKey()</code>. Then it checks whether an index is defined for
+     * this node. If this is the case, the index is added. (Note that indices
+     * for XPATH are 1-based.)
+     *
+     * @param node the node for which a key is to be constructed
+     * @param parentKey the key of the parent node
+     * @param handler the node handler
+     * @return the key for the given node
+     */
+    public <T> String uniqueNodeKey(T node, String parentKey,
+            NodeHandler<T> handler)
+    {
+        String key = nodeKey(node, parentKey, handler);
+
+        int index = handler.indexOfChild(node);
+        if (index >= 0)
+        {
+            StringBuilder buf = new StringBuilder(key);
+            buf.append(INDEX_START).append(index + 1).append(INDEX_END);
+            key = buf.toString();
+        }
+
+        return key;
+    }
+
+    /**
      * Returns a key for the specified attribute. This method works similar to
      * <code>nodeKey()</code>, but deals with attributes.
      *

Modified: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/def/TestDefaultExpressionEngine.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/def/TestDefaultExpressionEngine.java?rev=676049&r1=676048&r2=676049&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/def/TestDefaultExpressionEngine.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/def/TestDefaultExpressionEngine.java Fri Jul 11 12:04:46 2008
@@ -179,6 +179,24 @@
     }
 
     /**
+     * Tests obtaining unique keys for nodes.
+     */
+    public void testUniqueNodeKey()
+    {
+        ConfigurationNode node = root.getChild(0);
+        assertEquals("Invalid name for descendant of root", "tables(0)", engine
+                .uniqueNodeKey(node, "", handler));
+        assertEquals("Parent key not respected", "test.tables(0)", engine
+                .uniqueNodeKey(node, "test", handler));
+        assertEquals("Full parent key not taken into account",
+                "a.full.parent.key.tables(0)", engine.uniqueNodeKey(node,
+                        "a.full.parent.key", handler));
+        node = node.getChild(1);
+        assertEquals("Wrong key for child 1", "tables.table(1)", engine
+                .uniqueNodeKey(node, "tables", handler));
+    }
+
+    /**
      * Tests obtaining keys when the root node is involved.
      */
     public void testNodeKeyWithRoot()
@@ -190,6 +208,17 @@
     }
 
     /**
+     * Tests obtaining unique keys when the root node is involved.
+     */
+    public void testUniqueNodeKeyWithRoot()
+    {
+        assertEquals("Wrong name for root node", "", engine.uniqueNodeKey(root, null,
+                handler));
+        assertEquals("Null name not detected", "test", engine.uniqueNodeKey(root,
+                "test", handler));
+    }
+
+    /**
      * Tests obtaining keys for attribute nodes.
      */
     public void testNodeKeyWithAttribute()
@@ -219,6 +248,20 @@
     }
 
     /**
+     * Tests obtaining unique keys for nodes that contain the delimiter character.
+     */
+    public void testUniqueNodeKeyWithEscapedDelimiters()
+    {
+        ConfigurationNode node = root.getChild(1);
+        assertEquals("Wrong escaped key", "connection..settings(0)", engine
+                .uniqueNodeKey(node, "", handler));
+        assertEquals("Wrong complex escaped key",
+                "connection..settings(0).usr..name(0)", engine.uniqueNodeKey(node
+                        .getChild(0), engine.uniqueNodeKey(node, "", handler),
+                        handler));
+    }
+
+    /**
      * Tests obtaining node keys when a different syntax is set.
      */
     public void testNodeKeyWithAlternativeSyntax()
@@ -235,6 +278,16 @@
     }
 
     /**
+     * Tests obtaining unique node keys when a different syntax is set.
+     */
+    public void testUniqueNodeKeyWithAlternativeSyntax()
+    {
+        setUpAlternativeSyntax();
+        assertEquals("Wrong child key", "tables/table[0]", engine.uniqueNodeKey(root
+                .getChild(0).getChild(0), "tables", handler));
+    }
+
+    /**
      * Tests adding direct child nodes to the existing hierarchy.
      */
     public void testPrepareAddDirectly()

Modified: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/xpath/TestXPathExpressionEngine.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/xpath/TestXPathExpressionEngine.java?rev=676049&r1=676048&r2=676049&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/xpath/TestXPathExpressionEngine.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/xpath/TestXPathExpressionEngine.java Fri Jul 11 12:04:46 2008
@@ -20,6 +20,8 @@
 import java.util.Iterator;
 import java.util.List;
 
+import junit.framework.TestCase;
+
 import org.apache.commons.configuration2.expr.ConfigurationNodeHandler;
 import org.apache.commons.configuration2.expr.NodeAddData;
 import org.apache.commons.configuration2.expr.NodeHandler;
@@ -30,8 +32,6 @@
 import org.apache.commons.jxpath.ri.JXPathContextReferenceImpl;
 import org.apache.commons.jxpath.ri.model.NodePointerFactory;
 
-import junit.framework.TestCase;
-
 /**
  * Test class for XPathExpressionEngine.
  *
@@ -166,6 +166,18 @@
     }
 
     /**
+     * Tests a normal call of uniqueNodeKey().
+     */
+    public void testUniqueNodeKeyNormal()
+    {
+        ConfigurationNode parent = new DefaultConfigurationNode();
+        ConfigurationNode child = new DefaultConfigurationNode("child");
+        parent.addChild(child);
+        assertEquals("Wrong node key", "parent/child[1]", engine.uniqueNodeKey(
+                child, "parent", handler));
+    }
+
+    /**
      * Tests querying the key of an attribute node.
      */
     public void testAttributeKey()
@@ -188,6 +200,16 @@
     }
 
     /**
+     * Tests uniqueNodeKey() for the root node.
+     */
+    public void testUniqueNodeKeyForRootNode()
+    {
+        assertEquals("Wrong key for root node", "", engine.uniqueNodeKey(root, null, handler));
+        assertEquals("Null name not detected", "test", engine.uniqueNodeKey(
+                new DefaultConfigurationNode(), "test", handler));
+    }
+
+    /**
      * Tests nodeKey() for direct children of the root node.
      */
     public void testNodeKeyForRootChild()
@@ -198,6 +220,18 @@
     }
 
     /**
+     * Tests uniqueNodeKey() for direct children of the root node.
+     */
+    public void testUniqueNodeKeyForRootChild()
+    {
+        ConfigurationNode root = new DefaultConfigurationNode();
+        ConfigurationNode node = new DefaultConfigurationNode("child");
+        root.addChild(node);
+        assertEquals("Wrong key for root child node", "child[1]", engine.uniqueNodeKey(
+                node, "", handler));
+    }
+
+    /**
      * Tests querying the key of an attribute that belongs to the root node when
      * the empty string is passed as parent name.
      */