KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > instruct > GeneralVariable


1 package net.sf.saxon.instruct;
2 import net.sf.saxon.expr.*;
3 import net.sf.saxon.om.*;
4 import net.sf.saxon.pattern.NoNodeTest;
5 import net.sf.saxon.style.StandardNames;
6 import net.sf.saxon.trans.XPathException;
7 import net.sf.saxon.type.ItemType;
8 import net.sf.saxon.value.SequenceType;
9
10 import java.io.PrintStream JavaDoc;
11 import java.util.Collections JavaDoc;
12 import java.util.Iterator JavaDoc;
13
14 /**
15 * This class defines common behaviour across xsl:variable, xsl:param, and xsl:with-param;
16 * also saxon:assign
17 */

18
19 public abstract class GeneralVariable extends Instruction implements Binding {
20
21
22     private static final int ASSIGNABLE = 1;
23     private static final int REQUIRED = 4;
24     private static final int TUNNEL = 8;
25
26     private byte properties = 0;
27     Expression select = null;
28     protected int nameCode = -1;
29     SequenceType requiredType;
30     private int slotNumber;
31     private String JavaDoc variableName;
32
33
34     public GeneralVariable() {};
35
36     public void init( Expression select,
37                         int nameCode) {
38         this.select = select;
39         this.nameCode = nameCode;
40         adoptChildExpression(select);
41     }
42
43     public void setSelectExpression(Expression select) {
44         this.select = select;
45         adoptChildExpression(select);
46     }
47
48     public Expression getSelectExpression() {
49         return select;
50     }
51
52     public void setRequiredType(SequenceType required) {
53         requiredType = required;
54     }
55
56     public SequenceType getRequiredType() {
57         return requiredType;
58     }
59
60     public void setNameCode(int nameCode) {
61         this.nameCode = nameCode;
62     }
63
64     public int getNameCode() {
65         return nameCode;
66     }
67
68     public void setAssignable(boolean assignable) {
69         if (assignable) {
70             properties |= ASSIGNABLE;
71         } else {
72             properties &= ~ASSIGNABLE;
73         }
74     }
75
76     public void setRequiredParam(boolean requiredParam) {
77         if (requiredParam) {
78             properties |= REQUIRED;
79         } else {
80             properties &= ~REQUIRED;
81         }
82     }
83
84
85
86     public void setTunnel(boolean tunnel) {
87         if (tunnel) {
88             properties |= TUNNEL;
89         } else {
90             properties &= ~TUNNEL;
91         }
92     }
93
94     /**
95     * Test whether it is permitted to assign to the variable using the saxon:assign
96     * extension element. This will only be true if the extra attribute saxon:assignable="yes"
97     * is present.
98     */

99
100     public final boolean isAssignable() {
101         return (properties & ASSIGNABLE) != 0;
102     }
103
104     /**
105      * Get the name of the variable (as a NamePool fingerprint)
106      * @return the NamePool fingerprint of the variable's expanded name.
107      */

108
109     public int getVariableFingerprint() {
110         return nameCode & 0xfffff;
111     }
112
113     /**
114      * Get the type of the result of this instruction. An xsl:variable instruction returns nothing, so the
115      * type is empty.
116      * @return the empty type.
117      */

118
119     public ItemType getItemType() {
120         return NoNodeTest.getInstance();
121     }
122
123     /**
124      * Get the cardinality of the result of this instruction. An xsl:variable instruction returns nothing, so the
125      * type is empty.
126      * @return the empty cardinality.
127      */

128
129     public int getCardinality() {
130         return StaticProperty.EMPTY;
131     }
132
133     public boolean isGlobal() {
134         return false;
135     }
136
137     /**
138      * If this is a local variable held on the local stack frame, return the corresponding slot number.
139      * In other cases, return -1.
140      */

141
142     public int getLocalSlotNumber() {
143         return slotNumber;
144     }
145
146     public final boolean isRequiredParam() {
147         return (properties & REQUIRED) != 0;
148     }
149
150     public final boolean isTunnelParam() {
151         return (properties & TUNNEL) != 0;
152     }
153
154     public int getInstructionNameCode() {
155         return StandardNames.XSL_VARIABLE;
156     }
157
158     public Expression simplify(StaticContext env) throws XPathException {
159         if (select != null) {
160             select = select.simplify(env);
161         }
162         return this;
163     }
164
165     public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException {
166         if (select != null) {
167             select = select.typeCheck(env, contextItemType);
168             adoptChildExpression(select);
169         }
170         checkAgainstRequiredType(env);
171         return this;
172     }
173
174     public Expression optimize(Optimizer opt, StaticContext env, ItemType contextItemType) throws XPathException {
175         if (select != null) {
176             select = select.optimize(opt, env, contextItemType);
177             adoptChildExpression(select);
178         }
179         return this;
180     }
181
182
183     /**
184      * Check the select expression against the required type.
185      * @param env
186      * @throws XPathException
187      */

188
189     private void checkAgainstRequiredType(StaticContext env)
190     throws XPathException {
191         // Note, in some cases we are doing this twice.
192
RoleLocator role = new RoleLocator(RoleLocator.VARIABLE, variableName, 0, null);
193         role.setSourceLocator(this);
194         SequenceType r = requiredType;
195         if (r != null && select != null) {
196             // check that the expression is consistent with the required type
197
select = TypeChecker.staticTypeCheck(select, requiredType, false, role, env);
198         }
199     }
200
201     /**
202      * Evaluate an expression as a single item. This always returns either a single Item or
203      * null (denoting the empty sequence). No conversion is done. This method should not be
204      * used unless the static type of the expression is a subtype of "item" or "item?": that is,
205      * it should not be called if the expression may return a sequence. There is no guarantee that
206      * this condition will be detected.
207      *
208      * @param context The context in which the expression is to be evaluated
209      * @exception XPathException if any dynamic error occurs evaluating the
210      * expression
211      * @return the node or atomic value that results from evaluating the
212      * expression; or null to indicate that the result is an empty
213      * sequence
214      */

215
216     public Item evaluateItem(XPathContext context) throws XPathException {
217         process(context);
218         return null;
219     }
220
221     /**
222      * Return an Iterator to iterate over the values of a sequence. The value of every
223      * expression can be regarded as a sequence, so this method is supported for all
224      * expressions. This default implementation relies on the process() method: it
225      * "pushes" the results of the instruction to a sequence in memory, and then
226      * iterates over this in-memory sequence.
227      *
228      * In principle instructions should implement a pipelined iterate() method that
229      * avoids the overhead of intermediate storage.
230      *
231      * @exception XPathException if any dynamic error occurs evaluating the
232      * expression
233      * @param context supplies the context for evaluation
234      * @return a SequenceIterator that can be used to iterate over the result
235      * of the expression
236      */

237
238     public SequenceIterator iterate(XPathContext context) throws XPathException {
239         evaluateItem(context);
240         return EmptyIterator.getInstance();
241     }
242
243     /**
244      * Evaluate the variable. That is,
245      * get the value of the select expression if present or the content
246      * of the element otherwise, either as a tree or as a sequence
247     */

248
249     public ValueRepresentation getSelectValue(XPathContext context) throws XPathException {
250         if (select==null) {
251             throw new AssertionError JavaDoc("*** No select expression!!");
252             // The value of the variable is a sequence of nodes and/or atomic values
253

254         } else {
255             // There is a select attribute: do a lazy evaluation of the expression,
256
// which will already contain any code to force conversion to the required type.
257

258             if (isAssignable()) {
259                 return ExpressionTool.eagerEvaluate(select, context);
260             } else {
261                 return ExpressionTool.lazyEvaluate(select, context, 10);
262             }
263
264         }
265     }
266
267     /**
268      * Handle promotion offers, that is, non-local tree rewrites.
269      * @param offer The type of rewrite being offered
270      * @throws XPathException
271      */

272
273     protected void promoteInst(PromotionOffer offer) throws XPathException {
274         if (select != null) {
275             select = doPromotion(select, offer);
276         }
277     }
278
279     /**
280      * Get all the XPath expressions associated with this instruction
281      * (in XSLT terms, the expression present on attributes of the instruction,
282      * as distinct from the child instructions in a sequence construction)
283      */

284
285
286     public Iterator JavaDoc iterateSubExpressions() {
287         if (select != null) {
288             return new MonoIterator(select);
289         } else {
290             return Collections.EMPTY_LIST.iterator();
291         }
292     }
293
294     /**
295      * Diagnostic print of expression structure. The expression is written to the System.err
296      * output stream
297      *
298      * @param level indentation level for this expression
299      * @param out
300      */

301
302     public void display(int level, NamePool pool, PrintStream JavaDoc out) {
303         out.println(ExpressionTool.indent(level) + "variable " +
304                 pool.getDisplayName(nameCode));
305         if (select != null) {
306             select.display(level+1, pool, out);
307         }
308     }
309
310     public int getSlotNumber() {
311         return slotNumber;
312     }
313
314     public void setSlotNumber(int s) {
315         slotNumber = s;
316     }
317
318     public void setVariableName(String JavaDoc s) {
319         variableName = s;
320     }
321
322     public String JavaDoc getVariableName() {
323         return variableName;
324     }
325 }
326
327 //
328
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
329
// you may not use this file except in compliance with the License. You may obtain a copy of the
330
// License at http://www.mozilla.org/MPL/
331
//
332
// Software distributed under the License is distributed on an "AS IS" basis,
333
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
334
// See the License for the specific language governing rights and limitations under the License.
335
//
336
// The Original Code is: all this file.
337
//
338
// The Initial Developer of the Original Code is Michael H. Kay.
339
//
340
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
341
//
342
// Contributor(s): none.
343
//
344
Popular Tags