commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ohe...@apache.org
Subject svn commit: r632613 - in /commons/proper/configuration/branches/configuration2_experimental/src: main/java/org/apache/commons/configuration2/expr/ test/java/org/apache/commons/configuration2/expr/
Date Sat, 01 Mar 2008 16:18:31 GMT
Author: oheger
Date: Sat Mar  1 08:18:31 2008
New Revision: 632613

URL: http://svn.apache.org/viewvc?rev=632613&view=rev
Log:
Added new NodeList class as result of the ExpressionEngine.query() method

Added:
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/NodeList.java
  (with props)
    commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/TestNodeList.java
  (with props)
Modified:
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/ExpressionEngine.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=632613&r1=632612&r2=632613&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
Sat Mar  1 08:18:31 2008
@@ -51,10 +51,11 @@
      * 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)
+     * provided by this implementation, it is free to throw a (runtime)
      * exception indicating this error condition. The passed in
      * <code>{@link NodeHandler}</code> can be used for accessing the properties
-     * of the node.
+     * of the node. The resulting <code>NodeList</code> object can be used to
+     * browse the results. It can contain nodes and attributes as well.
      *
      * @param root the root node of a hierarchy of configuration nodes
      * @param key the key to be evaluated
@@ -62,7 +63,7 @@
      * @return a list with the nodes that are matched by the key (should never
      * be <b>null</b>)
      */
