KickJava   Java API By Example, From Geeks To Geeks.

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


1 package net.sf.saxon.instruct;
2
3 import net.sf.saxon.Controller;
4 import net.sf.saxon.expr.*;
5 import net.sf.saxon.om.Item;
6 import net.sf.saxon.om.NamePool;
7 import net.sf.saxon.om.SequenceIterator;
8 import net.sf.saxon.trace.TraceListener;
9 import net.sf.saxon.trans.XPathException;
10 import net.sf.saxon.type.ItemType;
11
12 import java.io.PrintStream JavaDoc;
13 import java.util.Iterator JavaDoc;
14
15 /**
16  * This class is a tracing wrapper around any expression: it delivers the same result as the
17  * wrapped expression, but traces its evaluation to a TraceListener
18  */

19
20 public class TraceWrapper extends Instruction {
21     Expression child; // the instruction or other expression to be traced
22

23     /**
24      * Simplify an expression. This performs any static optimization (by rewriting the expression
25      * as a different expression). The default implementation does nothing.
26      *
27      * @exception net.sf.saxon.trans.XPathException if an error is discovered during expression
28      * rewriting
29      * @return the simplified expression
30      */

31
32     public Expression simplify(StaticContext env) throws XPathException {
33         child = child.simplify(env);
34         return this;
35     }
36
37     public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException {
38         child = child.typeCheck(env, contextItemType);
39         adoptChildExpression(child);
40         return this;
41     }
42
43     public Expression optimize(Optimizer opt, StaticContext env, ItemType contextItemType) throws XPathException {
44         child = child.optimize(opt, env, contextItemType);
45         adoptChildExpression(child);
46         return this;
47     }
48
49     /**
50      * Offer promotion for this subexpression. The offer will be accepted if the subexpression
51      * is not dependent on the factors (e.g. the context item) identified in the PromotionOffer.
52      * This method is always called at compile time.
53      *
54      * @param offer details of the offer, for example the offer to move
55      * expressions that don't depend on the context to an outer level in
56      * the containing expression
57      * @return if the offer is not accepted, return this expression unchanged.
58      * Otherwise return the result of rewriting the expression to promote
59      * this subexpression
60      * @throws net.sf.saxon.trans.XPathException
61      * if any error is detected
62      */

63
64     public Expression promote(PromotionOffer offer) throws XPathException {
65         // Many rewrites are not attempted if tracing is activated. But those that are, for example
66
// rewriting of calls to current(), must be carried out.
67
Expression newChild = child.promote(offer);
68         if (newChild != child) {
69             child = newChild;
70             adoptChildExpression(child);
71             return this;
72         }
73         return this;
74     }
75
76     /**
77      * Execute this instruction, with the possibility of returning tail calls if there are any.
78      * This outputs the trace information via the registered TraceListener,
79      * and invokes the instruction being traced.
80      * @param context the dynamic execution context
81      * @return either null, or a tail call that the caller must invoke on return
82      * @throws net.sf.saxon.trans.XPathException
83      */

84     public TailCall processLeavingTail(XPathContext context) throws XPathException {
85         Controller controller = context.getController();
86         TraceListener listener = controller.getTraceListener();
87         if (controller.isTracing()) {
88             listener.enter(getInstructionInfo(), context);
89         }
90         // Don't attempt tail call optimization when tracing, the results are too confusing
91
child.process(context);
92         if (controller.isTracing()) {
93             listener.leave(getInstructionInfo());
94         }
95         return null;
96     }
97
98     /**
99      * Get the item type of the items returned by evaluating this instruction
100      * @return the static item type of the instruction
101      */

102
103     public ItemType getItemType() {
104         return child.getItemType();
105     }
106
107     /**
108      * Determine the static cardinality of the expression. This establishes how many items
109      * there will be in the result of the expression, at compile time (i.e., without
110      * actually evaluating the result.
111      *
112      * @return one of the values Cardinality.ONE_OR_MORE,
113      * Cardinality.ZERO_OR_MORE, Cardinality.EXACTLY_ONE,
114      * Cardinality.ZERO_OR_ONE, Cardinality.EMPTY. This default
115      * implementation returns ZERO_OR_MORE (which effectively gives no
116      * information).
117      */

118
119     public int getCardinality() {
120         return child.getCardinality();
121     }
122
123     /**
124      * Determine which aspects of the context the expression depends on. The result is
125      * a bitwise-or'ed value composed from constants such as {@link net.sf.saxon.expr.StaticProperty#DEPENDS_ON_CONTEXT_ITEM} and
126      * {@link net.sf.saxon.expr.StaticProperty#DEPENDS_ON_CURRENT_ITEM}. The default implementation combines the intrinsic
127      * dependencies of this expression with the dependencies of the subexpressions,
128      * computed recursively. This is overridden for expressions such as FilterExpression
129      * where a subexpression's dependencies are not necessarily inherited by the parent
130      * expression.
131      *
132      * @return a set of bit-significant flags identifying the dependencies of
133      * the expression
134      */

135
136     public int getDependencies() {
137         return child.getDependencies();
138     }
139
140     /**
141      * Determine whether this instruction creates new nodes.
142      *
143      *
144      */

145
146     public final boolean createsNewNodes() {
147         return (child.getSpecialProperties() & StaticProperty.NON_CREATIVE) == 0;
148     }
149
150     /**
151      * Get the static properties of this expression (other than its type). The result is
152      * bit-signficant. These properties are used for optimizations. In general, if
153      * property bit is set, it is true, but if it is unset, the value is unknown.
154      *
155      * @return a set of flags indicating static properties of this expression
156      */

157
158     public int computeDependencies() {
159         if (child instanceof ComputedExpression) {
160             return ((ComputedExpression)child).computeDependencies();
161         } else {
162             return 0;
163         }
164     }
165
166     /**
167      * Evaluate an expression as a single item. This always returns either a single Item or
168      * null (denoting the empty sequence). No conversion is done. This method should not be
169      * used unless the static type of the expression is a subtype of "item" or "item?": that is,
170      * it should not be called if the expression may return a sequence. There is no guarantee that
171      * this condition will be detected.
172      *
173      * @param context The context in which the expression is to be evaluated
174      * @exception net.sf.saxon.trans.XPathException if any dynamic error occurs evaluating the
175      * expression
176      * @return the node or atomic value that results from evaluating the
177      * expression; or null to indicate that the result is an empty
178      * sequence
179      */

180
181     public Item evaluateItem(XPathContext context) throws XPathException {
182         Controller controller = context.getController();
183         if (controller.isTracing()) {
184             controller.getTraceListener().enter(getInstructionInfo(), context);
185         }
186         Item result = child.evaluateItem(context);
187         if (controller.isTracing()) {
188             controller.getTraceListener().leave(getInstructionInfo());
189         }
190         return result;
191     }
192
193     /**
194      * Return an Iterator to iterate over the values of a sequence. The value of every
195      * expression can be regarded as a sequence, so this method is supported for all
196      * expressions. This default implementation handles iteration for expressions that
197      * return singleton values: for non-singleton expressions, the subclass must
198      * provide its own implementation.
199      *
200      * @exception net.sf.saxon.trans.XPathException if any dynamic error occurs evaluating the
201      * expression
202      * @param context supplies the context for evaluation
203      * @return a SequenceIterator that can be used to iterate over the result
204      * of the expression
205      */

206
207     public SequenceIterator iterate(XPathContext context) throws XPathException {
208         Controller controller = context.getController();
209         if (controller.isTracing()) {
210             controller.getTraceListener().enter(getInstructionInfo(), context);
211         }
212         SequenceIterator result = child.iterate(context);
213         if (controller.isTracing()) {
214             controller.getTraceListener().leave(getInstructionInfo());
215         }
216         return result;
217     }
218
219     public Iterator iterateSubExpressions() {
220         return new MonoIterator(child);
221     }
222
223     public int getInstructionNameCode() {
224         if (child instanceof Instruction) {
225             return ((Instruction)child).getInstructionNameCode();
226         } else {
227             return -1;
228         }
229     }
230
231     /**
232      * Diagnostic print of expression structure. The expression is written to the System.err
233      * output stream
234      *
235      * @param level indentation level for this expression
236      * @param out
237      */

238
239     public void display(int level, NamePool pool, PrintStream JavaDoc out) {
240         child.display(level, pool, out);
241     }
242 }
243
Popular Tags