KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > pattern > PatternSponsor


1 package net.sf.saxon.pattern;
2
3 import net.sf.saxon.expr.*;
4 import net.sf.saxon.om.*;
5 import net.sf.saxon.trans.XPathException;
6 import net.sf.saxon.type.ItemType;
7 import net.sf.saxon.type.SchemaType;
8 import net.sf.saxon.type.Type;
9 import net.sf.saxon.value.BooleanValue;
10
11 import java.io.PrintStream JavaDoc;
12 import java.util.Iterator JavaDoc;
13
14 /**
15  * The PatternSponsor class allows a Pattern to be treated like an expression. Although
16  * patterns are not evaluated at run-time in the same way as expressions, they need to
17  * be manipulated in much the same way as expressions at compile time: for example variables
18  * need to be bound, dependencies need to be analyzed, and so on. This is especially true
19  * of patterns appearing in the xsl:number and xsl:for-each-group instructions (less so for
20  * the more common match patterns in xsl:template).
21  *
22  * <p>This class implements the Expression interface, so that an Expression can have a
23  * PatternSponsor as a subexpression; it wraps a Pattern.</p>
24  *
25  * <p>A Pattern is treated as a boolean expression that returns true if the pattern matches
26  * the context node. However, it is not currently evaluated in that way.</p>
27  */

