KickJava   Java API By Example, From Geeks To Geeks.

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


1 package net.sf.saxon.expr;
2
3 import net.sf.saxon.Controller;
4 import net.sf.saxon.value.Value;
5 import net.sf.saxon.event.SequenceOutputter;
6 import net.sf.saxon.om.*;
7 import net.sf.saxon.trans.XPathException;
8 import net.sf.saxon.type.ItemType;
9 import net.sf.saxon.type.Type;
10
11 import java.io.PrintStream JavaDoc;
12 import java.util.Arrays JavaDoc;
13 import java.util.Iterator JavaDoc;
14
15
16 /**
17  * An abstract implementation of Expression designed to make it easy to implement new expressions,
18  * in particular, expressions to support extension instructions.
19  */

20
21 public abstract class SimpleExpression extends ComputedExpression {
22
23     public static final Expression[] NO_ARGUMENTS = new Expression[0];
24
25     protected Expression[] arguments = NO_ARGUMENTS;
26
27     /**
28      * Constructor
29      */

30
31     public SimpleExpression() {
32     }
33
34
35
36     /**
37      * Set the immediate sub-expressions of this expression.
38      * @param sub an array containing the sub-expressions of this expression
39      */

40
41     public void setArguments(Expression[] sub) {
42         arguments = sub;
43         for (int i=0; i<sub.length; i++) {
44             adoptChildExpression(sub[i]);
45         }
46     }
47
48     /**
49      * Get the immediate sub-expressions of this expression.
50      * @return an array containing the sub-expressions of this expression
51      */

52
53     public Iterator JavaDoc iterateSubExpressions() {
54         return Arrays.asList(arguments).iterator();
55     }
56
57     /**
58      * Simplify the expression
59      * @return the simplified expression
60      */

61
62     public Expression simplify(StaticContext env) throws XPathException {
63         for (int i = 0; i < arguments.length; i++) {
64             if (arguments[i] != null) {
65                 arguments[i] = arguments[i].simplify(env);
66             }
67         }
68         return this;
69     }
70
71
72     public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException {
73         for (int i = 0; i < arguments.length; i++) {
74             if (arguments[i] != null) {
75                 arguments[i] = arguments[i].typeCheck(env, contextItemType);
76             }
77         }
78         return this;
79     }
80
81     public Expression optimize(Optimizer opt, StaticContext env, ItemType contextItemType) throws XPathException {
82         for (int i = 0; i < arguments.length; i++) {
83             if (arguments[i] != null) {
84                 arguments[i] = arguments[i].optimize(opt, env, contextItemType);
85             }
86         }
87         return this;
88     }
89
90
91     /**
92      * Offer promotion for this subexpression. The offer will be accepted if the subexpression
93      * is not dependent on the factors (e.g. the context item) identified in the PromotionOffer.
94      * By default the offer is not accepted - this is appropriate in the case of simple expressions
95      * such as constant values and variable references where promotion would give no performance
96      * advantage. This method is always called at compile time.
97      *
98      * @param offer details of the offer, for example the offer to move
99      * expressions that don't depend on the context to an outer level in
100      * the containing expression
101      * @exception XPathException if any error is detected
102      * @return if the offer is not accepted, return this expression unchanged.
103      * Otherwise return the result of rewriting the expression to promote
104      * this subexpression
105      */

106
107     public Expression promote(PromotionOffer offer) throws XPathException {
108         for (int i = 0; i < arguments.length; i++) {
109             if (arguments[i] != null) {
110                 arguments[i] = doPromotion(arguments[i], offer);
111             }
112         }
113         return this;
114     }
115
116
117     /**
118      * Determine the data type of the items returned by this expression. This implementation
119      * returns "item()", which can be overridden in a subclass.
120      * @return the data type
121      */

122
123     public ItemType getItemType() {
124         return Type.ITEM_TYPE;
125     }
126
127     /**
128      * Determine the static cardinality of the expression. This implementation
129      * returns "zero or more", which can be overridden in a subclass.
130      */

131
132     public int computeCardinality() {
133         if ((getImplementationMethod() & Expression.EVALUATE_METHOD) == 0) {
134             return StaticProperty.ALLOWS_ONE_OR_MORE;
135         } else {
136             return StaticProperty.ALLOWS_ZERO_OR_ONE;
137         }
138     }
139
140     /**
141      * Compute the dependencies of an expression, as the union of the
142      * dependencies of its subexpressions. (This is overridden for path expressions
143      * and filter expressions, where the dependencies of a subexpression are not all
144      * propogated). This method should be called only once, to compute the dependencies;
145      * after that, getDependencies should be used.
146      * @return the depencies, as a bit-mask
147      */

148
149     public int computeDependencies() {
150         return super.computeDependencies();
151     }
152
153     /**
154      * Evaluate an expression as a single item. This always returns either a single Item or
155      * null (denoting the empty sequence). No conversion is done. This method should not be
156      * used unless the static type of the expression is a subtype of "item" or "item?": that is,
157      * it should not be called if the expression may return a sequence. There is no guarantee that
158      * this condition will be detected.
159      *
160      * @param context The context in which the expression is to be evaluated
161      * @exception XPathException if any dynamic error occurs evaluating the
162      * expression
163      * @return the node or atomic value that results from evaluating the
164      * expression; or null to indicate that the result is an empty
165      * sequence
166      */

167
168     public Item evaluateItem(XPathContext context) throws XPathException {
169         int m = getImplementationMethod();
170         if ((m & Expression.EVALUATE_METHOD) != 0) {
171             dynamicError("evaluateItem() is not implemented in the subclass " + this.getClass(), context);
172         } else if ((m & Expression.ITERATE_METHOD) != 0) {
173             return iterate(context).next();
174         } else {
175             Controller controller = context.getController();
176             XPathContext c2 = context.newMinorContext();
177             c2.setOrigin(this);
178             SequenceOutputter seq = new SequenceOutputter(1);
179             seq.setPipelineConfiguration(controller.makePipelineConfiguration());
180             c2.setTemporaryReceiver(seq);
181             process(c2);
182             return seq.getFirstItem();
183         }
184         return null;
185     }
186
187     /**
188      * Return an Iterator to iterate over the values of a sequence. The value of every
189      * expression can be regarded as a sequence, so this method is supported for all
190      * expressions. This default implementation handles iteration for expressions that
191      * return singleton values: for non-singleton expressions, the subclass must
192      * provide its own implementation.
193      *
194      * @exception XPathException if any dynamic error occurs evaluating the
195      * expression
196      * @param context supplies the context for evaluation
197      * @return a SequenceIterator that can be used to iterate over the result
198      * of the expression
199      */

200
201     public SequenceIterator iterate(XPathContext context) throws XPathException {
202         int m = getImplementationMethod();
203         if ((m & Expression.EVALUATE_METHOD) != 0) {
204             Item item = evaluateItem(context);
205             if (item==null) {
206                 return EmptyIterator.getInstance();
207             } else {
208                 return SingletonIterator.makeIterator(item);
209             }
210         } else if ((m & Expression.ITERATE_METHOD) != 0) {
211             dynamicError("iterate() is not implemented in the subclass " + this.getClass(), context);
212
213         } else {
214             Controller controller = context.getController();
215             XPathContext c2 = context.newMinorContext();
216             c2.setOrigin(this);
217             SequenceOutputter seq = new SequenceOutputter();
218             seq.setPipelineConfiguration(controller.makePipelineConfiguration());
219             c2.setTemporaryReceiver(seq);
220
221             process(c2);
222
223             return Value.getIterator(seq.getSequence());
224         }
225         return null;
226     }
227
228     /**
229      * Process the instruction, without returning any tail calls
230      * @param context The dynamic context, giving access to the current node,
231      * the current variables, etc.
232      */

233
234     public void process(XPathContext context) throws XPathException {
235         int m = getImplementationMethod();
236         if ((m & Expression.EVALUATE_METHOD) == 0) {
237             SequenceIterator iter = iterate(context);
238             while (true) {
239                 Item it = iter.next();
240                 if (it==null) break;
241                 context.getReceiver().append(it, locationId, NodeInfo.ALL_NAMESPACES);
242             }
243         } else {
244             Item item = evaluateItem(context);
245             context.getReceiver().append(item, locationId, NodeInfo.ALL_NAMESPACES);
246         }
247     }
248
249     /**
250      * Diagnostic print of expression structure. The expression is written to the System.err
251      * output stream
252      *
253      * @param level indentation level for this expression
254      * @param out
255      */

256
257     public void display(int level, NamePool pool, PrintStream JavaDoc out) {
258         out.println(ExpressionTool.indent(level) + getExpressionType());
259         for (int i = 0; i < arguments.length; i++) {
260             arguments[i].display(level+1, pool, out);
261         }
262     }
263
264     /**
265      * Return a distinguishing name for the expression, for use in diagnostics.
266      * By default the class name is used.
267      */

268
269     public String JavaDoc getExpressionType() {
270         return getClass().getName();
271     }
272
273 }
274
275 //
276
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
277
// you may not use this file except in compliance with the License. You may obtain a copy of the
278
// License at http://www.mozilla.org/MPL/
279
//
280
// Software distributed under the License is distributed on an "AS IS" basis,
281
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
282
// See the License for the specific language governing rights and limitations under the License.
283
//
284
// The Original Code is: all this file.
285
//
286
// The Initial Developer of the Original Code is Michael H. Kay.
287
//
288
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
289
//
290
// Contributor(s): none.
291
//
292
Popular Tags