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/03/12 21:52:32 UTC

svn commit: r636505 - /commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/

Author: oheger
Date: Wed Mar 12 13:52:11 2008
New Revision: 636505

URL: http://svn.apache.org/viewvc?rev=636505&view=rev
Log:
Ported helper classes for XPathExpressionEngine to use the NodeHandler approach

Added:
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationAttributePointer.java   (with props)
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodeIteratorAttribute.java
      - copied, changed from r635335, commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodeIteratorAttribute.java
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodeIteratorBase.java
      - copied, changed from r635335, commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodeIteratorBase.java
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodeIteratorChildren.java
      - copied, changed from r635335, commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodeIteratorChildren.java
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodePointer.java
      - copied, changed from r635335, commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodePointer.java

Added: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationAttributePointer.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationAttributePointer.java?rev=636505&view=auto
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationAttributePointer.java (added)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationAttributePointer.java Wed Mar 12 13:52:11 2008
@@ -0,0 +1,221 @@
+/*
+ * 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.xpath;
+
+import org.apache.commons.configuration2.expr.NodeHandler;
+import org.apache.commons.jxpath.ri.Compiler;
+import org.apache.commons.jxpath.ri.QName;
+import org.apache.commons.jxpath.ri.compiler.NodeTest;
+import org.apache.commons.jxpath.ri.compiler.NodeTypeTest;
+import org.apache.commons.jxpath.ri.model.NodePointer;
+
+/**
+ * <p>
+ * A specialized <code>NodePointer</code> implementation for the attributes of
+ * a configuration.
+ * </p>
+ * <p>
+ * This is needed for queries using JXPath.
+ * </p>
+ *
+ * @author Oliver Heger
+ * @version $Id$
+ * @param <T> the type of the nodes this pointer deals with
+ */
+class ConfigurationAttributePointer<T> extends NodePointer
+{
+    /**
+     * The serial version UID.
+     */
+    private static final long serialVersionUID = 5504551041716043748L;
+
+    /** Stores the parent node. */
+    private T parentNode;
+
+    /** Stores the name of the managed attribute. */
+    private String attributeName;
+
+    /**
+     * Creates a new instance of <code>ConfigurationAttributePointer</code>.
+     *
+     * @param parent the parent node pointer
+     * @param attrName the name of the managed attribute
+     */
+    public ConfigurationAttributePointer(ConfigurationNodePointer<T> parent,
+            String attrName)
+    {
+        super(parent);
+        parentNode = parent.getConfigurationNode();
+        attributeName = attrName;
+    }
+
+    /**
+     * Returns a reference to the parent node pointer.
+     *
+     * @return the parent pointer
+     */
+    @SuppressWarnings("unchecked")
+    public ConfigurationNodePointer<T> getParentPointer()
+    {
+        return (ConfigurationNodePointer<T>) getParent();
+    }
+
+    /**
+     * Compares two child node pointers. Attributes do not have any children, so
+     * this is just a dummy implementation.
+     *
+     * @param p1 the first pointer
+     * @param p2 the second pointer
+     * @return the order of these pointers
+     */
+    @Override
+    public int compareChildNodePointers(NodePointer p1, NodePointer p2)
+    {
+        return 0;
+    }
+
+    /**
+     * Returns the base value. We return the value.
+     *
+     * @return the base value
+     */
+    @Override
+    public Object getBaseValue()
+    {
+        return getValue();
+    }
+
+    /**
+     * Returns the immediate node. We return the parent node here.
+     *
+     * @return the immediate node
+     */
+    @Override
+    public Object getImmediateNode()
+    {
+        return parentNode;
+    }
+
+    /**
+     * Returns the length of the represented node. This is always 1.
+     *
+     * @return the length
+     */
+    @Override
+    public int getLength()
+    {
+        return 1;
+    }
+
+    /**
+     * Returns the name of this node. This is the attribute name.
+     *
+     * @return the name of this node
+     */
+    @Override
+    public QName getName()
+    {
+        return new QName(null, attributeName);
+    }
+
+    /**
+     * Returns a flag whether the represented node is a collection. This is not
+     * the case.
+     *
+     * @return the collection flag
+     */
+    @Override
+    public boolean isCollection()
+    {
+        return false;
+    }
+
+    /**
+     * Returns a flag whether the represented node is a leaf. This is the case
+     * for attributes.
+     *
+     * @return the leaf flag
+     */
+    @Override
+    public boolean isLeaf()
+    {
+        return true;
+    }
+
+    /**
+     * Returns a flag whether this node is an attribute. Of course, this is the
+     * case.
+     *
+     * @return the attribute flag
+     */
+    @Override
+    public boolean isAttribute()
+    {
+        return true;
+    }
+
+    /**
+     * Returns the value of this node.
+     *
+     * @return this node's value
+     */
+    @Override
+    public Object getValue()
+    {
+        return getNodeHandler().getAttributeValue(parentNode, attributeName);
+    }
+
+    /**
+     * Sets the value of this node.
+     *
+     * @param value the new value
+     */
+    @Override
+    public void setValue(Object value)
+    {
+        getNodeHandler().setAttributeValue(parentNode, attributeName, value);
+    }
+
+    /**
+     * Tests if this node matches the given test. Attributes nodes are text
+     * nodes, too, because they can contain a value.
+     *
+     * @param test the test object
+     * @return a flag if this node corresponds to the test
+     */
+    @Override
+    public boolean testNode(NodeTest test)
+    {
+        if (test instanceof NodeTypeTest
+                && ((NodeTypeTest) test).getNodeType() == Compiler.NODE_TYPE_TEXT)
+        {
+            return true;
+        }
+        return super.testNode(test);
+    }
+
+    /**
+     * Returns a reference to the current node handler. The handler is obtained
+     * from the parent pointer.
+     *
+     * @return the node handler
+     */
+    protected NodeHandler<T> getNodeHandler()
+    {
+        return getParentPointer().getNodeHandler();
+    }
+}

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

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

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

