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/04/29 22:34:31 UTC

svn commit: r1591090 - in /commons/proper/configuration/trunk/src: main/java/org/apache/commons/configuration/tree/xpath/ test/java/org/apache/commons/configuration/tree/xpath/

Author: oheger
Date: Tue Apr 29 20:34:31 2014
New Revision: 1591090

URL: http://svn.apache.org/r1591090
Log:
[CONFIGURATION-573] ConfigurationNodeIteratorChildren now supports qualified names.

Namespace prefixes are now handled when iterating over a node's children.

Modified:
    commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/tree/xpath/ConfigurationNodeIteratorChildren.java
    commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/tree/xpath/TestConfigurationNodeIteratorChildren.java

Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/tree/xpath/ConfigurationNodeIteratorChildren.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/tree/xpath/ConfigurationNodeIteratorChildren.java?rev=1591090&r1=1591089&r2=1591090&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/tree/xpath/ConfigurationNodeIteratorChildren.java (original)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/tree/xpath/ConfigurationNodeIteratorChildren.java Tue Apr 29 20:34:31 2014
@@ -38,6 +38,12 @@ import org.apache.commons.lang3.StringUt
 class ConfigurationNodeIteratorChildren<T> extends
         ConfigurationNodeIteratorBase<T>
 {
+    /** Constant for the prefix separator. */
+    private static final String PREFIX_SEPARATOR = ":";
+
+    /** A format for constructing a node name with a namespace prefix. */
+    private static final String FMT_NAMESPACE = "%s" + PREFIX_SEPARATOR + "%s";
+
     /** The list with the sub nodes to iterate over. */
     private final List<T> subNodes;
 
@@ -108,11 +114,9 @@ class ConfigurationNodeIteratorChildren<
      */
     private List<T> createSubNodeList(T node, NodeTest test)
     {
-        List<T> children = getNodeHandler().getChildren(node);
-
         if (test == null)
         {
-            return children;
+            return getNodeHandler().getChildren(node);
         }
         else
         {
@@ -120,24 +124,8 @@ class ConfigurationNodeIteratorChildren<
             {
                 NodeNameTest nameTest = (NodeNameTest) test;
                 QName name = nameTest.getNodeName();
-                if (name.getPrefix() == null)
-                {
-                    if (nameTest.isWildcard())
-                    {
-                        return children;
-                    }
-
-                    List<T> result = new ArrayList<T>();
-                    for (T child : children)
-                    {
-                        if (StringUtils.equals(name.getName(), getNodeHandler()
-                                .nodeName(child)))
-                        {
-                            result.add(child);
-                        }
-                    }
-                    return result;
-                }
+                return nameTest.isWildcard() ? createSubNodeListForWildcardName(
+                        node, name) : createSubNodeListForName(node, name);
             }
 
             else if (test instanceof NodeTypeTest)
@@ -146,7 +134,7 @@ class ConfigurationNodeIteratorChildren<
                 if (typeTest.getNodeType() == Compiler.NODE_TYPE_NODE
                         || typeTest.getNodeType() == Compiler.NODE_TYPE_TEXT)
                 {
-                    return children;
+                    return getNodeHandler().getChildren(node);
                 }
             }
         }
@@ -155,6 +143,62 @@ class ConfigurationNodeIteratorChildren<
     }
 
     /**
+     * Obtains the list of selected nodes for a {@code NodeNameTest} with either
+     * a simple or a qualified name.
+     *
+     * @param node the current node
+     * @param name the name to be selected
+     * @return the list with selected sub nodes
+     */
+    private List<T> createSubNodeListForName(T node, QName name)
+    {
+        String compareName =
+                (name.getPrefix() == null) ? name.getName() : prefixName(
+                        name.getPrefix(), name.getName());
+        List<T> result = new ArrayList<T>();
+        for (T child : getNodeHandler().getChildren(node))
+        {
+            if (StringUtils.equals(compareName, getNodeHandler()
+                    .nodeName(child)))
+            {
+                result.add(child);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Obtains the list of selected sub nodes for a {@code NodeNameTest} with a
+     * wildcard name.
+     *
+     * @param node the current node
+     * @param name the name to be selected
+     * @return the list with selected sub nodes
+     */
+    private List<T> createSubNodeListForWildcardName(T node, QName name)
+    {
+        List<T> children = getNodeHandler().getChildren(node);
+        if (name.getPrefix() == null)
+        {
+            return children;
+        }
+        else
+        {
+            List<T> prefixChildren = new ArrayList<T>(children.size());
+            String prefix = prefixName(name.getPrefix(), null);
+            for (T child : children)
+            {
+                if (StringUtils.startsWith(getNodeHandler().nodeName(child),
+                        prefix))
+                {
+                    prefixChildren.add(child);
+                }
+            }
+            return prefixChildren;
+        }
+    }
+
+    /**
      * Determines the start position of the iteration. Finds the index of the
      * given start node in the children of the root node.
      *
@@ -176,4 +220,17 @@ class ConfigurationNodeIteratorChildren<
 
         return -1;
     }
+
+    /**
+     * Generates a qualified name with a namespace prefix.
+     *
+     * @param prefix the prefix
+     * @param name the name
+     * @return the qualified name
+     */
+    private static String prefixName(String prefix, String name)
+    {
+        return String.format(FMT_NAMESPACE, prefix,
+                StringUtils.defaultString(name));
+    }
 }

Modified: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/tree/xpath/TestConfigurationNodeIteratorChildren.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/tree/xpath/TestConfigurationNodeIteratorChildren.java?rev=1591090&r1=1591089&r2=1591090&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/tree/xpath/TestConfigurationNodeIteratorChildren.java (original)
+++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/tree/xpath/TestConfigurationNodeIteratorChildren.java Tue Apr 29 20:34:31 2014
@@ -24,6 +24,7 @@ import java.util.List;
 import java.util.Locale;
 
 import org.apache.commons.configuration.tree.ImmutableNode;
+import org.apache.commons.configuration.tree.NodeStructureHelper;
 import org.apache.commons.jxpath.ri.Compiler;
 import org.apache.commons.jxpath.ri.QName;
 import org.apache.commons.jxpath.ri.compiler.NodeNameTest;
@@ -42,6 +43,12 @@ import org.junit.Test;
  */
 public class TestConfigurationNodeIteratorChildren extends AbstractXPathTest
 {
+    /** Constant for a namespace prefix. */
+    private static final String PREFIX = "commons";
+
+    /** Constant for the name of a node with a namespace. */
+    private static final String PREFIX_NODE = "configuration";
+
     /** Stores the node pointer to the root node. */
     private ConfigurationNodePointer<ImmutableNode> rootPointer;
 
@@ -50,9 +57,20 @@ public class TestConfigurationNodeIterat
     public void setUp() throws Exception
     {
         super.setUp();
-        rootPointer =
-                new ConfigurationNodePointer<ImmutableNode>(root,
-                        Locale.getDefault(), handler);
+        rootPointer = createPointer(root);
+    }
+
+    /**
+     * Helper method for creating a node pointer for a given node.
+     *
+     * @param node the node the pointer points to
+     * @return the node pointer
+     */
+    private ConfigurationNodePointer<ImmutableNode> createPointer(
+            ImmutableNode node)
+    {
+        return new ConfigurationNodePointer<ImmutableNode>(node,
+                Locale.getDefault(), handler);
     }
 
     /**
@@ -235,6 +253,60 @@ public class TestConfigurationNodeIterat
     }
 
     /**
+     * Creates a node pointer to a node which also contains a child node with a
+     * namespace prefix.
+     *
+     * @return the node pointer
+     */
+    private ConfigurationNodePointer<ImmutableNode> createPointerWithNamespace()
+    {
+        ImmutableNode node =
+                new ImmutableNode.Builder(2)
+                        .addChild(root)
+                        .addChild(
+                                NodeStructureHelper.createNode(PREFIX + ':'
+                                        + PREFIX_NODE, "test")
+                        ).create();
+        return createPointer(node);
+    }
+
+    /**
+     * Tests whether all nodes with a specific prefix can be obtained.
+     */
+    @Test
+    public void testIterateWithWildcardTestPrefix()
+    {
+        NodeNameTest test = new NodeNameTest(new QName(PREFIX, "*"));
+        ConfigurationNodeIteratorChildren<ImmutableNode> it =
+                new ConfigurationNodeIteratorChildren<ImmutableNode>(
+                        createPointerWithNamespace(), test, false, null);
+        assertEquals("Wrong number of elements", 1, iteratorSize(it));
+        for (NodePointer p : iterationElements(it))
+        {
+            assertEquals("Wrong element", PREFIX + ':' + PREFIX_NODE, p
+                    .getName().getName());
+        }
+    }
+
+    /**
+     * Tests whether nodes with a matching namespace prefix can be obtained.
+     */
+    @Test
+    public void testIterateWithMatchingPrefixTest()
+    {
+        NodeNameTest test = new NodeNameTest(new QName(PREFIX, PREFIX_NODE));
+        ConfigurationNodeIteratorChildren<ImmutableNode> it =
+                new ConfigurationNodeIteratorChildren<ImmutableNode>(
+                        createPointerWithNamespace(), test, false, null);
+        assertEquals("Wrong number of elements", 1, iteratorSize(it));
+        for (NodePointer p : iterationElements(it))
+        {
+            assertEquals("Wrong element", PREFIX + ':' + PREFIX_NODE, p
+                    .getName().getName());
+        }
+    }
+
+    /**
      * Helper method for checking the values of the nodes returned by an
      * iterator. Because the values indicate the order of the child nodes with
      * this test it can be checked whether the nodes were returned in the