[338494] Re-fixing this bug as it relied on constants from generated
grammar
diff --git a/bundles/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/XPathParserException.java b/bundles/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/XPathParserException.java
index 06435ff..8f1e60d 100644
--- a/bundles/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/XPathParserException.java
+++ b/bundles/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/XPathParserException.java
@@ -36,4 +36,16 @@
public XPathParserException(String reason) {
super(INVALID_XPATH_EXPRESSION, reason);
}
+
+ /**
+ * Constructor for XPathParserException.
+ *
+ * @param code
+ * the XPath2 standard code for the problem.
+ * @param reason
+ * is the reason why the exception has been thrown.
+ */
+ public XPathParserException(String code, String reason) {
+ super(code, reason);
+ }
}
diff --git a/bundles/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/internal/DefaultVisitor.java b/bundles/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/internal/DefaultVisitor.java
new file mode 100644
index 0000000..4a8545f
--- /dev/null
+++ b/bundles/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/internal/DefaultVisitor.java
@@ -0,0 +1,640 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Jesper Steen Moeller, 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:
+ * Jesper Steen Moller - bug 338494 - But without dependency on magic constants
+ *******************************************************************************/
+
+package org.eclipse.wst.xml.xpath2.processor.internal;
+
+import java.util.Iterator;
+
+import org.eclipse.wst.xml.xpath2.processor.ast.XPath;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.AddExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.AndExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.AnyKindTest;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.AttributeTest;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.AxisStep;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.CastExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.CastableExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.CmpExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.CntxItemExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.CommentTest;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.DecimalLiteral;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.DivExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.DocumentTest;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.DoubleLiteral;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.ElementTest;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.ExceptExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.Expr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.FilterExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.ForExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.ForwardStep;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.FunctionCall;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.IDivExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.IfExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.InstOfExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.IntegerLiteral;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.IntersectExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.ItemType;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.LetExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.MinusExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.ModExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.MulExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.NameTest;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.OrExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.PITest;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.ParExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.PipeExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.PlusExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.QuantifiedExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.RangeExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.ReverseStep;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.SchemaAttrTest;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.SchemaElemTest;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.SequenceType;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.SingleType;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.StringLiteral;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.SubExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.TextTest;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.TreatAsExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.UnionExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.VarExprPair;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.VarRef;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.XPathExpr;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.XPathVisitor;
+
+@SuppressWarnings({"unchecked", "deprecation"})
+public class DefaultVisitor implements XPathVisitor {
+
+ /**
+ * Returns the normalized tree
+ *
+ * @param xp
+ * is the xpath expression.
+ * @return the xpath expressions.
+ */
+ public Object visit(XPath xp) {
+ for (Iterator<Expr> i = xp.iterator(); i.hasNext();) {
+ Expr e = (Expr) i.next();
+ e.accept(this);
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @param fex
+ * is the For expression.
+ * @return fex expression.
+ */
+ public Object visit(ForExpr fex) {
+ for (Iterator<VarExprPair> i = fex.iterator(); i.hasNext();) {
+ i.next().expr().accept(this);
+ }
+ fex.expr().accept(this);
+ return null;
+ }
+
+ /**
+ *
+ * @param lex
+ * is the Let expression.
+ * @return lex expression.
+ */
+ public Object visit(LetExpr lex) {
+ for (Iterator<VarExprPair> i = lex.iterator(); i.hasNext();) {
+ i.next().expr().accept(this);
+ }
+ lex.expr().accept(this);
+ return null;
+ }
+
+ /**
+ *
+ * @param qex
+ * is the Quantified expression.
+ * @return qex expression.
+ */
+ public Object visit(QuantifiedExpr qex) {
+ for (Iterator<VarExprPair> i = qex.iterator(); i.hasNext();) {
+ i.next().expr().accept(this);
+ }
+ qex.expr().accept(this);
+ return null;
+ }
+
+ /**
+ *
+ * @param ifex
+ * is the 'if' expression.
+ * @return ifex expression.
+ */
+ public Object visit(IfExpr ifex) {
+ for (Iterator<Expr> i = ifex.iterator(); i.hasNext();) {
+ i.next().accept(this);
+ }
+ ifex.then_clause().accept(this);
+ ifex.else_clause().accept(this);
+ return ifex;
+ }
+
+ /**
+ * @param ex
+ * is the 'or' expression.
+ * @return make logic expr(orex).
+ */
+ public Object visit(OrExpr ex) {
+ ex.left().accept(this);
+ ex.right().accept(this);
+ return null;
+ }
+
+ /**
+ * @param ex
+ * is the 'and' expression.
+ * @return make logic expr(andex).
+ */
+ public Object visit(AndExpr ex) {
+ ex.left().accept(this);
+ ex.right().accept(this);
+ return null;
+ }
+
+ /**
+ * @param cmpex
+ * is the compare expression.
+ * @return cmpex.
+ */
+ public Object visit(CmpExpr ex) {
+ ex.left().accept(this);
+ ex.right().accept(this);
+ return null;
+ }
+
+ /**
+ * @param rex
+ * is the range expression.
+ * @return a new function.
+ */
+ public Object visit(RangeExpr ex) {
+ ex.left().accept(this);
+ ex.right().accept(this);
+ return null;
+ }
+
+ /**
+ * @param ex
+ * is the add expression.
+ * @return a new function.
+ */
+ public Object visit(AddExpr ex) {
+ ex.left().accept(this);
+ ex.right().accept(this);
+ return null;
+ }
+
+ /**
+ * @param ex
+ * is the sub expression.
+ * @return a new function.
+ */
+ public Object visit(SubExpr ex) {
+ ex.left().accept(this);
+ ex.right().accept(this);
+ return null;
+ }
+
+ /**
+ * @param mulex
+ * is the multiply expression.
+ * @return a new function.
+ */
+ public Object visit(MulExpr ex) {
+ ex.left().accept(this);
+ ex.right().accept(this);
+ return null;
+ }
+
+ /**
+ * @param ex
+ * is the division expression.
+ * @return a new function.
+ */
+ public Object visit(DivExpr ex) {
+ ex.left().accept(this);
+ ex.right().accept(this);
+ return null;
+ }
+
+ /**
+ * @param ex
+ * is the integer division expression that always returns an
+ * integer.
+ * @return a new function.
+ */
+ public Object visit(IDivExpr ex) {
+ ex.left().accept(this);
+ ex.right().accept(this);
+ return null;
+ }
+
+ /**
+ * @param ex
+ * is the mod expression.
+ * @return a new function.
+ */
+ public Object visit(ModExpr ex) {
+ ex.left().accept(this);
+ ex.right().accept(this);
+ return null;
+ }
+
+ /**
+ * @param ex
+ * is the union expression.
+ * @return a new function.
+ */
+ public Object visit(UnionExpr ex) {
+ ex.left().accept(this);
+ ex.right().accept(this);
+ return null;
+ }
+
+ /**
+ * @param ex
+ * is the pipe expression.
+ * @return a new function.
+ */
+ public Object visit(PipeExpr ex) {
+ ex.left().accept(this);
+ ex.right().accept(this);
+ return null;
+ }
+
+ /**
+ * @param ex
+ * is the intersect expression.
+ * @return a new function.
+ */
+ public Object visit(IntersectExpr ex) {
+ ex.left().accept(this);
+ ex.right().accept(this);
+ return null;
+ }
+
+ /**
+ * @param ex
+ * is the except expression.
+ * @return a new function.
+ */
+ public Object visit(ExceptExpr ex) {
+ ex.left().accept(this);
+ ex.right().accept(this);
+ return null;
+ }
+
+ /**
+ * @param ioexp
+ * is the instance of expression.
+ * @return a ioexp.
+ */
+ public Object visit(InstOfExpr ex) {
+ ex.left().accept(this);
+ ex.right().accept(this);
+ return null;
+ }
+
+ /**
+ * @param taexp
+ * is the treat as expression.
+ * @return a taexp.
+ */
+ public Object visit(TreatAsExpr ex) {
+ ex.left().accept(this);
+ ex.right().accept(this);
+ return null;
+ }
+
+ /**
+ * @param cexp
+ * is the castable expression.
+ * @return cexp.
+ */
+ public Object visit(CastableExpr cexp) {
+ cexp.left().accept(this);
+ cexp.right().accept(this);
+ return null;
+ }
+
+ /**
+ * @param cexp
+ * is the cast expression.
+ * @return cexp.
+ */
+ public Object visit(CastExpr cexp) {
+ cexp.left().accept(this);
+ cexp.right().accept(this);
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the minus expression.
+ * @return new sub expression
+ */
+ public Object visit(MinusExpr e) {
+ e.arg().accept(this);
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the plus expression.
+ * @return new add expression
+ */
+ public Object visit(PlusExpr e) {
+ e.arg().accept(this);
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the xpath expression.
+ * @return result.
+ */
+ public Object visit(XPathExpr e) {
+ e.expr().accept(this);
+ e.next().accept(this);
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the forward step.
+ * @return e
+ */
+ public Object visit(ForwardStep e) {
+ e.node_test().accept(this);
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the reverse step.
+ * @return e
+ */
+ public Object visit(ReverseStep e) {
+ e.node_test().accept(this);
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the Name test.
+ * @return e
+ */
+ public Object visit(NameTest e) {
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the veriable reference.
+ * @return e
+ */
+ public Object visit(VarRef e) {
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the string literal.
+ * @return e
+ */
+ public Object visit(StringLiteral e) {
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the integer literal.
+ * @return e
+ */
+ public Object visit(IntegerLiteral e) {
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the double literal.
+ * @return e
+ */
+ public Object visit(DoubleLiteral e) {
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the decimal literal.
+ * @return e
+ */
+ public Object visit(DecimalLiteral e) {
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the par expression.
+ * @return e
+ */
+ public Object visit(ParExpr e) {
+ for (Iterator<Expr> i = e.iterator(); i.hasNext();) {
+ i.next().accept(this);
+ }
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the Cntx Item Expression.
+ * @return new function
+ */
+ public Object visit(CntxItemExpr e) {
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the fucntion call.
+ * @return e
+ */
+ public Object visit(FunctionCall e) {
+ for (Iterator<Expr> i = e.iterator(); i.hasNext();) {
+ i.next().accept(this);
+ }
+ return e;
+ }
+
+ /**
+ * @param e
+ * is the single type.
+ * @return e
+ */
+ public Object visit(SingleType e) {
+ return e;
+ }
+
+ /**
+ * @param e
+ * is the sequence type.
+ * @return e
+ */
+ public Object visit(SequenceType e) {
+ ItemType it = e.item_type();
+ if (it != null)
+ it.accept(this);
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the item type.
+ * @return e
+ */
+ public Object visit(ItemType e) {
+
+ switch (e.type()) {
+ case ItemType.ITEM:
+ break;
+ case ItemType.QNAME:
+ break;
+
+ case ItemType.KINDTEST:
+ e.kind_test().accept(this);
+ break;
+ }
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the any kind test.
+ * @return e
+ */
+ public Object visit(AnyKindTest e) {
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the document test.
+ * @return e
+ */
+ public Object visit(DocumentTest e) {
+
+ switch (e.type()) {
+ case DocumentTest.ELEMENT:
+ e.elem_test().accept(this);
+ break;
+
+ case DocumentTest.SCHEMA_ELEMENT:
+ e.schema_elem_test().accept(this);
+ break;
+ }
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the text test.
+ * @return e
+ */
+ public Object visit(TextTest e) {
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the common test.
+ * @return e
+ */
+ public Object visit(CommentTest e) {
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the PI test.
+ * @return e
+ */
+ public Object visit(PITest e) {
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the attribute test.
+ * @return e
+ */
+ public Object visit(AttributeTest e) {
+ return e;
+ }
+
+ /**
+ * @param e
+ * is the schema attribute test.
+ * @return e
+ */
+ public Object visit(SchemaAttrTest e) {
+ return e;
+ }
+
+ /**
+ * @param e
+ * is the element test.
+ * @return e
+ */
+ public Object visit(ElementTest e) {
+ return e;
+ }
+
+ /**
+ * @param e
+ * is the schema element test.
+ * @return e
+ */
+ public Object visit(SchemaElemTest e) {
+ return e;
+ }
+
+ /**
+ * @param e
+ * is the axis step.
+ * @return e
+ */
+ public Object visit(AxisStep e) {
+ e.step().accept(this);
+ for (Iterator<Expr> i = e.iterator(); i.hasNext();) {
+ i.next().accept(this);
+ }
+ return null;
+ }
+
+ /**
+ * @param e
+ * is the filter expression.
+ * @return e
+ */
+ public Object visit(FilterExpr e) {
+ e.primary().accept(this);
+ for (Iterator<Expr> i = e.iterator(); i.hasNext();) {
+ i.next().accept(this);
+ }
+ return e;
+ }
+}
diff --git a/bundles/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/internal/InternalXPathParser.java b/bundles/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/internal/InternalXPathParser.java
index 01f8de9..73b81b5 100644
--- a/bundles/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/internal/InternalXPathParser.java
+++ b/bundles/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/internal/InternalXPathParser.java
@@ -19,10 +19,12 @@
import org.eclipse.wst.xml.xpath2.processor.StaticError;
import org.eclipse.wst.xml.xpath2.processor.XPathParserException;
import org.eclipse.wst.xml.xpath2.processor.ast.XPath;
+import org.eclipse.wst.xml.xpath2.processor.internal.ast.XPathExpr;
/**
* JFlexCupParser parses the xpath expression
*/
+@SuppressWarnings("deprecation")
public class InternalXPathParser {
/**
@@ -40,20 +42,31 @@
XPathFlex lexer = new XPathFlex(new StringReader(xpath));
- XPathCup p = null;
- if (isRootlessAccess) {
- p = new XPathCupRestricted(lexer);
- }
- else {
- p = new XPathCup(lexer);
- }
try {
+ XPathCup p = new XPathCup(lexer);
Symbol res = p.parse();
- return (XPath) res.value;
+ XPath xPath2 = (XPath) res.value;
+ if (isRootlessAccess) {
+ xPath2.accept(new DefaultVisitor() {
+ public Object visit(XPathExpr e) {
+ if (e.slashes() > 0) {
+ throw new XPathParserException("Access to root node is not allowed (set by caller)");
+ }
+ do {
+ e.expr().accept(this); // check the single step (may have filter with root access)
+ e = e.next(); // follow singly linked list of the path, it's all relative past the first one
+ } while (e != null);
+ return null;
+ }
+ });
+ }
+ return xPath2;
} catch (JFlexError e) {
throw new XPathParserException("JFlex lexer error: " + e.reason());
} catch (CupError e) {
throw new XPathParserException("CUP parser error: " + e.reason());
+ } catch (StaticError e) {
+ throw new XPathParserException(e.code(), e.getMessage());
} catch (Exception e) {
throw new XPathParserException(e.getMessage());
}
diff --git a/bundles/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/internal/XPathCupRestricted.java b/bundles/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/internal/XPathCupRestricted.java
deleted file mode 100644
index b267d3f..0000000
--- a/bundles/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/internal/XPathCupRestricted.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2011 Mukul Gandhi, 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:
- * Mukul Gandhi - initial API and implementation
- * Bug 338494 - prohibiting xpath expressions starting with / or // to be parsed.
- *******************************************************************************/
-
-package org.eclipse.wst.xml.xpath2.processor.internal;
-
-public class XPathCupRestricted extends XPathCup {
-
- /** Default constructor. */
- public XPathCupRestricted() {super();}
-
- /** Constructor which sets the default scanner. */
- public XPathCupRestricted(java_cup.runtime.Scanner s) {super(s);}
-
- /** Invoke a user supplied parse action. */
- public java_cup.runtime.Symbol do_action(
- int act_num,
- java_cup.runtime.lr_parser parser,
- java.util.Stack stack,
- int top)
- throws java.lang.Exception
- {
- if (act_num == 67 || act_num == 68 || act_num == 69) {
- // these action numbers correspond to following grammar productions,
- // a) FORWARD_SLASH
- // b) FORWARD_SLASH RelativePathExpr
- // c) FORWARD_SLASHSLASH RelativePathExpr
- throw new Exception("Expression starts with / or //");
- }
- else {
- return action_obj.CUP$XPathCup$do_action(act_num, parser, stack, top);
- }
- }
-
-}
-