Copied: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodeIteratorAttribute.java (from r635335, commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodeIteratorAttribute.java)
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodeIteratorAttribute.java?p2=commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodeIteratorAttribute.java&p1=commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodeIteratorAttribute.java&r1=635335&r2=636505&rev=636505&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodeIteratorAttribute.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodeIteratorAttribute.java Wed Mar 12 13:52:11 2008
@@ -14,14 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-package org.apache.commons.configuration2.tree.xpath;
+package org.apache.commons.configuration2.expr.xpath;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-import org.apache.commons.configuration2.tree.ConfigurationNode;
 import org.apache.commons.jxpath.ri.QName;
 import org.apache.commons.jxpath.ri.model.NodePointer;
 
@@ -31,31 +29,42 @@
  * @author Oliver Heger
  * @version $Id$
  */
-class ConfigurationNodeIteratorAttribute extends
-        ConfigurationNodeIteratorBase
+class ConfigurationNodeIteratorAttribute<T> extends
+        ConfigurationNodeIteratorBase<T>
 {
-    /** Constant for the wildcard node name.*/
+    /** Constant for the wildcard node name. */
     private static final String WILDCARD = "*";
 
+    /** Stores the parent node pointer. */
+    private ConfigurationNodePointer<T> parentPointer;
+
+    /** A list with the names of the managed attributes. */
+    private List<String> attributeNames;
+
     /**
      * Creates a new instance of <code>ConfigurationNodeIteratorAttribute</code>.
+     *
      * @param parent the parent node pointer
      * @param name the name of the selected attribute
      */
-    public ConfigurationNodeIteratorAttribute(NodePointer parent, QName name)
+    public ConfigurationNodeIteratorAttribute(
+            ConfigurationNodePointer<T> parent, QName name)
     {
         super(parent, false);
-        initSubNodeList(createSubNodeList((ConfigurationNode) parent.getNode(), name));
+        parentPointer = parent;
+        attributeNames = createAttributeNameList(parent, name);
     }
 
     /**
      * Determines which attributes are selected based on the passed in node
      * name.
-     * @param node the current node
+     *
+     * @param parent the parent node pointer
      * @param name the name of the selected attribute
      * @return a list with the selected attributes
      */
-    protected List<ConfigurationNode> createSubNodeList(ConfigurationNode node, QName name)
+    protected List<String> createAttributeNameList(
+            ConfigurationNodePointer<T> parent, QName name)
     {
         if (name.getPrefix() != null)
         {
@@ -63,16 +72,45 @@
             return Collections.emptyList();
         }
 
-        List<ConfigurationNode> result = new ArrayList<ConfigurationNode>();
+        List<String> result = new ArrayList<String>();
         if (!WILDCARD.equals(name.getName()))
         {
-            result.addAll(node.getAttributes(name.getName()));
+            if (parent.getNodeHandler().getAttributeValue(
+                    parent.getConfigurationNode(), name.getName()) != null)
+            {
+                result.add(name.getName());
+            }
         }
         else
         {
-            result.addAll(node.getAttributes());
+            result.addAll(parent.getNodeHandler().getAttributes(
+                    parent.getConfigurationNode()));
         }
 
         return result;
+    }
+
+    /**
+     * Creates a pointer for the node at the specified position.
+     *
+     * @param position
+     * @return a pointer for the attribute at this position
+     */
+    @Override
+    protected NodePointer createNodePointer(int position)
+    {
+        return new ConfigurationAttributePointer<T>(parentPointer,
+                attributeNames.get(position));
+    }
+
+    /**
+     * Returns the size of the managed iteration.
+     *
+     * @return the iteration size
+     */
+    @Override
+    protected int size()
+    {
+        return attributeNames.size();
     }
 }

