KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > expr > PositionRange


1 package net.sf.saxon.expr;
2 import net.sf.saxon.om.Item;
3 import net.sf.saxon.om.NamePool;
4 import net.sf.saxon.om.SequenceIterator;
5 import net.sf.saxon.trans.XPathException;
6 import net.sf.saxon.type.ItemType;
7 import net.sf.saxon.type.Type;
8 import net.sf.saxon.value.BooleanValue;
9 import net.sf.saxon.value.NumericValue;
10 import net.sf.saxon.value.IntegerValue;
11
12 import java.io.PrintStream JavaDoc;
13 import java.util.Iterator JavaDoc;
14
15 /**
16 * PositionRange: a boolean expression that tests whether the position() is
17 * within a certain range. This expression can occur in any context but it is
18 * optimized when it appears as a predicate (see FilterIterator)
19 */

20
21 public final class PositionRange extends ComputedExpression {
22
23     private Expression minPosition;
24     private Expression maxPosition; // may be null to indicate an open range
25

26     /**
27     * Create a position range
28     */

29
30     public PositionRange(Expression min, Expression max) {
31         minPosition = min;
32         maxPosition = max;
33         adoptChildExpression(min);
34         adoptChildExpression(max);
35     }
36
37     /**
38     * Create a constant position range
39     */

40
41     public PositionRange(int min, int max) {
42         minPosition = new IntegerValue(min);
43         if (max == Integer.MAX_VALUE) {
44             maxPosition = null;
45         } else {
46             maxPosition = new IntegerValue(max);
47         }
48     }
49
50     /**
51     * Simplify an expression
52     * @return the simplified expression
53     */

54
55      public Expression simplify(StaticContext env) throws XPathException {
56         minPosition = minPosition.simplify(env);
57         if (maxPosition != null) {
58             maxPosition = maxPosition.simplify(env);
59         }
60         return this;
61     }
62
63     /**
64     * Type-check the expression
65     */

66
67     public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException {
68         minPosition = minPosition.typeCheck(env, contextItemType);
69         if (maxPosition != null) {
70             maxPosition = maxPosition.typeCheck(env, contextItemType);
71         }
72         return this;
73     }
74
75     /**
76      * Perform optimisation of an expression and its subexpressions.
77      * <p/>
78      * <p>This method is called after all references to functions and variables have been resolved
79      * to the declaration of the function or variable, and after all type checking has been done.</p>
80      *
81      * @param opt the optimizer in use. This provides access to supporting functions; it also allows
82      * different optimization strategies to be used in different circumstances.
83      * @param env the static context of the expression
84      * @param contextItemType the static type of "." at the point where this expression is invoked.
85      * The parameter is set to null if it is known statically that the context item will be undefined.
86      * If the type of the context item is not known statically, the argument is set to
87      * {@link net.sf.saxon.type.Type#ITEM_TYPE}
88      * @return the original expression, rewritten if appropriate to optimize execution
89      * @throws net.sf.saxon.trans.StaticError if an error is discovered during this phase
90      * (typically a type error)
91      */

92
93     public Expression optimize(Optimizer opt, StaticContext env, ItemType contextItemType) throws XPathException {
94         minPosition = minPosition.optimize(opt, env, contextItemType);
95         if (maxPosition != null) {
96             maxPosition = maxPosition.optimize(opt, env, contextItemType);
97         }
98         return this;
99     }
100
101     /**
102      * Determine the special properties of this expression
103      * @return {@link StaticProperty#NON_CREATIVE}.
104      */

105
106     public int computeSpecialProperties() {
107         int p = super.computeSpecialProperties();
108         return p | StaticProperty.NON_CREATIVE;
109     }
110
111     /**
112     * Evaluate the expression
113     */

114
115     public Item evaluateItem(XPathContext c) throws XPathException {
116         int p = c.getContextPosition();
117         if (maxPosition == null) {
118             NumericValue min = (NumericValue)minPosition.evaluateItem(c);
119             return BooleanValue.get(p >= min.longValue());
120         } else {
121             NumericValue min = (NumericValue)minPosition.evaluateItem(c);
122             NumericValue max = (NumericValue)maxPosition.evaluateItem(c);
123             return BooleanValue.get(p >= min.longValue() && p <= max.longValue());
124         }
125     }
126
127     /**
128      * Make an iterator over a range of a sequence determined by this position range
129      */

130
131     public SequenceIterator makePositionIterator(SequenceIterator base, XPathContext c) throws XPathException {
132         int low, high;
133         NumericValue min = (NumericValue)minPosition.evaluateItem(c);
134         low = (int)min.longValue();
135         if (maxPosition == null) {
136             high = Integer.MAX_VALUE;
137         } else {
138             NumericValue max = (NumericValue)maxPosition.evaluateItem(c);
139             high = (int)max.longValue();
140         }
141         return PositionIterator.make(base, low, high);
142     }
143
144     /**
145     * Determine the data type of the expression
146     * @return Type.BOOLEAN
147     */

148
149     public ItemType getItemType() {
150         return Type.BOOLEAN_TYPE;
151     }
152
153     /**
154     * Determine the static cardinality
155     */

156
157     public int computeCardinality() {
158         return StaticProperty.EXACTLY_ONE;
159     }
160
161     /**
162     * Get the dependencies
163     */

164
165     public int getIntrinsicDependencies() {
166         return StaticProperty.DEPENDS_ON_POSITION;
167     }
168
169     /**
170      * Get the immediate sub-expressions of this expression. Default implementation
171      * returns a zero-length array, appropriate for an expression that has no
172      * sub-expressions.
173      *
174      * @return an iterator containing the sub-expressions of this expression
175      */

176
177     public Iterator iterateSubExpressions() {
178         if (maxPosition == null) {
179             return new MonoIterator(minPosition);
180         } else {
181             return new PairIterator(minPosition, maxPosition);
182         }
183     }
184
185     /**
186      * Test if the first and last position are both constant 1
187      */

188
189     public boolean isFirstPositionOnly() {
190         try {
191             return (minPosition instanceof NumericValue && ((NumericValue)minPosition).longValue() == 1) &&
192                     (maxPosition instanceof NumericValue && ((NumericValue)maxPosition).longValue() == 1);
193         } catch (XPathException e) {
194             return false;
195         }
196     }
197
198     /**
199      * Test whether the range is focus-dependent. An example of a focus-dependent range is
200      * (1 to position()). We could treat last() specially but we don't.
201      */

202
203     public boolean hasFocusDependentRange() {
204         return ((minPosition.getDependencies() & StaticProperty.DEPENDS_ON_FOCUS) != 0) ||
205                 (maxPosition != null && (maxPosition.getDependencies() & StaticProperty.DEPENDS_ON_FOCUS) != 0);
206     }
207
208     /**
209      * Test if the position range matches at most one item
210      */

211
212     public boolean matchesAtMostOneItem() {
213         return maxPosition != null && minPosition.equals(maxPosition) && !hasFocusDependentRange();
214     }
215
216     /**
217      * If this is an open-ended range with a constant start position, make a TailExpression.
218      * Otherwise return null
219      */

220
221     public TailExpression makeTailExpression(Expression start) {
222         if (maxPosition == null && minPosition instanceof IntegerValue) {
223             return new TailExpression(start, (int)((IntegerValue)minPosition).longValue());
224         } else {
225             return null;
226         }
227
228     }
229
230     /**
231     * Diagnostic print of expression structure
232     */

233
234     public void display(int level, NamePool pool, PrintStream JavaDoc out) {
235         out.println(ExpressionTool.indent(level) + "positionRange");
236         minPosition.display(level+1, pool, out);
237         maxPosition.display(level+1, pool, out);
238     }
239 }
240
241 //
242
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
243
// you may not use this file except in compliance with the License. You may obtain a copy of the
244
// License at http://www.mozilla.org/MPL/
245
//
246
// Software distributed under the License is distributed on an "AS IS" basis,
247
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
248
// See the License for the specific language governing rights and limitations under the License.
249
//
250
// The Original Code is: all this file.
251
//
252
// The Initial Developer of the Original Code is Michael H. Kay.
253
//
254
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
255
//
256
// Contributor(s): none.
257
//
258
Popular Tags