KickJava   Java API By Example, From Geeks To Geeks.

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


1 package net.sf.saxon.instruct;
2 import net.sf.saxon.Configuration;
3 import net.sf.saxon.event.Stripper;
4 import net.sf.saxon.functions.FunctionLibrary;
5 import net.sf.saxon.om.NamespaceConstant;
6 import net.sf.saxon.query.StaticQueryContext;
7 import net.sf.saxon.query.QueryReader;
8 import net.sf.saxon.sort.CodepointCollator;
9 import net.sf.saxon.trans.*;
10
11 import javax.xml.transform.TransformerException JavaDoc;
12 import java.io.Serializable JavaDoc;
13 import java.util.*;
14
15 /**
16 * A compiled stylesheet or query in executable form.
17 * Note that the original stylesheet tree is not retained.
18 */

19
20 public class Executable implements Serializable JavaDoc {
21
22                 // the Configuration options
23
private transient Configuration config;
24
25                 // definitions of strip/preserve space action
26
private Mode stripperRules;
27
28                 // boolean indicating whether any whitespace is stripped
29
private boolean stripsWhitespace;
30
31                 // definitions of template rules
32
private RuleManager ruleManager;
33
34                 // definitions of keys
35
private KeyManager keyManager;
36
37                 // definitions of decimal formats
38
private DecimalFormatManager decimalFormatManager;
39
40                 // the map of slots used for global variables and params
41
private SlotManager globalVariableMap;
42
43                 // index of global variables and parameters, by fingerprint
44
// (overridden variables are excluded).
45
// Used at compile-time only, except for debugging
46
private HashMap globalVariableIndex = new HashMap(32);
47
48                 // default collating sequence
49
private String JavaDoc defaultCollationName;
50
51                 // default output properties (for the unnamed output format)
52
private Properties defaultOutputProperties;
53
54                 // index of named templates.
55
private HashMap namedTemplateTable = new HashMap(32);
56
57                 // count of the maximum number of local variables in the match pattern of any template rule
58
private int largestPatternStackFrame = 0;
59
60                 // table of named collations defined in the stylesheet/query
61
private HashMap collationTable = new HashMap(10);
62
63                 // table of character maps
64
private HashMap characterMapIndex;
65
66                 // location map for expressions in this executable
67
private LocationMap locationMap;
68
69                 // hash table of query library modules
70
private HashMap queryLibraryModules;
71
72                 // flag to indicate that source documents are to have their type annotations stripped
73
private boolean stripsInputTypeAnnotations;
74
75                 // list of functions available in the static context
76
private FunctionLibrary functionLibrary;
77
78                 // flag to indicate whether the principal language is for example XSLT or XQuery
79
private int hostLanguage = Configuration.XSLT;
80
81                 // a list of required parameters, identified by the fingerprint of their names
82
private Set requiredParams = null;
83
84                 // a string explaining why this Executable can't be compiled, or null if it can
85
private String JavaDoc reasonUnableToCompile = null;
86
87     public Executable() {
88
89     }
90
91     /**
92      * Set the configuration
93      */

94
95     public void setConfiguration(Configuration config) {
96         this.config = config;
97     }
98
99     /**
100      * Get the configuration
101      */

102
103     public Configuration getConfiguration() {
104         return config;
105     }
106
107     /**
108      * Set the host language
109      */

110
111     public void setHostLanguage(int language) {
112         hostLanguage = language;
113     }
114
115     /**
116      * Get the host language
117      * @return a value identifying the host language: {@link Configuration#XQUERY} or {@link Configuration#XSLT}
118      * or {@link Configuration#JAVA_APPLICATION}
119      */

120
121     public int getHostLanguage() {
122         return hostLanguage;
123     }
124     /**
125     * Set the RuleManager that handles template rules
126     * @param rm the RuleManager containing details of all the template rules
127     */

128
129     public void setRuleManager(RuleManager rm) {
130         ruleManager = rm;
131     }
132
133     /**
134     * Get the RuleManager which handles template rules
135     * @return the RuleManager registered with setRuleManager
136     */

137
138     public RuleManager getRuleManager() {
139         return ruleManager;
140     }
141
142     /**
143     * Get the named template table
144     * @return a hash table containing entries that map the names of named
145     * templates to the instructions representing the xsl:template instruction
146     */

147
148     public HashMap getNamedTemplateTable() {
149         if (namedTemplateTable==null) {
150             namedTemplateTable = new HashMap(32);
151         }
152         return namedTemplateTable;
153     }
154
155     /**
156      * Get the named template with a given name.
157      * @param fingerprint The namepool fingerprint of the template name
158      * @return The template (of highest import precedence) with this name if there is one;
159      * null if none is found.
160      */

161
162     public Template getNamedTemplate(int fingerprint) {
163         return (Template)namedTemplateTable.get(new Integer JavaDoc(fingerprint));
164     }
165
166     /**
167      * Get the library containing all the in-scope functions in the static context
168      * @return the function libary
169      */

170
171     public FunctionLibrary getFunctionLibrary() {
172         return functionLibrary;
173     }
174
175     /**
176      * Set the library containing all the in-scope functions in the static context
177      * @param functionLibrary the function libary
178      */

179
180     public void setFunctionLibrary(FunctionLibrary functionLibrary) {
181         //System.err.println("***" + this + " setFunctionLib to " + functionLibrary);
182
this.functionLibrary = functionLibrary;
183     }
184
185     /**
186     * Set the index of named character maps
187     * @param cmi a hash table that maps the names of character maps
188     * to the HashMap objects representing the character maps
189     */

190
191     public void setCharacterMapIndex(HashMap cmi) {
192         characterMapIndex = cmi;
193     }
194
195     /**
196     * Get the index of named character maps
197     * @return the hash table that maps the names of character maps
198     * to the HashMap objects representing the character maps
199     */

200
201     public HashMap getCharacterMapIndex() {
202         if (characterMapIndex==null) {
203             characterMapIndex = new HashMap(10);
204         }
205         return characterMapIndex;
206     }
207
208     /**
209     * Set the rules determining which nodes are to be stripped from the tree
210     * @param rules a Mode object containing the whitespace stripping rules. A Mode
211     * is generally a collection of template rules, but it is reused here to represent
212     * a collection of stripping rules.
213     */

214
215     public void setStripperRules(Mode rules) {
216         stripperRules = rules;
217     }
218
219     /**
220     * Get the rules determining which nodes are to be stripped from the tree
221     * @return a Mode object containing the whitespace stripping rules. A Mode
222     * is generally a collection of template rules, but it is reused here to represent
223     * a collection of stripping rules.
224     */

225
226     public Mode getStripperRules() {
227         return stripperRules;
228     }
229
230     /**
231     * Indicate that the stylesheet does some whitespace stripping
232     * @param strips true if the stylesheet performs whitespace stripping
233     * of one or more elements.
234     */

235
236     public void setStripsWhitespace(boolean strips) {
237         stripsWhitespace = strips;
238     }
239
240     /**
241     * Create a Stripper which handles whitespace stripping definitions
242     * @return the constructed Stripper object
243     */

244
245     public Stripper newStripper() {
246         return new Stripper(stripperRules);
247     }
248
249     /**
250     * Determine whether this stylesheet does any whitespace stripping
251     * @return true if the stylesheet performs whitespace stripping
252     * of one or more elements.
253     */

254
255     public boolean stripsWhitespace() {
256         return stripsWhitespace;
257     }
258
259     /**
260      * Set whether source documents are to have their type annotations stripped
261      */

262
263     public void setStripsInputTypeAnnotations(boolean strips) {
264         stripsInputTypeAnnotations = strips;
265     }
266
267     /**
268      * Determine whether source documents are to have their type annotations stripped
269      */

270
271     public boolean stripsInputTypeAnnotations() {
272         return stripsInputTypeAnnotations;
273     }
274
275     /**
276     * Set the KeyManager which handles key definitions
277     * @param km the KeyManager containing the xsl:key definitions
278     */

279
280     public void setKeyManager(KeyManager km) {
281         keyManager = km;
282     }
283
284     /**
285     * Get the KeyManager which handles key definitions
286     * @return the KeyManager containing the xsl:key definitions
287     */

288
289     public KeyManager getKeyManager() {
290         if (keyManager==null) {
291             keyManager = new KeyManager(getConfiguration());
292         }
293         return keyManager;
294     }
295
296     /**
297     * Set the default output properties (the properties for the unnamed output format)
298     * @param properties the output properties to be used when the unnamed output format
299     * is selected
300     */

301
302     public void setDefaultOutputProperties(Properties properties) {
303         defaultOutputProperties = properties;
304     }
305
306     /**
307     * Get the default output properties
308     * @return the properties for the unnamed output format
309     */

310
311     public Properties getDefaultOutputProperties() {
312         if (defaultOutputProperties==null) {
313             defaultOutputProperties = new Properties();
314         }
315         return defaultOutputProperties;
316     }
317
318     /**
319     * Set the DecimalFormatManager which handles decimal-format definitions
320     * @param dfm the DecimalFormatManager containing the named xsl:decimal-format definitions
321     */

322
323     public void setDecimalFormatManager(DecimalFormatManager dfm) {
324         decimalFormatManager = dfm;
325     }
326
327     /**
328     * Get the DecimalFormatManager which handles decimal-format definitions
329     * @return the DecimalFormatManager containing the named xsl:decimal-format definitions
330     */

331
332     public DecimalFormatManager getDecimalFormatManager() {
333         if (decimalFormatManager==null) {
334             decimalFormatManager = new DecimalFormatManager();
335         }
336         return decimalFormatManager;
337     }
338
339     /**
340     * Set the default collation
341     * @param name the name of the default collation
342     */

343
344     public void setDefaultCollationName(String JavaDoc name) {
345         defaultCollationName = name;
346     }
347
348     /**
349     * Get the name of the default collation
350     * @return the name of the default collation; this is the code point collation URI if no other default
351      * has been set up.
352     */

353
354     public String JavaDoc getDefaultCollationName() {
355         if (defaultCollationName==null) {
356             return NamespaceConstant.CODEPOINT_COLLATION_URI;
357         } else {
358             return defaultCollationName;
359         }
360     }
361
362     /**
363     * Get the default collation
364     * @return a Comparator that implements the default collation
365     */

366
367     public Comparator getDefaultCollation() {
368         if (defaultCollationName==null) {
369             return CodepointCollator.getInstance();
370         } else {
371             return getNamedCollation(defaultCollationName);
372         }
373     }
374
375     /**
376     * Set the table of collations
377     * @param table a hash table that maps collation names (URIs) to objects representing the
378     * collation information
379     */

380
381     public void setCollationTable(HashMap table) {
382         collationTable = table;
383     }
384
385     /**
386     * Get the table of collations
387     * @return a hash table that maps collation names (URIs) to objects representing the
388     * collation information
389     */

390
391     public HashMap getCollationTable() {
392         return collationTable;
393     }
394
395     /**
396     * Find a named collation.
397     * @param name identifies the name of the collation required; null indicates that the default
398     * collation is required
399     * @return the requested collation, or null if the collation is not found
400     */

401
402     public Comparator getNamedCollation(String JavaDoc name) {
403         if (collationTable==null) {
404             collationTable = new HashMap(10);
405         }
406         return (Comparator)collationTable.get(name);
407     }
408
409     /**
410      * Add an XQuery library module to the configuration. The Executable maintains a table indicating
411      * for each module namespace, the set of modules that have been loaded from that namespace. If a
412      * module import is encountered that specifies no location hint, all the known modules for that
413      * namespace are imported.
414      */

415
416     public void addQueryLibraryModule(StaticQueryContext module) {
417         if (queryLibraryModules==null) {
418             queryLibraryModules = new HashMap(5);
419         }
420         String JavaDoc uri = module.getModuleNamespace();
421         List existing = (List)queryLibraryModules.get(uri);
422         if (existing == null) {
423             existing = new ArrayList(5);
424             existing.add(module);
425             queryLibraryModules.put(uri, existing);
426         } else {
427             existing.add(module);
428         }
429     }
430
431     /**
432      * Locate the known XQuery library modules for a given module namespace.
433      * @param namespace the module namespace URI
434      * @return a list of items each of which is the StaticQueryContext representing a module, or
435      * null if the module namespace is unknown
436      */

437
438     public List getQueryLibraryModules(String JavaDoc namespace) {
439         if (queryLibraryModules == null) {
440             return null;
441         }
442         return (List)queryLibraryModules.get(namespace);
443     }
444
445     /**
446      * Fix up global variables and functions in all query modules. This is done right at the end, because
447      * recursive imports are permitted
448      */

449
450     public void fixupQueryModules(StaticQueryContext main) throws XPathException {
451         HashMap varMap = new HashMap(10);
452         if (queryLibraryModules != null) {
453             Iterator iter = queryLibraryModules.values().iterator();
454             while (iter.hasNext()) {
455                 List modules = (List)iter.next();
456                 Iterator iter2 = modules.iterator();
457                 while (iter2.hasNext()) {
458                     StaticQueryContext env = (StaticQueryContext)iter2.next();
459                     List vars = fixupQueryModule(env);
460                     varMap.put(env, vars);
461                 }
462             }
463         }
464         List vars = fixupQueryModule(main);
465         varMap.put(main, vars);
466         Iterator iter = varMap.keySet().iterator();
467         while (iter.hasNext()) {
468             StaticQueryContext env = (StaticQueryContext)iter.next();
469             List varList = (List)varMap.get(env);
470             env.typeCheckGlobalVariables(varList);
471         }
472     }
473
474     private List fixupQueryModule(StaticQueryContext module) throws XPathException {
475         try {
476             // Import all functions and variables from other modules in an imported namespace
477
Iterator iter = module.iterateImportedNamespaces();
478             while (iter.hasNext()) {
479                 List modules = (List)queryLibraryModules.get(iter.next());
480                 Iterator iter3 = modules.iterator();
481                 while (iter3.hasNext()) {
482                     StaticQueryContext other = (StaticQueryContext)iter3.next();
483                     if (module != other) {
484                         QueryReader.importModuleContents(other, module);
485                     }
486                 }
487             }
488             // Now fix up the references to variables and functions
489
module.bindUnboundFunctionCalls();
490             List compiledVars = module.fixupGlobalVariables(module.getGlobalStackFrameMap());
491             module.fixupGlobalFunctions();
492             return compiledVars;
493         } catch (XPathException err) {
494             try {
495                 module.getConfiguration().getErrorListener().fatalError(err);
496                 throw err;
497             } catch (TransformerException JavaDoc err2) {
498                 if (err2 instanceof XPathException) {
499                     throw (XPathException) err2;
500                 } else {
501                     throw new StaticError(err2);
502                 }
503             }
504         }
505     }
506
507     /**
508     * Set the space requirements for variables used in template match patterns
509      * @param patternLocals The largest number of local variables used in the match pattern of any template rule
510     */

511
512     public void setPatternSlotSpace(int patternLocals) {
513         largestPatternStackFrame = patternLocals;
514     }
515
516     /**
517      * Get the global variable map
518      * @return the SlotManager defining the allocation of slots to global variables
519      */

520
521     public SlotManager getGlobalVariableMap() {
522         if (globalVariableMap == null) {
523             globalVariableMap = config.makeSlotManager();
524         }
525         return globalVariableMap;
526     }
527
528     /**
529      * Get the index of global variables
530      * @return the index of global variables. This is a HashMap in which the key is the integer fingerprint
531      * of the variable name, and the value is the VariableDeclaration of the global variable
532      */

533
534     public HashMap getGlobalVariableIndex() {
535         return globalVariableIndex;
536     }
537
538     /**
539      * Register a global variable
540      */

541
542     public void registerGlobalVariable(GeneralVariable variable) {
543         globalVariableIndex.put(new Integer JavaDoc(variable.getVariableFingerprint()), variable);
544     }
545
546     /**
547     * Allocate space in bindery for all the variables needed
548     * @param bindery The bindery to be initialized
549     */

550
551     public void initialiseBindery(Bindery bindery) {
552         bindery.allocateGlobals(getGlobalVariableMap());
553     }
554
555     /**
556      * Determine the size of the stack frame needed for evaluating match patterns
557      */

558
559     public int getLargestPatternStackFrame() {
560         return largestPatternStackFrame;
561     }
562
563     /**
564      * Set the location map
565      */

566
567     public void setLocationMap(LocationMap map) {
568         locationMap = map;
569     }
570
571     /**
572      * Get the location map
573      */

574
575     public LocationMap getLocationMap() {
576         return locationMap;
577     }
578
579     /**
580      * Add a required parameter
581      */

582
583     public void addRequiredParam(int fingerprint) {
584         if (requiredParams == null) {
585             requiredParams = new HashSet(5);
586         }
587         requiredParams.add(new Integer JavaDoc(fingerprint));
588     }
589
590     /**
591      * Check that all required parameters have been supplied
592      */

593
594     public void checkAllRequiredParamsArePresent(GlobalParameterSet params) throws XPathException {
595         if (requiredParams == null) {
596             return;
597         }
598         Iterator iter = requiredParams.iterator();
599         while (iter.hasNext()) {
600             int req = ((Integer JavaDoc)iter.next()).intValue();
601             if (params==null || params.get(req) == null) {
602                 DynamicError err = new DynamicError("No value supplied for required parameter " +
603                         config.getNamePool().getDisplayName(req));
604                 err.setErrorCode("XTDE0050");
605                 throw err;
606             }
607         }
608     }
609
610     /**
611      * If this Executable can't be compiled, set a message explaining why
612      */

613
614     public void setReasonUnableToCompile(String JavaDoc reason) {
615         reasonUnableToCompile = reason;
616     }
617
618     /**
619      * Determine whether this executable can be compiled; and if it can't, return the reason why
620      * @return null if the executable can be compiled, or a message otherwise
621      */

622
623     public String JavaDoc getReasonUnableToCompile() {
624         return reasonUnableToCompile;
625     }
626
627 }
628
629 //
630
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
631
// you may not use this file except in compliance with the License. You may obtain a copy of the
632
// License at http://www.mozilla.org/MPL/
633
//
634
// Software distributed under the License is distributed on an "AS IS" basis,
635
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
636
// See the License for the specific language governing rights and limitations under the License.
637
//
638
// The Original Code is: all this file.
639
//
640
// The Initial Developer of the Original Code is Michael H. Kay.
641
//
642
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
643
//
644
// Contributor(s):
645
// Portions marked "e.g." are from Edwin Glaser (edwin@pannenleiter.de)
646
//
647
Popular Tags