Author: oheger
Date: Wed Mar 12 14:27:01 2008
New Revision: 636515

URL: http://svn.apache.org/viewvc?rev=636515&view=rev
Log:
Implementation of the NodePointerFactory for configuration nodes based on the 
NodeHandler approach

Added:
    
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodePointerFactory.java
      - copied, changed from r635335, 
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodePointerFactory.java
    
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/xpath/TestConfigurationNodePointerFactory.java
      - copied, changed from r636104, 
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/tree/xpath/TestConfigurationNodePointerFactory.java

Copied: 
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodePointerFactory.java
 (from r635335, 
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodePointerFactory.java)
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodePointerFactory.java?p2=commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodePointerFactory.java&p1=commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodePointerFactory.java&r1=635335&r2=636515&rev=636515&view=diff
==============================================================================
--- 
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/tree/xpath/ConfigurationNodePointerFactory.java
 (original)
+++ 
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/expr/xpath/ConfigurationNodePointerFactory.java
 Wed Mar 12 14:27:01 2008
@@ -14,21 +14,29 @@
  * 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.Locale;
 
-import org.apache.commons.configuration2.tree.ConfigurationNode;
+import org.apache.commons.configuration2.expr.NodeHandler;
 import org.apache.commons.jxpath.ri.QName;
 import org.apache.commons.jxpath.ri.model.NodePointer;
 import org.apache.commons.jxpath.ri.model.NodePointerFactory;
 
 /**
- * Implementation of the <code>NodePointerFactory</code> interface for
- * configuration nodes.
+ * <p>Implementation of the <code>NodePointerFactory</code> interface for
+ * configuration nodes.</p>
+ * <p>This class is able to create <code>NodePointer</code>s for the nodes of
+ * hierarchical configurations. Because there is no common base class for
+ * configuration nodes (any specific configuration implementation can use its
+ * own node class) a trick is needed for activating this factory for a concrete
+ * JXPath query: The <code>wrapNode()</code> method has to be called with the
+ * node object and its corresponding <code>NodeHandler</code>. This creates a
+ * wrapper object containing all information required by the factory for 
processing
+ * a query. Then this wrapper object has to be passed to the query methods of
+ * the JXPath context.</p>
  *
- * @since 1.3
+ * @since 2.0
  * @author Oliver Heger
  * @version $Id$
  */
@@ -56,11 +64,14 @@
      * @param locale the locale
      * @return a pointer for a configuration node if the bean is such a node
      */
+    @SuppressWarnings("unchecked")
     public NodePointer createNodePointer(QName name, Object bean, Locale 
locale)
     {
-        if (bean instanceof ConfigurationNode)
+        if (bean instanceof NodeWrapper)
         {
-            return new ConfigurationNodePointer((ConfigurationNode) bean, 
locale);
+            NodeWrapper<?> wrapper = (NodeWrapper<?>) bean;
+            return new ConfigurationNodePointer(wrapper.getNode(), wrapper
+                    .getNodeHandler(), locale);
         }
         return null;
     }
@@ -74,12 +85,78 @@
      * @param bean the bean
      * @return a pointer for a configuration node if the bean is such a node
      */
-    public NodePointer createNodePointer(NodePointer parent, QName name, 
Object bean)
+    @SuppressWarnings("unchecked")
+    public NodePointer createNodePointer(NodePointer parent, QName name,
+            Object bean)
     {
-        if (bean instanceof ConfigurationNode)
+        if (bean instanceof NodeWrapper)
         {
-            return new ConfigurationNodePointer(parent, (ConfigurationNode) 
bean);
+            NodeWrapper<?> wrapper = (NodeWrapper<?>) bean;
+            return new ConfigurationNodePointer(
+                    (ConfigurationNodePointer) parent, wrapper.getNode(),
+                    wrapper.getNodeHandler());
         }
         return null;
+    }
+
+    /**
+     * Creates a node wrapper for the specified node and its handler. This
+     * wrapper has to be passed to the JXPath context instead of the original
+     * node.
+     *
+     * @param <T> the type of the node
+     * @param node the node
+     * @param handler the corresponding node handler
+     * @return a wrapper for this node
+     */
+    public static <T> Object wrapNode(T node, NodeHandler<T> handler)
+    {
+        return new NodeWrapper<T>(node, handler);
+    }
+
+    /**
+     * An internally used wrapper class that holds all information for
+     * processing a query for a specific node.
+     */
+    private static class NodeWrapper<T>
+    {
+        /** Stores the node. */
+        private T node;
+
+        /** Stores the corresponding node handler. */
+        private NodeHandler<T> nodeHandler;
+
+        /**
+         * Creates a new instance of <code>NodeWrapper</code> and initializes
+         * it.
+         *
+         * @param nd the node
+         * @param handler the node handler
+         */
+        public NodeWrapper(T nd, NodeHandler<T> handler)
+        {
+            node = nd;
+            nodeHandler = handler;
+        }
+
+        /**
+         * Returns the wrapped node.
+         *
+         * @return the node
+         */
+        public T getNode()
+        {
+            return node;
+        }
+
+        /**
+         * Returns the node handler for the wrapped node.
+         *
+         * @return the node handler
+         */
+        public NodeHandler<T> getNodeHandler()
+        {
+            return nodeHandler;
+        }
     }
 }

