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--)