KickJava   Java API By Example, From Geeks To Geeks.

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


1 package net.sf.saxon.expr;
2 import net.sf.saxon.Configuration;
3 import net.sf.saxon.Controller;
4 import net.sf.saxon.instruct.*;
5 import net.sf.saxon.om.AxisIterator;
6 import net.sf.saxon.om.Item;
7 import net.sf.saxon.om.SingletonIterator;
8 import net.sf.saxon.om.ValueRepresentation;
9 import net.sf.saxon.sort.GroupIterator;
10 import net.sf.saxon.trace.InstructionInfoProvider;
11 import net.sf.saxon.trans.Mode;
12 import net.sf.saxon.trans.XPathException;
13
14 /**
15  * This class represents a "major context" in which an XPath expression is evaluated:
16  * a "major context" object allows all aspects of the dynamic context to change, whereas
17  * a "minor context" only allows changes to the focus and the destination for push output.
18 */

19
20 public class XPathContextMajor extends XPathContextMinor {
21
22     private StackFrame stackFrame = null;
23     private ParameterSet localParameters = null;
24     private XSLTContext xsltContext = null;
25
26     /**
27     * Constructor should only be called by the Controller,
28     * which acts as a XPathContext factory.
29     */

30
31     public XPathContextMajor(Controller c) {
32         controller = c;
33         stackFrame = StackFrame.EMPTY;
34         origin = controller;
35     }
36
37     /**
38     * Private Constructor
39     */

40
41     private XPathContextMajor() {
42     }
43
44     /**
45     * Constructor for use in free-standing Java applications.
46     */

47
48     public XPathContextMajor(Item item, Configuration config) {
49         Executable exec = new Executable();
50         exec.setHostLanguage(Configuration.JAVA_APPLICATION);
51         controller = new Controller(config, exec);
52         AxisIterator iter = SingletonIterator.makeIterator(item);
53         iter.next();
54         currentIterator = iter;
55         origin = controller;
56     }
57
58     /**
59     * Construct a new context as a copy of another. The new context is effectively added
60     * to the top of a stack, and contains a pointer to the previous context
61     */

62
63     public XPathContextMajor newContext() {
64         XPathContextMajor c = new XPathContextMajor();
65         c.controller = controller;
66         c.currentIterator = currentIterator;
67         c.stackFrame = stackFrame;
68         c.localParameters = localParameters;
69         c.last = last;
70         c.currentReceiver = currentReceiver;
71         c.isTemporaryDestination = isTemporaryDestination;
72         c.xsltContext = xsltContext;
73         c.caller = this;
74         return c;
75     }
76
77     public static XPathContextMajor newContext(XPathContextMinor p) {
78         XPathContextMajor c = new XPathContextMajor();
79         c.controller = p.getController();
80         c.currentIterator = p.getCurrentIterator();
81         c.stackFrame = p.getStackFrame();
82         c.localParameters = p.getLocalParameters();
83
84         c.last = p.last;
85         c.currentReceiver = p.currentReceiver;
86         c.isTemporaryDestination = p.isTemporaryDestination;
87         c.xsltContext = p.getXSLTContext();
88         c.caller = p;
89         return c;
90     }
91
92     /**
93      * Get the XSLT-specific part of the context
94      */

95
96     public XSLTContext getXSLTContext() {
97         return xsltContext;
98     }
99
100     /**
101      * Get the local parameters for the current template call.
102      * @return the supplied parameters
103      */

104
105     public ParameterSet getLocalParameters() {
106         return localParameters;
107     }
108
109     /**
110      * Set the local parameters for the current template call.
111      * @param localParameters the supplied parameters
112      */

113
114     public void setLocalParameters(ParameterSet localParameters) {
115         this.localParameters = localParameters;
116     }
117
118     /**
119      * Get the tunnel parameters for the current template call.
120      * @return the supplied tunnel parameters
121      */

122
123     public ParameterSet getTunnelParameters() {
124         if (xsltContext != null) {
125             return xsltContext.tunnelParameters;
126         } else {
127             return null;
128         }
129     }
130
131     /**
132      * Set the tunnel parameters for the current template call.
133      * @param tunnelParameters the supplied tunnel parameters
134      */

135
136     public void setTunnelParameters(ParameterSet tunnelParameters) {
137         xsltContext = new XSLTContext(xsltContext);
138         xsltContext.tunnelParameters = tunnelParameters;
139     }
140
141     /**
142      * Set the creating expression (for use in diagnostics). The origin is generally set to "this" by the
143      * object that creates the new context. It's up to the debugger to determine whether this information
144      * is useful. The object will either be an {@link InstructionInfoProvider}, allowing information
145      * about the calling instruction to be obtained, or null.
146      */

147
148     public void setOrigin(InstructionInfoProvider expr) {
149         origin = expr;
150     }
151
152     /**
153      * Get a reference to the local stack frame for variables. Note that it's
154      * the caller's job to make a local copy of this. This is used for creating
155      * a Closure containing a retained copy of the variables for delayed evaluation.
156      * @return array of variables.
157      */

158
159     public StackFrame getStackFrame() {
160         return stackFrame;
161     }
162
163
164     /**
165      * Set the local stack frame. This method is used when creating a Closure to support
166      * delayed evaluation of expressions. The "stack frame" is actually on the Java heap, which
167      * means it can survive function returns and the like.
168      */

169
170     public void setStackFrame(SlotManager map, ValueRepresentation[] variables) {
171         stackFrame = new StackFrame(map, variables);
172         if (map != null && variables.length != map.getNumberOfVariables()) {
173             stackFrame.slots = new ValueRepresentation[map.getNumberOfVariables()];
174             System.arraycopy(variables, 0, stackFrame.slots, 0, variables.length);
175         }
176     }
177
178     /**
179      * Create a new stack frame for local variables, using the supplied SlotManager to
180      * define the allocation of slots to individual variables
181      * @param map the SlotManager for the new stack frame
182      */

183     public void openStackFrame(SlotManager map) {
184         int slots = map.getNumberOfVariables();
185         if (slots == 0) {
186             stackFrame = StackFrame.EMPTY;
187         } else {
188             stackFrame = new StackFrame(map, new ValueRepresentation[slots]);
189         }
190     }
191
192     /**
193      * Create a new stack frame large enough to hold a given number of local variables,
194      * for which no stack frame map is available. This is used in particular when evaluating
195      * match patterns of template rules.
196      * @param numberOfVariables The number of local variables to be accommodated.
197      */

198
199     public void openStackFrame(int numberOfVariables) {
200         stackFrame = new StackFrame(null, new ValueRepresentation[numberOfVariables]);
201     }
202
203     /**
204      * Get the value of a local variable, identified by its slot number
205      */

206
207     public ValueRepresentation evaluateLocalVariable(int slotnumber) {
208         return stackFrame.slots[slotnumber];
209     }
210
211     /**
212      * Set the value of a local variable, identified by its slot number
213      */

214
215     public void setLocalVariable(int slotnumber, ValueRepresentation value) {
216         stackFrame.slots[slotnumber] = value;
217     }
218
219
220     /**
221      * Set the current mode.
222      * @param mode the new current mode
223      */

224
225     public void setCurrentMode(Mode mode) {
226         if ((mode != null && !mode.isDefaultMode()) || (getCurrentMode() != null)) {
227             xsltContext = new XSLTContext(xsltContext);
228             xsltContext.currentMode = mode;
229         }
230     }
231
232     /**
233      * Get the current mode.
234      * @return the current mode. May return null if the current mode is the default mode.
235      */

236
237     public Mode getCurrentMode() {
238         if (xsltContext != null) {
239             return xsltContext.currentMode;
240         } else {
241             return null;
242         }
243     }
244
245     /**
246      * Set the current template. This is used to support xsl:apply-imports. The caller
247      * is responsible for remembering the previous current template and resetting it
248      * after use.
249      *
250      * @param template the current template
251      */

252
253     public void setCurrentTemplate(Template template) {
254         xsltContext = new XSLTContext(xsltContext);
255         xsltContext.currentTemplate = template;
256     }
257
258     /**
259      * Get the current template. This is used to support xsl:apply-imports
260      *
261      * @return the current template
262      */

263
264     public Template getCurrentTemplate() {
265         if (xsltContext != null) {
266             return xsltContext.currentTemplate;
267         } else {
268             return null;
269         }
270     }
271
272     /**
273      * Set the current grouping iterator. This supports the current-group() and
274      * current-grouping-key() functions in XSLT 2.0
275      * @param collection the new current GroupIterator
276      */

277
278     public void setCurrentGroupIterator(GroupIterator collection) {
279         xsltContext = new XSLTContext(xsltContext);
280         xsltContext.currentGroupIterator = collection;
281     }
282
283     /**
284      * Get the current group iterator. This supports the current-group() and
285      * current-grouping-key() functions in XSLT 2.0
286      * @return the current grouped collection
287      */

288
289     public GroupIterator getCurrentGroupIterator() {
290         if (xsltContext != null) {
291             return xsltContext.currentGroupIterator;
292         } else {
293             return null;
294         }
295     }
296
297     /**
298      * Set the current regex iterator. This supports the functionality of the regex-group()
299      * function in XSLT 2.0.
300      * @param currentRegexIterator the current regex iterator
301      */

302
303     public void setCurrentRegexIterator(RegexIterator currentRegexIterator) {
304         xsltContext = new XSLTContext(xsltContext);
305         xsltContext.currentRegexIterator = currentRegexIterator;
306     }
307
308     /**
309      * Get the current regex iterator. This supports the functionality of the regex-group()
310      * function in XSLT 2.0.
311      * @return the current regular expressions iterator
312      */

313
314     public RegexIterator getCurrentRegexIterator() {
315         if (xsltContext != null) {
316             return xsltContext.currentRegexIterator;
317         } else {
318             return null;
319         }
320     }
321
322     /**
323     * Use local parameter. This is called when a local xsl:param element is processed.
324     * If a parameter of the relevant name was supplied, it is bound to the xsl:param element.
325     * Otherwise the method returns false, so the xsl:param default will be evaluated
326     * @param fingerprint The fingerprint of the parameter name
327     * @param binding The XSLParam element to bind its value to
328     * @param isTunnel True if a tunnel parameter is required, else false
329     * @return true if a parameter of this name was supplied, false if not
330     */

331
332     public boolean useLocalParameter(int fingerprint,
333                                      LocalParam binding,
334                                      boolean isTunnel) throws XPathException {
335
336         ParameterSet params = (isTunnel ? getTunnelParameters() : localParameters);
337         if (params==null) return false;
338         ValueRepresentation val = params.get(fingerprint);
339         stackFrame.slots[binding.getSlotNumber()] = val;
340         return (val != null);
341     }
342
343     /**
344      * An XSLTContext object holds all the additional dynamic context items used in XSLT.
345      * These are held in a separate object for two reasons: firstly, they don't change often,
346      * so it's costly to copy them every time a new context object is created, and secondly,
347      * they aren't used at all in XQuery, they just add overhead.
348      */

349
350     protected static class XSLTContext {
351         public ParameterSet tunnelParameters = null;
352         public Mode currentMode = null;
353         public Template currentTemplate = null;
354         public GroupIterator currentGroupIterator = null;
355         public RegexIterator currentRegexIterator = null;
356
357         /**
358          * Create a new XSLTContext optionally by copying an existing XSLTContext
359          * @param original the existing XSLTContext. May be null, in which case a new XSLTContext is
360          * created from scratch.
361          */

362
363         public XSLTContext(XSLTContext original) {
364             if (original != null) {
365                 this.tunnelParameters = original.tunnelParameters;
366                 this.currentMode = original.currentMode;
367                 this.currentTemplate = original.currentTemplate;
368                 this.currentGroupIterator = original.currentGroupIterator;
369                 this.currentRegexIterator = original.currentRegexIterator;
370             }
371         }
372     }
373
374 }
375
376 //
377
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
378
// you may not use this file except in compliance with the License. You may obtain a copy of the
379
// License at http://www.mozilla.org/MPL/
380
//
381
// Software distributed under the License is distributed on an "AS IS" basis,
382
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
383
// See the License for the specific language governing rights and limitations under the License.
384
//
385
// The Original Code is: all this file.
386
//
387
// The Initial Developer of the Original Code is Michael H. Kay.
388
//
389
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
390
//
391
// Contributor(s): none.
392
//
393
Popular Tags