KickJava   Java API By Example, From Geeks To Geeks.

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


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.EmptySequence;
10 import net.sf.saxon.value.SequenceType;
11
12 import java.io.PrintStream JavaDoc;
13
14 /**
15 * A QuantifiedExpression tests whether some/all items in a sequence satisfy
16 * some condition.
17 */

18
19 class QuantifiedExpression extends Assignation {
20
21     private int operator; // Tokenizer.SOME or Tokenizer.EVERY
22

23     public void setOperator(int operator) {
24         this.operator = operator;
25     }
26
27     /**
28     * Determine the static cardinality
29     */

30
31     public int computeCardinality() {
32         return StaticProperty.EXACTLY_ONE;
33     }
34
35     /**
36     * Type-check the expression
37     */

38
39     public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException {
40
41         if (declaration==null) {
42             // we've already done the type checking, no need to do it again
43
return this;
44         }
45
46         // The order of events is critical here. First we ensure that the type of the
47
// sequence expression is established. This is used to establish the type of the variable,
48
// which in turn is required when type-checking the action part.
49

50         sequence = sequence.typeCheck(env, contextItemType);
51         if (sequence instanceof EmptySequence) {
52             return BooleanValue.get(operator != Token.SOME);
53         }
54
55         // "some" and "every" have no ordering constraints
56

57         Optimizer opt = env.getConfiguration().getOptimizer();
58         sequence = ExpressionTool.unsorted(opt, sequence, false);
59
60         SequenceType decl = declaration.getRequiredType();
61         SequenceType sequenceType = SequenceType.makeSequenceType(decl.getPrimaryType(),
62                                              StaticProperty.ALLOWS_ZERO_OR_MORE);
63         RoleLocator role = new RoleLocator(RoleLocator.VARIABLE, new Integer JavaDoc(nameCode), 0, env.getNamePool());
64         role.setSourceLocator(this);
65         sequence = TypeChecker.strictTypeCheck(
66                                 sequence, sequenceType, role, env);
67         ItemType actualItemType = sequence.getItemType();
68         declaration.refineTypeInformation(actualItemType,
69                 StaticProperty.EXACTLY_ONE,
70                 null,
71                 sequence.getSpecialProperties());
72
73         declaration = null; // let the garbage collector take it
74

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

96
97     public Expression optimize(Optimizer opt, StaticContext env, ItemType contextItemType) throws XPathException {
98         sequence = sequence.optimize(opt, env, contextItemType);
99         action = action.optimize(opt, env, contextItemType);
100         PromotionOffer offer = new PromotionOffer(opt);
101         offer.containingExpression = this;
102         offer.action = PromotionOffer.RANGE_INDEPENDENT;
103         Binding[] bindingList = {this};
104         offer.bindingList = bindingList;
105         action = doPromotion(action, offer);
106         if (offer.containingExpression instanceof LetExpression) {
107             offer.containingExpression =
108                     offer.containingExpression.typeCheck(env, contextItemType).optimize(opt, env, contextItemType);
109         }
110         return offer.containingExpression;
111
112     }
113
114
115     /**
116      * Determine the special properties of this expression
117      * @return {@link StaticProperty#NON_CREATIVE}.
118      */

119
120     public int computeSpecialProperties() {
121         int p = super.computeSpecialProperties();
122         return p | StaticProperty.NON_CREATIVE;
123     }
124
125     /**
126     * Evaluate the expression to return a singleton value
127     */

128
129     public Item evaluateItem(XPathContext context) throws XPathException {
130         return BooleanValue.get(effectiveBooleanValue(context));
131     }
132
133     /**
134     * Get the result as a boolean
135     */

136
137     public boolean effectiveBooleanValue(XPathContext context) throws XPathException {
138
139         // First create an iteration of the base sequence.
140

141         SequenceIterator base = sequence.iterate(context);
142
143         // Now test to see if some or all of the tests are true. The same
144
// logic is used for the SOME and EVERY operators
145

146         boolean some = (operator==Token.SOME);
147         while (true) {
148             Item it = base.next();
149             if (it == null) {
150                 break;
151             }
152             context.setLocalVariable(slotNumber, it);
153             if (some == action.effectiveBooleanValue(context)) {
154                 return some;
155             }
156         }
157         return !some;
158     }
159
160
161     /**
162     * Determine the data type of the items returned by the expression
163     * @return Type.BOOLEAN
164     */

165
166     public ItemType getItemType() {
167         return Type.BOOLEAN_TYPE;
168     }
169
170     /**
171     * Diagnostic print of expression structure
172     */

173
174     public void display(int level, NamePool pool, PrintStream JavaDoc out) {
175         out.println(ExpressionTool.indent(level) + Token.tokens[operator] + " $" + getVariableName(pool) + " in");
176         sequence.display(level+1, pool, out);
177         out.println(ExpressionTool.indent(level) + "satisfies");
178         action.display(level+1, pool, out);
179     }
180
181 }
182
183
184
185 //
186
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
187
// you may not use this file except in compliance with the License. You may obtain a copy of the
188
// License at http://www.mozilla.org/MPL/
189
//
190
// Software distributed under the License is distributed on an "AS IS" basis,
191
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
192
// See the License for the specific language governing rights and limitations under the License.
193
//
194
// The Original Code is: all this file.
195
//
196
// The Initial Developer of the Original Code is Michael H. Kay
197
//
198
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
199
//
200
// Contributor(s): none.
201
//
202
Popular Tags