-    <T> List<T> query(T root, String key, NodeHandler<T> handler);
+    <T> NodeList<T> query(T root, String key, NodeHandler<T> handler);
 
     /**
      * Returns the key for the specified node in the expression language

Added: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/NodeList.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/NodeList.java?rev=632613&view=auto
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/NodeList.java
(added)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/NodeList.java
Sat Mar  1 08:18:31 2008
@@ -0,0 +1,335 @@
+/*
+ * 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.configuration2.expr;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ * A class for maintaining a list of nodes that are returned by a query.
+ * </p>
+ * <p>
+ * This class is used by an <code>{@link ExpressionEngine}</code> to deliver
+ * the results of a query. It basically implements a list that can contain nodes
+ * and attributes (in the result of a query both node types can occur). There
+ * are methods for querying the content of the list. It is also possible to set
+ * or retrieve the values of list elements.
+ * </p>
+ * <p>
+ * Implementation note: This class is intended for internal use by an expression
+ * engine only. It is not thread-safe and does not perform any parameter
+ * checking.
+ * </p>
+ *
+ * @author Oliver Heger
+ * @version $Id$
+ * @param <T> the type of the nodes contained in this node list
+ */
+public class NodeList<T>
+{
+    /** Stores the entries of this list. */
+    private List<ListElement<T>> elements;
+
+    /**
+     * Creates a new instance of <code>NodeList</code>.
+     */
+    public NodeList()
+    {
+        elements = new ArrayList<ListElement<T>>();
+    }
+
+    /**
+     * Returns the number of elements stored in this list.
+     *
+     * @return
+     */
+    public int size()
+    {
+        return elements.size();
+    }
+
+    /**
+     * Returns a flag whether the element at the specified index is a node.
+     *
+     * @param index the index of the desired element
+     * @return <b>true</b> if the element at this index is a node, <b>false</b>
+     *         otherwise
+     * @throws IndexOutOfBoundsException if the index is invalid
+     */
+    public boolean isNode(int index)
+    {
+        return element(index).isNode();
+    }
+
+    /**
+     * Returns a flag whether the element at the specified index is an
+     * attribute.
+     *
+     * @param index the index of the desired element
+     * @return <b>true</b> if the element at this index is an attribute,
+     *         <b>false</b> otherwise
+     * @throws IndexOutOfBoundsException if the index is invalid
+     */
+    public boolean isAttribute(int index)
+    {
+        return !isNode(index);
+    }
+
+    /**
+     * Returns the node at the specified index.
+     *
+     * @param index the index
+     * @return the node at this index
+     * @throws IndexOutOfBoundsException if the index is invalid
+     * @throws IllegalArgumentException if the element at this index is not a
+     *         node
+     */
+    public T getNode(int index)
+    {
+        if (!isNode(index))
+        {
+            throw new IllegalArgumentException("Element at " + index
+                    + " is not a node!");
+        }
+
+        return element(index).getAssociatedNode();
+    }
+
+    /**
+     * Returns the value of the element at the specified index. This method
+     * works for both nodes and attributes.
+     *
+     * @param index the index
+     * @param handler the node handler for accessing the node data
+     * @return the value of the element at this index
+     * @throws IndexOutOfBoundsException if the index is invalid
+     */
+    public Object getValue(int index, NodeHandler<T> handler)
+    {
+        return element(index).getValue(handler);
+    }
+
+    /**
+     * Sets the value of the element at the specified index. This method works
+     * for both nodes and attributes.
+     *
+     * @param index the index
+     * @param value the new value for this element
+     * @param handler the node handler for accessing the node data
+     * @throws IndexOutOfBoundsException if the index is invalid
+     */
+    public void setValue(int index, Object value, NodeHandler<T> handler)
+    {
+        element(index).setValue(value, handler);
+    }
+
+    /**
+     * Adds a new node to this list.
+     *
+     * @param node the node to be added
+     */
+    public void addNode(T node)
+    {
+        elements.add(new NodeListElement<T>(node));
+    }
+
+    /**
+     * Adds a new attribute to this list.
+     *
+     * @param parent the parent node of this attribute
+     * @param name the name of this attribute
+     */
+    public void addAttribute(T parent, String name)
+    {
+        elements.add(new AttributeListElement<T>(parent, name));
+    }
+
+    /**
+     * Returns the list element with the given index.
+     *
+     * @param index the index
+     * @return the list element with this index
+     */
+    private ListElement<T> element(int index)
+    {
+        return elements.get(index);
+    }
+
+    /**
+     * A simple data class for managing list elements. This is an abstract base
+     * class. There will be concrete subclasses for nodes and attributes.
+     */
+    private static abstract class ListElement<T>
+    {
+        /** Stores the involved node. */
+        private T node;
+
+        /**
+         * Creates a new instance of <code>ListElement</code> and sets the
+         * node associated with this list element.
+         *
+         * @param nd the associated node
+         */
+        protected ListElement(T nd)
+        {
+            node = nd;
+        }
+
+        /**
+         * Returns a flag whether this element represents a node.
+         *
+         * @return a flag whether this is a node
+         */
+        public abstract boolean isNode();
+
+        /**
+         * Obtains the value from this list element.
+         *
+         * @param handler the node handler
+         * @return the value of this element
+         */
+        public abstract Object getValue(NodeHandler<T> handler);
+
+        /**
+         * Sets the value of this list element.
+         *
+         * @param value the new value
+         * @param handler the node handler
+         */
+        public abstract void setValue(Object value, NodeHandler<T> handler);
+
+        /**
+         * Returns the node associated with this list element.
+         *
+         * @return the associated node
+         */
+        protected T getAssociatedNode()
+        {
+            return node;
+        }
+    }
+
+    /**
+     * A data class for representing node list elements.
+     */
+    private static class NodeListElement<T> extends ListElement<T>
+    {
+        /**
+         * Creates a new instance of <code>NodeListElement</code> and sets the
+         * represented node.
+         *
+         * @param nd the node
+         */
+        public NodeListElement(T nd)
+        {
+            super(nd);
+        }
+
+        /**
+         * Returns the value of the represented node.
+         *
+         * @param handler the node handler
+         * @return the node value
+         */
+        @Override
+        public Object getValue(NodeHandler<T> handler)
+        {
+            return handler.getValue(getAssociatedNode());
+        }
+
+        /**
+         * Returns a flag whether this element is a node. This is the case.
+         *
+         * @return a flag if this is a node
+         */
+        @Override
+        public boolean isNode()
+        {
+            return true;
+        }
+
+        /**
+         * Sets the value of the represented node.
+         *
+         * @param value the new value
+         * @param handler the node handler
+         */
+        @Override
+        public void setValue(Object value, NodeHandler<T> handler)
+        {
+            handler.setValue(getAssociatedNode(), value);
+        }
+    }
+
+    /**
+     * A data class for representing attribute list elements.
+     */
+    private static class AttributeListElement<T> extends ListElement<T>
+    {
+        /** Stores the name of the attribute. */
+        private String name;
+
+        /**
+         * Creates a new instance of <code>AttributeListElement</code> and
+         * initializes it.
+         *
+         * @param nd the parent node
+         * @param attrName the name of the attribute
+         */
+        public AttributeListElement(T nd, String attrName)
+        {
+            super(nd);
+            name = attrName;
+        }
+
+        /**
+         * Returns the value of the represented attribute.
+         *
+         * @param handler the node handler
+         * @return the value of this attribute
+         */
+        @Override
+        public Object getValue(NodeHandler<T> handler)
+        {
+            return handler.getAttributeValue(getAssociatedNode(), name);
+        }
+
+        /**
+         * Returns a flag whether this element is a node. This is not the case.
+         *
+         * @return a flag if this is a node
+         */
+        @Override
+        public boolean isNode()
+        {
+            return false;
+        }
+
+        /**
+         * Sets the value of the represented attribute.
+         *
+         * @param value the new value
+         * @param handler the node handler
+         */
+        @Override
+        public void setValue(Object value, NodeHandler<T> handler)
+        {
+            handler.setAttributeValue(getAssociatedNode(), name, value);
+        }
+    }
+}

