001: package net.sf.saxon.expr;
002:
003: import net.sf.saxon.om.Item;
004: import net.sf.saxon.om.NamePool;
005: import net.sf.saxon.trans.XPathException;
006: import net.sf.saxon.type.ItemType;
007: import net.sf.saxon.type.Type;
008: import net.sf.saxon.type.TypeHierarchy;
009: import net.sf.saxon.value.AtomicValue;
010: import net.sf.saxon.value.BooleanValue;
011: import net.sf.saxon.value.NumericValue;
012:
013: import java.io.PrintStream;
014: import java.util.Arrays;
015: import java.util.Iterator;
016:
017: /**
018: * An IntegerRangeTest is an expression of the form
019: * E = N to M
020: * where E, N, and M are all expressions of type integer.
021: */
022:
023: public class IntegerRangeTest extends ComputedExpression {
024:
025: Expression value;
026: Expression min;
027: Expression max;
028:
029: /**
030: * Construct a IntegerRangeTest
031: */
032:
033: public IntegerRangeTest(Expression value, Expression min,
034: Expression max) {
035: this .value = value;
036: this .min = min;
037: this .max = max;
038: }
039:
040: public Expression typeCheck(StaticContext env,
041: ItemType contextItemType) throws XPathException {
042: // Already done, we only get one of these expressions after the operands
043: // have been analyzed
044: return this ;
045: }
046:
047: /**
048: * Perform optimisation of an expression and its subexpressions.
049: * <p/>
050: * <p>This method is called after all references to functions and variables have been resolved
051: * to the declaration of the function or variable, and after all type checking has been done.</p>
052: *
053: * @param opt the optimizer in use. This provides access to supporting functions; it also allows
054: * different optimization strategies to be used in different circumstances.
055: * @param env the static context of the expression
056: * @param contextItemType the static type of "." at the point where this expression is invoked.
057: * The parameter is set to null if it is known statically that the context item will be undefined.
058: * If the type of the context item is not known statically, the argument is set to
059: * {@link net.sf.saxon.type.Type#ITEM_TYPE}
060: * @return the original expression, rewritten if appropriate to optimize execution
061: * @throws net.sf.saxon.trans.StaticError if an error is discovered during this phase
062: * (typically a type error)
063: */
064:
065: public Expression optimize(Optimizer opt, StaticContext env,
066: ItemType contextItemType) throws XPathException {
067: return this ;
068: }
069:
070: /**
071: * Get the data type of the items returned
072: * @param th
073: */
074:
075: public ItemType getItemType(TypeHierarchy th) {
076: return Type.BOOLEAN_TYPE;
077: }
078:
079: /**
080: * Determine the static cardinality
081: */
082:
083: public int computeCardinality() {
084: return StaticProperty.EXACTLY_ONE;
085: }
086:
087: /**
088: * Get the immediate sub-expressions of this expression. Default implementation
089: * returns a zero-length array, appropriate for an expression that has no
090: * sub-expressions.
091: *
092: * @return an iterator containing the sub-expressions of this expression
093: */
094:
095: public Iterator iterateSubExpressions() {
096: Expression[] e = { value, min, max };
097: return Arrays.asList(e).iterator();
098: }
099:
100: /**
101: * Evaluate the expression
102: */
103:
104: public Item evaluateItem(XPathContext c) throws XPathException {
105: AtomicValue av = (AtomicValue) value.evaluateItem(c);
106: if (av == null) {
107: return BooleanValue.FALSE;
108: }
109: NumericValue v = (NumericValue) av.getPrimitiveValue();
110:
111: AtomicValue av2 = (AtomicValue) min.evaluateItem(c);
112: NumericValue v2 = (NumericValue) av2.getPrimitiveValue();
113:
114: if (v.compareTo(v2) < 0) {
115: return BooleanValue.FALSE;
116: }
117: AtomicValue av3 = (AtomicValue) max.evaluateItem(c);
118: NumericValue v3 = (NumericValue) av3.getPrimitiveValue();
119:
120: return BooleanValue.get(v.compareTo(v3) <= 0);
121: }
122:
123: /**
124: * Display this instruction as an expression, for diagnostics
125: */
126:
127: public void display(int level, NamePool pool, PrintStream out) {
128: out.println(ExpressionTool.indent(level)
129: + "rangeTest min<value<max");
130: min.display(level + 1, pool, out);
131: value.display(level + 1, pool, out);
132: max.display(level + 1, pool, out);
133: }
134: }
135:
136: //
137: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
138: // you may not use this file except in compliance with the License. You may obtain a copy of the
139: // License at http://www.mozilla.org/MPL/
140: //
141: // Software distributed under the License is distributed on an "AS IS" basis,
142: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
143: // See the License for the specific language governing rights and limitations under the License.
144: //
145: // The Original Code is: all this file.
146: //
147: // The Initial Developer of the Original Code is Michael H. Kay
148: //
149: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
150: //
151: // Contributor(s): none.
152: //
|