Copied: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodeIteratorBase.java (from r635335, commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodeIteratorBase.java)
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodeIteratorBase.java?p2=commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodeIteratorBase.java&p1=commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodeIteratorBase.java&r1=635335&r2=636505&rev=636505&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodeIteratorBase.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodeIteratorBase.java Wed Mar 12 13:52:11 2008
@@ -15,11 +15,9 @@
  * limitations under the License.
  */
 
-package org.apache.commons.configuration2.tree.xpath;
+package org.apache.commons.configuration2.expr.xpath;
 
-import java.util.List;
-
-import org.apache.commons.configuration2.tree.ConfigurationNode;
+import org.apache.commons.configuration2.expr.NodeHandler;
 import org.apache.commons.jxpath.ri.model.NodeIterator;
 import org.apache.commons.jxpath.ri.model.NodePointer;
 
@@ -33,17 +31,15 @@
  * the concrete node type (child node or attribute node).
  * </p>
  *
- * @since 1.3
+ * @since 2.0
  * @author Oliver Heger
  * @version $Id$
+ * @param <T> the type of the nodes this iterator deals with
  */
-abstract class ConfigurationNodeIteratorBase implements NodeIterator
+abstract class ConfigurationNodeIteratorBase<T> implements NodeIterator
 {
     /** Stores the parent node pointer. */
-    private NodePointer parent;
-
-    /** Stores the list with the sub nodes. */
-    private List<ConfigurationNode> subNodes;
+    private ConfigurationNodePointer<T> parent;
 
     /** Stores the current position. */
     private int position;
@@ -61,7 +57,7 @@
      * @param parent the parent pointer
      * @param reverse the reverse flag
      */
-    protected ConfigurationNodeIteratorBase(NodePointer parent, boolean reverse)
+    protected ConfigurationNodeIteratorBase(ConfigurationNodePointer<T> parent, boolean reverse)
     {
         this.parent = parent;
         this.reverse = reverse;
@@ -101,7 +97,7 @@
             return null;
         }
 
-        return createNodePointer(subNodes.get(positionToIndex(getPosition())));
+        return createNodePointer(positionToIndex(getPosition()));
     }
 
     /**
@@ -109,12 +105,23 @@
      *
      * @return the parent node pointer
      */
