diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/gnu/xml/xpath | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/gnu/xml/xpath')
56 files changed, 9318 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/xml/xpath/AndExpr.java b/libjava/classpath/gnu/xml/xpath/AndExpr.java new file mode 100644 index 000000000..9213a40cc --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/AndExpr.java @@ -0,0 +1,87 @@ +/* AndExpr.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * Logical and. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public final class AndExpr + extends Expr +{ + + final Expr lhs; + final Expr rhs; + + public AndExpr(Expr lhs, Expr rhs) + { + this.lhs = lhs; + this.rhs = rhs; + } + + public Object evaluate(Node context, int pos, int len) + { + Object left = lhs.evaluate(context, pos, len); + if (!_boolean(context, left)) + { + return Boolean.FALSE; + } + Object right = rhs.evaluate(context, pos, len); + return _boolean(context, right) ? Boolean.TRUE : Boolean.FALSE; + } + + public Expr clone(Object context) + { + return new AndExpr(lhs.clone(context), rhs.clone(context)); + } + + public boolean references(QName var) + { + return (lhs.references(var) || rhs.references(var)); + } + + public String toString() + { + return lhs + " and " + rhs; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/ArithmeticExpr.java b/libjava/classpath/gnu/xml/xpath/ArithmeticExpr.java new file mode 100644 index 000000000..a7bc62f2e --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/ArithmeticExpr.java @@ -0,0 +1,170 @@ +/* ArithmeticExpr.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import gnu.java.lang.CPStringBuilder; + +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * Binary arithmetic expression. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class ArithmeticExpr + extends Expr +{ + + static final int ADD = 0; + static final int SUBTRACT = 1; + static final int MULTIPLY = 2; + static final int DIVIDE = 3; + static final int MODULO = 4; + + final Expr lhs; + final Expr rhs; + final int op; + + ArithmeticExpr(Expr lhs, Expr rhs, int op) + { + this.lhs = lhs; + this.rhs = rhs; + switch (op) + { + case ADD: + case SUBTRACT: + case MULTIPLY: + case DIVIDE: + case MODULO: + this.op = op; + break; + default: + throw new IllegalArgumentException(); + } + } + + public Object evaluate(Node context, int pos, int len) + { + Object left = lhs.evaluate(context, pos, len); + Object right = rhs.evaluate(context, pos, len); + + double ln = _number(context, left); + double rn = _number(context, right); + switch (op) + { + case ADD: + return new Double(ln + rn); + case SUBTRACT: + return new Double(ln - rn); + case MULTIPLY: + return new Double(ln * rn); + case DIVIDE: + if (rn == 0.0d || rn == -0.0d) + { + if (ln == 0.0d || ln == -0.0d) + { + return new Double(Double.NaN); + } + else + { + return new Double(ln < 0.0d ? + Double.NEGATIVE_INFINITY : + Double.POSITIVE_INFINITY); + } + } + return new Double(ln / rn); + case MODULO: + if (rn == 0.0d || rn == 0.0d) + { + if (ln == 0.0d || ln == -0.0d) + { + return new Double(Double.NaN); + } + else + { + return new Double(ln < 0.0d ? + Double.NEGATIVE_INFINITY : + Double.POSITIVE_INFINITY); + } + } + return new Double(ln % rn); + default: + throw new IllegalStateException(); + } + } + + public Expr clone(Object context) + { + return new ArithmeticExpr(lhs.clone(context), rhs.clone(context), op); + } + + public boolean references(QName var) + { + return (lhs.references(var) || rhs.references(var)); + } + + public String toString() + { + CPStringBuilder buf = new CPStringBuilder(); + buf.append(lhs); + buf.append(' '); + switch (op) + { + case ADD: + buf.append('+'); + break; + case SUBTRACT: + buf.append('-'); + break; + case MULTIPLY: + buf.append('*'); + break; + case DIVIDE: + buf.append("div"); + break; + case MODULO: + buf.append("mod"); + break; + } + buf.append(' '); + buf.append(rhs); + return buf.toString(); + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/BooleanFunction.java b/libjava/classpath/gnu/xml/xpath/BooleanFunction.java new file mode 100644 index 000000000..05e0bd5bc --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/BooleanFunction.java @@ -0,0 +1,95 @@ +/* BooleanFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>boolean</code> function converts its argument to a boolean as + * follows: + * <ul> + * <li>a number is true if and only if it is neither positive or negative + * zero nor NaN</li> + * <li>a node-set is true if and only if it is non-empty</li> + * <li>a string is true if and only if its length is non-zero</li> + * <li>an object of a type other than the four basic types is converted to a + * boolean in a way that is dependent on that type</li> + * </ul> + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class BooleanFunction + extends Expr +{ + + final Expr arg; + + BooleanFunction(List<Expr> args) + { + this(args.get(0)); + } + + BooleanFunction(Expr arg) + { + this.arg = arg; + } + + public Object evaluate(Node context, int pos, int len) + { + Object val = arg.evaluate(context, pos, len); + return _boolean(context, val) ? Boolean.TRUE : Boolean.FALSE; + } + + public Expr clone(Object context) + { + return new BooleanFunction(arg.clone(context)); + } + + public boolean references(QName var) + { + return arg.references(var); + } + + public String toString() + { + return "boolean(" + arg + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/CeilingFunction.java b/libjava/classpath/gnu/xml/xpath/CeilingFunction.java new file mode 100644 index 000000000..aa906e0dd --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/CeilingFunction.java @@ -0,0 +1,89 @@ +/* CeilingFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>ceiling</code> function returns the smallest (closest to + * negative infinity) number that is not less than the argument and that + * is an integer. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class CeilingFunction + extends Expr +{ + + final Expr arg; + + CeilingFunction(List<Expr> args) + { + this(args.get(0)); + } + + CeilingFunction(Expr arg) + { + this.arg = arg; + } + + public Object evaluate(Node context, int pos, int len) + { + Object val = arg.evaluate(context, pos, len); + double n = _number(context, val); + return new Double(Math.ceil(n)); + } + + public Expr clone(Object context) + { + return new CeilingFunction(arg.clone(context)); + } + + public boolean references(QName var) + { + return arg.references(var); + } + + public String toString() + { + return "ceiling(" + arg + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/ConcatFunction.java b/libjava/classpath/gnu/xml/xpath/ConcatFunction.java new file mode 100644 index 000000000..58096e5ac --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/ConcatFunction.java @@ -0,0 +1,115 @@ +/* ConcatFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import gnu.java.lang.CPStringBuilder; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>concat</code> function returns the concatenation of its arguments. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class ConcatFunction + extends Expr +{ + + final List<Expr> args; + + ConcatFunction(List<Expr> args) + { + this.args = args; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + CPStringBuilder buf = new CPStringBuilder(); + for (Expr arg : args) + { + Object val = arg.evaluate(context, pos, len); + buf.append(_string(context, val)); + } + return buf.toString(); + } + + public Expr clone(Object context) + { + int len = args.size(); + List<Expr> args2 = new ArrayList<Expr>(len); + for (int i = 0; i < len; i++) + { + args2.add(args.get(i).clone(context)); + } + return new ConcatFunction(args2); + } + + public boolean references(QName var) + { + for (Iterator<Expr> i = args.iterator(); i.hasNext(); ) + { + if (i.next().references(var)) + { + return true; + } + } + return false; + } + + public String toString() + { + CPStringBuilder buf = new CPStringBuilder("concat("); + int len = args.size(); + for (int i = 0; i < len; i++) + { + if (i > 0) + { + buf.append(','); + } + buf.append(args.get(i)); + } + buf.append(')'); + return buf.toString(); + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/Constant.java b/libjava/classpath/gnu/xml/xpath/Constant.java new file mode 100644 index 000000000..5ed39cc05 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/Constant.java @@ -0,0 +1,98 @@ +/* Constant.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * Constant value (string literal or number). + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public final class Constant + extends Expr +{ + + final Object value; + + public Constant(Object value) + { + this.value = value; + } + + public Object evaluate(Node context, int pos, int len) + { + return value; + } + + public Expr clone(Object context) + { + return new Constant(value); + } + + public boolean references(QName var) + { + return false; + } + + public String toString() + { + String ret = value.toString(); + if (value instanceof String) + { + if (ret.indexOf('\'') == -1) + { + return '\'' + ret + '\''; + } + else + { + return '"' + ret + '"'; + } + } + if (value instanceof Double) + { + if (ret.endsWith(".0")) + { + ret = ret.substring(0, ret.length() - 2); + } + } + return ret; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/ContainsFunction.java b/libjava/classpath/gnu/xml/xpath/ContainsFunction.java new file mode 100644 index 000000000..473d2532f --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/ContainsFunction.java @@ -0,0 +1,93 @@ +/* ContainsFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>contains</code> function returns true if the first argument + * string contains the second argument string, and otherwise returns false. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class ContainsFunction + extends Expr +{ + + final Expr arg1; + final Expr arg2; + + ContainsFunction(List<Expr> args) + { + this(args.get(0), args.get(1)); + } + + ContainsFunction(Expr arg1, Expr arg2) + { + this.arg1 = arg1; + this.arg2 = arg2; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + Object val1 = arg1.evaluate(context, pos, len); + Object val2 = arg2.evaluate(context, pos, len); + String s1 = _string(context, val1); + String s2 = _string(context, val2); + return (s1.indexOf(s2) != -1) ? Boolean.TRUE : Boolean.FALSE; + } + + public Expr clone(Object context) + { + return new ContainsFunction(arg1.clone(context), arg2.clone(context)); + } + + public boolean references(QName var) + { + return (arg1.references(var) || arg2.references(var)); + } + + public String toString() + { + return "contains(" + arg1 + "," + arg2 + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/CountFunction.java b/libjava/classpath/gnu/xml/xpath/CountFunction.java new file mode 100644 index 000000000..e1892a058 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/CountFunction.java @@ -0,0 +1,89 @@ +/* CountFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.Collection; +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>count</code> function returns the number of nodes in the + * argument node-set. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class CountFunction + extends Expr +{ + + final Expr arg; + + CountFunction(List<Expr> args) + { + this(args.get(0)); + } + + CountFunction(Expr arg) + { + this.arg = arg; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + Object val = arg.evaluate(context, pos, len); + return new Double((double) ((Collection<?>) val).size()); + } + + public Expr clone(Object context) + { + return new CountFunction(arg.clone(context)); + } + + public boolean references(QName var) + { + return arg.references(var); + } + + public String toString() + { + return "count(" + arg + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/DocumentOrderComparator.java b/libjava/classpath/gnu/xml/xpath/DocumentOrderComparator.java new file mode 100644 index 000000000..c4471c120 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/DocumentOrderComparator.java @@ -0,0 +1,57 @@ +/* DocumentOrderComparator.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.Comparator; +import org.w3c.dom.Node; + +/** + * Sorts nodes into document order. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class DocumentOrderComparator + implements Comparator<Node> +{ + + public int compare(Node n1, Node n2) + { + return (int) n1.compareDocumentPosition(n2); + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/EqualityExpr.java b/libjava/classpath/gnu/xml/xpath/EqualityExpr.java new file mode 100644 index 000000000..133e1ff20 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/EqualityExpr.java @@ -0,0 +1,274 @@ +/* EqualityExpr.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.Collection; +import java.util.Iterator; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * Boolean equality expression. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class EqualityExpr + extends Expr +{ + + final Expr lhs; + final Expr rhs; + final boolean invert; + + EqualityExpr(Expr lhs, Expr rhs, boolean invert) + { + this.lhs = lhs; + this.rhs = rhs; + this.invert = invert; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + boolean val = evaluateImpl(context, pos, len); + if (invert) + { + return val ? Boolean.FALSE : Boolean.TRUE; + } + else + { + return val ? Boolean.TRUE : Boolean.FALSE; + } + } + + private boolean evaluateImpl(Node context, int pos, int len) + { + Object left = lhs.evaluate(context, pos, len); + Object right = rhs.evaluate(context, pos, len); + + /* + * If both objects to be compared are node-sets, then the comparison + * will be true if and only if there is a node in the first node-set and + * a node in the second node-set such that the result of performing the + * comparison on the string-values of the two nodes is true. + */ + boolean flns = left instanceof Collection; + boolean frns = right instanceof Collection; + if (flns && frns) + { + /* Suppression is safe, as we know context produces Collection<Node> */ + @SuppressWarnings("unchecked") + Collection<Node> lns = (Collection<Node>) left; + @SuppressWarnings("unchecked") + Collection<Node> rns = (Collection<Node>) right; + if (lns.isEmpty()) + { + return false; + } + boolean all = true; + for (Node ltest : lns) + { + for (Node rtest : rns) + { + if (ltest == rtest || ltest.equals(rtest)) + { + // much shorter + if (!invert) + { + return true; + } + } + else if (stringValue(ltest).equals(stringValue(rtest))) + { + if (!invert) + { + return true; + } + } + else + { + all = false; + } + } + } + return all; + } + /* + * If one object to be compared is a node-set and the other is a number, + * then the comparison will be true if and only if there is a node in + * the node-set such that the result of performing the comparison on the + * number to be compared and on the result of converting the + * string-value of that node to a number using the number function is + * true. + */ + boolean fln = left instanceof Double; + boolean frn = right instanceof Double; + if ((flns && frn) || (frns && fln)) + { + /* Suppression is safe, as we know context produces Collection<Node> */ + @SuppressWarnings("unchecked") + Collection<Node> ns = flns ? (Collection<Node>) left : (Collection<Node>) right; + double n = fln ? ((Double) left).doubleValue() : + ((Double) right).doubleValue(); + boolean all = true; + for (Node test : ns) + { + double nn = _number(context, stringValue(test)); + if (nn == n) + { + if (!invert) + { + return true; + } + } + else + { + all = false; + } + } + return invert ? all : false; + } + /* + * If one object to be compared is a node-set and the other is a + * string, then the comparison will be true if and only if there is a + * node in the node-set such that the result of performing the + * comparison on the string-value of the node and the other string is + * true. + */ + boolean fls = left instanceof String; + boolean frs = right instanceof String; + if ((flns && frs) || (frns && fls)) + { + /* Suppression is safe, as we know context produces Collection<Node> */ + @SuppressWarnings("unchecked") + Collection<Node> ns = flns ? (Collection<Node>) left : (Collection<Node>) right; + String s = fls ? (String) left : (String) right; + boolean all = true; + for (Node test : ns) + { + if (stringValue(test).equals(s)) + { + if (!invert) + { + return true; + } + } + else + { + all = false; + } + } + return invert ? all : false; + } + /* + * If one object to be compared is a node-set and the other is a + * boolean, then the comparison will be true if and only if the result + * of performing the comparison on the boolean and on the result of + * converting the node-set to a boolean using the boolean function is + * true. + */ + boolean flb = left instanceof Boolean; + boolean frb = right instanceof Boolean; + if ((flns && frb) || (frns && flb)) + { + /* Suppression is safe, as we know context produces Collection<Node> */ + @SuppressWarnings("unchecked") + Collection<Node> ns = flns ? (Collection<Node>) left : (Collection<Node>) right; + boolean b = flb ? ((Boolean) left).booleanValue() : + ((Boolean) right).booleanValue(); + return _boolean(context, ns) == b; + } + /* + * If at least one object to be compared is a boolean, then each object + * to be compared is converted to a boolean as if by applying the + * boolean function. + */ + if (flb || frb) + { + boolean lb = flb ? ((Boolean) left).booleanValue() : + _boolean(context, left); + boolean rb = frb ? ((Boolean) right).booleanValue() : + _boolean(context, right); + return lb == rb; + } + /* + * Otherwise, if at least one object to be compared is + * a number, then each object to be compared is converted to a number as + * if by applying the number function. + */ + if (fln || frn) + { + double ln = fln ? ((Double) left).doubleValue() : + _number(context, left); + double rn = frn ? ((Double) right).doubleValue() : + _number(context, right); + return ln == rn; + } + /* + * Otherwise, both objects to be + * compared are converted to strings as if by applying the string + * function. + */ + String ls = fls ? (String) left : _string(context, left); + String rs = frs ? (String) right : _string(context, right); + return ls.equals(rs); + } + + public Expr clone(Object context) + { + return new EqualityExpr(lhs.clone(context), rhs.clone(context), invert); + } + + public boolean references(QName var) + { + return (lhs.references(var) || rhs.references(var)); + } + + public String toString() + { + if (invert) + { + return lhs + " != " + rhs; + } + else + { + return lhs + " = " + rhs; + } + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/Expr.java b/libjava/classpath/gnu/xml/xpath/Expr.java new file mode 100644 index 000000000..0e98f43f5 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/Expr.java @@ -0,0 +1,549 @@ +/* Expr.java -- + Copyright (C) 2004,2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import gnu.java.lang.CPStringBuilder; + +import java.io.IOException; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Set; +import java.util.StringTokenizer; +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * An XPath expression. + * This can be evaluated in the context of a node to produce a result. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public abstract class Expr + implements XPathExpression +{ + + protected static final Comparator<Node> documentOrderComparator = + new DocumentOrderComparator(); + + protected static final DecimalFormat decimalFormat = + new DecimalFormat("####################################################" + + ".####################################################", + new DecimalFormatSymbols(Locale.US)); + + static class ExprNodeSet implements NodeList + { + + private ArrayList<Node> list; + + ExprNodeSet(Collection<Node> collection) + { + if (collection instanceof ArrayList) + list = (ArrayList<Node>) collection; + else + list = new ArrayList<Node>(collection); + } + + public int getLength() + { + return list.size(); + } + + public Node item(int index) + { + try + { + return list.get(index); + } + catch (ArrayIndexOutOfBoundsException e) + { + return null; + } + } + + } + + public Object evaluate(Object item, QName returnType) + throws XPathExpressionException + { + Object ret = null; + Node context = null; + if (item instanceof Node) + { + context = (Node) item; + ret = evaluate(context, 1, 1); + if (XPathConstants.STRING == returnType && + !(ret instanceof String)) + { + ret = _string(context, ret); + } + else if (XPathConstants.NUMBER == returnType && + !(ret instanceof Double)) + { + ret = new Double(_number(context, ret)); + } + else if (XPathConstants.BOOLEAN == returnType && + !(ret instanceof Boolean)) + { + ret = _boolean(context, ret) ? Boolean.TRUE : Boolean.FALSE; + } + else if (XPathConstants.NODE == returnType) + { + if (ret instanceof Collection) + { + /* Suppression is safe, as we know context + produces Collection<Node> */ + @SuppressWarnings("unchecked") + Collection<Node> ns = (Collection<Node>) ret; + switch (ns.size()) + { + case 0: + ret = null; + break; + case 1: + ret = ns.iterator().next(); + break; + default: + throw new XPathExpressionException("multiple nodes in node-set"); + } + } + else if (ret != null) + { + throw new XPathExpressionException("return value is not a node-set"); + } + } + else if (XPathConstants.NODESET == returnType) + { + if (ret != null && !(ret instanceof Collection)) + { + throw new XPathExpressionException("return value is not a node-set"); + } + if (ret != null) + { + /* Suppression is safe, as we know context produces Collection<Node> */ + @SuppressWarnings("unchecked") + Collection<Node> nodes = (Collection<Node>) ret; + ret = new ExprNodeSet(nodes); + } + } + } + return ret; + } + + public String evaluate(Object item) + throws XPathExpressionException + { + return (String) evaluate(item, XPathConstants.STRING); + } + + public Object evaluate(InputSource source, QName returnType) + throws XPathExpressionException + { + try + { + DocumentBuilderFactory factory = + new gnu.xml.dom.JAXPFactory(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(source); + return evaluate(doc, returnType); + } + catch (ParserConfigurationException e) + { + throw new XPathExpressionException(e); + } + catch (SAXException e) + { + throw new XPathExpressionException(e); + } + catch (IOException e) + { + throw new XPathExpressionException(e); + } + } + + public String evaluate(InputSource source) + throws XPathExpressionException + { + return (String) evaluate(source, XPathConstants.STRING); + } + + public abstract Object evaluate(Node context, int pos, int len); + + public abstract Expr clone(Object context); + + public abstract boolean references(QName var); + + /* -- 4.1 Node Set Functions -- */ + + /** + * The id function selects elements by their unique ID. + * When the argument to id is of type node-set, then the result is + * the union of the result of applying id to the string-value of each of + * the nodes in the argument node-set. When the argument to id is of any + * other type, the argument is converted to a string as if by a call to + * the string function; the string is split into a whitespace-separated + * list of tokens (whitespace is any sequence of characters matching the + * production S); the result is a node-set containing the elements in the + * same document as the context node that have a unique ID equal to any of + * the tokens in the list. + */ + public static Collection<Node> _id(Node context, Object object) + { + Set<Node> ret = new HashSet<Node>(); + if (object instanceof Collection) + { + /* Suppression is safe, as the iteration will check each value is a Node */ + @SuppressWarnings("unchecked") + Collection<Node> nodeSet = (Collection<Node>) object; + for (Iterator<Node> i = nodeSet.iterator(); i.hasNext(); ) + { + String string = stringValue(i.next()); + ret.addAll(_id (context, string)); + } + } + else + { + Document doc = (context instanceof Document) ? (Document) context : + context.getOwnerDocument(); + String string = _string(context, object); + StringTokenizer st = new StringTokenizer(string, " \t\r\n"); + while (st.hasMoreTokens()) + { + Node element = doc.getElementById(st.nextToken()); + if (element != null) + { + ret.add(element); + } + } + } + return ret; + } + + /** + * The local-name function returns the local part of the expanded-name of + * the node in the argument node-set that is first in document order. If + * the argument node-set is empty or the first node has no expanded-name, + * an empty string is returned. If the argument is omitted, it defaults to + * a node-set with the context node as its only member. + */ + public static String _local_name(Node context, Collection<Node> nodeSet) + { + if (nodeSet == null || nodeSet.isEmpty()) + return ""; + Node node = firstNode(nodeSet); + String ret = node.getLocalName(); + return (ret == null) ? "" : ret; + } + + /** + * The namespace-uri function returns the namespace URI of the + * expanded-name of the node in the argument node-set that is first in + * document order. If the argument node-set is empty, the first node has + * no expanded-name, or the namespace URI of the expanded-name is null, an + * empty string is returned. If the argument is omitted, it defaults to a + * node-set with the context node as its only member. + */ + public static String _namespace_uri(Node context, Collection<Node> nodeSet) + { + if (nodeSet == null || nodeSet.isEmpty()) + return ""; + Node node = firstNode(nodeSet); + String ret = node.getNamespaceURI(); + return (ret == null) ? "" : ret; + } + + /** + * The name function returns a string containing a QName representing the + * expanded-name of the node in the argument node-set that is first in + * document order. The QName must represent the expanded-name with respect + * to the namespace declarations in effect on the node whose expanded-name + * is being represented. Typically, this will be the QName that occurred + * in the XML source. This need not be the case if there are namespace + * declarations in effect on the node that associate multiple prefixes + * with the same namespace. However, an implementation may include + * information about the original prefix in its representation of nodes; + * in this case, an implementation can ensure that the returned string is + * always the same as the QName used in the XML source. If the argument + * node-set is empty or the first node has no expanded-name, an empty + * string is returned. If the argument it omitted, it defaults to a + * node-set with the context node as its only member. + */ + public static String _name(Node context, Collection<Node> nodeSet) + { + if (nodeSet == null || nodeSet.isEmpty()) + return ""; + Node node = firstNode(nodeSet); + String ret = null; + switch (node.getNodeType()) + { + case Node.ATTRIBUTE_NODE: + case Node.ELEMENT_NODE: + case Node.PROCESSING_INSTRUCTION_NODE: + ret = node.getNodeName(); + } + return (ret == null) ? "" : ret; + } + + /** + * Returns the first node in the set in document order. + */ + static Node firstNode(Collection<Node> nodeSet) + { + List<Node> list = new ArrayList<Node>(nodeSet); + Collections.sort(list, documentOrderComparator); + return list.get(0); + } + + /* -- 4.2 String Functions -- */ + + /** + * Implementation of the XPath <code>string</code> function. + */ + public static String _string(Node context, Object object) + { + if (object == null) + { + return stringValue(context); + } + if (object instanceof String) + { + return (String) object; + } + if (object instanceof Boolean) + { + return object.toString(); + } + if (object instanceof Double) + { + double d = ((Double) object).doubleValue(); + if (Double.isNaN(d)) + { + return "NaN"; + } + else if (d == 0.0d) + { + return "0"; + } + else if (Double.isInfinite(d)) + { + if (d < 0) + { + return "-Infinity"; + } + else + { + return "Infinity"; + } + } + else + { + String ret = decimalFormat.format(d); + if (ret.endsWith (".0")) + { + ret = ret.substring(0, ret.length() - 2); + } + return ret; + } + } + if (object instanceof Collection) + { + /* Suppression is safe, as we fail immediately if the + * first element is not a Node and don't use the rest */ + @SuppressWarnings("unchecked") + Collection<Node> nodeSet = (Collection<Node>) object; + if (nodeSet.isEmpty()) + { + return ""; + } + Node node = firstNode(nodeSet); + return stringValue(node); + } + throw new IllegalArgumentException(object.toString()); + } + + /* -- 4.3 Boolean Functions -- */ + + /** + * Implementation of the XPath <code>boolean</code> function. + */ + public static boolean _boolean(Node context, Object object) + { + if (object instanceof Boolean) + { + return ((Boolean) object).booleanValue(); + } + if (object instanceof Double) + { + Double value = (Double) object; + if (value.isNaN()) + return false; + return value.doubleValue() != 0.0; + } + if (object instanceof String) + { + return ((String) object).length() != 0; + } + if (object instanceof Collection) + { + return ((Collection<?>) object).size() != 0; + } + return false; // TODO user defined types + } + + /* -- 4.4 Number Functions -- */ + + /** + * Implementation of the XPath <code>number</code> function. + */ + public static double _number(Node context, Object object) + { + if (object == null) + { + object = Collections.singleton(context); + } + if (object instanceof Double) + { + return ((Double) object).doubleValue(); + } + if (object instanceof Boolean) + { + return ((Boolean) object).booleanValue() ? 1.0 : 0.0; + } + if (object instanceof Collection) + { + /* Suppression is safe, as we fail immediately if one + * of the elements is not a Node */ + @SuppressWarnings("unchecked") + Collection<Node> nodeSet = (Collection<Node>) object; + // Convert node-set to string + object = stringValue(nodeSet); + } + if (object instanceof String) + { + String string = ((String) object).trim(); + try + { + return Double.parseDouble(string); + } + catch (NumberFormatException e) + { + return Double.NaN; + } + } + return Double.NaN; // TODO user-defined types + } + + /** + * Computes the XPath string-value of the specified node-set. + */ + public static String stringValue(Collection<Node> nodeSet) + { + CPStringBuilder buf = new CPStringBuilder(); + for (Iterator<Node> i = nodeSet.iterator(); i.hasNext(); ) + { + buf.append(stringValue(i.next())); + } + return buf.toString(); + } + + /** + * Computes the XPath string-value of the specified node. + */ + public static String stringValue(Node node) + { + return stringValue(node, false); + } + + static String stringValue(Node node, boolean elementMode) + { + switch (node.getNodeType()) + { + case Node.DOCUMENT_NODE: // 5.1 Root Node + case Node.DOCUMENT_FRAGMENT_NODE: + case Node.ELEMENT_NODE: // 5.2 Element Nodes + CPStringBuilder buf = new CPStringBuilder(); + for (Node ctx = node.getFirstChild(); ctx != null; + ctx = ctx.getNextSibling()) + { + buf.append(stringValue(ctx, true)); + } + return buf.toString(); + case Node.TEXT_NODE: // 5.7 Text Nodes + case Node.CDATA_SECTION_NODE: + return node.getNodeValue(); + case Node.ATTRIBUTE_NODE: // 5.3 Attribute Nodes + case Node.PROCESSING_INSTRUCTION_NODE: // 5.5 Processing Instruction + case Node.COMMENT_NODE: // 5.6 Comment Nodes + if (!elementMode) + { + return node.getNodeValue(); + } + default: + return ""; + } + } + + static int intValue(Object val) + { + if (val instanceof Double) + { + Double d = (Double) val; + return d.isNaN() ? 0 : d.intValue(); + } + else + return (int) Math.ceil(_number(null, val)); + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/FalseFunction.java b/libjava/classpath/gnu/xml/xpath/FalseFunction.java new file mode 100644 index 000000000..9a20f9163 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/FalseFunction.java @@ -0,0 +1,72 @@ +/* FalseFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>false</code> function returns false. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class FalseFunction + extends Expr +{ + + public Object evaluate(Node context, int pos, int len) + { + return Boolean.FALSE; + } + + public Expr clone(Object context) + { + return new FalseFunction(); + } + + public boolean references(QName var) + { + return false; + } + + public String toString() + { + return "false()"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/FloorFunction.java b/libjava/classpath/gnu/xml/xpath/FloorFunction.java new file mode 100644 index 000000000..ed61742a3 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/FloorFunction.java @@ -0,0 +1,90 @@ +/* FloorFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>floor</code> function returns the largest (closest to positive + * infinity) number that is not greater than the argument and that is an + * integer. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class FloorFunction + extends Expr +{ + + final Expr arg; + + FloorFunction(List<Expr> args) + { + this(args.get(0)); + } + + FloorFunction(Expr arg) + { + this.arg = arg; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + Object val = arg.evaluate(context, pos, len); + double n = _number(context, val); + return new Double(Math.floor(n)); + } + + public Expr clone(Object context) + { + return new FloorFunction(arg.clone(context)); + } + + public boolean references(QName var) + { + return arg.references(var); + } + + public String toString() + { + return "floor(" + arg + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/Function.java b/libjava/classpath/gnu/xml/xpath/Function.java new file mode 100644 index 000000000..f9eab2b73 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/Function.java @@ -0,0 +1,56 @@ +/* Function.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.List; + +/** + * Interface to be implemented by external functions that need to receive + * parameter values. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public interface Function +{ + + /** + * Sets the list of expressions to evaluate as parameter values. + */ + void setArguments(List<Expr> args); + +} diff --git a/libjava/classpath/gnu/xml/xpath/FunctionCall.java b/libjava/classpath/gnu/xml/xpath/FunctionCall.java new file mode 100644 index 000000000..977482a8f --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/FunctionCall.java @@ -0,0 +1,169 @@ +/* FunctionCall.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import gnu.java.lang.CPStringBuilder; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import javax.xml.namespace.QName; +import javax.xml.xpath.XPathFunction; +import javax.xml.xpath.XPathFunctionException; +import javax.xml.xpath.XPathFunctionResolver; +import org.w3c.dom.Node; + +/** + * Executes an XPath core or extension function. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public final class FunctionCall + extends Expr +{ + + final XPathFunctionResolver resolver; + final String name; + final List<Expr> args; + + public FunctionCall(XPathFunctionResolver resolver, String name) + { + this(resolver, name, null); + } + + public FunctionCall(XPathFunctionResolver resolver, String name, List<Expr> args) + { + this.resolver = resolver; + this.name = name; + if (args == null) + this.args = Collections.emptyList(); + else + this.args = args; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + if (resolver != null) + { + QName qname = QName.valueOf(name); + int arity = args.size(); + XPathFunction function = resolver.resolveFunction(qname, arity); + if (function != null) + { + //System.err.println("Calling "+toString()+" with "+values); + if (function instanceof Expr) + { + if (function instanceof Function) + { + ((Function) function).setArguments(args); + } + return ((Expr) function).evaluate(context, pos, len); + } + else + { + List<Object> values = new ArrayList<Object>(arity); + for (int i = 0; i < arity; i++) + { + Expr arg = (Expr) args.get(i); + values.add(arg.evaluate(context, pos, len)); + } + try + { + return function.evaluate(values); + } + catch (XPathFunctionException e) + { + e.printStackTrace(System.err); // FIXME + throw new RuntimeException(e.getMessage(), e); + } + } + } + } + throw new IllegalArgumentException("Invalid function call: " + + toString()); + } + + public Expr clone(Object context) + { + int len = args.size(); + List<Expr> args2 = new ArrayList<Expr>(len); + for (int i = 0; i < len; i++) + { + args2.add(args.get(i).clone(context)); + } + XPathFunctionResolver r = resolver; + if (context instanceof XPathFunctionResolver) + { + r = (XPathFunctionResolver) context; + } + return new FunctionCall(r, name, args2); + } + + public boolean references(QName var) + { + for (Iterator<Expr> i = args.iterator(); i.hasNext(); ) + { + if (i.next().references(var)) + { + return true; + } + } + return false; + } + + public String toString() + { + CPStringBuilder buf = new CPStringBuilder(); + buf.append(name); + buf.append('('); + int len = args.size(); + for (int i = 0; i < len; i++) + { + if (i > 0) + { + buf.append(','); + } + buf.append(args.get(i)); + } + buf.append(')'); + return buf.toString(); + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/IdFunction.java b/libjava/classpath/gnu/xml/xpath/IdFunction.java new file mode 100644 index 000000000..7b6c6ac25 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/IdFunction.java @@ -0,0 +1,103 @@ +/* IdFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.Collection; +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>id</code> function selects elements by their unique ID. + * When the argument to id is of type node-set, then the result is + * the union of the result of applying id to the string-value of each of the + * nodes in the argument node-set. When the argument to id is of any other + * type, the argument is converted to a string as if by a call to the string + * function; the string is split into a whitespace-separated list of tokens + * (whitespace is any sequence of characters matching the production S); the + * result is a node-set containing the elements in the same document as the + * context node that have a unique ID equal to any of the tokens in the + * list. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public final class IdFunction + extends Pattern +{ + + final Expr arg; + + IdFunction(List<Expr> args) + { + this(args.get(0)); + } + + public IdFunction(Expr arg) + { + this.arg = arg; + } + + public boolean matches(Node context) + { + Object ret = evaluate(context, 1, 1); + return !((Collection<?>) ret).isEmpty(); + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + Object val = arg.evaluate(context, pos, len); + return _id(context, val); + } + + public Expr clone(Object context) + { + return new IdFunction(arg.clone(context)); + } + + public boolean references(QName var) + { + return arg.references(var); + } + + public String toString() + { + return "id(" + arg + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/LangFunction.java b/libjava/classpath/gnu/xml/xpath/LangFunction.java new file mode 100644 index 000000000..5a8d32fc0 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/LangFunction.java @@ -0,0 +1,123 @@ +/* LangFunction.java -- + Copyright (C) 2004,2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * The <code>lang</code> function returns true or false depending on whether + * the language of the context node as specified by xml:lang attributes is + * the same as or is a sublanguage of the language specified by the argument + * string. The language of the context node is determined by the value of + * the xml:lang attribute on the context node, or, if the context node has + * no xml:lang attribute, by the value of the xml:lang attribute on the + * nearest ancestor of the context node that has an xml:lang attribute. If + * there is no such attribute, then lang returns false. If there is such an + * attribute, then lang returns true if the attribute value is equal to the + * argument ignoring case, or if there is some suffix starting with - such + * that the attribute value is equal to the argument ignoring that suffix of + * the attribute value and ignoring case. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class LangFunction + extends Expr +{ + + final Expr arg; + + LangFunction(List<Expr> args) + { + this(args.get(0)); + } + + LangFunction(Expr arg) + { + this.arg = arg; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + Object val = arg.evaluate(context, pos, len); + String lang = _string(context, val); + String clang = getLang(context); + while (clang == null && context != null) + { + context = context.getParentNode(); + clang = getLang(context); + } + boolean ret = (clang == null) ? false : + clang.toLowerCase().startsWith(lang.toLowerCase()); + return ret ? Boolean.TRUE : Boolean.FALSE; + } + + String getLang(Node node) + { + while (node != null) + { + if (node.getNodeType() == Node.ELEMENT_NODE) + { + String lang = ((Element) node).getAttribute("xml:lang"); + if (lang != null) + return lang; + } + node = node.getParentNode(); + } + return null; + } + + public Expr clone(Object context) + { + return new IdFunction(arg.clone(context)); + } + + public boolean references(QName var) + { + return arg.references(var); + } + + public String toString() + { + return "lang(" + arg + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/LastFunction.java b/libjava/classpath/gnu/xml/xpath/LastFunction.java new file mode 100644 index 000000000..51f988f3c --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/LastFunction.java @@ -0,0 +1,73 @@ +/* LastFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>last</code> function returns a number equal to the context + * size from the expression evaluation context. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class LastFunction + extends Expr +{ + + public Object evaluate(Node context, int pos, int len) + { + return new Double((double) len); + } + + public Expr clone(Object context) + { + return new LastFunction(); + } + + public boolean references(QName var) + { + return false; + } + + public String toString() + { + return "last()"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/LocalNameFunction.java b/libjava/classpath/gnu/xml/xpath/LocalNameFunction.java new file mode 100644 index 000000000..d829075c7 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/LocalNameFunction.java @@ -0,0 +1,98 @@ +/* LocalNameFunction.java -- + Copyright (C) 2004,2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>local-name</code> function returns the local part of the + * expanded-name of the node in the argument node-set that is first in + * document order. + * If the argument node-set is empty or the first node has no expanded-name, + * an empty string is returned. If the argument is omitted, it defaults to a + * node-set with the context node as its only member. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class LocalNameFunction + extends Expr +{ + + final Expr arg; + + LocalNameFunction(List<Expr> args) + { + this(args.size() > 0 ? args.get(0) : null); + } + + LocalNameFunction(Expr arg) + { + this.arg = arg; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + /* Suppression is safe, as we know context produces Collection<Node> */ + @SuppressWarnings("unchecked") + Collection<Node> val = (arg == null) ? Collections.singleton(context) : + (Collection<Node>) arg.evaluate(context, pos, len); + return _local_name(context, val); + } + + public Expr clone(Object context) + { + return new LocalNameFunction((arg == null) ? null : + arg.clone(context)); + } + + public boolean references(QName var) + { + return (arg == null) ? false : arg.references(var); + } + + public String toString() + { + return (arg == null) ? "local-name()" : "local-name(" + arg + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/NameFunction.java b/libjava/classpath/gnu/xml/xpath/NameFunction.java new file mode 100644 index 000000000..7db0be531 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/NameFunction.java @@ -0,0 +1,109 @@ +/* NameFunction.java -- + Copyright (C) 2004,2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>name</code> function returns a string containing a QName + * representing the expanded-name of the node in the argument node-set that + * is first in document order. The QName must represent the expanded-name + * with respect to the namespace declarations in effect on the node whose + * expanded-name is being represented. Typically, this will be the QName + * that occurred in the XML source. This need not be the case if there are + * namespace declarations in effect on the node that associate multiple + * prefixes with the same namespace. However, an implementation may include + * information about the original prefix in its representation of nodes; in + * this case, an implementation can ensure that the returned string is + * always the same as the QName used in the XML source. If the argument + * node-set is empty or the first node has no expanded-name, an empty string + * is returned. If the argument it omitted, it defaults to a node-set with + * the context node as its only member. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class NameFunction + extends Expr +{ + + final Expr arg; + + NameFunction(List<Expr> args) + { + this(args.size() > 0 ? args.get(0) : null); + } + + NameFunction(Expr arg) + { + this.arg = arg; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + /* Suppression is safe, as we know context produces Collection<Node> */ + @SuppressWarnings("unchecked") + Collection<Node> val = (arg == null) ? Collections.singleton(context) : + (Collection<Node>) arg.evaluate(context, pos, len); + return _name(context, val); + } + + @Override + public Expr clone(Object context) + { + return new NameFunction((arg == null) ? null : + arg.clone(context)); + } + + @Override + public boolean references(QName var) + { + return (arg == null) ? false : arg.references(var); + } + + @Override + public String toString() + { + return (arg == null) ? "name()" : "name(" + arg + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/NameTest.java b/libjava/classpath/gnu/xml/xpath/NameTest.java new file mode 100644 index 000000000..8bd06bd3b --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/NameTest.java @@ -0,0 +1,143 @@ +/* NameTest.java -- + Copyright (C) 2004,2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import javax.xml.XMLConstants; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * Tests whether a node has the specified name. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public final class NameTest + extends Test +{ + + final QName qName; + final boolean anyLocalName; + final boolean any; + + public NameTest(QName qName, boolean anyLocalName, boolean any) + { + this.anyLocalName = anyLocalName; + this.any = any; + this.qName = qName; + } + + public boolean matchesAny() + { + return any; + } + + public boolean matchesAnyLocalName() + { + return anyLocalName; + } + + public boolean matches(Node node, int pos, int len) + { + switch (node.getNodeType()) + { + case Node.ATTRIBUTE_NODE: + // Do not match namespace attributes + String uri = node.getNamespaceURI(); + if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(uri) || + XMLConstants.XMLNS_ATTRIBUTE.equals(node.getPrefix()) || + XMLConstants.XMLNS_ATTRIBUTE.equals(node.getNodeName())) + { + return false; + } + // Fall through + case Node.ELEMENT_NODE: + break; + default: + return false; + } + if (any) + return true; + String uri = qName.getNamespaceURI(); + String nodeUri = node.getNamespaceURI(); + if (!equal(uri, nodeUri)) + return false; + if (anyLocalName) + return true; + String localName = qName.getLocalPart(); + String nodeLocalName = getLocalName(node); + return (localName.equals(nodeLocalName)); + } + + static String getLocalName(Node node) + { + String localName = node.getLocalName(); + if (localName == null) + { + localName = node.getNodeName(); + int ci = localName.indexOf(':'); + if (ci != -1) + localName = localName.substring(ci + 1); + } + return localName; + } + + static boolean equal(String s1, String s2) + { + return (((s1 == null || s1.length() == 0) && + (s2 == null || s2.length() == 0)) || + s1 != null && s1.equals(s2)); + } + + public Test clone(Object context) + { + return new NameTest(qName, anyLocalName, any); + } + + public boolean references(QName var) + { + return false; + } + + public String toString () + { + if (any) + return "*"; + return qName.toString(); + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/NamespaceTest.java b/libjava/classpath/gnu/xml/xpath/NamespaceTest.java new file mode 100644 index 000000000..2f4fec179 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/NamespaceTest.java @@ -0,0 +1,120 @@ +/* NamespaceTest.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import javax.xml.XMLConstants; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * Tests whether a namespace attribute has the specified name. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public final class NamespaceTest + extends Test +{ + + final QName qName; + final boolean anyLocalName; + final boolean any; + + public NamespaceTest(QName qName, boolean anyLocalName, boolean any) + { + this.anyLocalName = anyLocalName; + this.any = any; + this.qName = qName; + } + + public boolean matchesAny() + { + return any; + } + + public boolean matchesAnyLocalName() + { + return anyLocalName; + } + + public boolean matches(Node node, int pos, int len) + { + switch (node.getNodeType()) + { + case Node.ATTRIBUTE_NODE: + // Only match namespace attributes + String uri = node.getNamespaceURI(); + if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(uri) || + XMLConstants.XMLNS_ATTRIBUTE.equals(node.getPrefix()) || + XMLConstants.XMLNS_ATTRIBUTE.equals(node.getNodeName())) + break; + // Fall through + default: + // Only process namespace attributes + return false; + } + if (any) + return true; + String uri = qName.getNamespaceURI(); + String nodeUri = node.getNamespaceURI(); + if (!NameTest.equal(uri, nodeUri)) + return false; + if (anyLocalName) + return true; + String localName = qName.getLocalPart(); + String nodeLocalName = NameTest.getLocalName(node); + return (localName.equals(nodeLocalName)); + } + + public Test clone(Object context) + { + return new NamespaceTest(qName, anyLocalName, any); + } + + public boolean references(QName var) + { + return false; + } + + public String toString () + { + if (any) + return "*"; + return qName.toString(); + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/NamespaceUriFunction.java b/libjava/classpath/gnu/xml/xpath/NamespaceUriFunction.java new file mode 100644 index 000000000..4972b0607 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/NamespaceUriFunction.java @@ -0,0 +1,98 @@ +/* NamespaceUriFunction.java -- + Copyright (C) 2004,2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>namespace-uri</code> function returns the namespace URI of the + * expanded-name of the node in the argument node-set that is first in + * document order. If the argument node-set is empty, the first node has no + * expanded-name, or the namespace URI of the expanded-name is null, an + * empty string is returned. If the argument is omitted, it defaults to a + * node-set with the context node as its only member. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class NamespaceUriFunction + extends Expr +{ + + final Expr arg; + + NamespaceUriFunction(List<Expr> args) + { + this(args.size() > 0 ? args.get(0) : null); + } + + NamespaceUriFunction(Expr arg) + { + this.arg = arg; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + /* Suppression is safe, as we know context produces Collection<Node> */ + @SuppressWarnings("unchecked") + Collection<Node> val = (arg == null) ? Collections.singleton(context) : + (Collection<Node>) arg.evaluate(context, pos, len); + return _namespace_uri(context, val); + } + + public Expr clone(Object context) + { + return new NamespaceUriFunction((arg == null) ? null : + arg.clone(context)); + } + + public boolean references(QName var) + { + return (arg == null) ? false : arg.references(var); + } + + public String toString() + { + return (arg == null) ? "namespace-uri()" : "namespace-uri(" + arg + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/NegativeExpr.java b/libjava/classpath/gnu/xml/xpath/NegativeExpr.java new file mode 100644 index 000000000..215ef3fa9 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/NegativeExpr.java @@ -0,0 +1,81 @@ +/* NegativeExpr.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * Unary negative. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class NegativeExpr + extends Expr +{ + + final Expr expr; + + NegativeExpr(Expr expr) + { + this.expr = expr; + } + + public Object evaluate(Node context, int pos, int len) + { + Object val = expr.evaluate(context, pos, len); + double n = _number(context, val); + return new Double(-n); + } + + public Expr clone(Object context) + { + return new NegativeExpr(expr.clone(context)); + } + + public boolean references(QName var) + { + return expr.references(var); + } + + public String toString() + { + return "-" + expr; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/NodeTypeTest.java b/libjava/classpath/gnu/xml/xpath/NodeTypeTest.java new file mode 100644 index 000000000..43e26994b --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/NodeTypeTest.java @@ -0,0 +1,141 @@ +/* NodeTypeTest.java -- + Copyright (C) 2004,2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import javax.xml.namespace.QName; +import org.w3c.dom.Node; +import org.w3c.dom.ProcessingInstruction; + +/** + * Tests whether a node is of a given type. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public final class NodeTypeTest + extends Test +{ + + final short type; + final String data; + + public NodeTypeTest(short type) + { + this(type, null); + } + + public NodeTypeTest(short type, String data) + { + this.type = type; + this.data = data; + } + + public short getNodeType() + { + return type; + } + + public String getData() + { + return data; + } + + public boolean matches(Node node, int pos, int len) + { + short nodeType = node.getNodeType(); + switch (nodeType) + { + case Node.ELEMENT_NODE: + case Node.ATTRIBUTE_NODE: + case Node.TEXT_NODE: + case Node.CDATA_SECTION_NODE: + case Node.COMMENT_NODE: + case Node.DOCUMENT_NODE: + if (type > 0) + { + if (nodeType != type) + return false; + } + return true; + case Node.PROCESSING_INSTRUCTION_NODE: + if (type > 0) + { + if (nodeType != type) + return false; + if (data != null && + !data.equals(((ProcessingInstruction) node).getTarget())) + return false; + } + return true; + default: + // Not part of XPath data model + return false; + } + } + + public Test clone(Object context) + { + return new NodeTypeTest(type, data); + } + + public boolean references(QName var) + { + return false; + } + + public String toString() + { + switch (type) + { + case 0: + return "node()"; + case Node.TEXT_NODE: + return "text()"; + case Node.COMMENT_NODE: + return "comment()"; + case Node.PROCESSING_INSTRUCTION_NODE: + if (data != null) + { + return "processing-instruction('" + data + "')"; + } + return "processing-instruction()"; + default: + throw new IllegalStateException(); + } + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/NormalizeSpaceFunction.java b/libjava/classpath/gnu/xml/xpath/NormalizeSpaceFunction.java new file mode 100644 index 000000000..6d728d9e7 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/NormalizeSpaceFunction.java @@ -0,0 +1,108 @@ +/* NormalizeSpaceFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import gnu.java.lang.CPStringBuilder; + +import java.util.List; +import java.util.StringTokenizer; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>normalize-space</code> function returns the argument string + * with whitespace normalized by stripping leading and trailing whitespace + * and replacing sequences of whitespace characters by a single space. + * Whitespace characters are the same as those allowed by the S production + * in XML. If the argument is omitted, it defaults to the context node + * converted to a string, in other words the string-value of the context + * node. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class NormalizeSpaceFunction + extends Expr +{ + + final Expr arg; + + NormalizeSpaceFunction(List<Expr> args) + { + this(args.get(0)); + } + + NormalizeSpaceFunction(Expr arg) + { + this.arg = arg; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + Object val = (arg == null) ? null : arg.evaluate(context, pos, len); + String s = _string(context, val); + StringTokenizer st = new StringTokenizer(s, " \t\r\n"); + CPStringBuilder buf = new CPStringBuilder(); + if (st.hasMoreTokens()) + { + buf.append(st.nextToken()); + while (st.hasMoreTokens()) + { + buf.append(' '); + buf.append(st.nextToken()); + } + } + return buf.toString(); + } + + public Expr clone(Object context) + { + return new NormalizeSpaceFunction(arg.clone(context)); + } + + public boolean references(QName var) + { + return (arg == null) ? false : arg.references(var); + } + + public String toString() + { + return (arg == null) ? "normalize-space()" : "normalize-space(" + arg + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/NotFunction.java b/libjava/classpath/gnu/xml/xpath/NotFunction.java new file mode 100644 index 000000000..a7c20a0c1 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/NotFunction.java @@ -0,0 +1,88 @@ +/* NotFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>not</code> function returns true if its argument is false, + * and false otherwise. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class NotFunction + extends Expr +{ + + final Expr arg; + + NotFunction(List<Expr> args) + { + this(args.get(0)); + } + + NotFunction(Expr arg) + { + this.arg = arg; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + Object val = arg.evaluate(context, pos, len); + return _boolean(context, val) ? Boolean.FALSE : Boolean.TRUE; + } + + public Expr clone(Object context) + { + return new NotFunction(arg.clone(context)); + } + + public boolean references(QName var) + { + return arg.references(var); + } + + public String toString() + { + return "not(" + arg + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/NumberFunction.java b/libjava/classpath/gnu/xml/xpath/NumberFunction.java new file mode 100644 index 000000000..08831020b --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/NumberFunction.java @@ -0,0 +1,103 @@ +/* NumberFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>number</code> function converts its argument to a number as + * follows: + * <ul> + * <li>a string that consists of optional whitespace followed by an optional + * minus sign followed by a Number followed by whitespace is converted to + * the IEEE 754 number that is nearest (according to the IEEE 754 + * round-to-nearest rule) to the mathematical value represented by the + * string; any other string is converted to NaN</li> + * <li>boolean true is converted to 1; boolean false is converted to 0</li> + * <li>a node-set is first converted to a string as if by a call to the + * string function and then converted in the same way as a string + * argument</li> + * <li>an object of a type other than the four basic types is converted to a + * number in a way that is dependent on that type</li> + * </ul> + * If the argument is omitted, it defaults to a node-set with the context + * node as its only member. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class NumberFunction + extends Expr +{ + + final Expr arg; + + NumberFunction(List<Expr> args) + { + this(args.size() > 0 ? args.get(0) : null); + } + + NumberFunction(Expr arg) + { + this.arg = arg; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + Object val = (arg == null) ? null : arg.evaluate(context, pos, len); + return new Double(_number(context, val)); + } + + public Expr clone(Object context) + { + return new NumberFunction(arg.clone(context)); + } + + public boolean references(QName var) + { + return arg.references(var); + } + + public String toString() + { + return "number(" + arg + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/OrExpr.java b/libjava/classpath/gnu/xml/xpath/OrExpr.java new file mode 100644 index 000000000..937dedf6a --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/OrExpr.java @@ -0,0 +1,87 @@ +/* OrExpr.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * Logical or. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public final class OrExpr + extends Expr +{ + + final Expr lhs; + final Expr rhs; + + public OrExpr(Expr lhs, Expr rhs) + { + this.lhs = lhs; + this.rhs = rhs; + } + + public Object evaluate(Node context, int pos, int len) + { + Object left = lhs.evaluate(context, pos, len); + if (_boolean(context, left)) + { + return Boolean.TRUE; + } + Object right = rhs.evaluate(context, pos, len); + return _boolean(context, right) ? Boolean.TRUE : Boolean.FALSE; + } + + public Expr clone(Object context) + { + return new OrExpr(lhs.clone(context), rhs.clone(context)); + } + + public boolean references(QName var) + { + return (lhs.references(var) || rhs.references(var)); + } + + public String toString() + { + return lhs + " or " + rhs; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/ParenthesizedExpr.java b/libjava/classpath/gnu/xml/xpath/ParenthesizedExpr.java new file mode 100644 index 000000000..e8ceb5aa5 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/ParenthesizedExpr.java @@ -0,0 +1,95 @@ +/* ParenthesizedExpr.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * Simple subexpression. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class ParenthesizedExpr + extends Expr +{ + + final Expr expr; + + ParenthesizedExpr(Expr expr) + { + this.expr = expr; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + Object ret = expr.evaluate(context, pos, len); + if (ret instanceof Collection) + { + /* Suppression is safe, as we know context produces + Collection<Node> */ + @SuppressWarnings("unchecked") + Collection<Node> nodes = (Collection<Node>) ret; + List<Node> list = new ArrayList<Node>(nodes); + Collections.sort(list, documentOrderComparator); + ret = list; + } + return ret; + } + + public Expr clone(Object context) + { + return new ParenthesizedExpr(expr.clone(context)); + } + + public boolean references(QName var) + { + return expr.references(var); + } + + public String toString() + { + return "(" + expr + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/Path.java b/libjava/classpath/gnu/xml/xpath/Path.java new file mode 100644 index 000000000..f19759567 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/Path.java @@ -0,0 +1,54 @@ +/* Path.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.Collection; +import org.w3c.dom.Node; + +/** + * An XPath path component expression. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +abstract class Path + extends Pattern +{ + + abstract Collection<Node> evaluate(Node context, Collection<Node> nodeSet); + +} diff --git a/libjava/classpath/gnu/xml/xpath/Pattern.java b/libjava/classpath/gnu/xml/xpath/Pattern.java new file mode 100644 index 000000000..ca03cda37 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/Pattern.java @@ -0,0 +1,53 @@ +/* Pattern.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import org.w3c.dom.Node; + +/** + * Interface implemented by expressions that can form part of XSL patterns. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public abstract class Pattern + extends Expr +{ + + public abstract boolean matches(Node context); + +} diff --git a/libjava/classpath/gnu/xml/xpath/PositionFunction.java b/libjava/classpath/gnu/xml/xpath/PositionFunction.java new file mode 100644 index 000000000..28ead3af0 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/PositionFunction.java @@ -0,0 +1,73 @@ +/* PositionFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>position</code> function returns a number equal to the context + * position from the expression evaluation context. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class PositionFunction + extends Expr +{ + + public Object evaluate(Node context, int pos, int len) + { + return new Double((double) pos); + } + + public Expr clone(Object context) + { + return new PositionFunction(); + } + + public boolean references(QName var) + { + return false; + } + + public String toString() + { + return "position()"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/Predicate.java b/libjava/classpath/gnu/xml/xpath/Predicate.java new file mode 100644 index 000000000..a02e22b94 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/Predicate.java @@ -0,0 +1,85 @@ +/* Predicate.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * Tests whether an expression matches against a given context node. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +class Predicate + extends Test +{ + + final Expr expr; + + Predicate(Expr expr) + { + this.expr = expr; + } + + public boolean matches(Node node, int pos, int len) + { + Object ret = expr.evaluate(node, pos, len); + if (ret instanceof Double) + { + // Same as [position() = x] + return ((Double) ret).intValue() == pos; + } + return Expr._boolean(node, expr.evaluate(node, pos, len)); + } + + public Test clone(Object context) + { + return new Predicate(expr.clone(context)); + } + + public boolean references(QName var) + { + return expr.references(var); + } + + public String toString() + { + return "[" + expr + "]"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/RelationalExpr.java b/libjava/classpath/gnu/xml/xpath/RelationalExpr.java new file mode 100644 index 000000000..ac79d5049 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/RelationalExpr.java @@ -0,0 +1,107 @@ +/* RelationalExpr.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * Numerical comparison expression. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class RelationalExpr + extends Expr +{ + + final Expr lhs; + final Expr rhs; + final boolean lt; + final boolean eq; + + RelationalExpr(Expr lhs, Expr rhs, boolean lt, boolean eq) + { + this.lhs = lhs; + this.rhs = rhs; + this.lt = lt; + this.eq = eq; + } + + public Object evaluate(Node context, int pos, int len) + { + Object left = lhs.evaluate(context, pos, len); + Object right = rhs.evaluate(context, pos, len); + double ln = _number(context, left); + double rn = _number(context, right); + if (eq && ln == rn) + { + return Boolean.TRUE; + } + if (lt) + { + if (ln < rn || Double.isInfinite(rn)) + { + return Boolean.TRUE; + } + } + else + { + if (ln > rn || Double.isInfinite(ln)) + { + return Boolean.TRUE; + } + } + return Boolean.FALSE; + } + + public Expr clone(Object context) + { + return new RelationalExpr(lhs.clone(context), rhs.clone(context), lt, eq); + } + + public boolean references(QName var) + { + return (lhs.references(var) || rhs.references(var)); + } + + public String toString() + { + return lhs + " " + (lt ? "<" : ">") + (eq ? "=" : "") + " " + rhs; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/Root.java b/libjava/classpath/gnu/xml/xpath/Root.java new file mode 100644 index 000000000..8eef3408f --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/Root.java @@ -0,0 +1,91 @@ +/* Root.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.Collection; +import java.util.Collections; +import java.util.Set; + +import javax.xml.namespace.QName; +import org.w3c.dom.Document; +import org.w3c.dom.Node; + +/** + * Expression that evaluates to the document root. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public final class Root + extends Path +{ + + public boolean matches(Node node) + { + return (node.getNodeType() == Node.DOCUMENT_NODE); + } + + public Object evaluate(Node context, int pos, int len) + { + Set<Node> emptySet = Collections.emptySet(); + return evaluate(context, emptySet); + } + + @Override + Collection<Node> evaluate(Node context, Collection<Node> ns) + { + Node doc = (context instanceof Document) ? context : + context.getOwnerDocument(); + return Collections.singleton(doc); + } + + public Expr clone(Object context) + { + return new Root(); + } + + public boolean references(QName var) + { + return false; + } + + public String toString() + { + return "/"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/RoundFunction.java b/libjava/classpath/gnu/xml/xpath/RoundFunction.java new file mode 100644 index 000000000..3b79e3e21 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/RoundFunction.java @@ -0,0 +1,97 @@ +/* RoundFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>round</code> function returns the number that is closest to the + * argument and that is an integer. If there are two such numbers, then the + * one that is closest to positive infinity is returned. If the argument is + * NaN, then NaN is returned. If the argument is positive infinity, then + * positive infinity is returned. If the argument is negative infinity, then + * negative infinity is returned. If the argument is positive zero, then + * positive zero is returned. If the argument is negative zero, then + * negative zero is returned. If the argument is less than zero, but greater + * than or equal to -0.5, then negative zero is returned. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class RoundFunction + extends Expr +{ + + final Expr arg; + + RoundFunction(List<Expr> args) + { + this(args.get(0)); + } + + RoundFunction(Expr arg) + { + this.arg = arg; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + Object val = arg.evaluate(context, pos, len); + double n = _number(context, val); + return (Double.isNaN(n) || Double.isInfinite(n)) ? + new Double(n) : new Double(Math.round(n)); + } + + public Expr clone(Object context) + { + return new RoundFunction(arg.clone(context)); + } + + public boolean references(QName var) + { + return arg.references(var); + } + + public String toString() + { + return "round(" + arg + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/Selector.java b/libjava/classpath/gnu/xml/xpath/Selector.java new file mode 100644 index 000000000..2146f26f5 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/Selector.java @@ -0,0 +1,503 @@ +/* Selector.java -- + Copyright (C) 2004,2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import gnu.java.lang.CPStringBuilder; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import javax.xml.XMLConstants; +import javax.xml.namespace.QName; +import org.w3c.dom.Attr; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; + +/** + * A single component of a location path. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public final class Selector + extends Path +{ + + public static final int ANCESTOR = 0; + public static final int ANCESTOR_OR_SELF = 1; + public static final int ATTRIBUTE = 2; + public static final int CHILD = 3; + public static final int DESCENDANT = 4; + public static final int DESCENDANT_OR_SELF = 5; + public static final int FOLLOWING = 6; + public static final int FOLLOWING_SIBLING = 7; + public static final int NAMESPACE = 8; + public static final int PARENT = 9; + public static final int PRECEDING = 10; + public static final int PRECEDING_SIBLING = 11; + public static final int SELF = 12; + + /** + * Axis to select nodes in. + */ + final int axis; + + /** + * List of tests to perform on candidates. + */ + final Test[] tests; + + public Selector(int axis, List<? extends Test> tests) + { + this.axis = axis; + int len = tests.size(); + this.tests = new Test[(len == 0) ? 1 : len]; + if (len > 0) + tests.toArray(this.tests); + else + this.tests[0] = new NodeTypeTest((short) 0); + if (axis == NAMESPACE && this.tests[0] instanceof NameTest) + { + NameTest nt = (NameTest) this.tests[0]; + this.tests[0] = new NamespaceTest(nt.qName, nt.anyLocalName, nt.any); + } + } + + /** + * Returns the list of tests to perform on candidates. + */ + public Test[] getTests() + { + return tests; + } + + public boolean matches(Node context) + { + // If called directly, selector is the top level of the path + return matches(context, + getContextPosition(context), + getContextSize(context)); + } + + boolean matches(Node context, int pos, int len) + { + short nodeType = context.getNodeType(); + switch (axis) + { + case CHILD: + if (nodeType == Node.ATTRIBUTE_NODE) + return false; + break; + case ATTRIBUTE: + case NAMESPACE: + if (nodeType != Node.ATTRIBUTE_NODE) + return false; + break; + case DESCENDANT_OR_SELF: + return true; + default: + return false; + } + for (int j = 0; j < tests.length && len > 0; j++) + { + Test test = tests[j]; + if (!test.matches(context, pos, len)) + return false; + } + return true; + } + + private int getContextPosition(Node ctx) + { + int pos = 1; + for (ctx = ctx.getPreviousSibling(); ctx != null; + ctx = ctx.getPreviousSibling()) + { + if (tests[0].matches(ctx, 1, 1)) + pos++; + } + return pos; + } + + private int getContextSize(Node ctx) + { + if (ctx.getNodeType() == Node.ATTRIBUTE_NODE) + { + Node owner = ((Attr) ctx).getOwnerElement(); + return owner.getAttributes().getLength(); + } + int count = 1; + Node sib = ctx.getPreviousSibling(); + for (; sib != null; sib = sib.getPreviousSibling()) + { + if (tests[0].matches(ctx, 1, 1)) + count++; + } + sib = ctx.getNextSibling(); + for (; sib != null; sib = sib.getNextSibling()) + { + if (tests[0].matches(ctx, 1, 1)) + count++; + } + return count; + } + + + @Override + public Object evaluate(Node context, int pos, int len) + { + Set<Node> acc = new LinkedHashSet<Node>(); + addCandidates(context, acc); + List<Node> candidates = new ArrayList<Node>(acc); + List<Node> ret = filterCandidates(candidates, false); + return ret; + } + + Collection<Node> evaluate(Node context, Collection<Node> ns) + { + Set<Node> acc = new LinkedHashSet<Node>(); + for (Iterator<Node> i = ns.iterator(); i.hasNext(); ) + addCandidates(i.next(), acc); + List<Node> candidates = new ArrayList<Node>(acc); + List<Node> ret = filterCandidates(candidates, true); + return ret; + } + + /** + * Filter the given list of candidates according to the node tests. + */ + List<Node> filterCandidates(List<Node> candidates, boolean cascade) + { + int len = candidates.size(); + int tlen = tests.length; + if (tlen > 0 && len > 0) + { + // Present the result of each successful generation to the next test + for (int j = 0; j < tlen && len > 0; j++) + { + Test test = tests[j]; + List<Node> successful = new ArrayList<Node>(len); + for (int i = 0; i < len; i++) + { + Node node = candidates.get(i); + if (cascade) + { + // Documents and DocumentFragments should be considered + // if part of a location path where the axis involves + // the SELF concept + short nodeType = node.getNodeType(); + if ((nodeType == Node.DOCUMENT_NODE || + nodeType == Node.DOCUMENT_FRAGMENT_NODE) && + (axis == DESCENDANT_OR_SELF || + axis == ANCESTOR_OR_SELF || + axis == SELF) && + (tests.length == 1 && + tests[0] instanceof NodeTypeTest && + ((NodeTypeTest) tests[0]).type == (short) 0)) + { + successful.add(node); + continue; + } + } + if (test.matches(node, i + 1, len)) + successful.add(node); + } + candidates = successful; + len = candidates.size(); + } + } + return candidates; + } + + void addCandidates(Node context, Collection<Node> candidates) + { + // Build list of candidates + switch (axis) + { + case CHILD: + addChildNodes(context, candidates, false); + break; + case DESCENDANT: + addChildNodes(context, candidates, true); + break; + case DESCENDANT_OR_SELF: + candidates.add (context); + addChildNodes(context, candidates, true); + break; + case PARENT: + addParentNode(context, candidates, false); + break; + case ANCESTOR: + addParentNode(context, candidates, true); + break; + case ANCESTOR_OR_SELF: + candidates.add(context); + addParentNode(context, candidates, true); + break; + case FOLLOWING_SIBLING: + addFollowingNodes(context, candidates, false); + break; + case PRECEDING_SIBLING: + addPrecedingNodes(context, candidates, false); + break; + case FOLLOWING: + addFollowingNodes(context, candidates, true); + break; + case PRECEDING: + addPrecedingNodes(context, candidates, true); + break; + case ATTRIBUTE: + addAttributes(context, candidates); + break; + case NAMESPACE: + addNamespaceAttributes(context, candidates); + break; + case SELF: + candidates.add(context); + break; + } + } + + void addChildNodes(Node context, Collection<Node> acc, boolean recurse) + { + Node child = context.getFirstChild(); + while (child != null) + { + acc.add(child); + if (recurse) + addChildNodes(child, acc, recurse); + child = child.getNextSibling(); + } + } + + void addParentNode(Node context, Collection<Node> acc, boolean recurse) + { + Node parent = (context.getNodeType() == Node.ATTRIBUTE_NODE) ? + ((Attr) context).getOwnerElement() : context.getParentNode(); + if (parent != null) + { + acc.add(parent); + if (recurse) + addParentNode(parent, acc, recurse); + } + } + + void addFollowingNodes(Node context, Collection<Node> acc, boolean recurse) + { + if (context != null && recurse) + addChildNodes(context, acc, true); + Node cur = (context.getNodeType() == Node.ATTRIBUTE_NODE) ? null : + context.getNextSibling(); + while (cur != null) + { + acc.add(cur); + if (recurse) + addChildNodes(cur, acc, true); + cur = cur.getNextSibling(); + } + if (recurse) + { + while (context != null) + { + context = (context.getNodeType() == Node.ATTRIBUTE_NODE) ? + ((Attr) context).getOwnerElement() : context.getParentNode(); + if (context != null) + { + cur = context.getNextSibling(); + while (cur != null) + { + acc.add(cur); + if (recurse) + addChildNodes(cur, acc, true); + cur = cur.getNextSibling(); + } + } + } + } + } + + void addPrecedingNodes(Node context, Collection<Node> acc, boolean recurse) + { + Node cur = (context.getNodeType() == Node.ATTRIBUTE_NODE) ? null : + context.getPreviousSibling(); + while (cur != null) + { + acc.add(cur); + if (recurse) + addChildNodes(cur, acc, true); + cur = cur.getPreviousSibling(); + } + if (recurse) + { + cur = context; + cur = (cur.getNodeType() == Node.ATTRIBUTE_NODE) ? + ((Attr) cur).getOwnerElement() : cur.getParentNode(); + if (cur != null) + addPrecedingNodes(cur, acc, recurse); + } + } + + void addAttributes(Node context, Collection<Node> acc) + { + NamedNodeMap attrs = context.getAttributes(); + if (attrs != null) + { + int attrLen = attrs.getLength(); + for (int i = 0; i < attrLen; i++) + { + Node attr = attrs.item(i); + if (!isNamespaceAttribute(attr)) + { + acc.add(attr); + } + } + } + } + + void addNamespaceAttributes(Node context, Collection<Node> acc) + { + NamedNodeMap attrs = context.getAttributes(); + if (attrs != null) + { + int attrLen = attrs.getLength(); + for (int i = 0; i < attrLen; i++) + { + Node attr = attrs.item(i); + if (isNamespaceAttribute(attr)) + acc.add(attr); + } + } + } + + final boolean isNamespaceAttribute(Node node) + { + String uri = node.getNamespaceURI(); + return (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(uri) || + XMLConstants.XMLNS_ATTRIBUTE.equals(node.getPrefix()) || + XMLConstants.XMLNS_ATTRIBUTE.equals(node.getNodeName())); + } + + public Expr clone(Object context) + { + int len = tests.length; + List<Test> tests2 = new ArrayList<Test>(len); + for (int i = 0; i < len; i++) + tests2.add(tests[i].clone(context)); + return new Selector(axis, tests2); + } + + public boolean references(QName var) + { + for (int i = 0; i < tests.length; i++) + { + if (tests[i].references(var)) + return true; + } + return false; + } + + public String toString() + { + CPStringBuilder buf = new CPStringBuilder(); + switch (axis) + { + case ANCESTOR: + buf.append("ancestor::"); + break; + case ANCESTOR_OR_SELF: + buf.append("ancestor-or-self::"); + break; + case ATTRIBUTE: + if (tests.length == 0 || + (tests[0] instanceof NameTest)) + buf.append('@'); + else + buf.append("attribute::"); + break; + case CHILD: + //buf.append("child::"); + break; + case DESCENDANT: + buf.append("descendant::"); + break; + case DESCENDANT_OR_SELF: + buf.append("descendant-or-self::"); + break; + case FOLLOWING: + buf.append("following::"); + break; + case FOLLOWING_SIBLING: + buf.append("following-sibling::"); + break; + case NAMESPACE: + buf.append("namespace::"); + break; + case PARENT: + if (tests.length == 0 || + (tests[0] instanceof NodeTypeTest && + ((NodeTypeTest) tests[0]).type == 0)) + return ".."; + buf.append("parent::"); + break; + case PRECEDING: + buf.append("preceding::"); + break; + case PRECEDING_SIBLING: + buf.append("preceding-sibling::"); + break; + case SELF: + if (tests.length == 0 || + (tests[0] instanceof NodeTypeTest && + ((NodeTypeTest) tests[0]).type == 0)) + return "."; + buf.append("self::"); + break; + } + if (tests.length == 0) + buf.append("[error]"); + else + { + for (int i = 0; i < tests.length; i++) + buf.append(tests[i]); + } + return buf.toString(); + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/StartsWithFunction.java b/libjava/classpath/gnu/xml/xpath/StartsWithFunction.java new file mode 100644 index 000000000..6f9716a2d --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/StartsWithFunction.java @@ -0,0 +1,92 @@ +/* StartsWithFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>starts-with</code> function returns true if the first argument + * string starts with the second argument string, and otherwise returns false. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class StartsWithFunction + extends Expr +{ + + final Expr arg1; + final Expr arg2; + + StartsWithFunction(List<Expr> args) + { + this(args.get(0), args.get(1)); + } + + StartsWithFunction(Expr arg1, Expr arg2) + { + this.arg1 = arg1; + this.arg2 = arg2; + } + + public Object evaluate(Node context, int pos, int len) + { + Object val1 = arg1.evaluate(context, pos, len); + Object val2 = arg2.evaluate(context, pos, len); + String s1 = _string(context, val1); + String s2 = _string(context, val2); + return s1.startsWith(s2) ? Boolean.TRUE : Boolean.FALSE; + } + + public Expr clone(Object context) + { + return new StartsWithFunction(arg1.clone(context), arg2.clone(context)); + } + + public boolean references(QName var) + { + return (arg1.references(var) || arg2.references(var)); + } + + public String toString() + { + return "starts-with(" + arg1 + "," + arg2 + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/Steps.java b/libjava/classpath/gnu/xml/xpath/Steps.java new file mode 100644 index 000000000..75644541c --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/Steps.java @@ -0,0 +1,260 @@ +/* Steps.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import gnu.java.lang.CPStringBuilder; + +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.Set; +import javax.xml.namespace.QName; +import org.w3c.dom.Attr; +import org.w3c.dom.Node; + +/** + * A list of transitions between components in a location path. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public final class Steps + extends Path +{ + + final LinkedList<Expr> path; + + public Steps() + { + this(new LinkedList<Expr>()); + } + + Steps(LinkedList<Expr> path) + { + this.path = path; + } + + public boolean matches(Node context) + { + // Right to left + return matches(context, path.size() - 1); + } + + boolean matches(Node context, int pos) + { + Pattern right = (Pattern) path.get(pos); + if (!right.matches(context)) + { + return false; + } + if (pos > 0) + { + Pattern left = (Pattern) path.get(pos - 1); + for (Node candidate : possibleContexts(right, context)) + { + if (left.matches(candidate) && + matches(candidate, pos - 1)) + { + return true; + } + // keep going, there may be another candidate + } + return false; + } + return true; + } + + /** + * Essentially the reverse of Selector.addCandidates. + * The idea is to determine possible context nodes for a match. + */ + Collection<Node> possibleContexts(Pattern pattern, Node context) + { + if (pattern instanceof Selector) + { + Selector s = (Selector) pattern; + Collection<Node> candidates = new LinkedHashSet<Node>(); + switch (s.axis) + { + case Selector.PARENT: + s.addChildNodes(context, candidates, false); + break; + case Selector.ANCESTOR: + s.addChildNodes(context, candidates, true); + break; + case Selector.ANCESTOR_OR_SELF: + candidates.add (context); + s.addChildNodes(context, candidates, true); + break; + case Selector.CHILD: + s.addParentNode(context, candidates, false); + break; + case Selector.DESCENDANT: + s.addParentNode(context, candidates, true); + break; + case Selector.DESCENDANT_OR_SELF: + candidates.add(context); + s.addParentNode(context, candidates, true); + break; + case Selector.PRECEDING_SIBLING: + s.addFollowingNodes(context, candidates, false); + break; + case Selector.FOLLOWING_SIBLING: + s.addPrecedingNodes(context, candidates, false); + break; + case Selector.PRECEDING: + s.addFollowingNodes(context, candidates, true); + break; + case Selector.FOLLOWING: + s.addPrecedingNodes(context, candidates, true); + break; + case Selector.ATTRIBUTE: + case Selector.NAMESPACE: + if (context.getNodeType() == Node.ATTRIBUTE_NODE) + { + candidates.add(((Attr) context).getOwnerElement()); + } + break; + case Selector.SELF: + candidates.add(context); + break; + } + return candidates; + } + return Collections.emptySet(); + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + //System.err.println(toString()+" evaluate"); + // Left to right + Iterator<Expr> i = path.iterator(); + Expr lhs = i.next(); + Object val = lhs.evaluate(context, pos, len); + //System.err.println("\tevaluate "+lhs+" = "+val); + while (val instanceof Collection && i.hasNext()) + { + Path rhs = (Path) i.next(); + /* Suppression is safe, as we know context produces Collection<Node> */ + @SuppressWarnings("unchecked") + Collection<Node> nodes = (Collection<Node>) val; + val = rhs.evaluate(context, nodes); + //System.err.println("\tevaluate "+rhs+" = "+val); + } + return val; + } + + @Override + Collection<Node> evaluate(Node context, Collection<Node> ns) + { + // Left to right + Iterator<Expr> i = path.iterator(); + Expr lhs = i.next(); + if (lhs instanceof Path) + { + ns = ((Path) lhs).evaluate(context, ns); + } + else + { + Set<Node> acc = new LinkedHashSet<Node>(); + int pos = 1, len = ns.size(); + for (Node node : ns) + { + Object ret = lhs.evaluate(node, pos++, len); + if (ret instanceof Collection) + { + /* Suppression is safe, as we know context produces Collection<Node> */ + @SuppressWarnings("unchecked") + Collection<Node> nodes = (Collection<Node>) ret; + acc.addAll(nodes); + } + } + ns = acc; + } + while (i.hasNext()) + { + Path rhs = (Path) i.next(); + ns = rhs.evaluate(context, ns); + } + return ns; + } + + public Expr clone(Object context) + { + int len = path.size(); + LinkedList<Expr> path2 = new LinkedList<Expr>(); + for (int i = 0; i < len; i++) + { + path2.add(path.get(i).clone(context)); + } + return new Steps(path2); + } + + public boolean references(QName var) + { + for (Iterator<Expr> i = path.iterator(); i.hasNext(); ) + { + if (i.next().references(var)) + { + return true; + } + } + return false; + } + + public String toString() + { + CPStringBuilder buf = new CPStringBuilder(); + Iterator<Expr> i = path.iterator(); + Expr expr = i.next(); + if (!(expr instanceof Root)) + { + buf.append(expr); + } + while (i.hasNext()) + { + expr = i.next(); + buf.append('/'); + buf.append(expr); + } + return buf.toString(); + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/StringFunction.java b/libjava/classpath/gnu/xml/xpath/StringFunction.java new file mode 100644 index 000000000..b2b3cecf7 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/StringFunction.java @@ -0,0 +1,119 @@ +/* StringFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>string function converts an object to a string as follows: + * <ul> + * <li>A node-set is converted to a string by returning the string-value of + * the node in the node-set that is first in document order. If the node-set + * is empty, an empty string is returned.</li> + * <li>A number is converted to a string as follows + * <ul> + * <li>NaN is converted to the string NaN</li> + * <li>positive zero is converted to the string 0</li> + * <li>negative zero is converted to the string 0</li> + * <li>positive infinity is converted to the string Infinity</li> + * <li>negative infinity is converted to the string -Infinity</li> + * <li>if the number is an integer, the number is represented in decimal + * form as a Number with no decimal point and no leading zeros, preceded by + * a minus sign (-) if the number is negative</li> + * <li>otherwise, the number is represented in decimal form as a Number + * including a decimal point with at least one digit before the decimal + * point and at least one digit after the decimal point, preceded by a minus + * sign (-) if the number is negative; there must be no leading zeros before + * the decimal point apart possibly from the one required digit immediately + * before the decimal point; beyond the one required digit after the decimal + * point there must be as many, but only as many, more digits as are needed + * to uniquely distinguish the number from all other IEEE 754 numeric + * values.</li> + * </ul> + * </li> + * <li>The boolean false value is converted to the string false. The boolean + * true value is converted to the string true.</li> + * <li>An object of a type other than the four basic types is converted to a + * string in a way that is dependent on that type.</li> + * </ul> + * If the argument is omitted, it defaults to a node-set with the context + * node as its only member. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class StringFunction + extends Expr +{ + + final Expr arg; + + StringFunction(List<Expr> args) + { + this(args.size() > 0 ? args.get(0) : null); + } + + StringFunction(Expr arg) + { + this.arg = arg; + } + + public Object evaluate(Node context, int pos, int len) + { + Object val = (arg == null) ? null : arg.evaluate(context, pos, len); + return _string(context, val); + } + + public Expr clone(Object context) + { + return new StringFunction((arg == null) ? null : + arg.clone(context)); + } + + public boolean references(QName var) + { + return (arg == null) ? false : arg.references(var); + } + + public String toString() + { + return (arg == null) ? "string()" : "string(" + arg + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/StringLengthFunction.java b/libjava/classpath/gnu/xml/xpath/StringLengthFunction.java new file mode 100644 index 000000000..c72b0d9bc --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/StringLengthFunction.java @@ -0,0 +1,92 @@ +/* StringLengthFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>string-length</code> function returns the number of characters + * in the string. + * If the argument is omitted, it defaults to the context node converted to + * a string, in other words the string-value of the context node. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class StringLengthFunction + extends Expr +{ + + final Expr arg; + + StringLengthFunction(List<Expr> args) + { + this(args.isEmpty() ? null : (Expr) args.get(0)); + } + + StringLengthFunction(Expr arg) + { + this.arg = arg; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + Object val = (arg == null) ? null : arg.evaluate(context, pos, len); + String s = _string(context, val); + return new Double((double) s.length()); + } + + public Expr clone(Object context) + { + return new StringLengthFunction((arg == null) ? null : + arg.clone(context)); + } + + public boolean references(QName var) + { + return (arg == null) ? false : arg.references(var); + } + + public String toString() + { + return (arg == null) ? "string-length()" : "string-length(" + arg + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/SubstringAfterFunction.java b/libjava/classpath/gnu/xml/xpath/SubstringAfterFunction.java new file mode 100644 index 000000000..4f10723a7 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/SubstringAfterFunction.java @@ -0,0 +1,98 @@ +/* SubstringAfterFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>substring-after</code> function returns the substring of the + * first argument string that follows the first occurrence of the second + * argument string in the first argument string, or the empty string if the + * first argument string does not contain the second argument string. For + * example, substring-after("1999/04/01","/") returns 04/01, and + * substring-after("1999/04/01","19") returns 99/04/01. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class SubstringAfterFunction + extends Expr +{ + + final Expr arg1; + final Expr arg2; + + SubstringAfterFunction(List<Expr> args) + { + this(args.get(0), args.get(1)); + } + + SubstringAfterFunction(Expr arg1, Expr arg2) + { + this.arg1 = arg1; + this.arg2 = arg2; + } + + public Object evaluate(Node context, int pos, int len) + { + Object val1 = arg1.evaluate(context, pos, len); + Object val2 = arg2.evaluate(context, pos, len); + String s1 = _string(context, val1); + String s2 = _string(context, val2); + int index = s1.indexOf(s2); + return (index == -1) ? "" : s1.substring(index + s2.length()); + } + + public Expr clone(Object context) + { + return new SubstringAfterFunction(arg1.clone(context), + arg2.clone(context)); + } + + public boolean references(QName var) + { + return (arg1.references(var) || arg2.references(var)); + } + + public String toString() + { + return "substring-after(" + arg1 + "," + arg2 + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/SubstringBeforeFunction.java b/libjava/classpath/gnu/xml/xpath/SubstringBeforeFunction.java new file mode 100644 index 000000000..1a5a04c4f --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/SubstringBeforeFunction.java @@ -0,0 +1,97 @@ +/* SubstringBeforeFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>substring-before</code> function returns the substring of the + * first argument string that precedes the first occurrence of the second + * argument string in the first argument string, or the empty string if the + * first argument string does not contain the second argument string. For + * example, substring-before("1999/04/01","/") returns 1999. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class SubstringBeforeFunction + extends Expr +{ + + final Expr arg1; + final Expr arg2; + + SubstringBeforeFunction(List<Expr> args) + { + this(args.get(0), args.get(1)); + } + + SubstringBeforeFunction(Expr arg1, Expr arg2) + { + this.arg1 = arg1; + this.arg2 = arg2; + } + + public Object evaluate(Node context, int pos, int len) + { + Object val1 = arg1.evaluate(context, pos, len); + Object val2 = arg2.evaluate(context, pos, len); + String s1 = _string(context, val1); + String s2 = _string(context, val2); + int index = s1.indexOf(s2); + return (index == -1) ? "" : s1.substring(0, index); + } + + public Expr clone(Object context) + { + return new SubstringBeforeFunction(arg1.clone(context), + arg2.clone(context)); + } + + public boolean references(QName var) + { + return (arg1.references(var) || arg2.references(var)); + } + + public String toString() + { + return "substring-before(" + arg1 + "," + arg2 + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/SubstringFunction.java b/libjava/classpath/gnu/xml/xpath/SubstringFunction.java new file mode 100644 index 000000000..d17c3b662 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/SubstringFunction.java @@ -0,0 +1,119 @@ +/* SubstringFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The substring function returns the substring of the first argument + * starting at the position specified in the second argument with length + * specified in the third argument. For example, substring("12345",2,3) + * returns "234". If the third argument is not specified, it returns the + * substring starting at the position specified in the second argument and + * continuing to the end of the string. For example, substring("12345",2) + * returns "2345". + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class SubstringFunction + extends Expr +{ + + final Expr arg1; + final Expr arg2; + final Expr arg3; + + SubstringFunction(List<Expr> args) + { + this(args.get(0), args.get(1), + (args.size() > 2) ? args.get(2) : null); + } + + SubstringFunction(Expr arg1, Expr arg2, Expr arg3) + { + this.arg1 = arg1; + this.arg2 = arg2; + this.arg3 = arg3; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + Object val1 = arg1.evaluate(context, pos, len); + Object val2 = arg2.evaluate(context, pos, len); + String s = _string(context, val1); + int p = Expr.intValue(val2) - 1; + if (p < 0) + p = 0; + + int l = s.length() - p; + if (l <= 0) + return ""; + + if (arg3 != null) + { + Object val3 = arg3.evaluate(context, pos, len); + int v3 = Expr.intValue(val3); + if (v3 < l) + l = v3; + } + + return s.substring(p, p + l); + } + + public Expr clone(Object context) + { + return new SubstringFunction(arg1.clone(context), arg2.clone(context), + (arg3 == null) ? null : arg3.clone(context)); + } + + public boolean references(QName var) + { + return (arg1.references(var) || arg2.references(var) || + (arg3 == null) ? false : arg3.references(var)); + } + + public String toString() + { + return (arg3 == null) ? "substring(" + arg1 + "," + arg2 + ")" : + "substring(" + arg1 + "," + arg2 + "," + arg3 + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/SumFunction.java b/libjava/classpath/gnu/xml/xpath/SumFunction.java new file mode 100644 index 000000000..6c3323fb2 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/SumFunction.java @@ -0,0 +1,104 @@ +/* SumFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>sum</code> function returns the sum, for each node in the + * argument node-set, of the result of converting the string-values of the + * node to a number. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class SumFunction + extends Expr +{ + + final Expr arg; + + SumFunction(List<Expr> args) + { + this(args.get(0)); + } + + SumFunction(Expr arg) + { + this.arg = arg; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + Object val = arg.evaluate(context, pos, len); + double sum = 0.0d; + if (val instanceof Collection) + { + /* Suppression is safe, as we know context produces + Collection<Node> */ + @SuppressWarnings("unchecked") + Collection<Node> nodes = (Collection<Node>) val; + for (Node node : nodes) + { + String s = stringValue(node); + sum += _number(context, s); + } + } + return new Double(sum); + } + + public Expr clone(Object context) + { + return new SumFunction(arg.clone(context)); + } + + public boolean references(QName var) + { + return arg.references(var); + } + + public String toString() + { + return "sum(" + arg + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/Test.java b/libjava/classpath/gnu/xml/xpath/Test.java new file mode 100644 index 000000000..529c99bd8 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/Test.java @@ -0,0 +1,58 @@ +/* Test.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * A test that can be performed on a node to determine whether to include it + * in a selection. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public abstract class Test +{ + + public abstract boolean matches(Node node, int pos, int len); + + public abstract Test clone(Object context); + + public abstract boolean references(QName var); + +} diff --git a/libjava/classpath/gnu/xml/xpath/TranslateFunction.java b/libjava/classpath/gnu/xml/xpath/TranslateFunction.java new file mode 100644 index 000000000..4e06354c3 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/TranslateFunction.java @@ -0,0 +1,135 @@ +/* TranslateFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import gnu.java.lang.CPStringBuilder; + +import java.util.List; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>translate</code> function returns the first argument string + * with occurrences of characters in the second argument string replaced by + * the character at the corresponding position in the third argument string. + * For example, translate("bar","abc","ABC") returns the string BAr. If + * there is a character in the second argument string with no character at a + * corresponding position in the third argument string (because the second + * argument string is longer than the third argument string), then + * occurrences of that character in the first argument string are removed. + * For example, translate("--aaa--","abc-","ABC") returns "AAA". If a + * character occurs more than once in the second argument string, then the + * first occurrence determines the replacement character. If the third + * argument string is longer than the second argument string, then excess + * characters are ignored. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class TranslateFunction + extends Expr +{ + + final Expr arg1; + final Expr arg2; + final Expr arg3; + + TranslateFunction(List<Expr> args) + { + this(args.get(0), args.get(1), args.get(2)); + } + + TranslateFunction(Expr arg1, Expr arg2, Expr arg3) + { + this.arg1 = arg1; + this.arg2 = arg2; + this.arg3 = arg3; + } + + public Object evaluate(Node context, int pos, int len) + { + Object val1 = arg1.evaluate(context, pos, len); + Object val2 = arg2.evaluate(context, pos, len); + Object val3 = arg3.evaluate(context, pos, len); + String string = _string(context, val1); + String search = _string(context, val2); + String replace = _string(context, val3); + CPStringBuilder buf = new CPStringBuilder(); + int l1 = string.length(); + int l2 = search.length(); + int l3 = replace.length(); + for (int i = 0; i < l1; i++) + { + char c = string.charAt(i); + boolean replaced = false; + for (int j = 0; j < l2; j++) + { + if (c == search.charAt(j)) + { + if (j < l3) + { + buf.append(replace.charAt(j)); + } + replaced = true; + } + } + if (!replaced) + { + buf.append(c); + } + } + return buf.toString(); + } + + public Expr clone(Object context) + { + return new TranslateFunction(arg1.clone(context), arg2.clone(context), + arg3.clone(context)); + } + + public boolean references(QName var) + { + return (arg1.references(var) || arg2.references(var) || + arg3.references(var)); + } + + public String toString() + { + return "translate(" + arg1 + "," + arg2 + "," + arg3 + ")"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/TrueFunction.java b/libjava/classpath/gnu/xml/xpath/TrueFunction.java new file mode 100644 index 000000000..41ab54b75 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/TrueFunction.java @@ -0,0 +1,72 @@ +/* TrueFunction.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The <code>true</code> function returns true. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class TrueFunction + extends Expr +{ + + public Object evaluate(Node context, int pos, int len) + { + return Boolean.TRUE; + } + + public Expr clone(Object context) + { + return new TrueFunction(); + } + + public boolean references(QName var) + { + return false; + } + + public String toString() + { + return "true()"; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/UnionExpr.java b/libjava/classpath/gnu/xml/xpath/UnionExpr.java new file mode 100644 index 000000000..bd5f5e990 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/UnionExpr.java @@ -0,0 +1,117 @@ +/* UnionExpr.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import javax.xml.namespace.QName; +import org.w3c.dom.Node; + +/** + * The union of two node-sets. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public final class UnionExpr + extends Pattern +{ + + final Expr lhs; + final Expr rhs; + + public UnionExpr(Expr lhs, Expr rhs) + { + this.lhs = lhs; + this.rhs = rhs; + } + + public boolean matches(Node context) + { + if (lhs instanceof Pattern && rhs instanceof Pattern) + { + return ((Pattern) lhs).matches(context) || + ((Pattern) rhs).matches(context); + } + return false; + } + + @Override + public Object evaluate(Node context, int pos, int len) + { + Object left = lhs.evaluate(context, pos, len); + Object right = rhs.evaluate(context, pos, len); + List<Node> list; + if (left instanceof Collection && right instanceof Collection) + { + Set<Node> set = new HashSet<Node>(); + /* Suppression is safe as addAll will check the types + of the elements and throw a ClassCastException as necessary */ + @SuppressWarnings("unchecked") + Collection<Node> l = (Collection<Node>) left; + @SuppressWarnings("unchecked") + Collection<Node> r = (Collection<Node>) right; + set.addAll (l); + set.addAll (r); + list = new ArrayList<Node>(set); + Collections.sort(list, documentOrderComparator); + } + else + list = Collections.emptyList(); + return list; + } + + public Expr clone(Object context) + { + return new UnionExpr(lhs.clone(context), rhs.clone(context)); + } + + public boolean references(QName var) + { + return (lhs.references(var) || rhs.references(var)); + } + + public String toString() + { + return lhs + " | " + rhs; + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/VariableReference.java b/libjava/classpath/gnu/xml/xpath/VariableReference.java new file mode 100644 index 000000000..e1698c94c --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/VariableReference.java @@ -0,0 +1,102 @@ +/* VariableReference.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import gnu.java.lang.CPStringBuilder; + +import javax.xml.namespace.QName; +import javax.xml.xpath.XPathVariableResolver; +import org.w3c.dom.Node; +import gnu.xml.transform.Bindings; + +public class VariableReference + extends Expr +{ + + final XPathVariableResolver resolver; + final QName name; + + public VariableReference(XPathVariableResolver resolver, QName name) + { + this.resolver = resolver; + this.name = name; + } + + public Object evaluate(Node context, int pos, int len) + { + if (resolver != null) + { + if (resolver instanceof Bindings) + { + // Needs context to operate properly + return ((Bindings) resolver).get(name, context, pos, len); + } + return resolver.resolveVariable(name); + } + throw new IllegalStateException("no variable resolver"); + } + + public Expr clone(Object context) + { + XPathVariableResolver r = resolver; + if (context instanceof XPathVariableResolver) + { + r = (XPathVariableResolver) context; + } + return new VariableReference(r, name); + } + + public boolean references(QName var) + { + return name.equals(var); + } + + public String toString() + { + CPStringBuilder buf = new CPStringBuilder("$"); + String prefix = name.getPrefix(); + if (prefix != null && !"".equals(prefix)) + { + buf.append(prefix); + buf.append(':'); + } + buf.append(name.getLocalPart()); + return buf.toString(); + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/XPathFactoryImpl.java b/libjava/classpath/gnu/xml/xpath/XPathFactoryImpl.java new file mode 100644 index 000000000..970cf0e5d --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/XPathFactoryImpl.java @@ -0,0 +1,90 @@ +/* XPathFactoryImpl.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathFactory; +import javax.xml.xpath.XPathFactoryConfigurationException; +import javax.xml.xpath.XPathFunctionResolver; +import javax.xml.xpath.XPathVariableResolver; + +/** + * GNU XPath factory implementation. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class XPathFactoryImpl + extends XPathFactory +{ + + XPathVariableResolver variableResolver; + XPathFunctionResolver functionResolver; + + public boolean isObjectModelSupported(String objectModel) + { + return XPathFactory.DEFAULT_OBJECT_MODEL_URI.equals(objectModel); + } + + public void setFeature(String name, boolean value) + throws XPathFactoryConfigurationException + { + throw new XPathFactoryConfigurationException(name); + } + + public boolean getFeature(String name) + throws XPathFactoryConfigurationException + { + throw new XPathFactoryConfigurationException(name); + } + + public void setXPathVariableResolver(XPathVariableResolver resolver) + { + variableResolver = resolver; + } + + public void setXPathFunctionResolver(XPathFunctionResolver resolver) + { + functionResolver = resolver; + } + + public XPath newXPath() + { + return new XPathImpl(null, variableResolver, functionResolver); + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/XPathImpl.java b/libjava/classpath/gnu/xml/xpath/XPathImpl.java new file mode 100644 index 000000000..62f86171b --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/XPathImpl.java @@ -0,0 +1,164 @@ +/* XPathImpl.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import java.io.IOException; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFunctionResolver; +import javax.xml.xpath.XPathVariableResolver; +import org.xml.sax.InputSource; + +/** + * JAXP XPath implementation. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class XPathImpl + implements XPath +{ + + XPathParser parser; + NamespaceContext namespaceContext; + XPathVariableResolver variableResolver; + XPathFunctionResolver functionResolver; + + XPathImpl(NamespaceContext namespaceContext, + XPathVariableResolver variableResolver, + XPathFunctionResolver functionResolver) + { + parser = new XPathParser(); + this.namespaceContext = namespaceContext; + this.variableResolver = variableResolver; + this.functionResolver = functionResolver; + reset(); + } + + public void reset() + { + parser.namespaceContext = namespaceContext; + parser.variableResolver = variableResolver; + parser.functionResolver = functionResolver; + } + + public void setXPathVariableResolver(XPathVariableResolver resolver) + { + parser.variableResolver = resolver; + } + + public XPathVariableResolver getXPathVariableResolver() + { + return parser.variableResolver; + } + + public void setXPathFunctionResolver(XPathFunctionResolver resolver) + { + parser.functionResolver = resolver; + } + + public XPathFunctionResolver getXPathFunctionResolver() + { + return parser.functionResolver; + } + + public void setNamespaceContext(NamespaceContext nsContext) + { + parser.namespaceContext = nsContext; + } + + public NamespaceContext getNamespaceContext() + { + return parser.namespaceContext; + } + + public XPathExpression compile(String expression) + throws XPathExpressionException + { + XPathTokenizer tokenizer = new XPathTokenizer(expression); + try + { + return (Expr) parser.yyparse(tokenizer); + } + catch (IOException e) + { + throw new XPathExpressionException(e); + } + catch (XPathParser.yyException e) + { + throw new XPathExpressionException(expression); + } + } + + public Object evaluate(String expression, + Object item, + QName returnType) + throws XPathExpressionException + { + XPathExpression expr = compile(expression); + return expr.evaluate(item, returnType); + } + + public String evaluate(String expression, + Object item) + throws XPathExpressionException + { + XPathExpression expr = compile(expression); + return expr.evaluate(item); + } + + public Object evaluate(String expression, + InputSource source, + QName returnType) + throws XPathExpressionException + { + XPathExpression expr = compile(expression); + return expr.evaluate(source, returnType); + } + + public String evaluate(String expression, + InputSource source) + throws XPathExpressionException + { + XPathExpression expr = compile(expression); + return expr.evaluate(source); + } + +} diff --git a/libjava/classpath/gnu/xml/xpath/XPathParser.java b/libjava/classpath/gnu/xml/xpath/XPathParser.java new file mode 100644 index 000000000..26e59091e --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/XPathParser.java @@ -0,0 +1,1475 @@ +// created by jay 0.8 (c) 1998 Axel.Schreiner@informatik.uni-osnabrueck.de + + // line 2 "XPathParser.y" +/* XPathParser.y - An XPath 1.0 parser. + Copyright (C) 2004 The Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.xml.xpath; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.xpath.XPathFunctionResolver; +import javax.xml.xpath.XPathVariableResolver; +import org.w3c.dom.Node; + +/** + * An XPath 1.0 parser. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class XPathParser +{ + + NamespaceContext namespaceContext; + XPathVariableResolver variableResolver; + XPathFunctionResolver functionResolver; + + QName getQName(String name) + { + QName qName = QName.valueOf(name); + if (namespaceContext != null) + { + String prefix = qName.getPrefix(); + String uri = qName.getNamespaceURI(); + if (prefix != null && (uri == null || uri.length() == 0)) + { + uri = namespaceContext.getNamespaceURI(prefix); + String localName = qName.getLocalPart(); + qName = new QName(uri, localName, prefix); + } + } + return qName; + } + + Expr lookupFunction(String name, List<Expr> args) + { + int arity = args.size(); + if ("position".equals(name) && arity == 0) + { + return new PositionFunction(); + } + else if ("last".equals(name) && arity == 0) + { + return new LastFunction(); + } + else if ("string".equals(name) && (arity == 1 || arity == 0)) + { + return new StringFunction(args); + } + else if ("number".equals(name) && (arity == 1 || arity == 0)) + { + return new NumberFunction(args); + } + else if ("boolean".equals(name) && arity == 1) + { + return new BooleanFunction(args); + } + else if ("count".equals(name) && arity == 1) + { + return new CountFunction(args); + } + else if ("not".equals(name) && arity == 1) + { + return new NotFunction(args); + } + else if ("id".equals(name) && arity == 1) + { + return new IdFunction(args); + } + else if ("concat".equals(name) && arity > 1) + { + return new ConcatFunction(args); + } + else if ("true".equals(name) && arity == 0) + { + return new TrueFunction(); + } + else if ("false".equals(name) && arity == 0) + { + return new FalseFunction(); + } + else if ("name".equals(name) && (arity == 1 || arity == 0)) + { + return new NameFunction(args); + } + else if ("local-name".equals(name) && (arity == 1 || arity == 0)) + { + return new LocalNameFunction(args); + } + else if ("namespace-uri".equals(name) && (arity == 1 || arity == 0)) + { + return new NamespaceUriFunction(args); + } + else if ("starts-with".equals(name) && arity == 2) + { + return new StartsWithFunction(args); + } + else if ("contains".equals(name) && arity == 2) + { + return new ContainsFunction(args); + } + else if ("string-length".equals(name) && (arity == 1 || arity == 0)) + { + return new StringLengthFunction(args); + } + else if ("translate".equals(name) && arity == 3) + { + return new TranslateFunction(args); + } + else if ("normalize-space".equals(name) && (arity == 1 || arity == 0)) + { + return new NormalizeSpaceFunction(args); + } + else if ("substring".equals(name) && (arity == 2 || arity == 3)) + { + return new SubstringFunction(args); + } + else if ("substring-before".equals(name) && arity == 2) + { + return new SubstringBeforeFunction(args); + } + else if ("substring-after".equals(name) && arity == 2) + { + return new SubstringAfterFunction(args); + } + else if ("lang".equals(name) && arity == 1) + { + return new LangFunction(args); + } + else if ("sum".equals(name) && arity == 1) + { + return new SumFunction(args); + } + else if ("floor".equals(name) && arity == 1) + { + return new FloorFunction(args); + } + else if ("ceiling".equals(name) && arity == 1) + { + return new CeilingFunction(args); + } + else if ("round".equals(name) && arity == 1) + { + return new RoundFunction(args); + } + else if (functionResolver != null) + { + QName qName = QName.valueOf(name); + Object function = functionResolver.resolveFunction(qName, arity); + if (function != null && + function instanceof Function && + function instanceof Expr) + { + Function f = (Function) function; + f.setArguments(args); + return (Expr) function; + } + } + return new FunctionCall(functionResolver, name, args); + } + + // line 211 "-" +// %token constants + + public static final int LITERAL = 257; + public static final int DIGITS = 258; + public static final int NAME = 259; + public static final int LP = 260; + public static final int RP = 261; + public static final int LB = 262; + public static final int RB = 263; + public static final int COMMA = 264; + public static final int PIPE = 265; + public static final int SLASH = 266; + public static final int DOUBLE_SLASH = 267; + public static final int EQ = 268; + public static final int NE = 269; + public static final int GT = 270; + public static final int LT = 271; + public static final int GTE = 272; + public static final int LTE = 273; + public static final int PLUS = 274; + public static final int MINUS = 275; + public static final int AT = 276; + public static final int STAR = 277; + public static final int DOLLAR = 278; + public static final int COLON = 279; + public static final int DOUBLE_COLON = 280; + public static final int DOT = 281; + public static final int DOUBLE_DOT = 282; + public static final int ANCESTOR = 283; + public static final int ANCESTOR_OR_SELF = 284; + public static final int ATTRIBUTE = 285; + public static final int CHILD = 286; + public static final int DESCENDANT = 287; + public static final int DESCENDANT_OR_SELF = 288; + public static final int FOLLOWING = 289; + public static final int FOLLOWING_SIBLING = 290; + public static final int NAMESPACE = 291; + public static final int PARENT = 292; + public static final int PRECEDING = 293; + public static final int PRECEDING_SIBLING = 294; + public static final int SELF = 295; + public static final int DIV = 296; + public static final int MOD = 297; + public static final int OR = 298; + public static final int AND = 299; + public static final int COMMENT = 300; + public static final int PROCESSING_INSTRUCTION = 301; + public static final int TEXT = 302; + public static final int NODE = 303; + public static final int UNARY = 304; + public static final int yyErrorCode = 256; + + /** thrown for irrecoverable syntax errors and stack overflow. + */ + public static class yyException extends java.lang.Exception { + public yyException (String message) { + super(message); + } + } + + /** must be implemented by a scanner object to supply input to the parser. + */ + public interface yyInput { + /** move on to next token. + @return false if positioned beyond tokens. + @throws IOException on input error. + */ + boolean advance () throws java.io.IOException; + /** classifies current token. + Should not be called if advance() returned false. + @return current %token or single character. + */ + int token (); + /** associated with current token. + Should not be called if advance() returned false. + @return value for token(). + */ + Object value (); + } + + /** simplified error message. + @see <a href="#yyerror(java.lang.String, java.lang.String[])">yyerror</a> + */ + public void yyerror (String message) { + yyerror(message, null); + } + + /** (syntax) error message. + Can be overwritten to control message format. + @param message text to be displayed. + @param expected vector of acceptable tokens, if available. + */ + public void yyerror (String message, String[] expected) { + if (expected != null && expected.length > 0) { + System.err.print(message+", expecting"); + for (int n = 0; n < expected.length; ++ n) + System.err.print(" "+expected[n]); + System.err.println(); + } else + System.err.println(message); + } + + /** debugging support, requires the package jay.yydebug. + Set to null to suppress debugging messages. + */ +//t protected jay.yydebug.yyDebug yydebug; + + protected static final int yyFinal = 30; + + /** index-checked interface to yyName[]. + @param token single character or %token value. + @return token name or [illegal] or [unknown]. + */ +//t public static final String yyname (int token) { +//t if (token < 0 || token > YyNameClass.yyName.length) return "[illegal]"; +//t String name; +//t if ((name = YyNameClass.yyName[token]) != null) return name; +//t return "[unknown]"; +//t } + + /** computes list of expected tokens on error by tracing the tables. + @param state for which to compute the list. + @return list of token names. + */ + protected String[] yyExpecting (int state) { + int token, n, len = 0; + boolean[] ok = new boolean[YyNameClass.yyName.length]; + + if ((n = YySindexClass.yySindex[state]) != 0) + for (token = n < 0 ? -n : 0; + token < YyNameClass.yyName.length && n+token < YyTableClass.yyTable.length; ++ token) + if (YyCheckClass.yyCheck[n+token] == token && !ok[token] && YyNameClass.yyName[token] != null) { + ++ len; + ok[token] = true; + } + if ((n = YyRindexClass.yyRindex[state]) != 0) + for (token = n < 0 ? -n : 0; + token < YyNameClass.yyName.length && n+token < YyTableClass.yyTable.length; ++ token) + if (YyCheckClass.yyCheck[n+token] == token && !ok[token] && YyNameClass.yyName[token] != null) { + ++ len; + ok[token] = true; + } + + String result[] = new String[len]; + for (n = token = 0; n < len; ++ token) + if (ok[token]) result[n++] = YyNameClass.yyName[token]; + return result; + } + + /** the generated parser, with debugging messages. + Maintains a state and a value stack, currently with fixed maximum size. + @param yyLex scanner. + @param yydebug debug message writer implementing yyDebug, or null. + @return result of the last reduction, if any. + @throws yyException on irrecoverable parse error. + */ + public Object yyparse (yyInput yyLex, Object yydebug) + throws java.io.IOException, yyException { +//t this.yydebug = (jay.yydebug.yyDebug)yydebug; + return yyparse(yyLex); + } + + /** initial size and increment of the state/value stack [default 256]. + This is not final so that it can be overwritten outside of invocations + of yyparse(). + */ + protected int yyMax; + + /** executed at the beginning of a reduce action. + Used as $$ = yyDefault($1), prior to the user-specified action, if any. + Can be overwritten to provide deep copy, etc. + @param first value for $1, or null. + @return first. + */ + protected Object yyDefault (Object first) { + return first; + } + + /** the generated parser. + Maintains a state and a value stack, currently with fixed maximum size. + @param yyLex scanner. + @return result of the last reduction, if any. + @throws yyException on irrecoverable parse error. + */ + public Object yyparse (yyInput yyLex) + throws java.io.IOException, yyException { + if (yyMax <= 0) yyMax = 256; // initial size + int yyState = 0, yyStates[] = new int[yyMax]; // state stack + Object yyVal = null, yyVals[] = new Object[yyMax]; // value stack + int yyToken = -1; // current input + int yyErrorFlag = 0; // #tks to shift + + yyLoop: for (int yyTop = 0;; ++ yyTop) { + if (yyTop >= yyStates.length) { // dynamically increase + int[] i = new int[yyStates.length+yyMax]; + System.arraycopy(yyStates, 0, i, 0, yyStates.length); + yyStates = i; + Object[] o = new Object[yyVals.length+yyMax]; + System.arraycopy(yyVals, 0, o, 0, yyVals.length); + yyVals = o; + } + yyStates[yyTop] = yyState; + yyVals[yyTop] = yyVal; +//t if (yydebug != null) yydebug.push(yyState, yyVal); + + yyDiscarded: for (;;) { // discarding a token does not change stack + int yyN; + if ((yyN = YyDefRedClass.yyDefRed[yyState]) == 0) { // else [default] reduce (yyN) + if (yyToken < 0) { + yyToken = yyLex.advance() ? yyLex.token() : 0; +//t if (yydebug != null) +//t yydebug.lex(yyState, yyToken, yyname(yyToken), yyLex.value()); + } + if ((yyN = YySindexClass.yySindex[yyState]) != 0 && (yyN += yyToken) >= 0 + && yyN < YyTableClass.yyTable.length && YyCheckClass.yyCheck[yyN] == yyToken) { +//t if (yydebug != null) +//t yydebug.shift(yyState, YyTableClass.yyTable[yyN], yyErrorFlag-1); + yyState = YyTableClass.yyTable[yyN]; // shift to yyN + yyVal = yyLex.value(); + yyToken = -1; + if (yyErrorFlag > 0) -- yyErrorFlag; + continue yyLoop; + } + if ((yyN = YyRindexClass.yyRindex[yyState]) != 0 && (yyN += yyToken) >= 0 + && yyN < YyTableClass.yyTable.length && YyCheckClass.yyCheck[yyN] == yyToken) + yyN = YyTableClass.yyTable[yyN]; // reduce (yyN) + else + switch (yyErrorFlag) { + + case 0: + yyerror("syntax error", yyExpecting(yyState)); +//t if (yydebug != null) yydebug.error("syntax error"); + + case 1: case 2: + yyErrorFlag = 3; + do { + if ((yyN = YySindexClass.yySindex[yyStates[yyTop]]) != 0 + && (yyN += yyErrorCode) >= 0 && yyN < YyTableClass.yyTable.length + && YyCheckClass.yyCheck[yyN] == yyErrorCode) { +//t if (yydebug != null) +//t yydebug.shift(yyStates[yyTop], YyTableClass.yyTable[yyN], 3); + yyState = YyTableClass.yyTable[yyN]; + yyVal = yyLex.value(); + continue yyLoop; + } +//t if (yydebug != null) yydebug.pop(yyStates[yyTop]); + } while (-- yyTop >= 0); +//t if (yydebug != null) yydebug.reject(); + throw new yyException("irrecoverable syntax error"); + + case 3: + if (yyToken == 0) { +//t if (yydebug != null) yydebug.reject(); + throw new yyException("irrecoverable syntax error at end-of-file"); + } +//t if (yydebug != null) +//t yydebug.discard(yyState, yyToken, yyname(yyToken), +//t yyLex.value()); + yyToken = -1; + continue yyDiscarded; // leave stack alone + } + } + int yyV = yyTop + 1-YyLenClass.yyLen[yyN]; +//t if (yydebug != null) +//t yydebug.reduce(yyState, yyStates[yyV-1], yyN, YyRuleClass.yyRule[yyN], YyLenClass.yyLen[yyN]); + yyVal = yyDefault(yyV > yyTop ? null : yyVals[yyV]); + switch (yyN) { +case 4: + // line 277 "XPathParser.y" + { + yyVal = new Root(); + } + break; +case 5: + // line 281 "XPathParser.y" + { + Steps steps; + if (yyVals[0+yyTop] instanceof Steps) + { + steps = (Steps) yyVals[0+yyTop]; + } + else + { + steps = new Steps(); + steps.path.addFirst((Expr) yyVals[0+yyTop]); + } + steps.path.addFirst(new Root()); + yyVal = steps; + /*$$ = new Step(new Root(), (Path) $2);*/ + } + break; +case 6: + // line 297 "XPathParser.y" + { + Test nt = new NodeTypeTest((short) 0); + Selector s = new Selector(Selector.DESCENDANT_OR_SELF, + Collections.singletonList (nt)); + Steps steps; + if (yyVals[0+yyTop] instanceof Steps) + { + steps = (Steps) yyVals[0+yyTop]; + } + else + { + steps = new Steps(); + steps.path.addFirst((Expr) yyVals[0+yyTop]); + } + steps.path.addFirst(s); + steps.path.addFirst(new Root()); + yyVal = steps; + /*Step step = new Step(s, (Path) $2);*/ + /*$$ = new Step(new Root(), step);*/ + } + break; +case 8: + // line 322 "XPathParser.y" + { + Steps steps; + if (yyVals[-2+yyTop] instanceof Steps) + { + steps = (Steps) yyVals[-2+yyTop]; + } + else + { + steps = new Steps(); + steps.path.addFirst((Expr) yyVals[-2+yyTop]); + } + steps.path.addLast((Expr) yyVals[0+yyTop]); + yyVal = steps; + /*$$ = new Step((Expr) $1, (Path) $3);*/ + } + break; +case 9: + // line 338 "XPathParser.y" + { + Test nt = new NodeTypeTest((short) 0); + Selector s = new Selector(Selector.DESCENDANT_OR_SELF, + Collections.singletonList (nt)); + Steps steps; + if (yyVals[-2+yyTop] instanceof Steps) + { + steps = (Steps) yyVals[-2+yyTop]; + } + else + { + steps = new Steps(); + steps.path.addFirst((Expr) yyVals[-2+yyTop]); + } + steps.path.addLast(s); + steps.path.addLast((Expr) yyVals[0+yyTop]); + yyVal = steps; + /*Step step = new Step(s, (Path) $3);*/ + /*$$ = new Step((Expr) $1, step);*/ + } + break; +case 10: + // line 362 "XPathParser.y" + { + @SuppressWarnings("unchecked") List<Test> tests = (List<Test>) yyVals[0+yyTop]; + yyVal = new Selector (Selector.CHILD, tests); + } + break; +case 11: + // line 366 "XPathParser.y" + { + /* This is safe as we create this in one of the other cases */ + @SuppressWarnings("unchecked") List<Test> tests = (List<Test>) yyVals[0+yyTop]; + yyVal = new Selector (Selector.ATTRIBUTE, tests); + } + break; +case 12: + // line 370 "XPathParser.y" + { + /* This is safe as we create this in one of the other cases */ + @SuppressWarnings("unchecked") List<Test> tests = (List<Test>) yyVals[0+yyTop]; + yyVal = new Selector (((Integer) yyVals[-2+yyTop]).intValue (), tests); + } + break; +case 13: + // line 374 "XPathParser.y" + { + List<Test> emptyList = Collections.emptyList(); + yyVal = new Selector (Selector.SELF, emptyList); + } + break; +case 14: + // line 378 "XPathParser.y" + { + List<Test> emptyList = Collections.emptyList(); + yyVal = new Selector (Selector.PARENT, emptyList); + } + break; +case 15: + // line 385 "XPathParser.y" + { + List<Test> list = new ArrayList<Test>(); + list.add((Test) yyVals[0+yyTop]); + yyVal = list; + } + break; +case 16: + // line 391 "XPathParser.y" + { + /* This is safe as we create this in one of the other cases */ + @SuppressWarnings("unchecked") List<Test> tests = (List<Test>)yyVals[-1+yyTop]; + tests.add((Test) yyVals[0+yyTop]); + yyVal = tests; + } + break; +case 17: + // line 415 "XPathParser.y" + { + yyVal = new Integer(Selector.ANCESTOR); + } + break; +case 18: + // line 419 "XPathParser.y" + { + yyVal = new Integer(Selector.ANCESTOR_OR_SELF); + } + break; +case 19: + // line 423 "XPathParser.y" + { + yyVal = new Integer(Selector.ATTRIBUTE); + } + break; +case 20: + // line 427 "XPathParser.y" + { + yyVal = new Integer(Selector.CHILD); + } + break; +case 21: + // line 431 "XPathParser.y" + { + yyVal = new Integer(Selector.DESCENDANT); + } + break; +case 22: + // line 435 "XPathParser.y" + { + yyVal = new Integer(Selector.DESCENDANT_OR_SELF); + } + break; +case 23: + // line 439 "XPathParser.y" + { + yyVal = new Integer(Selector.FOLLOWING); + } + break; +case 24: + // line 443 "XPathParser.y" + { + yyVal = new Integer(Selector.FOLLOWING_SIBLING); + } + break; +case 25: + // line 447 "XPathParser.y" + { + yyVal = new Integer(Selector.NAMESPACE); + } + break; +case 26: + // line 451 "XPathParser.y" + { + yyVal = new Integer(Selector.PARENT); + } + break; +case 27: + // line 455 "XPathParser.y" + { + yyVal = new Integer(Selector.PRECEDING); + } + break; +case 28: + // line 459 "XPathParser.y" + { + yyVal = new Integer(Selector.PRECEDING_SIBLING); + } + break; +case 29: + // line 463 "XPathParser.y" + { + yyVal = new Integer(Selector.SELF); + } + break; +case 31: + // line 472 "XPathParser.y" + { + yyVal = new NodeTypeTest(Node.PROCESSING_INSTRUCTION_NODE, (String) yyVals[-1+yyTop]); + } + break; +case 32: + // line 477 "XPathParser.y" + { + yyVal = new NodeTypeTest(((Short) yyVals[-1+yyTop]).shortValue()); + } + break; +case 33: + // line 484 "XPathParser.y" + { + yyVal = new Predicate((Expr) yyVals[-1+yyTop]); + } + break; +case 35: + // line 492 "XPathParser.y" + { + yyVal = new ParenthesizedExpr((Expr) yyVals[-1+yyTop]); + } + break; +case 36: + // line 496 "XPathParser.y" + { + yyVal = new Constant(yyVals[0+yyTop]); + } + break; +case 37: + // line 500 "XPathParser.y" + { + yyVal = new Constant(yyVals[0+yyTop]); + } + break; +case 39: + // line 508 "XPathParser.y" + { + List<Expr> emptyList = Collections.emptyList(); + yyVal = lookupFunction((String) yyVals[-2+yyTop], emptyList); + } + break; +case 40: + // line 512 "XPathParser.y" + { + /* This is safe as we create this below */ + @SuppressWarnings("unchecked") List<Expr> exprs = (List<Expr>) yyVals[-1+yyTop]; + yyVal = lookupFunction((String) yyVals[-3+yyTop], exprs); + } + break; +case 41: + // line 519 "XPathParser.y" + { + List<Expr> list = new ArrayList<Expr>(); + list.add((Expr) yyVals[0+yyTop]); + yyVal = list; + } + break; +case 42: + // line 525 "XPathParser.y" + { + /* This is safe as we create this above */ + @SuppressWarnings("unchecked") List<Expr> list = (List<Expr>) yyVals[0+yyTop]; + list.add(0, (Expr) yyVals[-2+yyTop]); + yyVal = list; + } + break; +case 44: + // line 535 "XPathParser.y" + { + yyVal = new UnionExpr((Expr) yyVals[-2+yyTop], (Expr) yyVals[0+yyTop]); + } + break; +case 47: + // line 544 "XPathParser.y" + { + Steps steps; + if (yyVals[0+yyTop] instanceof Steps) + { + steps = (Steps) yyVals[0+yyTop]; + } + else + { + steps = new Steps(); + steps.path.addFirst((Expr) yyVals[0+yyTop]); + } + steps.path.addFirst((Expr) yyVals[-2+yyTop]); + yyVal = steps; + /*$$ = new Step ((Expr) $1, (Path) $3);*/ + } + break; +case 48: + // line 560 "XPathParser.y" + { + Test nt = new NodeTypeTest((short) 0); + Selector s = new Selector(Selector.DESCENDANT_OR_SELF, + Collections.singletonList(nt)); + Steps steps; + if (yyVals[0+yyTop] instanceof Steps) + { + steps = (Steps) yyVals[0+yyTop]; + } + else + { + steps = new Steps(); + steps.path.addFirst((Expr) yyVals[0+yyTop]); + } + steps.path.addFirst(s); + steps.path.addFirst((Expr) yyVals[-2+yyTop]); + yyVal = steps; + /*Step step = new Step (s, (Path) $3);*/ + /*$$ = new Step ((Expr) $1, step);*/ + } + break; +case 50: + // line 585 "XPathParser.y" + { + Predicate filter = (Predicate) yyVals[0+yyTop]; + Selector s = new Selector(Selector.SELF, + Collections.singletonList(filter)); + Steps steps; + if (yyVals[-1+yyTop] instanceof Steps) + { + steps = (Steps) yyVals[-1+yyTop]; + } + else + { + steps = new Steps(); + steps.path.addFirst((Expr) yyVals[-1+yyTop]); + } + steps.path.addLast(s); + yyVal = steps; + /*$$ = new Step ((Expr) $1, s);*/ + } + break; +case 52: + // line 608 "XPathParser.y" + { + yyVal = new OrExpr((Expr) yyVals[-2+yyTop], (Expr) yyVals[0+yyTop]); + } + break; +case 54: + // line 616 "XPathParser.y" + { + yyVal = new AndExpr((Expr) yyVals[-2+yyTop], (Expr) yyVals[0+yyTop]); + } + break; +case 56: + // line 624 "XPathParser.y" + { + yyVal = new EqualityExpr((Expr) yyVals[-2+yyTop], (Expr) yyVals[0+yyTop], false); + } + break; +case 57: + // line 628 "XPathParser.y" + { + yyVal = new EqualityExpr((Expr) yyVals[-2+yyTop], (Expr) yyVals[0+yyTop], true); + } + break; +case 59: + // line 636 "XPathParser.y" + { + yyVal = new RelationalExpr((Expr) yyVals[-2+yyTop], (Expr) yyVals[0+yyTop], true, false); + } + break; +case 60: + // line 640 "XPathParser.y" + { + yyVal = new RelationalExpr((Expr) yyVals[-2+yyTop], (Expr) yyVals[0+yyTop], false, false); + } + break; +case 61: + // line 644 "XPathParser.y" + { + yyVal = new RelationalExpr((Expr) yyVals[-2+yyTop], (Expr) yyVals[0+yyTop], true, true); + } + break; +case 62: + // line 648 "XPathParser.y" + { + yyVal = new RelationalExpr((Expr) yyVals[-2+yyTop], (Expr) yyVals[0+yyTop], false, true); + } + break; +case 64: + // line 656 "XPathParser.y" + { + yyVal = new ArithmeticExpr((Expr) yyVals[-2+yyTop], (Expr) yyVals[0+yyTop], ArithmeticExpr.ADD); + } + break; +case 65: + // line 660 "XPathParser.y" + { + yyVal = new ArithmeticExpr((Expr) yyVals[-2+yyTop], (Expr) yyVals[0+yyTop], ArithmeticExpr.SUBTRACT); + } + break; +case 67: + // line 668 "XPathParser.y" + { + yyVal = new ArithmeticExpr((Expr) yyVals[-2+yyTop], (Expr) yyVals[0+yyTop], ArithmeticExpr.MULTIPLY); + } + break; +case 68: + // line 672 "XPathParser.y" + { + yyVal = new ArithmeticExpr((Expr) yyVals[-2+yyTop], (Expr) yyVals[0+yyTop], ArithmeticExpr.DIVIDE); + } + break; +case 69: + // line 676 "XPathParser.y" + { + yyVal = new ArithmeticExpr((Expr) yyVals[-2+yyTop], (Expr) yyVals[0+yyTop], ArithmeticExpr.MODULO); + } + break; +case 71: + // line 684 "XPathParser.y" + { + yyVal = new NegativeExpr((Expr) yyVals[0+yyTop]); + } + break; +case 72: + // line 691 "XPathParser.y" + { + yyVal = new Double((String) yyVals[0+yyTop] + ".0"); + } + break; +case 73: + // line 695 "XPathParser.y" + { + yyVal = new Double((String) yyVals[-1+yyTop] + ".0"); + } + break; +case 74: + // line 699 "XPathParser.y" + { + yyVal = new Double((String) yyVals[-2+yyTop] + "." + (String) yyVals[0+yyTop]); + } + break; +case 75: + // line 703 "XPathParser.y" + { + yyVal = new Double("0." + (String) yyVals[0+yyTop]); + } + break; +case 77: + // line 732 "XPathParser.y" + { + String name = (String) yyVals[0+yyTop]; + yyVal = new VariableReference(variableResolver, getQName(name)); + } + break; +case 78: + // line 740 "XPathParser.y" + { + yyVal = new NameTest(null, true, true); + } + break; +case 79: + // line 744 "XPathParser.y" + { + QName qName = getQName((String) yyVals[-2+yyTop]); + yyVal = new NameTest(qName, true, false); + } + break; +case 80: + // line 749 "XPathParser.y" + { + QName qName = getQName((String) yyVals[0+yyTop]); + yyVal = new NameTest(qName, false, false); + } + break; +case 82: + // line 758 "XPathParser.y" + { + yyVal = (String) yyVals[-2+yyTop] + ':' + (String) yyVals[0+yyTop]; + } + break; +case 83: + // line 765 "XPathParser.y" + { + yyVal = new Short(Node.COMMENT_NODE); + } + break; +case 84: + // line 769 "XPathParser.y" + { + yyVal = new Short(Node.TEXT_NODE); + } + break; +case 85: + // line 773 "XPathParser.y" + { + yyVal = new Short(Node.PROCESSING_INSTRUCTION_NODE); + } + break; +case 86: + // line 777 "XPathParser.y" + { + yyVal = new Short((short) 0); + } + break; + // line 988 "-" + } + yyTop -= YyLenClass.yyLen[yyN]; + yyState = yyStates[yyTop]; + int yyM = YyLhsClass.yyLhs[yyN]; + if (yyState == 0 && yyM == 0) { +//t if (yydebug != null) yydebug.shift(0, yyFinal); + yyState = yyFinal; + if (yyToken < 0) { + yyToken = yyLex.advance() ? yyLex.token() : 0; +//t if (yydebug != null) +//t yydebug.lex(yyState, yyToken,yyname(yyToken), yyLex.value()); + } + if (yyToken == 0) { +//t if (yydebug != null) yydebug.accept(yyVal); + return yyVal; + } + continue yyLoop; + } + if ((yyN = YyGindexClass.yyGindex[yyM]) != 0 && (yyN += yyState) >= 0 + && yyN < YyTableClass.yyTable.length && YyCheckClass.yyCheck[yyN] == yyState) + yyState = YyTableClass.yyTable[yyN]; + else + yyState = YyDgotoClass.yyDgoto[yyM]; +//t if (yydebug != null) yydebug.shift(yyStates[yyTop], yyState); + continue yyLoop; + } + } + } + + protected static final class YyLhsClass { + + public static final short yyLhs [] = { -1, + 0, 2, 2, 4, 4, 4, 3, 3, 3, 5, + 5, 5, 5, 5, 6, 6, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, + 8, 8, 9, 12, 12, 12, 12, 12, 15, 15, + 17, 17, 18, 18, 19, 19, 19, 19, 20, 20, + 1, 1, 21, 21, 22, 22, 22, 23, 23, 23, + 23, 23, 24, 24, 24, 25, 25, 25, 25, 26, + 26, 14, 14, 14, 14, 16, 13, 10, 10, 10, + 27, 27, 11, 11, 11, 11, + }; + } /* End of class YyLhsClass */ + + protected static final class YyLenClass { + + public static final short yyLen [] = { 2, + 1, 1, 1, 1, 2, 2, 1, 3, 3, 1, + 2, 3, 1, 1, 1, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 3, 2, 3, 1, 3, 1, 1, 1, 3, 4, + 1, 3, 1, 3, 1, 1, 3, 3, 1, 2, + 1, 3, 1, 3, 1, 3, 3, 1, 3, 3, + 3, 3, 1, 3, 3, 1, 3, 3, 3, 1, + 2, 1, 2, 3, 2, 1, 2, 1, 3, 1, + 1, 3, 1, 1, 1, 1, + }; + } /* End class YyLenClass */ + + protected static final class YyDefRedClass { + + public static final short yyDefRed [] = { 0, + 36, 0, 0, 0, 0, 0, 0, 0, 78, 0, + 0, 14, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 83, 0, 84, 86, 0, + 0, 45, 0, 3, 7, 0, 0, 15, 30, 0, + 49, 34, 37, 38, 0, 0, 43, 0, 0, 0, + 0, 0, 0, 66, 0, 0, 0, 0, 13, 0, + 80, 0, 71, 0, 0, 77, 75, 0, 0, 0, + 0, 0, 16, 0, 32, 0, 0, 0, 0, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 74, 82, 79, 35, 0, 31, 0, 8, + 9, 0, 0, 39, 0, 0, 44, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 67, 68, + 69, 33, 0, 40, 42, + }; + } /* End of class YyDefRedClass */ + + protected static final class YyDgotoClass { + + public static final short yyDgoto [] = { 105, + 31, 32, 33, 34, 35, 36, 37, 38, 73, 39, + 40, 41, 42, 43, 44, 45, 106, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, + }; + } /* End of class YyDgotoClass */ + + protected static final class YySindexClass { + + public static final short yySindex [] = { -97, + 0, -271, -267, -97, -239, -239, -97, -199, 0, -236, + -222, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -218, 0, 0, 0, + -257, 0, -241, 0, 0, -205, -221, 0, 0, -194, + 0, 0, 0, 0, -190, -185, 0, -238, -211, -234, + -255, -209, -275, 0, 0, -169, -250, -168, 0, -241, + 0, -241, 0, -205, -187, 0, 0, -167, -97, -239, + -239, -97, 0, -199, 0, -151, -43, -239, -239, 0, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, 0, 0, 0, 0, -164, 0, -211, 0, + 0, -166, -205, 0, -165, -163, 0, -241, -241, -234, + -255, -255, -209, -209, -209, -209, -275, -275, 0, 0, + 0, 0, -97, 0, 0, + }; + } /* End of class YySindexClass */ + + protected static final class YyRindexClass { + + public static final short yyRindex [] = { 0, + 0, 58, 1, 0, 420, 0, 0, 0, 0, 0, + 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -161, 0, 0, 0, + 40, 0, 237, 0, 0, 168, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 459, 0, 277, 557, 544, + 656, 561, 474, 0, 19, 75, 0, 0, 0, 295, + 0, 334, 0, 183, 114, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 686, 0, + 0, 0, 222, 0, -156, 0, 0, 351, 405, 553, + 665, 697, 577, 600, 617, 639, 513, 528, 0, 0, + 0, 0, 0, 0, 0, + }; + } /* End of class YyRindexClass */ + + protected static final class YyGindexClass { + + public static final short yyGindex [] = { 7, + 0, 0, 8, 0, 3, -3, 0, 0, 48, 0, + 0, 0, 0, 0, 0, 0, -12, 0, 35, 0, + 44, 36, -1, -54, 2, -7, -2, + }; + } /* End of class YyGindexClass */ + + protected static final class YyTableClass { + + public static final short yyTable [] = { 63, + 81, 90, 61, 61, 64, 61, 30, 66, 94, 56, + 58, 57, 60, 62, 84, 85, 86, 87, 80, 3, + 91, 92, 65, 72, 70, 71, 95, 78, 79, 113, + 114, 115, 116, 82, 83, 67, 8, 9, 68, 1, + 69, 59, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 72, 72, 74, 3, + 26, 27, 28, 29, 88, 89, 75, 61, 61, 76, + 103, 61, 100, 101, 73, 61, 61, 9, 102, 77, + 111, 112, 119, 120, 121, 108, 109, 81, 93, 117, + 118, 97, 96, 98, 94, 80, 122, 124, 123, 85, + 26, 27, 28, 29, 41, 1, 2, 3, 4, 104, + 125, 107, 99, 81, 5, 6, 110, 0, 0, 0, + 0, 0, 0, 7, 8, 9, 10, 0, 13, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 0, 0, 0, 0, 26, 27, + 28, 29, 0, 0, 0, 0, 0, 0, 0, 1, + 2, 3, 4, 0, 0, 0, 0, 10, 5, 6, + 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, + 10, 0, 11, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, + 0, 0, 26, 27, 28, 29, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, + 0, 12, 5, 6, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 9, 10, 0, 2, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 0, 0, 0, 0, 26, 27, 28, 29, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 46, 81, 76, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 5, 80, 81, 81, 81, 81, + 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 80, 80, 80, 80, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 6, 72, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 47, 73, 0, 72, 72, 72, 72, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 73, 73, 73, 73, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 13, + 81, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 48, 13, 0, 0, 0, 81, + 81, 81, 81, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 0, 13, 13, 13, 13, 10, 0, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 11, 10, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 70, 11, + 0, 0, 0, 10, 10, 10, 10, 0, 0, 0, + 0, 0, 0, 63, 0, 0, 0, 0, 11, 11, + 11, 11, 12, 0, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 2, 12, 2, + 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, + 2, 2, 64, 2, 0, 0, 0, 12, 12, 12, + 12, 0, 0, 0, 0, 0, 0, 65, 0, 0, + 0, 0, 2, 2, 2, 2, 0, 46, 0, 46, + 46, 46, 0, 53, 46, 46, 46, 46, 46, 46, + 46, 46, 54, 46, 0, 5, 51, 5, 5, 5, + 58, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 5, 46, 46, 46, 46, 60, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 6, 0, 6, 6, 6, 59, + 0, 6, 6, 6, 6, 6, 6, 6, 6, 0, + 6, 47, 0, 47, 47, 47, 62, 0, 47, 47, + 47, 47, 47, 47, 47, 47, 0, 47, 0, 6, + 6, 6, 6, 0, 0, 0, 0, 0, 61, 0, + 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, + 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, + 0, 0, 0, 0, 56, 48, 0, 48, 48, 48, + 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, + 4, 48, 4, 4, 4, 52, 0, 4, 4, 4, + 4, 4, 4, 4, 4, 0, 57, 0, 0, 0, + 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 4, 4, 4, 70, + 0, 70, 70, 0, 0, 0, 70, 70, 70, 70, + 70, 70, 70, 70, 63, 70, 63, 63, 0, 0, + 0, 63, 63, 63, 63, 63, 63, 63, 63, 0, + 0, 0, 0, 0, 70, 70, 70, 70, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 63, 63, 64, 0, 64, 64, 0, 0, 0, + 64, 64, 64, 64, 64, 64, 64, 64, 65, 0, + 65, 65, 0, 0, 0, 65, 65, 65, 65, 65, + 65, 65, 65, 0, 53, 0, 53, 53, 0, 0, + 64, 64, 0, 54, 0, 54, 54, 51, 0, 51, + 51, 58, 0, 58, 58, 65, 65, 0, 58, 58, + 58, 58, 58, 58, 0, 0, 0, 60, 0, 60, + 60, 53, 53, 0, 60, 60, 60, 60, 60, 60, + 54, 54, 0, 0, 51, 0, 0, 0, 58, 58, + 59, 0, 59, 59, 0, 0, 0, 59, 59, 59, + 59, 59, 59, 0, 60, 60, 0, 62, 0, 62, + 62, 0, 0, 0, 62, 62, 62, 62, 62, 62, + 0, 0, 0, 0, 0, 0, 0, 59, 59, 61, + 0, 61, 61, 0, 0, 0, 61, 61, 61, 61, + 61, 61, 0, 0, 62, 62, 55, 0, 55, 55, + 0, 0, 0, 55, 55, 56, 0, 56, 56, 0, + 0, 0, 56, 56, 0, 0, 61, 61, 0, 0, + 0, 0, 0, 0, 0, 0, 52, 0, 52, 52, + 0, 0, 0, 55, 55, 0, 0, 57, 0, 57, + 57, 0, 56, 56, 57, 57, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 57, 57, + }; + } /* End of class YyTableClass */ + + protected static final class YyCheckClass { + + public static final short yyCheck [] = { 7, + 0, 277, 5, 6, 8, 8, 0, 10, 259, 281, + 4, 279, 5, 6, 270, 271, 272, 273, 0, 259, + 296, 297, 259, 262, 266, 267, 277, 266, 267, 84, + 85, 86, 87, 268, 269, 258, 276, 277, 257, 0, + 298, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 262, 0, 280, 259, + 300, 301, 302, 303, 274, 275, 261, 70, 71, 260, + 74, 74, 70, 71, 0, 78, 79, 277, 72, 265, + 82, 83, 90, 91, 92, 78, 79, 299, 258, 88, + 89, 279, 261, 261, 259, 48, 263, 261, 264, 261, + 300, 301, 302, 303, 261, 257, 258, 259, 260, 261, + 123, 77, 69, 0, 266, 267, 81, -1, -1, -1, + -1, -1, -1, 275, 276, 277, 278, -1, 0, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 293, 294, 295, -1, -1, -1, -1, 300, 301, + 302, 303, -1, -1, -1, -1, -1, -1, -1, 257, + 258, 259, 260, -1, -1, -1, -1, 0, 266, 267, + -1, -1, -1, -1, -1, -1, -1, 275, 276, 277, + 278, -1, 0, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, -1, -1, + -1, -1, 300, 301, 302, 303, -1, -1, -1, -1, + -1, -1, -1, 257, 258, 259, 260, -1, -1, -1, + -1, 0, 266, 267, -1, -1, -1, -1, -1, -1, + -1, -1, 276, 277, 278, -1, 0, 281, 282, 283, + 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, + 294, 295, -1, -1, -1, -1, 300, 301, 302, 303, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 0, 277, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 0, 277, 296, 297, 298, 299, + 261, -1, 263, 264, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 296, 297, 298, 299, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 0, 277, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, + 0, 277, -1, 296, 297, 298, 299, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 296, 297, 298, 299, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 261, + 277, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 0, 277, -1, -1, -1, 296, + 297, 298, 299, -1, -1, -1, -1, -1, -1, 0, + -1, -1, -1, -1, 296, 297, 298, 299, 261, -1, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 261, 277, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 0, 277, + -1, -1, -1, 296, 297, 298, 299, -1, -1, -1, + -1, -1, -1, 0, -1, -1, -1, -1, 296, 297, + 298, 299, 261, -1, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 261, 277, 263, + 264, 265, -1, -1, 268, 269, 270, 271, 272, 273, + 274, 275, 0, 277, -1, -1, -1, 296, 297, 298, + 299, -1, -1, -1, -1, -1, -1, 0, -1, -1, + -1, -1, 296, 297, 298, 299, -1, 261, -1, 263, + 264, 265, -1, 0, 268, 269, 270, 271, 272, 273, + 274, 275, 0, 277, -1, 261, 0, 263, 264, 265, + 0, -1, 268, 269, 270, 271, 272, 273, 274, 275, + -1, 277, 296, 297, 298, 299, 0, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 296, 297, 298, 299, 261, -1, 263, 264, 265, 0, + -1, 268, 269, 270, 271, 272, 273, 274, 275, -1, + 277, 261, -1, 263, 264, 265, 0, -1, 268, 269, + 270, 271, 272, 273, 274, 275, -1, 277, -1, 296, + 297, 298, 299, -1, -1, -1, -1, -1, 0, -1, + -1, -1, -1, -1, -1, -1, 296, 297, 298, 299, + -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, + -1, -1, -1, -1, 0, 261, -1, 263, 264, 265, + -1, -1, 268, 269, 270, 271, 272, 273, 274, 275, + 261, 277, 263, 264, 265, 0, -1, 268, 269, 270, + 271, 272, 273, 274, 275, -1, 0, -1, -1, -1, + 296, 297, 298, 299, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 296, 297, 298, 299, 261, + -1, 263, 264, -1, -1, -1, 268, 269, 270, 271, + 272, 273, 274, 275, 261, 277, 263, 264, -1, -1, + -1, 268, 269, 270, 271, 272, 273, 274, 275, -1, + -1, -1, -1, -1, 296, 297, 298, 299, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 298, 299, 261, -1, 263, 264, -1, -1, -1, + 268, 269, 270, 271, 272, 273, 274, 275, 261, -1, + 263, 264, -1, -1, -1, 268, 269, 270, 271, 272, + 273, 274, 275, -1, 261, -1, 263, 264, -1, -1, + 298, 299, -1, 261, -1, 263, 264, 261, -1, 263, + 264, 261, -1, 263, 264, 298, 299, -1, 268, 269, + 270, 271, 272, 273, -1, -1, -1, 261, -1, 263, + 264, 298, 299, -1, 268, 269, 270, 271, 272, 273, + 298, 299, -1, -1, 298, -1, -1, -1, 298, 299, + 261, -1, 263, 264, -1, -1, -1, 268, 269, 270, + 271, 272, 273, -1, 298, 299, -1, 261, -1, 263, + 264, -1, -1, -1, 268, 269, 270, 271, 272, 273, + -1, -1, -1, -1, -1, -1, -1, 298, 299, 261, + -1, 263, 264, -1, -1, -1, 268, 269, 270, 271, + 272, 273, -1, -1, 298, 299, 261, -1, 263, 264, + -1, -1, -1, 268, 269, 261, -1, 263, 264, -1, + -1, -1, 268, 269, -1, -1, 298, 299, -1, -1, + -1, -1, -1, -1, -1, -1, 261, -1, 263, 264, + -1, -1, -1, 298, 299, -1, -1, 261, -1, 263, + 264, -1, 298, 299, 268, 269, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 298, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 298, 299, + }; + } /* End of class YyCheckClass */ + + +//t protected static final class YyRuleClass { + +//t public static final String yyRule [] = { +//t "$accept : expr", +//t "expr : or_expr", +//t "location_path : relative_location_path", +//t "location_path : absolute_location_path", +//t "absolute_location_path : SLASH", +//t "absolute_location_path : SLASH relative_location_path", +//t "absolute_location_path : DOUBLE_SLASH relative_location_path", +//t "relative_location_path : step", +//t "relative_location_path : relative_location_path SLASH step", +//t "relative_location_path : relative_location_path DOUBLE_SLASH step", +//t "step : step_node_test", +//t "step : AT step_node_test", +//t "step : axis_name DOUBLE_COLON step_node_test", +//t "step : DOT", +//t "step : DOUBLE_DOT", +//t "step_node_test : node_test", +//t "step_node_test : step_node_test predicate", +//t "axis_name : ANCESTOR", +//t "axis_name : ANCESTOR_OR_SELF", +//t "axis_name : ATTRIBUTE", +//t "axis_name : CHILD", +//t "axis_name : DESCENDANT", +//t "axis_name : DESCENDANT_OR_SELF", +//t "axis_name : FOLLOWING", +//t "axis_name : FOLLOWING_SIBLING", +//t "axis_name : NAMESPACE", +//t "axis_name : PARENT", +//t "axis_name : PRECEDING", +//t "axis_name : PRECEDING_SIBLING", +//t "axis_name : SELF", +//t "node_test : name_test", +//t "node_test : PROCESSING_INSTRUCTION LITERAL RP", +//t "node_test : node_type RP", +//t "predicate : LB expr RB", +//t "primary_expr : variable_reference", +//t "primary_expr : LP expr RP", +//t "primary_expr : LITERAL", +//t "primary_expr : number", +//t "primary_expr : function_call", +//t "function_call : function_name LP RP", +//t "function_call : function_name LP argument_list RP", +//t "argument_list : expr", +//t "argument_list : expr COMMA argument_list", +//t "union_expr : path_expr", +//t "union_expr : union_expr PIPE path_expr", +//t "path_expr : location_path", +//t "path_expr : filter_expr", +//t "path_expr : filter_expr SLASH relative_location_path", +//t "path_expr : filter_expr DOUBLE_SLASH relative_location_path", +//t "filter_expr : primary_expr", +//t "filter_expr : filter_expr predicate", +//t "or_expr : and_expr", +//t "or_expr : or_expr OR and_expr", +//t "and_expr : equality_expr", +//t "and_expr : and_expr AND equality_expr", +//t "equality_expr : relational_expr", +//t "equality_expr : equality_expr EQ relational_expr", +//t "equality_expr : equality_expr NE relational_expr", +//t "relational_expr : additive_expr", +//t "relational_expr : relational_expr LT additive_expr", +//t "relational_expr : relational_expr GT additive_expr", +//t "relational_expr : relational_expr LTE additive_expr", +//t "relational_expr : relational_expr GTE additive_expr", +//t "additive_expr : multiplicative_expr", +//t "additive_expr : additive_expr PLUS multiplicative_expr", +//t "additive_expr : additive_expr MINUS multiplicative_expr", +//t "multiplicative_expr : unary_expr", +//t "multiplicative_expr : multiplicative_expr STAR unary_expr", +//t "multiplicative_expr : multiplicative_expr DIV unary_expr", +//t "multiplicative_expr : multiplicative_expr MOD unary_expr", +//t "unary_expr : union_expr", +//t "unary_expr : MINUS unary_expr", +//t "number : DIGITS", +//t "number : DIGITS DOT", +//t "number : DIGITS DOT DIGITS", +//t "number : DOT DIGITS", +//t "function_name : qname", +//t "variable_reference : DOLLAR qname", +//t "name_test : STAR", +//t "name_test : NAME COLON STAR", +//t "name_test : qname", +//t "qname : NAME", +//t "qname : NAME COLON NAME", +//t "node_type : COMMENT", +//t "node_type : TEXT", +//t "node_type : PROCESSING_INSTRUCTION", +//t "node_type : NODE", +//t }; +//t } /* End of class YyRuleClass */ + + protected static final class YyNameClass { + + public static final String yyName [] = { + "end-of-file",null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,"LITERAL","DIGITS","NAME","LP", + "RP","LB","RB","COMMA","PIPE","SLASH","DOUBLE_SLASH","EQ","NE","GT", + "LT","GTE","LTE","PLUS","MINUS","AT","STAR","DOLLAR","COLON", + "DOUBLE_COLON","DOT","DOUBLE_DOT","ANCESTOR","ANCESTOR_OR_SELF", + "ATTRIBUTE","CHILD","DESCENDANT","DESCENDANT_OR_SELF","FOLLOWING", + "FOLLOWING_SIBLING","NAMESPACE","PARENT","PRECEDING", + "PRECEDING_SIBLING","SELF","DIV","MOD","OR","AND","COMMENT", + "PROCESSING_INSTRUCTION","TEXT","NODE","UNARY", + }; + } /* End of class YyNameClass */ + + + // line 783 "XPathParser.y" + +} + // line 1463 "-" diff --git a/libjava/classpath/gnu/xml/xpath/XPathParser.y b/libjava/classpath/gnu/xml/xpath/XPathParser.y new file mode 100644 index 000000000..a6d3fd130 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/XPathParser.y @@ -0,0 +1,794 @@ +%{ +/* XPathParser.y - An XPath 1.0 parser. + Copyright (C) 2004 The Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.xml.xpath; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.xpath.XPathFunctionResolver; +import javax.xml.xpath.XPathVariableResolver; +import org.w3c.dom.Node; + +/** + * An XPath 1.0 parser. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class XPathParser +{ + + NamespaceContext namespaceContext; + XPathVariableResolver variableResolver; + XPathFunctionResolver functionResolver; + + QName getQName(String name) + { + QName qName = QName.valueOf(name); + if (namespaceContext != null) + { + String prefix = qName.getPrefix(); + String uri = qName.getNamespaceURI(); + if (prefix != null && (uri == null || uri.length() == 0)) + { + uri = namespaceContext.getNamespaceURI(prefix); + String localName = qName.getLocalPart(); + qName = new QName(uri, localName, prefix); + } + } + return qName; + } + + Expr lookupFunction(String name, List<Expr> args) + { + int arity = args.size(); + if ("position".equals(name) && arity == 0) + { + return new PositionFunction(); + } + else if ("last".equals(name) && arity == 0) + { + return new LastFunction(); + } + else if ("string".equals(name) && (arity == 1 || arity == 0)) + { + return new StringFunction(args); + } + else if ("number".equals(name) && (arity == 1 || arity == 0)) + { + return new NumberFunction(args); + } + else if ("boolean".equals(name) && arity == 1) + { + return new BooleanFunction(args); + } + else if ("count".equals(name) && arity == 1) + { + return new CountFunction(args); + } + else if ("not".equals(name) && arity == 1) + { + return new NotFunction(args); + } + else if ("id".equals(name) && arity == 1) + { + return new IdFunction(args); + } + else if ("concat".equals(name) && arity > 1) + { + return new ConcatFunction(args); + } + else if ("true".equals(name) && arity == 0) + { + return new TrueFunction(); + } + else if ("false".equals(name) && arity == 0) + { + return new FalseFunction(); + } + else if ("name".equals(name) && (arity == 1 || arity == 0)) + { + return new NameFunction(args); + } + else if ("local-name".equals(name) && (arity == 1 || arity == 0)) + { + return new LocalNameFunction(args); + } + else if ("namespace-uri".equals(name) && (arity == 1 || arity == 0)) + { + return new NamespaceUriFunction(args); + } + else if ("starts-with".equals(name) && arity == 2) + { + return new StartsWithFunction(args); + } + else if ("contains".equals(name) && arity == 2) + { + return new ContainsFunction(args); + } + else if ("string-length".equals(name) && (arity == 1 || arity == 0)) + { + return new StringLengthFunction(args); + } + else if ("translate".equals(name) && arity == 3) + { + return new TranslateFunction(args); + } + else if ("normalize-space".equals(name) && (arity == 1 || arity == 0)) + { + return new NormalizeSpaceFunction(args); + } + else if ("substring".equals(name) && (arity == 2 || arity == 3)) + { + return new SubstringFunction(args); + } + else if ("substring-before".equals(name) && arity == 2) + { + return new SubstringBeforeFunction(args); + } + else if ("substring-after".equals(name) && arity == 2) + { + return new SubstringAfterFunction(args); + } + else if ("lang".equals(name) && arity == 1) + { + return new LangFunction(args); + } + else if ("sum".equals(name) && arity == 1) + { + return new SumFunction(args); + } + else if ("floor".equals(name) && arity == 1) + { + return new FloorFunction(args); + } + else if ("ceiling".equals(name) && arity == 1) + { + return new CeilingFunction(args); + } + else if ("round".equals(name) && arity == 1) + { + return new RoundFunction(args); + } + else if (functionResolver != null) + { + QName qName = QName.valueOf(name); + Object function = functionResolver.resolveFunction(qName, arity); + if (function != null && + function instanceof Function && + function instanceof Expr) + { + Function f = (Function) function; + f.setArguments(args); + return (Expr) function; + } + } + return new FunctionCall(functionResolver, name, args); + } + +%} + +%token LITERAL +%token DIGITS +%token NAME + +%token LP // '(' +%token RP // ')' +%token LB // '[' +%token RB // ']' +%token COMMA // ',' +%token PIPE // '|' +%token SLASH // '/' +%token DOUBLE_SLASH // '//' +%token EQ // '=' +%token NE // '!=' +%token GT // '>' +%token LT // '<' +%token GTE // '>=' +%token LTE // '<=' +%token PLUS // '+' +%token MINUS // '-' +%token AT // '@' +%token STAR // '*' +%token DOLLAR // '$' +%token COLON // ':' +%token DOUBLE_COLON // '::' +%token DOT // '.' +%token DOUBLE_DOT // '..' + +%token ANCESTOR +%token ANCESTOR_OR_SELF +%token ATTRIBUTE +%token CHILD +%token DESCENDANT +%token DESCENDANT_OR_SELF +%token FOLLOWING +%token FOLLOWING_SIBLING +%token NAMESPACE +%token PARENT +%token PRECEDING +%token PRECEDING_SIBLING +%token SELF +%token DIV +%token MOD +%token OR +%token AND +%token COMMENT +%token PROCESSING_INSTRUCTION +%token TEXT +%token NODE + +%right UNARY + +%start expr + +%% + +expr: + or_expr + ; + +location_path: + relative_location_path + | absolute_location_path + ; + +absolute_location_path: + SLASH + { + $$ = new Root(); + } + | SLASH relative_location_path + { + Steps steps; + if ($2 instanceof Steps) + { + steps = (Steps) $2; + } + else + { + steps = new Steps(); + steps.path.addFirst((Expr) $2); + } + steps.path.addFirst(new Root()); + $$ = steps; + //$$ = new Step(new Root(), (Path) $2); + } + | DOUBLE_SLASH relative_location_path + { + Test nt = new NodeTypeTest((short) 0); + Selector s = new Selector(Selector.DESCENDANT_OR_SELF, + Collections.singletonList (nt)); + Steps steps; + if ($2 instanceof Steps) + { + steps = (Steps) $2; + } + else + { + steps = new Steps(); + steps.path.addFirst((Expr) $2); + } + steps.path.addFirst(s); + steps.path.addFirst(new Root()); + $$ = steps; + //Step step = new Step(s, (Path) $2); + //$$ = new Step(new Root(), step); + } + ; + +relative_location_path: + step + | relative_location_path SLASH step + { + Steps steps; + if ($1 instanceof Steps) + { + steps = (Steps) $1; + } + else + { + steps = new Steps(); + steps.path.addFirst((Expr) $1); + } + steps.path.addLast((Expr) $3); + $$ = steps; + //$$ = new Step((Expr) $1, (Path) $3); + } + | relative_location_path DOUBLE_SLASH step + { + Test nt = new NodeTypeTest((short) 0); + Selector s = new Selector(Selector.DESCENDANT_OR_SELF, + Collections.singletonList (nt)); + Steps steps; + if ($1 instanceof Steps) + { + steps = (Steps) $1; + } + else + { + steps = new Steps(); + steps.path.addFirst((Expr) $1); + } + steps.path.addLast(s); + steps.path.addLast((Expr) $3); + $$ = steps; + //Step step = new Step(s, (Path) $3); + //$$ = new Step((Expr) $1, step); + } + ; + +step: + step_node_test + { + @SuppressWarnings("unchecked") List<Test> tests = (List<Test>) $1; + $$ = new Selector (Selector.CHILD, tests); + } + | AT step_node_test + { + @SuppressWarnings("unchecked") List<Test> tests = (List<Test>) $2; + $$ = new Selector (Selector.ATTRIBUTE, tests); + } + | axis_name DOUBLE_COLON step_node_test + { + @SuppressWarnings("unchecked") List<Test> tests = (List<Test>) $3; + $$ = new Selector (((Integer) $1).intValue (), tests); + } + | DOT + { + List<Test> emptyList = Collections.emptyList(); + $$ = new Selector (Selector.SELF, emptyList); + } + | DOUBLE_DOT + { + List<Test> emptyList = Collections.emptyList(); + $$ = new Selector (Selector.PARENT, emptyList); + } + ; + +step_node_test: + node_test + { + List<Test> list = new ArrayList<Test>(); + list.add((Test) $1); + $$ = list; + } + | step_node_test predicate + { + /* This is safe as we create this in one of the other cases */ + @SuppressWarnings("unchecked") List<Test> tests = (List<Test>)$1; + tests.add((Test) $2); + $$ = list; + } + ; + +/*predicate_list: + predicate + { + List list = new ArrayList (); + list.add ($1); + $$ = list; + } + | predicate predicate_list + { + List list = (List) $3; + list.add (0, $1); + $$ = list; + } + ;*/ + +axis_name: + ANCESTOR + { + $$ = new Integer(Selector.ANCESTOR); + } + | ANCESTOR_OR_SELF + { + $$ = new Integer(Selector.ANCESTOR_OR_SELF); + } + | ATTRIBUTE + { + $$ = new Integer(Selector.ATTRIBUTE); + } + | CHILD + { + $$ = new Integer(Selector.CHILD); + } + | DESCENDANT + { + $$ = new Integer(Selector.DESCENDANT); + } + | DESCENDANT_OR_SELF + { + $$ = new Integer(Selector.DESCENDANT_OR_SELF); + } + | FOLLOWING + { + $$ = new Integer(Selector.FOLLOWING); + } + | FOLLOWING_SIBLING + { + $$ = new Integer(Selector.FOLLOWING_SIBLING); + } + | NAMESPACE + { + $$ = new Integer(Selector.NAMESPACE); + } + | PARENT + { + $$ = new Integer(Selector.PARENT); + } + | PRECEDING + { + $$ = new Integer(Selector.PRECEDING); + } + | PRECEDING_SIBLING + { + $$ = new Integer(Selector.PRECEDING_SIBLING); + } + | SELF + { + $$ = new Integer(Selector.SELF); + } + ; + +node_test: + name_test + /*| PROCESSING_INSTRUCTION LP LITERAL RP*/ + | PROCESSING_INSTRUCTION LITERAL RP + { + $$ = new NodeTypeTest(Node.PROCESSING_INSTRUCTION_NODE, (String) $2); + } + /*| node_type LP RP*/ + | node_type RP + { + $$ = new NodeTypeTest(((Short) $1).shortValue()); + } + ; + +predicate: + LB expr RB + { + $$ = new Predicate((Expr) $2); + } + ; + +primary_expr: + variable_reference + | LP expr RP + { + $$ = new ParenthesizedExpr((Expr) $2); + } + | LITERAL + { + $$ = new Constant($1); + } + | number + { + $$ = new Constant($1); + } + | function_call + ; + +function_call: + function_name LP RP + { + List<Expr> emptyList = Collections.emptyList(); + $$ = lookupFunction((String) $1, emptyList); + } + | function_name LP argument_list RP + { + /* This is safe as we create this below */ + @SuppressWarnings("unchecked") List<Expr> exprs = (List<Expr>) $3; + $$ = lookupFunction((String) $1, (List) exprs); + } + ; + +argument_list: + expr + { + List<Expr> list = new ArrayList<Expr>(); + list.add((Expr) $1); + $$ = list; + } + | expr COMMA argument_list + { + /* This is safe as we create this above */ + @SuppressWarnings("unchecked") List<Expr> list = (List<Expr>) $3; + list.add(0, (Expr) $1); + $$ = list; + } + ; + +union_expr: + path_expr + | union_expr PIPE path_expr + { + $$ = new UnionExpr((Expr) $1, (Expr) $3); + } + ; + +path_expr: + location_path + | filter_expr + | filter_expr SLASH relative_location_path + { + Steps steps; + if ($3 instanceof Steps) + { + steps = (Steps) $3; + } + else + { + steps = new Steps(); + steps.path.addFirst((Expr) $3); + } + steps.path.addFirst((Expr) $1); + $$ = steps; + //$$ = new Step ((Expr) $1, (Path) $3); + } + | filter_expr DOUBLE_SLASH relative_location_path + { + Test nt = new NodeTypeTest((short) 0); + Selector s = new Selector(Selector.DESCENDANT_OR_SELF, + Collections.singletonList(nt)); + Steps steps; + if ($3 instanceof Steps) + { + steps = (Steps) $3; + } + else + { + steps = new Steps(); + steps.path.addFirst($3); + } + steps.path.addFirst(s); + steps.path.addFirst((Expr) $1); + $$ = steps; + //Step step = new Step (s, (Path) $3); + //$$ = new Step ((Expr) $1, step); + } + ; + +filter_expr: + primary_expr + | filter_expr predicate + { + Predicate filter = (Predicate) $2; + Selector s = new Selector(Selector.SELF, + Collections.singletonList(filter)); + Steps steps; + if ($1 instanceof Steps) + { + steps = (Steps) $1; + } + else + { + steps = new Steps(); + steps.path.addFirst((Expr) $1); + } + steps.path.addLast(s); + $$ = steps; + //$$ = new Step ((Expr) $1, s); + } + ; + +or_expr: + and_expr + | or_expr OR and_expr + { + $$ = new OrExpr((Expr) $1, (Expr) $3); + } + ; + +and_expr: + equality_expr + | and_expr AND equality_expr + { + $$ = new AndExpr((Expr) $1, (Expr) $3); + } + ; + +equality_expr: + relational_expr + | equality_expr EQ relational_expr + { + $$ = new EqualityExpr((Expr) $1, (Expr) $3, false); + } + | equality_expr NE relational_expr + { + $$ = new EqualityExpr((Expr) $1, (Expr) $3, true); + } + ; + +relational_expr: + additive_expr + | relational_expr LT additive_expr + { + $$ = new RelationalExpr((Expr) $1, (Expr) $3, true, false); + } + | relational_expr GT additive_expr + { + $$ = new RelationalExpr((Expr) $1, (Expr) $3, false, false); + } + | relational_expr LTE additive_expr + { + $$ = new RelationalExpr((Expr) $1, (Expr) $3, true, true); + } + | relational_expr GTE additive_expr + { + $$ = new RelationalExpr((Expr) $1, (Expr) $3, false, true); + } + ; + +additive_expr: + multiplicative_expr + | additive_expr PLUS multiplicative_expr + { + $$ = new ArithmeticExpr((Expr) $1, (Expr) $3, ArithmeticExpr.ADD); + } + | additive_expr MINUS multiplicative_expr + { + $$ = new ArithmeticExpr((Expr) $1, (Expr) $3, ArithmeticExpr.SUBTRACT); + } + ; + +multiplicative_expr: + unary_expr + | multiplicative_expr STAR unary_expr + { + $$ = new ArithmeticExpr((Expr) $1, (Expr) $3, ArithmeticExpr.MULTIPLY); + } + | multiplicative_expr DIV unary_expr + { + $$ = new ArithmeticExpr((Expr) $1, (Expr) $3, ArithmeticExpr.DIVIDE); + } + | multiplicative_expr MOD unary_expr + { + $$ = new ArithmeticExpr((Expr) $1, (Expr) $3, ArithmeticExpr.MODULO); + } + ; + +unary_expr: + union_expr + | MINUS unary_expr %prec UNARY + { + $$ = new NegativeExpr((Expr) $2); + } + ; + +number: + DIGITS + { + $$ = new Double((String) $1 + ".0"); + } + | DIGITS DOT + { + $$ = new Double((String) $1 + ".0"); + } + | DIGITS DOT DIGITS + { + $$ = new Double((String) $1 + "." + (String) $3); + } + | DOT DIGITS + { + $$ = new Double("0." + (String) $2); + } + ; + +function_name: + qname +/* | node_type + { + switch (((Short) $1).shortValue ()) + { + case Node.COMMENT_NODE: + $$ = "comment"; + break; + case Node.TEXT_NODE: + $$ = "text"; + break; + case Node.PROCESSING_INSTRUCTION_NODE: + $$ = "processing-instruction"; + break; + default: + $$ = "node"; + break; + } + }*/ + ; + +variable_reference: + DOLLAR qname + { + String name = (String) $2; + $$ = new VariableReference(variableResolver, getQName(name)); + } + ; + +name_test: + STAR + { + $$ = new NameTest(null, true, true); + } + | NAME COLON STAR + { + QName qName = getQName((String) $1); + $$ = new NameTest(qName, true, false); + } + | qname + { + QName qName = getQName((String) $1); + $$ = new NameTest(qName, false, false); + } + ; + +qname: + NAME + | NAME COLON NAME + { + $$ = (String) $1 + ':' + (String) $3; + } + ; + +node_type: + COMMENT + { + $$ = new Short(Node.COMMENT_NODE); + } + | TEXT + { + $$ = new Short(Node.TEXT_NODE); + } + | PROCESSING_INSTRUCTION + { + $$ = new Short(Node.PROCESSING_INSTRUCTION_NODE); + } + | NODE + { + $$ = new Short((short) 0); + } + ; + +%% + +} diff --git a/libjava/classpath/gnu/xml/xpath/XPathTokenizer.java b/libjava/classpath/gnu/xml/xpath/XPathTokenizer.java new file mode 100644 index 000000000..879931bd5 --- /dev/null +++ b/libjava/classpath/gnu/xml/xpath/XPathTokenizer.java @@ -0,0 +1,594 @@ +/* XPathTokenizer.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.xpath; + +import gnu.java.lang.CPStringBuilder; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.util.Map; +import java.util.TreeMap; + +/*import antlr.Token; +import antlr.TokenStream; +import antlr.TokenStreamException; +import antlr.TokenStreamIOException;*/ + +/** + * XPath 1.0 expression tokenizer. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +public class XPathTokenizer +implements XPathParser.yyInput +//implements TokenStream +{ + + static class XPathToken + //extends Token + { + + int type; + String val; + + XPathToken (int type) + { + this (type, null); + } + + XPathToken (int type, String val) + { + //super (type); + this.type = type; + this.val = val; + } + + public String getText () + { + return val; + } + + public String toString () + { + return val; + } + + } + + static final Map<String,Integer> keywords = new TreeMap<String,Integer> (); + static + { + keywords.put ("ancestor", new Integer (XPathParser.ANCESTOR)); + keywords.put ("ancestor-or-self", new Integer (XPathParser.ANCESTOR_OR_SELF)); + keywords.put ("attribute", new Integer (XPathParser.ATTRIBUTE)); + keywords.put ("child", new Integer (XPathParser.CHILD)); + keywords.put ("descendant", new Integer (XPathParser.DESCENDANT)); + keywords.put ("descendant-or-self", new Integer (XPathParser.DESCENDANT_OR_SELF)); + keywords.put ("following", new Integer (XPathParser.FOLLOWING)); + keywords.put ("following-sibling", new Integer (XPathParser.FOLLOWING_SIBLING)); + keywords.put ("namespace", new Integer (XPathParser.NAMESPACE)); + keywords.put ("parent", new Integer (XPathParser.PARENT)); + keywords.put ("preceding", new Integer (XPathParser.PRECEDING)); + keywords.put ("preceding-sibling", new Integer (XPathParser.PRECEDING_SIBLING)); + keywords.put ("self", new Integer (XPathParser.SELF)); + keywords.put ("div", new Integer (XPathParser.DIV)); + keywords.put ("mod", new Integer (XPathParser.MOD)); + keywords.put ("or", new Integer (XPathParser.OR)); + keywords.put ("and", new Integer (XPathParser.AND)); + keywords.put ("comment", new Integer (XPathParser.COMMENT)); + keywords.put ("processing-instruction", new Integer (XPathParser.PROCESSING_INSTRUCTION)); + keywords.put ("text", new Integer (XPathParser.TEXT)); + keywords.put ("node", new Integer (XPathParser.NODE)); + } + + Reader in; + XPathToken token; + XPathToken lastToken; + + public XPathTokenizer (String expr) + { + this (new StringReader (expr)); + } + + XPathTokenizer (Reader in) + { + this.in = in.markSupported () ? in : new BufferedReader (in); + } + + /* Begin ANTLR specific * + + public Token nextToken () + throws TokenStreamException + { + try + { + if (!advance ()) + { + throw new TokenStreamException ("eof"); + } + token (); + return token; + } + catch (IOException e) + { + throw new TokenStreamIOException (e); + } + } + + * End ANTLR specific */ + + public boolean advance () + throws IOException + { + lastToken = token; + int c = in.read (); + switch (c) + { + case -1: // eof + return false; + case 0x20: + case 0x09: + case 0x0d: + case 0x0a: // skip whitespace + return advance (); + case 0x22: // " + case 0x27: // ' + token = consume_literal (c); + break; + case 0x28: // ( + token = new XPathToken (XPathParser.LP); + break; + case 0x29: // ) + token = new XPathToken (XPathParser.RP); + break; + case 0x5b: // [ + token = new XPathToken (XPathParser.LB); + break; + case 0x5d: // ] + token = new XPathToken (XPathParser.RB); + break; + case 0x2c: // , + token = new XPathToken (XPathParser.COMMA); + break; + case 0x7c: // | + token = new XPathToken (XPathParser.PIPE); + break; + case 0x2f: // / + in.mark (1); + int d1 = in.read (); + if (d1 == 0x2f) + { + token = new XPathToken (XPathParser.DOUBLE_SLASH); + } + else + { + in.reset (); + token = new XPathToken (XPathParser.SLASH); + } + break; + case 0x3d: // = + token = new XPathToken (XPathParser.EQ); + break; + case 0x21: // ! + in.mark (1); + int d2 = in.read (); + if (d2 == 0x3d) // = + { + token = new XPathToken (XPathParser.NE); + } + else + { + in.reset (); + token = new XPathToken (XPathParser.yyErrorCode); + } + break; + case 0x3e: // > + in.mark (1); + int d3 = in.read (); + if (d3 == 0x3d) // = + { + token = new XPathToken (XPathParser.GTE); + } + else + { + in.reset (); + token = new XPathToken (XPathParser.GT); + } + break; + case 0x3c: // < + in.mark (1); + int d4 = in.read (); + if (d4 == 0x3d) // = + { + token = new XPathToken (XPathParser.LTE); + } + else + { + in.reset (); + token = new XPathToken (XPathParser.LT); + } + break; + case 0x2b: // + + token = new XPathToken (XPathParser.PLUS); + break; + case 0x2d: // - + token = new XPathToken (XPathParser.MINUS); + break; + case 0x40: // @ + token = new XPathToken (XPathParser.AT); + break; + case 0x2a: // * + token = new XPathToken (XPathParser.STAR); + break; + case 0x24: // $ + token = new XPathToken (XPathParser.DOLLAR); + break; + case 0x3a: // : + in.mark (1); + int d5 = in.read (); + if (d5 == 0x3a) + { + token = new XPathToken (XPathParser.DOUBLE_COLON); + } + else + { + in.reset (); + token = new XPathToken (XPathParser.COLON); + } + break; + case 0x2e: // . + in.mark (1); + int d6 = in.read (); + if (d6 == 0x2e) + { + token = new XPathToken (XPathParser.DOUBLE_DOT); + } + else + { + in.reset (); + token = new XPathToken (XPathParser.DOT); + } + break; + default: + if (c >= 0x30 && c <= 0x39) + { + token = consume_digits (c); + } + else if (c == 0x5f || Character.isLetter ((char) c)) + { + token = consume_name (c); + } + else + { + token = new XPathToken (XPathParser.yyErrorCode); + } + } + return true; + } + + public int token () + { + return token.type; + } + + public Object value () + { + return token.val; + } + + XPathToken consume_literal (int delimiter) + throws IOException + { + CPStringBuilder buf = new CPStringBuilder (); + while (true) + { + int c = in.read (); + if (c == -1) + { + return new XPathToken (XPathParser.yyErrorCode); + } + else if (c == delimiter) + { + return new XPathToken (XPathParser.LITERAL, buf.toString ()); + } + else + { + buf.append ((char) c); + } + } + } + + XPathToken consume_digits (int c) + throws IOException + { + CPStringBuilder buf = new CPStringBuilder (); + buf.append ((char) c); + while (true) + { + in.mark (1); + c = in.read (); + if (c >= 0x30 && c <= 0x39) + { + buf.append ((char) c); + } + else + { + in.reset (); + return new XPathToken (XPathParser.DIGITS, buf.toString ()); + } + } + } + + XPathToken consume_name (int c) + throws IOException + { + CPStringBuilder buf = new CPStringBuilder (); + buf.append ((char) c); + while (true) + { + in.mark (1); + c = in.read (); + if (isNameChar (c)) + { + buf.append ((char) c); + } + else + { + in.reset (); + String name = buf.toString (); + Integer keyword = (Integer) keywords.get (name); + if (keyword == null) + { + return new XPathToken (XPathParser.NAME, name); + } + else + { + int val = keyword.intValue (); + switch (val) + { + case XPathParser.NODE: + case XPathParser.COMMENT: + case XPathParser.TEXT: + case XPathParser.PROCESSING_INSTRUCTION: + // Consume subsequent ( + in.mark (1); + do + { + c = in.read (); + } + while (c == 0x20 || c == 0x09); + if (c != 0x28) + { + in.reset (); + return new XPathToken (XPathParser.NAME, name); + } + break; + case XPathParser.CHILD: + case XPathParser.PARENT: + case XPathParser.SELF: + case XPathParser.DESCENDANT: + case XPathParser.ANCESTOR: + case XPathParser.DESCENDANT_OR_SELF: + case XPathParser.ANCESTOR_OR_SELF: + case XPathParser.ATTRIBUTE: + case XPathParser.NAMESPACE: + case XPathParser.FOLLOWING: + case XPathParser.FOLLOWING_SIBLING: + case XPathParser.PRECEDING: + case XPathParser.PRECEDING_SIBLING: + // Check that this is an axis specifier + in.mark(1); + do + { + c = in.read(); + } + while (c == 0x20 || c == 0x09); + if (c == 0x3a) + { + c = in.read(); + if (c == 0x3a) + { + in.reset(); + return new XPathToken(val); + } + } + in.reset(); + return new XPathToken(XPathParser.NAME, name); + case XPathParser.DIV: + case XPathParser.MOD: + // May be a name + if (lastToken == null) + { + return new XPathToken(XPathParser.NAME, name); + } + switch (lastToken.type) + { + case XPathParser.LP: + case XPathParser.LB: + case XPathParser.COMMA: + case XPathParser.PIPE: + case XPathParser.EQ: + case XPathParser.NE: + case XPathParser.GT: + case XPathParser.LT: + case XPathParser.GTE: + case XPathParser.LTE: + case XPathParser.PLUS: + case XPathParser.MINUS: + case XPathParser.STAR: + case XPathParser.AT: + case XPathParser.DOLLAR: + case XPathParser.COLON: + case XPathParser.DOUBLE_COLON: + case XPathParser.DIV: + case XPathParser.MOD: + case XPathParser.OR: + case XPathParser.AND: + case XPathParser.SLASH: + return new XPathToken(XPathParser.NAME, name); + } + break; + } + return new XPathToken (val); + } + } + } + } + + boolean isNameChar (int c) + { + /* Name */ + return (c == 0x5f + || c == 0x2d + || c == 0x2e + || (c >= 0x30 && c <= 0x39) + /* CombiningChar */ + || (c >= 0x0300 && c <= 0x0345) + || (c >= 0x0360 && c <= 0x0361) + || (c >= 0x0483 && c <= 0x0486) + || (c >= 0x0591 && c <= 0x05A1) + || (c >= 0x05A3 && c <= 0x05B9) + || (c >= 0x05BB && c <= 0x05BD) + || c == 0x05BF + || (c >= 0x05C1 && c <= 0x05C2) + || c == 0x05C4 + || (c >= 0x064B && c <= 0x0652) + || c == 0x0670 + || (c >= 0x06D6 && c <= 0x06DC) + || (c >= 0x06DD && c <= 0x06DF) + || (c >= 0x06E0 && c <= 0x06E4) + || (c >= 0x06E7 && c <= 0x06E8) + || (c >= 0x06EA && c <= 0x06ED) + || (c >= 0x0901 && c <= 0x0903) + || c == 0x093C + || (c >= 0x093E && c <= 0x094C) + || c == 0x094D + || (c >= 0x0951 && c <= 0x0954) + || (c >= 0x0962 && c <= 0x0963) + || (c >= 0x0981 && c <= 0x0983) + || c == 0x09BC + || c == 0x09BE + || c == 0x09BF + || (c >= 0x09C0 && c <= 0x09C4) + || (c >= 0x09C7 && c <= 0x09C8) + || (c >= 0x09CB && c <= 0x09CD) + || c == 0x09D7 + || (c >= 0x09E2 && c <= 0x09E3) + || c == 0x0A02 + || c == 0x0A3C + || c == 0x0A3E + || c == 0x0A3F + || (c >= 0x0A40 && c <= 0x0A42) + || (c >= 0x0A47 && c <= 0x0A48) + || (c >= 0x0A4B && c <= 0x0A4D) + || (c >= 0x0A70 && c <= 0x0A71) + || (c >= 0x0A81 && c <= 0x0A83) + || c == 0x0ABC + || (c >= 0x0ABE && c <= 0x0AC5) + || (c >= 0x0AC7 && c <= 0x0AC9) + || (c >= 0x0ACB && c <= 0x0ACD) + || (c >= 0x0B01 && c <= 0x0B03) + || c == 0x0B3C + || (c >= 0x0B3E && c <= 0x0B43) + || (c >= 0x0B47 && c <= 0x0B48) + || (c >= 0x0B4B && c <= 0x0B4D) + || (c >= 0x0B56 && c <= 0x0B57) + || (c >= 0x0B82 && c <= 0x0B83) + || (c >= 0x0BBE && c <= 0x0BC2) + || (c >= 0x0BC6 && c <= 0x0BC8) + || (c >= 0x0BCA && c <= 0x0BCD) + || c == 0x0BD7 + || (c >= 0x0C01 && c <= 0x0C03) + || (c >= 0x0C3E && c <= 0x0C44) + || (c >= 0x0C46 && c <= 0x0C48) + || (c >= 0x0C4A && c <= 0x0C4D) + || (c >= 0x0C55 && c <= 0x0C56) + || (c >= 0x0C82 && c <= 0x0C83) + || (c >= 0x0CBE && c <= 0x0CC4) + || (c >= 0x0CC6 && c <= 0x0CC8) + || (c >= 0x0CCA && c <= 0x0CCD) + || (c >= 0x0CD5 && c <= 0x0CD6) + || (c >= 0x0D02 && c <= 0x0D03) + || (c >= 0x0D3E && c <= 0x0D43) + || (c >= 0x0D46 && c <= 0x0D48) + || (c >= 0x0D4A && c <= 0x0D4D) + || c == 0x0D57 + || c == 0x0E31 + || (c >= 0x0E34 && c <= 0x0E3A) + || (c >= 0x0E47 && c <= 0x0E4E) + || c == 0x0EB1 + || (c >= 0x0EB4 && c <= 0x0EB9) + || (c >= 0x0EBB && c <= 0x0EBC) + || (c >= 0x0EC8 && c <= 0x0ECD) + || (c >= 0x0F18 && c <= 0x0F19) + || c == 0x0F35 + || c == 0x0F37 + || c == 0x0F39 + || c == 0x0F3E + || c == 0x0F3F + || (c >= 0x0F71 && c <= 0x0F84) + || (c >= 0x0F86 && c <= 0x0F8B) + || (c >= 0x0F90 && c <= 0x0F95) + || c == 0x0F97 + || (c >= 0x0F99 && c <= 0x0FAD) + || (c >= 0x0FB1 && c <= 0x0FB7) + || c == 0x0FB9 + || (c >= 0x20D0 && c <= 0x20DC) + || c == 0x20E1 + || (c >= 0x302A && c <= 0x302F) + || c == 0x3099 + || c == 0x309A + /* Extender */ + || c == 0x00B7 + || c == 0x02D0 + || c == 0x02D1 + || c == 0x0387 + || c == 0x0640 + || c == 0x0E46 + || c == 0x0EC6 + || c == 0x3005 + || (c >= 0x3031 && c <= 0x3035) + || (c >= 0x309D && c <= 0x309E) + || (c >= 0x30FC && c <= 0x30FE) + /* Name */ + || Character.isLetter ((char) c)); + } + +} |