Propchange: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/NodeList.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/NodeList.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/NodeList.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/TestNodeList.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/TestNodeList.java?rev=632613&view=auto
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/TestNodeList.java
(added)
+++ commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/TestNodeList.java
Sat Mar  1 08:18:31 2008
@@ -0,0 +1,173 @@
+/*
+ * 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.configuration2.expr;
+
+import java.util.List;
+
+import org.apache.commons.configuration2.tree.ConfigurationNode;
+import org.apache.commons.configuration2.tree.DefaultConfigurationNode;
+
+import junit.framework.TestCase;
+
+/**
+ * Test class for NodeList.
+ *
+ * @author Oliver Heger
+ * @version $Id$
+ */
+public class TestNodeList extends TestCase
+{
+    /** Constant for a test value. */
+    private static final String VALUE = "test";
+
+    /** Constant for the number of test nodes. */
+    private static final int COUNT = 10;
+
+    /** The list to be tested. */
+    private NodeList<ConfigurationNode> list;
+
+    @Override
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        list = new NodeList<ConfigurationNode>();
+    }
+
+    /**
+     * Tests a newly created node list.
+     */
+    public void testInit()
+    {
+        assertEquals("List is not empty", 0, list.size());
+    }
+
+    /**
+     * Tests adding nodes to a node list.
+     */
+    public void testAddNode()
+    {
+        for (int i = 0; i < COUNT; i++)
+        {
+            list.addNode(new DefaultConfigurationNode("node", VALUE + i));
+        }
+
+        assertEquals("Wrong number of nodes", COUNT, list.size());
+        ConfigurationNodeHandler handler = new ConfigurationNodeHandler();
+        for (int i = 0; i < COUNT; i++)
+        {
+            assertTrue("Not a node", list.isNode(i));
+            assertFalse("An attribute", list.isAttribute(i));
+            assertEquals("Wrong node value", VALUE + i, list.getValue(i,
+                    handler));
+            ConfigurationNode node = list.getNode(i);
+            assertEquals("Wrong node name", "node", node.getName());
+            assertEquals("Wrong node value", VALUE + i, node.getValue());
+        }
+    }
+
+    /**
+     * Tests adding attributes to a node list.
+     */
+    public void testAddAttribute()
+    {
+        final String attr = "attr";
+        ConfigurationNode parent = new DefaultConfigurationNode("parent");
+
+        for (int i = 0; i < COUNT; i++)
+        {
+            ConfigurationNode nd = new DefaultConfigurationNode(attr + i, VALUE
+                    + i);
+            parent.addAttribute(nd);
+            list.addAttribute(parent, nd.getName());
+        }
+
+        assertEquals("Wrong number of nodes", COUNT, list.size());
+        ConfigurationNodeHandler handler = new ConfigurationNodeHandler();
+        for (int i = 0; i < COUNT; i++)
+        {
+            assertFalse("A node", list.isNode(i));
+            assertTrue("Not an attribute", list.isAttribute(i));
+            assertEquals("Wrong node value", VALUE + i, list.getValue(i,
+                    handler));
+        }
+    }
+
+    /**
+     * Tests the getNode() method when the specified index is not a node. This
+     * should cause an exception.
+     */
+    public void testGetNodeInvalidType()
+    {
+        list.addAttribute(new DefaultConfigurationNode(), "test");
+        try
+        {
+            list.getNode(0);
+            fail("Could obtain node that does not exist!");
+        }
+        catch (IllegalArgumentException iex)
+        {
+            // ok
+        }
+    }
+
+    /**
+     * Tests the setValue() method for a node.
+     */
+    public void testSetValueNode()
+    {
+        ConfigurationNode node = new DefaultConfigurationNode("node");
+        list.addNode(node);
+        list.setValue(0, VALUE, new ConfigurationNodeHandler());
+        assertEquals("Value was not set", VALUE, node.getValue());
+    }
+
+    /**
+     * Tests setting the value of an attribute.
+     */
+    public void testSetValueAttribute()
+    {
+        ConfigurationNode node = new DefaultConfigurationNode("node");
+        list.addAttribute(node, "testAttr");
+        list.setValue(0, VALUE, new ConfigurationNodeHandler());
+        List<ConfigurationNode> attrs = node.getAttributes();
+        assertEquals("Wrong number of attributes", 1, attrs.size());
+        ConfigurationNode attr = attrs.get(0);
+        assertEquals("Wrong attribute name", "testAttr", attr.getName());
+        assertEquals("Wrong attribute value", VALUE, attr.getValue());
+    }
+
+    /**
+     * Tests specifying an invalid index. This should cause an exception.
+     */
+    public void testGetValueInvalidIndex()
+    {
+        for (int i = 0; i < COUNT; i++)
+        {
+            list.addNode(new DefaultConfigurationNode());
+        }
+
+        try
+        {
+            list.getValue(COUNT, new ConfigurationNodeHandler());
+            fail("Invalid index was not detected!");
+        }
+        catch (IndexOutOfBoundsException iex)
+        {
+            // ok
+        }
+    }
+}

Propchange: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/TestNodeList.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/TestNodeList.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/TestNodeList.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message