-    protected NodePointer getParent()
+    protected ConfigurationNodePointer<T> getParent()
     {
         return parent;
     }
 
     /**
+     * Returns the node handler for the managed nodes. This is a convenience
+     * method.
+     * 
+     * @return the node handler
+     */
+    protected NodeHandler<T> getNodeHandler()
+    {
+        return getParent().getNodeHandler();
+    }
+    
+    /**
      * Returns the start offset of the iteration.
      *
      * @return the start offset
@@ -144,28 +151,25 @@
     }
 
     /**
-     * Initializes the list of sub nodes for the iteration. This method must be
-     * called during initialization phase.
+     * Returns the maximum position for this iterator.
      *
-     * @param nodes the list with the sub nodes
+     * @return the maximum allowed position
      */
-    protected void initSubNodeList(List<ConfigurationNode> nodes)
+    protected int getMaxPosition()
     {
-        subNodes = nodes;
-        if (reverse)
-        {
-            setStartOffset(subNodes.size());
-        }
+        return reverse ? getStartOffset() + 1 : size() - getStartOffset();
     }
 
     /**
-     * Returns the maximum position for this iterator.
+     * Returns the index in the data list for the given position. This method
+     * also checks the reverse flag.
      *
-     * @return the maximum allowed position
+     * @param pos the position (1-based)
+     * @return the corresponding list index
      */
-    protected int getMaxPosition()
+    protected int positionToIndex(int pos)
     {
-        return reverse ? getStartOffset() + 1 : subNodes.size() - getStartOffset();
+        return (reverse ? 1 - pos : pos - 1) + getStartOffset();
     }
 
     /**
@@ -173,23 +177,15 @@
      * method is called by <code>getNodePointer()</code>. Derived classes
      * must create the correct pointer object.
      *
-     * @param node the current configuration node
+     * @param position the current position in the iteration
      * @return the node pointer
      */
-    protected NodePointer createNodePointer(ConfigurationNode node)
-    {
-        return new ConfigurationNodePointer(getParent(), node);
-    }
+    protected abstract NodePointer createNodePointer(int position);
 
     /**
-     * Returns the index in the data list for the given position. This method
-     * also checks the reverse flag.
-     *
-     * @param pos the position (1-based)
-     * @return the corresponding list index
+     * Returns the number of elements in this iteration.
+     * 
+     * @return the number of elements
      */
-    protected int positionToIndex(int pos)
-    {
-        return (reverse ? 1 - pos : pos - 1) + getStartOffset();
-    }
+    protected abstract int size();
 }

Copied: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodeIteratorChildren.java (from r635335, commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodeIteratorChildren.java)
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodeIteratorChildren.java?p2=commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodeIteratorChildren.java&p1=commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodeIteratorChildren.java&r1=635335&r2=636505&rev=636505&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodeIteratorChildren.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodeIteratorChildren.java Wed Mar 12 13:52:11 2008
@@ -14,14 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-package org.apache.commons.configuration2.tree.xpath;
+package org.apache.commons.configuration2.expr.xpath;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-import org.apache.commons.configuration2.tree.ConfigurationNode;
 import org.apache.commons.jxpath.ri.Compiler;
 import org.apache.commons.jxpath.ri.QName;
 import org.apache.commons.jxpath.ri.compiler.NodeNameTest;
@@ -37,9 +35,13 @@
  * @since 1.3
  * @author Oliver Heger
  * @version $Id$
+ * @param <T> the type of the nodes this iterator deals with
  */
