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