28
29 public class PatternSponsor implements Expression {
30
31     private Pattern pattern;
32
33     public PatternSponsor(Pattern pattern) {
34         this.pattern = pattern;
35     }
36
37     /**
38      * Get the wrapped pattern
39      */

40
41     public Pattern getPattern() {
42         return pattern;
43     }
44
45     /**
46      * An implementation of Expression must provide at least one of the methods evaluateItem(), iterate(), or process().
47      * This method indicates which of these methods is provided directly. The other methods will always be available
48      * indirectly, using an implementation that relies on one of the other methods.
49      */

50
51     public int getImplementationMethod() {
52         return EVALUATE_METHOD;
53     }
54
55     /**
56      * Simplify an expression. This performs any static optimization (by rewriting the expression
57      * as a different expression). The default implementation does nothing.
58      *
59      * @return the simplified expression
60      * @throws net.sf.saxon.trans.StaticError if an error is discovered during expression
61      * rewriting
62      */

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

86
87     public Expression optimize(Optimizer opt, StaticContext env, ItemType contextItemType) throws XPathException {
88         return this;
89     }
90
91     /**
92      * Perform type checking of an expression and its subexpressions.
93      * <p/>
94      * <p>This checks statically that the operands of the expression have
95      * the correct type; if necessary it generates code to do run-time type checking or type
96      * conversion. A static type error is reported only if execution cannot possibly succeed, that
97      * is, if a run-time type error is inevitable. The call may return a modified form of the expression.</p>
98      * <p/>
99      * <p>This method is called after all references to functions and variables have been resolved
100      * to the declaration of the function or variable. However, the types of such functions and
101      * variables may not be accurately known if they have not been explicitly declared.</p>
102      *
103      * @param env the static context of the expression
104      * @param contextItemType the static type of "." at the point where this expression is invoked.
105      * The parameter is set to null if it is known statically that the context item will be undefined.
106      * If the type of the context item is not known statically, the argument is set to
107      * {@link net.sf.saxon.type.Type#ITEM_TYPE}
108      * @return the original expression, rewritten to perform necessary
109      * run-time type checks, and to perform other type-related
110      * optimizations
111      * @throws net.sf.saxon.trans.StaticError if an error is discovered during this phase
112      * (typically a type error)
113      */

114
115     public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException {
116         pattern = pattern.analyze(env, contextItemType);
117         return this;
118     }
119
120     /**
121      * Offer promotion for this subexpression. The offer will be accepted if the subexpression
122      * is not dependent on the factors (e.g. the context item) identified in the PromotionOffer.
123      * By default the offer is not accepted - this is appropriate in the case of simple expressions
124      * such as constant values and variable references where promotion would give no performance
125      * advantage. This method is always called at compile time.
126      *
127      * @param offer details of the offer, for example the offer to move
128      * expressions that don't depend on the context to an outer level in
129      * the containing expression
130      * @return if the offer is not accepted, return this expression unchanged.
131      * Otherwise return the result of rewriting the expression to promote
132      * this subexpression
133      * @throws net.sf.saxon.trans.XPathException
134      * if any error is detected
135      */

136
137     public Expression promote(PromotionOffer offer) throws XPathException {
138         pattern.promote(offer);
139         return this;
140     }
141
142     /**
143      * Get the static properties of this expression (other than its type). The result is
144      * bit-signficant. These properties are used for optimizations. In general, if
145      * property bit is set, it is true, but if it is unset, the value is unknown.
146      *
147      * @return a set of flags indicating static properties of this expression
148      */

149
150     public int getSpecialProperties() {
151         return 0;
152     }
153
154     /**
155      * <p>Determine the static cardinality of the expression. This establishes how many items
156      * there will be in the result of the expression, at compile time (i.e., without
157      * actually evaluating the result.</p>
158      * <p/>
159      * <p>This method should always return a result, though it may be the best approximation
160      * that is available at the time.</p>
161      *
162      * @return one of the values {@link StaticProperty#ALLOWS_ONE},
163      * {@link StaticProperty#ALLOWS_ZERO_OR_MORE}, {@link StaticProperty#ALLOWS_ZERO_OR_ONE},
164      * {@link StaticProperty#ALLOWS_ONE_OR_MORE}, {@link StaticProperty#EMPTY}.
165      */

166
167     public int getCardinality() {
168         return StaticProperty.EXACTLY_ONE;
169     }
170
171     /**
172      * Determine the data type of the expression, if possible. All expression return
173      * sequences, in general; this method determines the type of the items within the
174      * sequence, assuming that (a) this is known in advance, and (b) it is the same for
175      * all items in the sequence.
176      * <p/>
177      * <p>This method should always return a result, though it may be the best approximation
178      * that is available at the time.</p>
179      *
180      * @return a value such as Type.STRING, Type.BOOLEAN, Type.NUMBER,
181      * Type.NODE, or Type.ITEM (meaning not known at compile time)
182      */

183
184     public ItemType getItemType() {
185         return Type.BOOLEAN_TYPE;
186     }
187
188     /**
189      * Determine which aspects of the context the expression depends on. The result is
190      * a bitwise-or'ed value composed from constants such as {@link net.sf.saxon.expr.StaticProperty#DEPENDS_ON_CONTEXT_ITEM} and
191      * {@link net.sf.saxon.expr.StaticProperty#DEPENDS_ON_CURRENT_ITEM}. The default implementation combines the intrinsic
192      * dependencies of this expression with the dependencies of the subexpressions,
193      * computed recursively. This is overridden for expressions such as FilterExpression
194      * where a subexpression's dependencies are not necessarily inherited by the parent
195      * expression.
196      *
197      * @return a set of bit-significant flags identifying the dependencies of
198      * the expression
199      */

200
201     public int getDependencies() {
202         return pattern.getDependencies();
203     }
204
205     /**
206      * Get the immediate sub-expressions of this expression. Default implementation
207      * returns a zero-length array, appropriate for an expression that has no
208      * sub-expressions.
209      *
210      * @return an iterator containing the sub-expressions of this expression
211      */

212
213     public Iterator JavaDoc iterateSubExpressions() {
214         return pattern.iterateSubExpressions();
215     }
216
217     /**
218      * Get the container that immediately contains this expression. This method
219      * returns null for an outermost expression; it also return null in the case
220      * of literal values. For an XPath expression occurring within an XSLT stylesheet,
221      * this method returns the XSLT instruction containing the XPath expression.
222      *
223      * @return the expression that contains this expression, if known; return null
224      * if there is no containing expression or if the containing expression is unknown.
225      */

226
227     public Container getParentExpression() {
228         return pattern;
229     }
230
231     /**
232      * Evaluate an expression as a single item. This always returns either a single Item or
233      * null (denoting the empty sequence). No conversion is done. This method should not be
234      * used unless the static type of the expression is a subtype of "item" or "item?": that is,
235      * it should not be called if the expression may return a sequence. There is no guarantee that
236      * this condition will be detected.
237      *
238      * @param context The context in which the expression is to be evaluated
239      * @return the node or atomic value that results from evaluating the
240      * expression; or null to indicate that the result is an empty
241      * sequence
242      * @throws net.sf.saxon.trans.XPathException
243      * if any dynamic error occurs evaluating the
244      * expression
245      */

246
247     public Item evaluateItem(XPathContext context) throws XPathException {
248         return BooleanValue.get(effectiveBooleanValue(context));
249     }
250
251     /**
252      * Return an Iterator to iterate over the values of a sequence. The value of every
253      * expression can be regarded as a sequence, so this method is supported for all
254      * expressions. This default implementation handles iteration for expressions that
255      * return singleton values: for non-singleton expressions, the subclass must
256      * provide its own implementation.
257      *
258      * @param context supplies the context for evaluation
259      * @return a SequenceIterator that can be used to iterate over the result
260      * of the expression
261      * @throws net.sf.saxon.trans.XPathException
262      * if any dynamic error occurs evaluating the
263      * expression
264      */

265
266     public SequenceIterator iterate(XPathContext context) throws XPathException {
267         return SingletonIterator.makeIterator(evaluateItem(context));
268     }
269
270     /**
271      * Get the effective boolean value of the expression. This returns false if the value
272      * is the empty sequence, a zero-length string, a number equal to zero, or the boolean
273      * false. Otherwise it returns true.
274      *
275      * @param context The context in which the expression is to be evaluated
276      * @return the effective boolean value
277      * @throws net.sf.saxon.trans.XPathException
278      * if any dynamic error occurs evaluating the
279      * expression
280      */

281
282     public boolean effectiveBooleanValue(XPathContext context) throws XPathException {
283         Item contextItem = context.getContextItem();
284         if (contextItem instanceof NodeInfo) {
285             return pattern.matches((NodeInfo)contextItem, context);
286         }
287         return false;
288     }
289
290     /**
291      * Evaluate an expression as a String. This function must only be called in contexts
292      * where it is known that the expression will return a single string (or where an empty sequence
293      * is to be treated as a zero-length string). Implementations should not attempt to convert
294      * the result to a string, other than converting () to "". This method is used mainly to
295      * evaluate expressions produced by compiling an attribute value template.
296      *
297      * @param context The context in which the expression is to be evaluated
298      * @return the value of the expression, evaluated in the current context.
299      * The expression must return a string or (); if the value of the
300      * expression is (), this method returns "".
301      * @throws net.sf.saxon.trans.XPathException
302      * if any dynamic error occurs evaluating the
303      * expression
304      * @throws ClassCastException if the result type of the
305      * expression is not xs:string?
306      */

307
308     public String JavaDoc evaluateAsString(XPathContext context) throws XPathException {
309         return evaluateItem(context).getStringValue();
310     }
311
312     /**
313      * Process the instruction, without returning any tail calls
314      *
315      * @param context The dynamic context, giving access to the current node,
316      * the current variables, etc.
317      */

318
319     public void process(XPathContext context) throws XPathException {
320         throw new UnsupportedOperationException JavaDoc("Patterns cannot be evaluated in push mode");
321     }
322
323     /**
324      * Diagnostic print of expression structure. The expression is written to the System.err
325      * output stream
326      *
327      * @param level indentation level for this expression
328      * @param pool NamePool used to expand any names appearing in the expression
329      * @param out Output destination
330      */

331
332     public void display(int level, NamePool pool, PrintStream JavaDoc out) {
333         out.println(ExpressionTool.indent(level) + "pattern " + pattern.toString());
334     }
335
336     /**
337      * Check statically that the results of the expression are capable of constructing the content
338      * of a given schema type.
339      *
340      * @param parentType The schema type
341      * @param env the static context
342      * @param whole true if this expression is expected to make the whole content of the type, false
343      * if it is expected to make up only a part
344      * @throws net.sf.saxon.trans.XPathException
345      * if the expression doesn't match the required content type
346      */

347
348     public void checkPermittedContents(SchemaType parentType, StaticContext env, boolean whole) throws XPathException {
349         throw new UnsupportedOperationException JavaDoc("checkPermittedContents() is not applicable to a pattern");
350     }
351 }
352
353 //
354
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
355
// you may not use this file except in compliance with the License. You may obtain a copy of the
356
// License at http://www.mozilla.org/MPL/
357
//
358
// Software distributed under the License is distributed on an "AS IS" basis,
359
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
360
// See the License for the specific language governing rights and limitations under the License.
361
//
362
// The Original Code is: all this file.
363
//
364
// The Initial Developer of the Original Code is Michael H. Kay.
365
//
366
// Contributor(s): Michael Kay
367
//
368
Popular Tags