-class ConfigurationNodeIteratorChildren extends ConfigurationNodeIteratorBase
+class ConfigurationNodeIteratorChildren<T> extends ConfigurationNodeIteratorBase<T>
 {
+    /** Stores the list with the sub nodes. */
+    private List<T> subNodes;
+
     /**
      * Creates a new instance of <code>ConfigurationNodeIteratorChildren</code>
      * and initializes it.
@@ -49,15 +51,25 @@
      * @param reverse the reverse flag
      * @param startsWith the first element of the iteration
      */
-    public ConfigurationNodeIteratorChildren(NodePointer parent, NodeTest nodeTest, boolean reverse, NodePointer startsWith)
+    public ConfigurationNodeIteratorChildren(
+            ConfigurationNodePointer<T> parent, NodeTest nodeTest,
+            boolean reverse, ConfigurationNodePointer<T> startsWith)
     {
         super(parent, reverse);
-        ConfigurationNode root = (ConfigurationNode) parent.getNode();
-        List<ConfigurationNode> childNodes = createSubNodeList(root, nodeTest);
-        initSubNodeList(childNodes);
+        T root = parent.getConfigurationNode();
+        subNodes = createSubNodeList(root, nodeTest);
+
         if (startsWith != null)
         {
-            setStartOffset(findStartIndex(root, (ConfigurationNode) startsWith.getNode()));
+            setStartOffset(findStartIndex(root, subNodes, startsWith
+                    .getConfigurationNode()));
+        }
+        else
+        {
+            if (reverse)
+            {
+                setStartOffset(size());
+            }
         }
     }
 
@@ -70,9 +82,9 @@
      * @param test the test object
      * @return a list with the matching nodes
      */
-    protected List<ConfigurationNode> createSubNodeList(ConfigurationNode node, NodeTest test)
+    protected List<T> createSubNodeList(T node, NodeTest test)
     {
-        List<ConfigurationNode> children = node.getChildren();
+        List<T> children = getNodeHandler().getChildren(node);
 
         if (test == null)
         {
@@ -91,10 +103,10 @@
                         return children;
                     }
 
-                    List<ConfigurationNode> result = new ArrayList<ConfigurationNode>();
-                    for (ConfigurationNode child : children)
+                    List<T> result = new ArrayList<T>();
+                    for (T child : children)
                     {
-                        if (StringUtils.equals(name.getName(), child.getName()))
+                        if (StringUtils.equals(name.getName(), getNodeHandler().nodeName(child)))
                         {
                             result.add(child);
                         }
@@ -122,20 +134,47 @@
      * given start node in the children of the root node.
      *
      * @param node the root node
+     * @param children the children of the root node
      * @param startNode the start node
      * @return the start node's index
      */
-    protected int findStartIndex(ConfigurationNode node,
-            ConfigurationNode startNode)
+    protected int findStartIndex(T node, List<T> children, T startNode)
     {
-        for (int index = 0; index < node.getChildrenCount(); index++)
+        int index = 0;
+        for(T child : children)
         {
-            if (node.getChild(index) == startNode)
+            if(child == startNode)
             {
                 return index;
             }
+            index++;
         }
 
         return -1;
+    }
+
+    /**
+     * Creates the configuration node pointer for the current position.
+     *
+     * @param position the current position in the iteration
+     * @return the node pointer
+     */
+    @Override
+    protected NodePointer createNodePointer(int position)
+    {
+        return new ConfigurationNodePointer<T>(getParent(), subNodes
+                .get(position), getNodeHandler());
+    }
+
+    /**
+     * Returns the number of elements in this iteration. This is the number of
+     * elements in the children list.
+     *
+     * @return the number of elements
+     */
+    @Override
+    protected int size()
+    {
+        return subNodes.size();
     }
 }

Copied: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodePointer.java (from r635335, commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodePointer.java)
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodePointer.java?p2=commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodePointer.java&p1=commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodePointer.java&r1=635335&r2=636505&rev=636505&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodePointer.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodePointer.java Wed Mar 12 13:52:11 2008
@@ -15,12 +15,11 @@
  * limitations under the License.
  */
 
-package org.apache.commons.configuration2.tree.xpath;
+package org.apache.commons.configuration2.expr.xpath;
 
-import java.util.List;
 import java.util.Locale;
 
-import org.apache.commons.configuration2.tree.ConfigurationNode;
+import org.apache.commons.configuration2.expr.NodeHandler;
 import org.apache.commons.jxpath.ri.Compiler;
 import org.apache.commons.jxpath.ri.QName;
 import org.apache.commons.jxpath.ri.compiler.NodeTest;
@@ -36,11 +35,12 @@
  * This is needed for queries using JXPath.
  * </p>
  *
- * @since 1.3
+ * @since 2.0
  * @author Oliver Heger
  * @version $Id$
+ * @param <T> the type of the nodes this pointer deals with
  */
-class ConfigurationNodePointer extends NodePointer
+class ConfigurationNodePointer<T> extends NodePointer
 {
     /**
      * The serial version UID.
@@ -48,18 +48,23 @@
     private static final long serialVersionUID = -1087475639680007713L;
 
     /** Stores the associated configuration node. */
-    private ConfigurationNode node;
+    private T node;
+
+    /** The node handler for the represented node.*/
+    private NodeHandler<T> nodeHandler;
 
     /**
      * Creates a new instance of <code>ConfigurationNodePointer</code>.
      *
      * @param node the node
+     * @param handler the node handler
      * @param locale the locale
      */
-    public ConfigurationNodePointer(ConfigurationNode node, Locale locale)
+    public ConfigurationNodePointer(T node, NodeHandler<T> handler, Locale locale)
     {
         super(null, locale);
         this.node = node;
+        nodeHandler = handler;
     }
 
     /**
@@ -69,21 +74,43 @@
      * @param parent the parent pointer
      * @param node the associated node
      */
-    public ConfigurationNodePointer(NodePointer parent, ConfigurationNode node)
+    public ConfigurationNodePointer(NodePointer parent, T node, NodeHandler<T> handler)
     {
         super(parent);
         this.node = node;
+        nodeHandler = handler;
+    }
+
+    /**
+     * Returns the <code>NodeHandler</code> used by this poiinter.
+     * @return the <code>NodeHandler</code>
+     */
+    public NodeHandler<T> getNodeHandler()
+    {
+        return nodeHandler;
+    }
+
+    /**
+     * Returns the wrapped configuration node.
+     * @return the wrapped configuration node
+     */
+    public T getConfigurationNode()
+    {
+        return node;
     }
 
     /**
      * Returns a flag whether this node is a leaf. This is the case if there are
-     * no child nodes.
+     * no child nodes or attributes.
      *
      * @return a flag if this node is a leaf
      */
+    @Override
     public boolean isLeaf()
     {
-        return node.getChildrenCount() < 1;
+        return getNodeHandler().getChildren(getConfigurationNode()).isEmpty()
+                && getNodeHandler().getAttributes(getConfigurationNode())
+                        .isEmpty();
     }
 
     /**
@@ -91,6 +118,7 @@
      *
      * @return the collection flag
      */
+    @Override
     public boolean isCollection()
     {
         return false;
@@ -101,20 +129,22 @@
      *
      * @return the node's length
      */
+    @Override
     public int getLength()
     {
         return 1;
     }
 
     /**
-     * Checks whether this node pointer refers to an attribute node. This method
-     * checks the attribute flag of the associated configuration node.
+     * Checks whether this node pointer refers to an attribute node. This is not
+     * the case for the nodes maintained by this pointer.
      *
      * @return the attribute flag
      */
+    @Override
     public boolean isAttribute()
     {
-        return node.isAttribute();
+        return false;
     }
 
     /**
@@ -122,9 +152,10 @@
      *
      * @return the name
      */
+    @Override
     public QName getName()
     {
-        return new QName(null, node.getName());
+        return new QName(null, getNodeHandler().nodeName(getConfigurationNode()));
     }
 
     /**
@@ -133,9 +164,10 @@
      *
      * @return the base value
      */
+    @Override
     public Object getBaseValue()
     {
-        return node;
+        return getConfigurationNode();
     }
 
     /**
@@ -143,9 +175,10 @@
      *
      * @return the immediate node
      */
+    @Override
     public Object getImmediateNode()
     {
-        return node;
+        return getConfigurationNode();
     }
 
     /**
@@ -153,9 +186,10 @@
      *
      * @return the represented node's value
      */
+    @Override
     public Object getValue()
     {
-        return node.getValue();
+        return getNodeHandler().getValue(getConfigurationNode());
     }
 
     /**
@@ -163,9 +197,10 @@
      *
      * @param value the new value
      */
+    @Override
     public void setValue(Object value)
     {
-        node.setValue(value);
+        getNodeHandler().setValue(getConfigurationNode(), value);
     }
 
     /**
@@ -175,38 +210,26 @@
      * @param pointer2 another pointer
      * @return a flag, which pointer should be sorted first
      */
+    @SuppressWarnings("unchecked")
+    @Override
     public int compareChildNodePointers(NodePointer pointer1, NodePointer pointer2)
     {
-        ConfigurationNode node1 = (ConfigurationNode) pointer1.getBaseValue();
-        ConfigurationNode node2 = (ConfigurationNode) pointer2.getBaseValue();
+        T node1 = ((ConfigurationNodePointer<T>) pointer1).getConfigurationNode();
+        T node2 = ((ConfigurationNodePointer<T>) pointer2).getConfigurationNode();
 
-        // attributes will be sorted before child nodes
-        if (node1.isAttribute() && !node2.isAttribute())
-        {
-            return -1;
-        }
-        else if (node2.isAttribute() && !node1.isAttribute())
+        // sort based on the occurrence in the sub node list
+        for (T child : getNodeHandler().getChildren(getConfigurationNode()))
         {
-            return 1;
-        }
-
-        else
-        {
-            // sort based on the occurrence in the sub node list
-            List<ConfigurationNode> subNodes = node1.isAttribute() ? node.getAttributes() : node.getChildren();
-            for (ConfigurationNode child : subNodes)
+            if (child == node1)
+            {
+                return -1;
+            }
+            else if (child == node2)
             {
-                if (child == node1)
-                {
-                    return -1;
-                }
-                else if (child == node2)
-                {
-                    return 1;
-                }
+                return 1;
             }
-            return 0; // should not happen
         }
+        return 0; // should not happen
     }
 
     /**
@@ -215,9 +238,10 @@
      * @param name the attribute name
      * @return the iterator for the attributes
      */
+    @Override
     public NodeIterator attributeIterator(QName name)
     {
-        return new ConfigurationNodeIteratorAttribute(this, name);
+        return new ConfigurationNodeIteratorAttribute<T>(this, name);
     }
 
     /**
@@ -228,9 +252,13 @@
      * @param reverse the reverse flag
      * @param startWith the start value of the iteration
      */
-    public NodeIterator childIterator(NodeTest test, boolean reverse, NodePointer startWith)
+    @SuppressWarnings("unchecked")
+    @Override
+    public NodeIterator childIterator(NodeTest test, boolean reverse,
+            NodePointer startWith)
     {
-        return new ConfigurationNodeIteratorChildren(this, test, reverse, startWith);
+        return new ConfigurationNodeIteratorChildren<T>(this, test, reverse,
+                (ConfigurationNodePointer<T>) startWith);
     }
 
     /**
@@ -240,6 +268,7 @@
      * @param test the test object
      * @return a flag if this node corresponds to the test
      */
+    @Override
     public boolean testNode(NodeTest test)
     {
         if (test instanceof NodeTypeTest