Copied: 
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/xpath/TestConfigurationNodePointerFactory.java
 (from r636104, 
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/tree/xpath/TestConfigurationNodePointerFactory.java)
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/xpath/TestConfigurationNodePointerFactory.java?p2=commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/xpath/TestConfigurationNodePointerFactory.java&p1=commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/tree/xpath/TestConfigurationNodePointerFactory.java&r1=636104&r2=636515&rev=636515&view=diff
==============================================================================
--- 
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/tree/xpath/TestConfigurationNodePointerFactory.java
 (original)
+++ 
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/expr/xpath/TestConfigurationNodePointerFactory.java
 Wed Mar 12 14:27:01 2008
@@ -14,14 +14,14 @@
  * 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.Iterator;
 import java.util.List;
 
+import org.apache.commons.configuration2.expr.ConfigurationNodeHandler;
 import org.apache.commons.configuration2.tree.ConfigurationNode;
 import org.apache.commons.configuration2.tree.DefaultConfigurationNode;
-import 
org.apache.commons.configuration2.tree.xpath.ConfigurationNodePointerFactory;
 import org.apache.commons.jxpath.JXPathContext;
 import org.apache.commons.jxpath.ri.JXPathContextReferenceImpl;
 
@@ -36,14 +36,16 @@
 public class TestConfigurationNodePointerFactory extends AbstractXPathTest
 {
     /** Stores the JXPathContext used for testing. */
-    JXPathContext context;
+    private JXPathContext context;
 
+    @Override
     protected void setUp() throws Exception
     {
         super.setUp();
         JXPathContextReferenceImpl
                 .addNodePointerFactory(new ConfigurationNodePointerFactory());
-        context = JXPathContext.newContext(root);
+        context = JXPathContext.newContext(ConfigurationNodePointerFactory
+                .wrapNode(root, new ConfigurationNodeHandler()));
         context.setLenient(true);
     }
 
@@ -52,9 +54,9 @@
      */
     public void testSimpleXPath()
     {
-        List nodes = context.selectNodes(CHILD_NAME1);
+        List<?> nodes = context.selectNodes(CHILD_NAME1);
         assertEquals("Incorrect number of results", 2, nodes.size());
-        for (Iterator it = nodes.iterator(); it.hasNext();)
+        for (Iterator<?> it = nodes.iterator(); it.hasNext();)
         {
             ConfigurationNode node = (ConfigurationNode) it.next();
             assertEquals("Incorrect node name", CHILD_NAME1, node.getName());
@@ -81,10 +83,10 @@
                 .valueOf(CHILD_COUNT), context.getValue(CHILD_NAME2
                 + "[last()]"));
 
-        List nodes = context.selectNodes("/" + CHILD_NAME1 + "[1]/*");
+        List<?> nodes = context.selectNodes("/" + CHILD_NAME1 + "[1]/*");
         assertEquals("Wrong number of children", CHILD_COUNT, nodes.size());
         int index = 1;
-        for (Iterator it = nodes.iterator(); it.hasNext(); index++)
+        for (Iterator<?> it = nodes.iterator(); it.hasNext(); index++)
         {
             ConfigurationNode node = (ConfigurationNode) it.next();
             assertEquals("Wrong node value for child " + index, "2." + index,
@@ -108,7 +110,7 @@
         ConfigurationNode node = (ConfigurationNode) root.getChild(2).getChild(
                 1).getChildren(CHILD_NAME2).get(1);
         node.addAttribute(new DefaultConfigurationNode("name", "testValue"));
-        List nodes = context.selectNodes("//" + CHILD_NAME2 + "[EMAIL 
PROTECTED]");
+        List<?> nodes = context.selectNodes("//" + CHILD_NAME2 + "[EMAIL 
PROTECTED]");
         assertEquals("Name attribute not found", 1, nodes.size());
         assertEquals("Wrong node returned", node, nodes.get(0));
     }
@@ -118,7 +120,7 @@
      */
     public void testText()
     {
-        List nodes = context.selectNodes("//" + CHILD_NAME2
+        List<?> nodes = context.selectNodes("//" + CHILD_NAME2
                 + "[text()='1.1.1']");
         assertEquals("Incorrect number of result nodes", 1, nodes.size());
     }
@@ -128,7 +130,7 @@
      */
     public void testParentAxis()
     {
-        List nodes = context.selectNodes("/" + CHILD_NAME2 + "/parent::*");
+        List<?> nodes = context.selectNodes("/" + CHILD_NAME2 + "/parent::*");
         assertEquals("Wrong number of parent nodes", 1, nodes.size());
     }
 
@@ -137,7 +139,7 @@
      */
     public void testFollowingSiblingAxis()
     {
-        List nodes = context.selectNodes("/" + CHILD_NAME1
+        List<?> nodes = context.selectNodes("/" + CHILD_NAME1
                 + "[2]/following-sibling::*");
         assertEquals("Wrong number of following siblings", 1, nodes.size());
         ConfigurationNode node = (ConfigurationNode) nodes.get(0);
@@ -151,7 +153,7 @@
      */
     public void testPrecedingSiblingAxis()
     {
-        List nodes = context.selectNodes("/" + CHILD_NAME1
+        List<?> nodes = context.selectNodes("/" + CHILD_NAME1
                 + "[2]/preceding-sibling::*");
         assertEquals("Wrong number of preceding siblings", 3, nodes.size());
         for (int index = 0, value = 3; index < nodes.size(); index++, value--)


Reply via email to