summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpelder2007-04-12 16:35:08 (EDT)
committerpelder2007-04-12 16:35:08 (EDT)
commitfa8f3e9ae43c97b2d63fd9ad1d90de1e7ed0d698 (patch)
treefb24d2991afa0e4d07db4da64c4b9ea1c29ffc7f
parent0cba460b0cd2f6866694e346c2624b458be9d0d3 (diff)
downloadorg.eclipse.jet-fa8f3e9ae43c97b2d63fd9ad1d90de1e7ed0d698.zip
org.eclipse.jet-fa8f3e9ae43c97b2d63fd9ad1d90de1e7ed0d698.tar.gz
org.eclipse.jet-fa8f3e9ae43c97b2d63fd9ad1d90de1e7ed0d698.tar.bz2
[172691] Correct application of predicate expressions to XPath steps.
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/ast/FilterExpr.java56
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/ast/Predicate.java47
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/ast/Step.java28
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/parser/XPathParser.java20
-rw-r--r--tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/xpath/XPathParserTests.java12
5 files changed, 118 insertions, 45 deletions
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/ast/FilterExpr.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/ast/FilterExpr.java
new file mode 100644
index 0000000..8a582e3
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/ast/FilterExpr.java
@@ -0,0 +1,56 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: FilterExpr.java,v 1.1 2007/04/12 20:35:08 pelder Exp $
+ */
+package org.eclipse.jet.internal.xpath.ast;
+
+
+import org.eclipse.jet.xpath.Context;
+import org.eclipse.jet.xpath.NodeSet;
+
+
+/**
+ * Represent an XPath predicate expression
+ *
+ */
+public class FilterExpr extends NodeSetExpr
+{
+
+ private final Predicate predicate;
+
+ private final NodeSetExpr leftNodeSet;
+
+ /**
+ *
+ */
+ public FilterExpr(NodeSetExpr leftNodeSet, Predicate predicate)
+ {
+ super();
+ this.leftNodeSet = leftNodeSet;
+ this.predicate = predicate;
+ }
+
+ public NodeSet evalAsNodeSet(Context context)
+ {
+ NodeSet nodeSet = leftNodeSet.evalAsNodeSet(context);
+ return predicate.filter(context, nodeSet);
+ }
+
+ public String toString()
+ {
+ return leftNodeSet.toString() + predicate;
+ }
+
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/ast/Predicate.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/ast/Predicate.java
index b291f1b..16ac61d 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/ast/Predicate.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/ast/Predicate.java
@@ -1,7 +1,7 @@
/**
* <copyright>
*
- * Copyright (c) 2006 IBM Corporation and others.
+ * Copyright (c) 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -16,7 +16,6 @@
*/
package org.eclipse.jet.internal.xpath.ast;
-
import java.util.Iterator;
import org.eclipse.jet.internal.xpath.NodeSetImpl;
@@ -24,31 +23,24 @@ import org.eclipse.jet.internal.xpath.functions.BooleanFunction;
import org.eclipse.jet.xpath.Context;
import org.eclipse.jet.xpath.NodeSet;
-
/**
- * Represent an XPath predicate expression
- *
+ * Represent a filtering predicate [...].
*/
-public class Predicate extends NodeSetExpr
+public final class Predicate
{
+ private final ExprNode expr;
- private final ExprNode predicateExpr;
-
- private final NodeSetExpr leftNodeSet;
+ public Predicate(ExprNode expr) {
+ this.expr = expr;
+ }
/**
- *
+ * Apply the predicate to the node set represented by nodeSet
+ * @param context
+ * @param nodeSet
+ * @return
*/
- public Predicate(NodeSetExpr leftNodeSet, ExprNode predicateExpr)
- {
- super();
- this.leftNodeSet = leftNodeSet;
- this.predicateExpr = predicateExpr;
- }
-
- private NodeSet filter(NodeSet nodeSet, Context context)
- {
-
+ public NodeSet filter(Context context, NodeSet nodeSet) {
int contextPosition = 1;
final int contextSize = nodeSet.size();
NodeSet result = new NodeSetImpl(contextSize);
@@ -56,7 +48,7 @@ public class Predicate extends NodeSetExpr
{
Object node = (Object)i.next();
Context subContext = context.newSubContext(node, contextPosition, contextSize);
- Object exprVal = predicateExpr.evalAsObject(subContext);
+ Object exprVal = expr.evalAsObject(subContext);
if (exprVal instanceof Number)
{
if (((Number)exprVal).doubleValue() == contextPosition)
@@ -72,18 +64,11 @@ public class Predicate extends NodeSetExpr
}
return result;
-
- }
-
- public NodeSet evalAsNodeSet(Context context)
- {
- NodeSet nodeSet = leftNodeSet.evalAsNodeSet(context);
- return filter(nodeSet, context);
+
}
-
+
public String toString()
{
- return leftNodeSet.toString() + "[" + predicateExpr + "]"; //$NON-NLS-1$//$NON-NLS-2$
+ return "[" + expr.toString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
}
-
}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/ast/Step.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/ast/Step.java
index 556c4f7..89a0211 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/ast/Step.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/ast/Step.java
@@ -30,21 +30,35 @@ import org.eclipse.jet.xpath.NodeSet;
public class Step extends NodeSetExpr
{
+ private static final Predicate[] EMPTY_PREDICATE_EXPRS = new Predicate[0];
+
private final Axis axis;
private final NodeTest nodeTest;
private final NodeSetExpr leftLocationPath;
+ private final Predicate[] predicates;
+
/**
*
*/
public Step(NodeSetExpr leftLocationPath, Axis axis, NodeTest nodeTest)
{
+ this(leftLocationPath, axis, nodeTest, EMPTY_PREDICATE_EXPRS);
+ }
+
+ /**
+ * @param predicates TODO
+ *
+ */
+ public Step(NodeSetExpr leftLocationPath, Axis axis, NodeTest nodeTest, Predicate[] predicates)
+ {
super();
this.leftLocationPath = leftLocationPath;
this.axis = axis;
this.nodeTest = nodeTest;
+ this.predicates = predicates;
}
public NodeSet evalAsNodeSet(Context context)
@@ -63,6 +77,12 @@ public class Step extends NodeSetExpr
NodeSet subResult = axis.evaluate(nodeTest, subContext);
+ for (int j = 0; j < predicates.length; j++)
+ {
+ Predicate predicate = predicates[j];
+ subResult = predicate.filter(context, subResult);
+ }
+
if (result.size() == 0 && subResult.size() > 0)
{
result = subResult; // save copying the set...
@@ -78,6 +98,12 @@ public class Step extends NodeSetExpr
public String toString()
{
- return leftLocationPath.toString() + "/" + axis.toString() + nodeTest.toString(); //$NON-NLS-1$
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(leftLocationPath).append("/").append(axis.toString()).append(nodeTest.toString()); //$NON-NLS-1$
+ for (int i = 0; i < predicates.length; i++)
+ {
+ buffer.append(predicates[i].toString());
+ }
+ return buffer.toString();
}
}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/parser/XPathParser.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/parser/XPathParser.java
index f488eee..5cfb96e 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/parser/XPathParser.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/parser/XPathParser.java
@@ -32,6 +32,7 @@ import org.eclipse.jet.internal.xpath.ast.NodeSetCast;
import org.eclipse.jet.internal.xpath.ast.NodeSetExpr;
import org.eclipse.jet.internal.xpath.ast.NodeTest;
import org.eclipse.jet.internal.xpath.ast.NumberLiteral;
+import org.eclipse.jet.internal.xpath.ast.FilterExpr;
import org.eclipse.jet.internal.xpath.ast.Predicate;
import org.eclipse.jet.internal.xpath.ast.RelOp;
import org.eclipse.jet.internal.xpath.ast.Root;
@@ -334,7 +335,7 @@ public class XPathParser
return result;
}
- public ExprNode predicate() throws XPathSyntaxException
+ public Predicate predicate() throws XPathSyntaxException
{
if (peekNext() != XPathTokens.LBRACKET)
{
@@ -347,7 +348,7 @@ public class XPathParser
throw new XPathSyntaxException(MessageFormat.format(JET2Messages.XPath_Expected, new Object []{ "]" })); //$NON-NLS-1$
}
consumeToken(); // ]
- return expr;
+ return new Predicate(expr);
}
public NodeSetExpr locationPath() throws XPathSyntaxException
@@ -564,13 +565,18 @@ public class XPathParser
return null;
}
- NodeSetExpr result = new Step(leftNodeExpr, axis, nodeTest);
// look for predicates...
- ExprNode predicate = null;
+ List predicates = new ArrayList();
+ Predicate predicate = null;
while ((predicate = predicate()) != null)
{
- result = new Predicate(result, predicate);
+ predicates.add(predicate);
}
+ // construct the node
+ NodeSetExpr result = predicates.size() > 0 ?
+ new Step(leftNodeExpr, axis, nodeTest, (Predicate[])predicates.toArray(new Predicate[predicates.size()]))
+ : new Step(leftNodeExpr, axis, nodeTest);
+
return result;
}
@@ -582,10 +588,10 @@ public class XPathParser
{
// must have a node set in order to use predicates.
NodeSetExpr expr = castToNodeSetExpr(primaryExpr);
- ExprNode predicate = null;
+ Predicate predicate = null;
while ((predicate = predicate()) != null)
{
- expr = new Predicate(expr, predicate);
+ expr = new FilterExpr(expr, predicate);
}
return expr;
}
diff --git a/tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/xpath/XPathParserTests.java b/tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/xpath/XPathParserTests.java
index 99506aa..c8acbd2 100644
--- a/tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/xpath/XPathParserTests.java
+++ b/tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/xpath/XPathParserTests.java
@@ -4,10 +4,10 @@ import junit.framework.TestCase;
import org.eclipse.jet.internal.xpath.ast.BinaryOp;
import org.eclipse.jet.internal.xpath.ast.ExprNode;
+import org.eclipse.jet.internal.xpath.ast.FilterExpr;
import org.eclipse.jet.internal.xpath.ast.Function;
import org.eclipse.jet.internal.xpath.ast.LogicalOp;
import org.eclipse.jet.internal.xpath.ast.NumberLiteral;
-import org.eclipse.jet.internal.xpath.ast.Predicate;
import org.eclipse.jet.internal.xpath.ast.RelOp;
import org.eclipse.jet.internal.xpath.ast.Root;
import org.eclipse.jet.internal.xpath.ast.Step;
@@ -670,7 +670,7 @@ public class XPathParserTests extends TestCase {
ExprNode expr = xp.filterExpr();
assertNotNull(expr);
- assertTrue(expr instanceof Predicate);
+ assertTrue(expr instanceof FilterExpr);
assertEquals("$x[(3.0=4.0)]", expr.toString());
}
@@ -681,7 +681,7 @@ public class XPathParserTests extends TestCase {
ExprNode expr = xp.filterExpr();
assertNotNull(expr);
- assertTrue(expr instanceof Predicate);
+ assertTrue(expr instanceof FilterExpr);
assertEquals("$x[(3.0=4.0)][2.0]", expr.toString());
}
@@ -692,7 +692,7 @@ public class XPathParserTests extends TestCase {
ExprNode expr = xp.pathExpr();
assertNotNull(expr);
- assertTrue(expr instanceof Predicate);
+ assertTrue(expr instanceof Step);
assertEquals("<ctx>/child::foo/child::bar[(3.0=4.0)]", expr.toString());
}
@@ -703,7 +703,7 @@ public class XPathParserTests extends TestCase {
ExprNode expr = xp.pathExpr();
assertNotNull(expr);
- assertTrue(expr instanceof Predicate);
+ assertTrue(expr instanceof Step);
assertEquals("<ctx>/child::foo/child::bar[(3.0=4.0)][2.0]", expr.toString());
}
@@ -748,7 +748,7 @@ public class XPathParserTests extends TestCase {
ExprNode expr = xp.filterExpr();
assertNotNull(expr);
- assertTrue(expr instanceof Predicate);
+ assertTrue(expr instanceof FilterExpr);
assertEquals("floor('boo')[3.0]", expr.toString());
}