KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > Configuration


1 package net.sf.saxon;
2
3 import net.sf.saxon.event.Builder;
4 import net.sf.saxon.event.PipelineConfiguration;
5 import net.sf.saxon.event.Receiver;
6 import net.sf.saxon.event.StandardOutputResolver;
7 import net.sf.saxon.expr.Optimizer;
8 import net.sf.saxon.expr.XPathContext;
9 import net.sf.saxon.functions.*;
10 import net.sf.saxon.instruct.Debugger;
11 import net.sf.saxon.instruct.SlotManager;
12 import net.sf.saxon.om.*;
13 import net.sf.saxon.pattern.NodeTest;
14 import net.sf.saxon.trace.TraceListener;
15 import net.sf.saxon.trans.XPathException;
16 import net.sf.saxon.trans.DynamicError;
17 import net.sf.saxon.type.*;
18 import net.sf.saxon.sort.CollationURIResolver;
19 import net.sf.saxon.sort.StandardCollationURIResolver;
20 import net.sf.saxon.pull.PullProvider;
21 import net.sf.saxon.query.ModuleURIResolver;
22 import net.sf.saxon.query.StandardModuleURIResolver;
23 import org.xml.sax.SAXException JavaDoc;
24 import org.xml.sax.SAXNotRecognizedException JavaDoc;
25 import org.xml.sax.SAXNotSupportedException JavaDoc;
26 import org.xml.sax.XMLReader JavaDoc;
27
28 import javax.xml.parsers.ParserConfigurationException JavaDoc;
29 import javax.xml.parsers.SAXParserFactory JavaDoc;
30 import javax.xml.transform.*;
31 import javax.xml.transform.dom.DOMSource JavaDoc;
32 import javax.xml.transform.sax.SAXSource JavaDoc;
33 import javax.xml.transform.stream.StreamSource JavaDoc;
34 import java.io.Serializable JavaDoc;
35 import java.util.*;
36
37
38 /**
39  * This class holds details of user-selected configuration options for a transformation
40  * or query. When running XSLT, the preferred way of setting configuration options is via
41  * the JAXP TransformerFactory interface, but the Configuration object provides a finer
42  * level of control. As yet there is no standard API for XQuery, so the only way of setting
43  * Configuration information is to use the methods on this class directly.
44  * <p>
45  * Since Saxon 8.4, the JavaDoc documentation for Saxon attempts to identify interfaces
46  * that are considered stable, and will only be changed in a backwards-incompatible way
47  * if there is an overriding reason to do so. These interfaces and methods are labelled
48  * with the JavaDoc "since" tag. The value 8.n indicates a method in this category that
49  * was introduced in Saxon version 8.n: or in the case of 8.4, that was present in Saxon 8.4
50  * and possibly in earlier releases. (In some cases, these methods have been unchanged for
51  * a long time.) Methods without a "since" tag, although public, are provided for internal
52  * use or for use by advanced users, and are subject to change from one release to the next.
53  * The presence of a "since" tag on a class or interface indicates that there are one or more
54  * methods in the class that are considered stable; it does not mean that all methods are
55  * stable.
56  *
57  * @since 8.4
58  */

59
60
61 public class Configuration implements ConversionContext, Serializable JavaDoc, SourceResolver {
62
63     private transient URIResolver uriResolver;
64     private StandardURIResolver systemURIResolver = new StandardURIResolver(this);
65     protected transient ErrorListener listener;
66     private int treeModel = Builder.TINY_TREE;
67     private boolean lineNumbering = false;
68     private TraceListener traceListener = null;
69     private FunctionLibrary extensionBinder;
70     private CollationURIResolver collationResolver = StandardCollationURIResolver.getInstance();
71     private CollectionURIResolver collectionResolver = new StandardCollectionURIResolver();
72     private ModuleURIResolver moduleURIResolver = null;
73     private ModuleURIResolver standardModuleURIResolver = new StandardModuleURIResolver();
74     private SourceResolver sourceResolver = this;
75     protected VendorFunctionLibrary vendorFunctionLibrary;
76     protected int recoveryPolicy = RECOVER_WITH_WARNINGS;
77     private String JavaDoc messageEmitterClass = "net.sf.saxon.event.MessageEmitter";
78     private String JavaDoc sourceParserClass;
79     private String JavaDoc styleParserClass;
80     private transient OutputURIResolver outputURIResolver;
81     private boolean timing = false;
82     private boolean versionWarning = true;
83     private boolean allowExternalFunctions = true;
84     private boolean traceExternalFunctions = false;
85     private boolean validation = false;
86     private boolean allNodesUntyped = false;
87     private boolean lazyConstructionMode = false;
88     private boolean allowMultiThreading = false;
89     private NamePool targetNamePool = null;
90     private DocumentNumberAllocator documentNumberAllocator = new DocumentNumberAllocator();
91     private boolean stripsAllWhiteSpace = false;
92     private int hostLanguage = XSLT;
93     private int schemaValidationMode = Validation.PRESERVE;
94     private boolean validationWarnings = false;
95     private boolean retainDTDattributeTypes = false;
96     private Debugger debugger = null;
97     protected Optimizer optimizer = null;
98     private ExtensionFunctionFactory extensionFunctionFactory = new ExtensionFunctionFactory(this);
99     private List externalObjectModels = new ArrayList(4);
100     private transient ClassLoader JavaDoc classLoader;
101     private int implicitTimezone;
102     private transient List sourceParserPool = new ArrayList(5);
103     private transient List styleParserPool = new ArrayList(5);
104
105     /**
106      * Constant indicating that the processor should take the recovery action
107      * when a recoverable error occurs, with no warning message.
108      */

109     public static final int RECOVER_SILENTLY = 0;
110     /**
111      * Constant indicating that the processor should produce a warning
112      * when a recoverable error occurs, and should then take the recovery
113      * action and continue.
114      */

115     public static final int RECOVER_WITH_WARNINGS = 1;
116     /**
117      * Constant indicating that when a recoverable error occurs, the
118      * processor should not attempt to take the defined recovery action,
119      * but should terminate with an error.
120      */

121     public static final int DO_NOT_RECOVER = 2;
122
123     /**
124      * Constant indicating that the host language is XSLT
125      */

126     public static final int XSLT = 10;
127
128     /**
129      * Constant indicating that the host language is XQuery
130      */

131     public static final int XQUERY = 11;
132
133     /**
134      * Constant indicating that the "host language" is XML Schema
135      */

136     public static final int XML_SCHEMA = 12;
137
138     /**
139      * Constant indicating that the host language is Java: that is, this is a free-standing
140      * Java application with no XSLT or XQuery content
141      */

142     public static final int JAVA_APPLICATION = 13;
143
144     /**
145      * Constant indicating that the host language is XPATH itself - that is, a free-standing XPath environment
146      */

147     public static final int XPATH = 14;
148
149     /**
150      * Create a configuration object with default settings for all options
151      * @since 8.4
152      */

153
154     public Configuration() {
155         targetNamePool = NamePool.getDefaultNamePool();
156         extensionBinder = new JavaExtensionLibrary(this);
157         registerStandardObjectModels();
158
159         // Get the implicit timezone from the current system clock
160
GregorianCalendar calendar = new GregorianCalendar();
161         int tzmsecs = (calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET));
162         implicitTimezone = tzmsecs / 60000;
163     }
164
165    /**
166     * Get a message used to identify this product when a transformation is run using the -t option
167     * @return A string containing both the product name and the product
168     * version
169     * @since 8.4
170     */

171
172     public String JavaDoc getProductTitle() {
173         return "Saxon " + Version.getProductVersion() + " from Saxonica";
174     }
175
176     /**
177      * Determine if the configuration is schema-aware, for the given host language
178      * @param language the required host language: XSLT, XQUERY, or XML_SCHEMA
179      * @since 8.4
180      */

181
182     public boolean isSchemaAware(int language) {
183         return false;
184         // changing this to true will do no good!
185
}
186
187     /**
188      * Display a message about the license status
189      */

190
191     public void displayLicenseMessage() {}
192
193     /**
194      * Get the host language used in this configuration. The typical values
195      * are XSLT and XQUERY. The values XML_SCHEMA and JAVA_APPLICATION may also
196      * be encountered.
197      * <p>
198      * This method is problematic because it is possible to run multiple transformations
199      * or queries within the same configuration. The method is therefore best avoided.
200      * Instead, use {@link net.sf.saxon.instruct.Executable#getHostLanguage}.
201      * Internally its only use is in deciding (in Saxon-SA only) which error listener to
202      * use by default at compile time, and since the standard XSLT and XQuery listeners have
203      * no differences when used for static errors, the choice is immaterial.
204      * @return Configuration.XSLT or Configuration.XQUERY
205      */

206
207     public int getHostLanguage() {
208         return hostLanguage;
209     }
210
211     /**
212      * Set the host language used in this configuration. The possible values
213      * are XSLT and XQUERY.
214      * @param hostLanguage Configuration.XSLT or Configuration.XQUERY
215      */

216
217     public void setHostLanguage(int hostLanguage) {
218         this.hostLanguage = hostLanguage;
219     }
220
221     /**
222      * Get the URIResolver used in this configuration
223      * @return the URIResolver. If no URIResolver has been set explicitly, the
224      * default URIResolver is used.
225      * @since 8.4
226      */

227
228     public URIResolver getURIResolver() {
229         if (uriResolver==null) {
230             return systemURIResolver;
231         }
232         return uriResolver;
233     }
234
235     /**
236      * Set the URIResolver to be used in this configuration. This will be used to
237      * resolve the URIs used statically (e.g. by xsl:include) and also the URIs used
238      * dynamically by functions such as document() and doc(). Note that the URIResolver
239      * does not resolve the URI in the sense of RFC 2396 (which is also the sense in which
240      * the resolve-uri() function uses the term): rather it dereferences an absolute URI
241      * to obtain an actual resource, which is returned as a Source object.
242      * @param resolver The URIResolver to be used.
243      * @since 8.4
244      */

245
246     public void setURIResolver(URIResolver resolver) {
247         this.uriResolver = resolver;
248     }
249
250     /**
251      * Get the system-defined URI Resolver. This is used when the user-defined URI resolver
252      * returns null as the result of the resolve() method
253      */

254
255     public StandardURIResolver getSystemURIResolver() {
256         return systemURIResolver;
257     }
258
259     /**
260      * Create an instance of a URIResolver with a specified class name
261      *
262      * @exception TransformerException if the requested class does not
263      * implement the javax.xml.transform.URIResolver interface
264      * @param className The fully-qualified name of the URIResolver class
265      * @return The newly created URIResolver
266      */

267     public URIResolver makeURIResolver(String JavaDoc className) throws TransformerException {
268         Object JavaDoc obj = getInstance(className, null);
269         if (obj instanceof URIResolver) {
270             return (URIResolver)obj;
271         }
272         throw new DynamicError("Class " + className + " is not a URIResolver");
273     }
274
275     /**
276      * Get the ErrorListener used in this configuration. If no ErrorListener
277      * has been supplied explicitly, the default ErrorListener is used.
278      * @return the ErrorListener.
279      * @since 8.4
280      */

281
282     public ErrorListener getErrorListener() {
283         if (listener == null) {
284             listener = new StandardErrorListener();
285             ((StandardErrorListener)listener).setRecoveryPolicy(recoveryPolicy);
286         }
287         return listener;
288     }
289
290     /**
291      * Set the ErrorListener to be used in this configuration. The ErrorListener
292      * is informed of all static and dynamic errors detected, and can decide whether
293      * run-time warnings are to be treated as fatal.
294      * @param listener the ErrorListener to be used
295      * @since 8.4
296      */

297
298     public void setErrorListener(ErrorListener listener) {
299         this.listener = listener;
300     }
301
302     /**
303      * Set whether multithreading optimizations are allowed
304      */

305
306     public void setMultiThreading(boolean multithreading) {
307         allowMultiThreading = multithreading;
308     }
309
310     /**
311      * Determine whether multithreading optimizations are allowed
312      */

313
314     public boolean isMultiThreading() {
315         return allowMultiThreading;
316     }
317
318     /**
319      * Get the Tree Model used by this Configuration. This is either
320      * Builder.STANDARD_TREE or Builder.TINY_TREE. The default (confusingly)
321      * is Builder.TINY_TREE.
322      * @return the selected Tree Model
323      * @since 8.4
324      */

325
326     public int getTreeModel() {
327         return treeModel;
328     }
329
330     /**
331      * Set the Tree Model used by this Configuration. This is either
332      * Builder.STANDARD_TREE or Builder.TINY_TREE. The default (confusingly)
333      * is Builder.TINY_TREE.
334      * @param treeModel the selected Tree Model
335      * @since 8.4
336      */

337
338     public void setTreeModel(int treeModel) {
339         this.treeModel = treeModel;
340     }
341
342     /**
343      * Determine whether source documents will maintain line numbers, for the
344      * benefit of the saxon:line-number() extension function as well as run-time
345      * tracing.
346      * @return true if line numbers are maintained in source documents
347      * @since 8.4
348      */

349
350     public boolean isLineNumbering() {
351         return lineNumbering;
352     }
353
354     /**
355      * Determine whether source documents will maintain line numbers, for the
356      * benefit of the saxon:line-number() extension function as well as run-time
357      * tracing.
358      * @param lineNumbering true if line numbers are maintained in source documents
359      * @since 8.4
360      */

361
362     public void setLineNumbering(boolean lineNumbering) {
363         this.lineNumbering = lineNumbering;
364     }
365
366     /**
367      * Get the TraceListener used for run-time tracing of instruction execution.
368      * @return the TraceListener, or null if none is in use.
369      * @since 8.4
370      */

371
372     public TraceListener getTraceListener() {
373         return traceListener;
374     }
375
376     /**
377      * Set the TraceListener to be used for run-time tracing of instruction execution.
378      * @param traceListener The TraceListener to be used.
379      * @since 8.4
380      */

381
382     public void setTraceListener(TraceListener traceListener) {
383         this.traceListener = traceListener;
384         setMultiThreading(false);
385     }
386
387     /** Create an instance of a TraceListener with a specified class name
388      *
389      * @exception net.sf.saxon.trans.XPathException if the requested class does not
390      * implement the net.sf.saxon.trace.TraceListener interface
391      * @param className The fully qualified class name of the TraceListener to
392      * be constructed
393      * @return the newly constructed TraceListener
394      */

395
396     public TraceListener makeTraceListener (String JavaDoc className)
397     throws XPathException
398     {
399         Object JavaDoc obj = getInstance(className, null);
400         if (obj instanceof TraceListener) {
401             return (TraceListener)obj;
402         }
403         throw new DynamicError("Class " + className + " is not a TraceListener");
404     }
405
406     /**
407      * Set the FunctionLibrary used to bind calls on extension functions. This allows the
408      * rules for identifying extension functions to be customized (in principle, it would
409      * allow support for extension functions in other languages to be provided).
410      * <p>
411      * When an application supplies its own FunctionLibrary for binding extension functions,
412      * this replaces the default binding mechanism for Java extension functions, namely
413      * {@link JavaExtensionLibrary}. It thus disables the function libraries
414      * for built-in Saxon extensions and for EXSLT extensions. It is possible to create a
415      * function library that adds to the existing mechanisms, rather than replacing them,
416      * by supplying as the FunctionLibrary a {@link net.sf.saxon.functions.FunctionLibraryList}
417      * that itself contains two FunctionLibrary objects: a JavaExtensionLibrary, and a user-written
418      * FunctionLibrary.
419      * @param binder The FunctionLibrary object used to locate implementations of extension
420      * functions, based on their name and arity
421      * @see #setExtensionFunctionFactory
422      */

423
424     public void setExtensionBinder(FunctionLibrary binder) {
425         extensionBinder = binder;
426     }
427
428     /**
429      * Get the FunctionLibrary used to bind calls on extension functions.
430      * <p>
431      * This mechanism is for advanced users only, and the details are subject to change.
432      * @return the registered FunctionLibrary for extension functions if one has been
433      * registered; or the default FunctionLibrary for extension functions otherwise
434      */

435
436     public FunctionLibrary getExtensionBinder() {
437         return extensionBinder;
438     }
439
440     /**
441      * Get the FunctionLibrary used to bind calls on Saxon-defined extension functions.
442      * <p>
443      * This method is intended for internal use only.
444      */

445
446     public VendorFunctionLibrary getVendorFunctionLibrary() {
447         if (vendorFunctionLibrary == null) {
448             vendorFunctionLibrary = new VendorFunctionLibrary();
449         }
450         return vendorFunctionLibrary;
451     }
452
453     /**
454      * Set a CollationURIResolver to be used to resolve collation URIs (that is,
455      * to take a URI identifying a collation, and return the corresponding collation).
456      * Note that Saxon attempts first to resolve a collation URI using the resolver
457      * registered with the Controller; if that returns null, it tries again using the
458      * resolver registered with the Configuration.
459      * <p>
460      * Note that it is undefined whether collation URIs are resolved at compile time
461      * or at run-time. It is therefore inadvisable to change the CollationURIResolver after
462      * compiling a query or stylesheet and before running it.
463      * @param resolver the collation URI resolver to be used. This replaces any collation
464      * URI resolver previously registered.
465      * @since 8.5
466      */

467
468     public void setCollationURIResolver(CollationURIResolver resolver) {
469         collationResolver = resolver;
470     }
471
472     /**
473      * Get the collation URI resolver associated with this configuration. This will
474      * return the CollationURIResolver previously set using the {@link #setCollationURIResolver}
475      * method; if this has not been called, it returns the system-defined collation URI resolver
476      * @return the registered CollationURIResolver
477      * @since 8.5
478      */

479
480     public CollationURIResolver getCollationURIResolver() {
481         return collationResolver;
482     }
483
484     /**
485      * Set a CollectionURIResolver to be used to resolve collection URIs (that is,
486      * the URI supplied in a call to the collection() function).
487      * <p>
488      * Collection URIs are always resolved at run-time, using the CollectionURIResolver
489      * in force at the time the collection() function is called.
490      * @param resolver the collection URI resolver to be used. This replaces any collection
491      * URI resolver previously registered.
492      * @since 8.5
493      */

494
495     public void setCollectionURIResolver(CollectionURIResolver resolver) {
496         collectionResolver = resolver;
497     }
498
499     /**
500      * Get the collection URI resolver associated with this configuration. This will
501      * return the CollectionURIResolver previously set using the {@link #setCollectionURIResolver}
502      * method; if this has not been called, it returns the system-defined collection URI resolver
503      * @return the registered CollationURIResolver
504      * @since 8.5
505      */

506
507     public CollectionURIResolver getCollectionURIResolver() {
508         return collectionResolver;
509     }
510
511     /**
512      * Set a user-defined ModuleURIResolver for resolving URIs used in "import module"
513      * declarations in the XQuery prolog
514      */

515
516     public void setModuleURIResolver(ModuleURIResolver resolver) {
517         moduleURIResolver = resolver;
518     }
519
520     /**
521      * Create and register an instance of a ModuleURIResolver with a specified class name
522      *
523      * @exception TransformerException if the requested class does not
524      * implement the net.sf.saxon.query.ModuleURIResolver interface
525      * @param className The fully-qualified name of the ModuleURIResolver class
526      */

527     public void setModuleURIResolver(String JavaDoc className) throws TransformerException {
528         Object JavaDoc obj = getInstance(className, null);
529         if (obj instanceof ModuleURIResolver) {
530             setModuleURIResolver((ModuleURIResolver)obj);
531         }
532         throw new DynamicError("Class " + className + " is not a ModuleURIResolver");
533     }
534
535     /**
536      * Get the user-defined ModuleURIResolver for resolving URIs used in "import module"
537      * declarations in the XQuery prolog; returns null if none has been explicitly set.
538      */

539
540     public ModuleURIResolver getModuleURIResolver() {
541         return moduleURIResolver;
542     }
543
544     /**
545      * Get the standard system-defined ModuleURIResolver for resolving URIs used in "import module"
546      * declarations in the XQuery prolog.
547      */

548
549     public ModuleURIResolver getStandardModuleURIResolver() {
550         return standardModuleURIResolver;
551     }
552
553     /**
554      * Determine how recoverable run-time errors are to be handled. This applies
555      * only if the standard ErrorListener is used.
556      * @return the current recovery policy. The options are {@link #RECOVER_SILENTLY},
557      * {@link #RECOVER_WITH_WARNINGS}, or {@link #DO_NOT_RECOVER}.
558      * @since 8.4
559      */

560
561     public int getRecoveryPolicy() {
562         return recoveryPolicy;
563     }
564
565     /**
566      * Determine how recoverable run-time errors are to be handled. This applies
567      * only if the standard ErrorListener is used. The recovery policy applies to
568      * errors classified in the XSLT 2.0 specification as recoverable dynamic errors,
569      * but only in those cases where Saxon provides a choice over how the error is handled:
570      * in some cases, Saxon makes the decision itself.
571      * @param recoveryPolicy the recovery policy to be used. The options are {@link #RECOVER_SILENTLY},
572      * {@link #RECOVER_WITH_WARNINGS}, or {@link #DO_NOT_RECOVER}.
573      * @since 8.4
574      */

575
576     public void setRecoveryPolicy(int recoveryPolicy) {
577         this.recoveryPolicy = recoveryPolicy;
578     }
579
580     /**
581      * Get the name of the class that will be instantiated to create a MessageEmitter,
582      * to process the output of xsl:message instructions in XSLT.
583      * @return the full class name of the message emitter class.
584      * @since 8.4
585      */

586
587     public String JavaDoc getMessageEmitterClass() {
588         return messageEmitterClass;
589     }
590
591     /**
592      * Set the name of the class that will be instantiated to create a MessageEmitter,
593      * to process the output of xsl:message instructions in XSLT.
594      * @param messageEmitterClass the full class name of the message emitter class. This
595      * must implement net.sf.saxon.event.Emitter.
596      * @since 8.4
597      */

598
599     public void setMessageEmitterClass(String JavaDoc messageEmitterClass) {
600         this.messageEmitterClass = messageEmitterClass;
601     }
602
603     /**
604      * Get the name of the class that will be instantiated to create an XML parser
605      * for parsing source documents (for example, documents loaded using the document()
606      * or doc() functions).
607      * <p>
608      * This method is retained in Saxon for backwards compatibility, but the preferred way
609      * of choosing an XML parser is to use JAXP interfaces, for example by supplying a
610      * JAXP Source object initialized with an appropriate implementation of org.xml.sax.XMLReader.
611      * @return the fully qualified name of the XML parser class
612      */

613
614     public String JavaDoc getSourceParserClass() {
615         return sourceParserClass;
616     }
617
618     /**
619      * Set the name of the class that will be instantiated to create an XML parser
620      * for parsing source documents (for example, documents loaded using the document()
621      * or doc() functions).
622      * <p>
623      * This method is retained in Saxon for backwards compatibility, but the preferred way
624      * of choosing an XML parser is to use JAXP interfaces, for example by supplying a
625      * JAXP Source object initialized with an appropriate implementation of org.xml.sax.XMLReader.
626      *
627      * @param sourceParserClass the fully qualified name of the XML parser class. This must implement
628      * the SAX2 XMLReader interface.
629      */

630
631     public void setSourceParserClass(String JavaDoc sourceParserClass) {
632         this.sourceParserClass = sourceParserClass;
633     }
634
635     /**
636      * Get the name of the class that will be instantiated to create an XML parser
637      * for parsing stylesheet modules.
638      * <p>
639      * This method is retained in Saxon for backwards compatibility, but the preferred way
640      * of choosing an XML parser is to use JAXP interfaces, for example by supplying a
641      * JAXP Source object initialized with an appropriate implementation of org.xml.sax.XMLReader.
642      *
643      * @return the fully qualified name of the XML parser class
644      */

645
646     public String JavaDoc getStyleParserClass() {
647         return styleParserClass;
648     }
649
650    /**
651     * Set the name of the class that will be instantiated to create an XML parser
652     * for parsing stylesheet modules.
653     * <p>
654     * This method is retained in Saxon for backwards compatibility, but the preferred way
655     * of choosing an XML parser is to use JAXP interfaces, for example by supplying a
656     * JAXP Source object initialized with an appropriate implementation of org.xml.sax.XMLReader.
657     *
658     * @param styleParserClass the fully qualified name of the XML parser class
659     */

660
661     public void setStyleParserClass(String JavaDoc styleParserClass) {
662         this.styleParserClass = styleParserClass;
663     }
664
665     /**
666      * Get the OutputURIResolver that will be used to resolve URIs used in the
667      * href attribute of the xsl:result-document instruction.
668      * @return the OutputURIResolver. If none has been supplied explicitly, the
669      * default OutputURIResolver is returned.
670      * @since 8.4
671      */

672
673     public OutputURIResolver getOutputURIResolver() {
674         if (outputURIResolver==null) {
675             outputURIResolver = StandardOutputResolver.getInstance();
676         }
677         return outputURIResolver;
678     }
679
680     /**
681      * Set the OutputURIResolver that will be used to resolve URIs used in the
682      * href attribute of the xsl:result-document instruction.
683      * @param outputURIResolver the OutputURIResolver to be used.
684      * @since 8.4
685      */

686
687     public void setOutputURIResolver(OutputURIResolver outputURIResolver) {
688         this.outputURIResolver = outputURIResolver;
689     }
690
691     /**
692      * Determine whether brief progress messages and timing information will be output
693      * to System.err.
694      * <p>
695      * This method is provided largely for internal use. Progress messages are normally
696      * controlled directly from the command line interfaces, and are not normally used when
697      * driving Saxon from the Java API.
698      *
699      * @return true if these messages are to be output.
700      */

701
702     public boolean isTiming() {
703         return timing;
704     }
705
706     /**
707      * Determine whether brief progress messages and timing information will be output
708      * to System.err.
709      * <p>
710      * This method is provided largely for internal use. Progress messages are normally
711      * controlled directly from the command line interfaces, and are not normally used when
712      *
713      * @param timing true if these messages are to be output.
714      */

715
716     public void setTiming(boolean timing) {
717         this.timing = timing;
718     }
719
720     /**
721      * Determine whether a warning is to be output when running against a stylesheet labelled
722      * as version="1.0". The XSLT specification requires such a warning unless the user disables it.
723      * @return true if these messages are to be output.
724      * @since 8.4
725      */

726
727     public boolean isVersionWarning() {
728         return versionWarning;
729     }
730
731     /**
732      * Determine whether a warning is to be output when running against a stylesheet labelled
733      * as version="1.0". The XSLT specification requires such a warning unless the user disables it.
734      * @param warn true if these messages are to be output.
735      * @since 8.4
736      */

737
738     public void setVersionWarning(boolean warn) {
739         this.versionWarning = warn;
740     }
741
742     /**
743      * Determine whether calls to external Java functions are permitted.
744      * @return true if such calls are permitted.
745      * @since 8.4
746      */

747
748     public boolean isAllowExternalFunctions() {
749         return allowExternalFunctions;
750     }
751
752     /**
753      * Determine whether calls to external Java functions are permitted. Allowing
754      * external function calls is potentially a security risk if the stylesheet or
755      * Query is untrusted, as it allows arbitrary Java methods to be invoked, which can
756      * examine or modify the contents of filestore and other resources on the machine
757      * where the query/stylesheet is executed
758      *
759      * @param allowExternalFunctions true if external function calls are to be
760      * permitted.
761      * @since 8.4
762      */

763
764     public void setAllowExternalFunctions(boolean allowExternalFunctions) {
765         this.allowExternalFunctions = allowExternalFunctions;
766     }
767
768     /**
769      * Determine whether calls on external functions are to be traced for diagnostic
770      * purposes.
771      * @return true if tracing is enabled for calls to external Java functions
772      */

773
774     public boolean isTraceExternalFunctions() {
775         return traceExternalFunctions;
776     }
777
778     /**
779      * Determine whether attribute types obtained from a DTD are to be used to set type annotations
780      * on the resulting nodes.
781      *
782      * @param useTypes set to true if DTD types are to be taken into account
783      * @since 8.4
784      */

785
786     public void setRetainDTDAttributeTypes(boolean useTypes) throws TransformerFactoryConfigurationError {
787         if (useTypes && !isSchemaAware(Configuration.XML_SCHEMA)) {
788             throw new TransformerFactoryConfigurationError(
789                     "Retaining DTD attribute types requires the schema-aware product");
790         }
791         retainDTDattributeTypes = useTypes;
792     }
793
794     /**
795      * Determine whether attribute types obtained from a DTD are to be used to set type annotations
796      * on the resulting nodes
797      *
798      * @return true if DTD types are to be taken into account
799      * @since 8.4
800      */

801
802     public boolean isRetainDTDAttributeTypes() {
803         return retainDTDattributeTypes;
804     }
805     /**
806      * Determine whether calls on external functions are to be traced for diagnostic
807      * purposes.
808      * @param traceExternalFunctions true if tracing is to be enabled
809      * for calls to external Java functions
810      */

811
812     public void setTraceExternalFunctions(boolean traceExternalFunctions) {
813         this.traceExternalFunctions = traceExternalFunctions;
814     }
815
816     /**
817      * Get an ExtensionFunctionFactory. This is used at compile time for generating
818      * the code that calls Java extension functions. It is possible to supply a user-defined
819      * ExtensionFunctionFactory to customize the way extension functions are bound.
820      * <p>
821      * This mechanism is intended for advanced use only, and is subject to change.
822      *
823      * @return the factory object registered to generate calls on extension functions,
824      * if one has been registered; if not, the default factory used by Saxon.
825      */

826
827     public ExtensionFunctionFactory getExtensionFunctionFactory() {
828         return extensionFunctionFactory;
829     }
830
831     /**
832      * Set an ExtensionFunctionFactory. This is used at compile time for generating
833      * the code that calls Java extension functions. It is possible to supply a user-defined
834      * ExtensionFunctionFactory to customize the way extension functions are called. The
835      * ExtensionFunctionFactory determines how external methods are called, but is not
836      * involved in binding the external method corresponding to a given function name or URI.
837      * <p>
838      * This mechanism is intended for advanced use only, and is subject to change.
839      * @see #setExtensionBinder
840      */

841
842     public void setExtensionFunctionFactory(ExtensionFunctionFactory factory) {
843         extensionFunctionFactory = factory;
844     }
845     /**
846      * Determine whether the XML parser for source documents will be asked to perform
847      * DTD validation of source documents
848      * @return true if DTD validation is requested.
849      * @since 8.4
850      */

851
852     public boolean isValidation() {
853         return validation;
854     }
855
856     /**
857      * Determine whether the XML parser for source documents will be asked to perform
858      * DTD validation of source documents
859      * @param validation true if DTD validation is to be requested.
860      * @since 8.4
861      */

862
863     public void setValidation(boolean validation) {
864         this.validation = validation;
865     }
866
867     /**
868      * Specify that all nodes encountered within this query or transformation will be untyped
869      */

870
871     public void setAllNodesUntyped(boolean allUntyped) {
872         allNodesUntyped = allUntyped;
873     }
874
875     /**
876      * Determine whether all nodes encountered within this query or transformation are guaranteed to be
877      * untyped
878      */

879
880     public boolean areAllNodesUntyped() {
881         return allNodesUntyped;
882     }
883
884     /**
885      * Determine whether source documents (supplied as a StreamSource or SAXSource)
886      * should be subjected to schema validation
887      * @return the schema validation mode previously set using setSchemaValidationMode(),
888      * or the default mode {@link Validation#STRIP} otherwise.
889      */

890
891     public int getSchemaValidationMode() {
892         return schemaValidationMode;
893     }
894
895     /**
896      * Indicate whether source documents (supplied as a StreamSource or SAXSource)
897      * should be subjected to schema validation
898      * @param validationMode the validation (or construction) mode to be used for source documents.
899      * One of {@link Validation#STRIP}, {@link Validation#PRESERVE}, {@link Validation#STRICT},
900      * {@link Validation#LAX}
901      * @since 8.4
902      */

903
904     public void setSchemaValidationMode(int validationMode) {
905         switch (validationMode) {
906             case Validation.STRIP:
907             case Validation.PRESERVE:
908                 break;
909             case Validation.LAX:
910             case Validation.STRICT:
911                 if (!isSchemaAware(XML_SCHEMA)) {
912                     needSchemaAwareVersion();
913                 }
914                 break;
915             default:
916                 throw new IllegalArgumentException JavaDoc("Unsupported validation mode " + validationMode);
917         }
918         schemaValidationMode = validationMode;
919     }
920
921     /**
922      * Indicate whether schema validation failures on result documents are to be treated
923      * as fatal errors or as warnings.
924      *
925      * @param warn true if schema validation failures are to be treated as warnings; false if they
926      * are to be treated as fatal errors.
927      * @since 8.4
928      */

929
930     public void setValidationWarnings(boolean warn) {
931         validationWarnings = warn;
932     }
933
934     /**
935      * Determine whether schema validation failures on result documents are to be treated
936      * as fatal errors or as warnings.
937      * @return true if validation errors are to be treated as warnings (that is, the
938      * validation failure is reported but processing continues as normal); false
939      * if validation errors are fatal.
940      * @since 8.4
941      */

942
943     public boolean isValidationWarnings() {
944         return validationWarnings;
945     }
946
947     /**
948      * Get the target namepool to be used for stylesheets/queries and for source documents.
949      * @return the target name pool. If no NamePool has been specified explicitly, the
950      * default NamePool is returned.
951      * @since 8.4
952      */

953
954     public NamePool getNamePool() {
955         return targetNamePool;
956     }
957
958     /**
959      * Set the NamePool to be used for stylesheets/queries and for source documents.
960      * <p>
961      * Normally all transformations and queries run under a single Java VM share the same
962      * NamePool. This creates a potential bottleneck, since changes to the namepool are
963      * synchronized. It is possible therefore to allocate a distinct NamePool to each
964      * Configuration. This requires considerable care and should only be done when the
965      * default arrangement is found to cause problems. There is a basic rule to follow:
966      * any compiled stylesheet or query must use the same NamePool as its source and
967      * result documents.
968      *
969      * @param targetNamePool The NamePool to be used.
970      * @since 8.4
971      */

972
973     public void setNamePool(NamePool targetNamePool) {
974         this.targetNamePool = targetNamePool;
975     }
976
977     /**
978      * Get the document number allocator.
979      * <p>
980      * This is intended primarily for internal use
981      */

982
983     public DocumentNumberAllocator getDocumentNumberAllocator() {
984         return documentNumberAllocator;
985     }
986
987     /**
988      * Determine whether whitespace-only text nodes are to be stripped unconditionally
989      * from source documents.
990      * @return true if all whitespace-only text nodes are stripped.
991      * @since 8.4
992      */

993
994     public boolean isStripsAllWhiteSpace() {
995         return stripsAllWhiteSpace;
996     }
997
998     /**
999      * Determine whether whitespace-only text nodes are to be stripped unconditionally
1000     * from source documents.
1001     * @param stripsAllWhiteSpace if all whitespace-only text nodes are to be stripped.
1002     * @since 8.4
1003     */

1004
1005    public void setStripsAllWhiteSpace(boolean stripsAllWhiteSpace) {
1006        this.stripsAllWhiteSpace = stripsAllWhiteSpace;
1007    }
1008
1009    /**
1010    * Get a parser for source documents. The parser is allocated from a pool if any are available
1011     * from the pool: the client should ideally return the parser to the pool after use, so that it
1012     * can be reused.
1013     * <p>
1014     * This method is intended primarily for internal use.
1015    */

1016
1017    public synchronized XMLReader JavaDoc getSourceParser() throws TransformerFactoryConfigurationError {
1018        if (sourceParserPool == null) {
1019            sourceParserPool = new ArrayList(10);
1020        }
1021        if (sourceParserPool.size() > 0) {
1022            int n = sourceParserPool.size()-1;
1023            XMLReader JavaDoc parser = (XMLReader JavaDoc)sourceParserPool.get(n);
1024            sourceParserPool.remove(n);
1025            return parser;
1026        }
1027        XMLReader JavaDoc parser;
1028        if (getSourceParserClass()!=null) {
1029            parser = makeParser(getSourceParserClass());
1030        } else {
1031            parser = loadParser();
1032        }
1033        if (isValidation()) {
1034            try {
1035                parser.setFeature("http://xml.org/sax/features/validation", true);
1036            } catch (SAXException JavaDoc err) {
1037                throw new TransformerFactoryConfigurationError("The XML parser does not support validation");
1038            }
1039        }
1040
1041        return parser;
1042    }
1043
1044    /**
1045     * Return a source parser to the pool, for reuse
1046     * @param parser The parser: the caller must not supply a parser that was obtained by any
1047     * mechanism other than calling the getSourceParser() method.
1048     */

1049
1050    public synchronized void reuseSourceParser(XMLReader JavaDoc parser) {
1051        if (sourceParserPool == null) {
1052            sourceParserPool = new ArrayList(10);
1053        }
1054        sourceParserPool.add(parser);
1055    }
1056
1057    /**
1058     * Get a parser by instantiating the SAXParserFactory
1059     * @return the parser (XMLReader)
1060     */

1061
1062    private XMLReader JavaDoc loadParser() {
1063        XMLReader JavaDoc parser;
1064        try {
1065            parser = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
1066        } catch (ParserConfigurationException JavaDoc err) {
1067            throw new TransformerFactoryConfigurationError(err);
1068        } catch (SAXException JavaDoc err) {
1069            throw new TransformerFactoryConfigurationError(err);
1070        }
1071        return parser;
1072    }
1073
1074    /**
1075    * Get the parser for stylesheet documents. This parser is also used for schema documents.
1076     * <p>
1077     * This method is intended for internal use only.
1078     *
1079    */

1080
1081    public synchronized XMLReader JavaDoc getStyleParser() throws TransformerFactoryConfigurationError {
1082        if (styleParserPool == null) {
1083            styleParserPool = new ArrayList(10);
1084        }
1085        if (styleParserPool.size() > 0) {
1086            int n = styleParserPool.size()-1;
1087            XMLReader JavaDoc parser = (XMLReader JavaDoc)styleParserPool.get(n);
1088            styleParserPool.remove(n);
1089            return parser;
1090        }
1091        XMLReader JavaDoc parser;
1092        if (getStyleParserClass()!=null) {
1093            parser = makeParser(getStyleParserClass());
1094        } else {
1095            parser = loadParser();
1096        }
1097        try {
1098            parser.setFeature("http://xml.org/sax/features/namespaces", true);
1099            parser.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
1100        } catch (SAXNotRecognizedException JavaDoc e) {
1101            throw new TransformerFactoryConfigurationError(e);
1102        } catch (SAXNotSupportedException JavaDoc e) {
1103            throw new TransformerFactoryConfigurationError(e);
1104        }
1105        return parser;
1106    }
1107
1108    /**
1109     * Return a stylesheet (or schema) parser to the pool, for reuse
1110     * @param parser The parser: the caller must not supply a parser that was obtained by any
1111     * mechanism other than calling the getStyleParser() method.
1112     */

1113
1114    public synchronized void reuseStyleParser(XMLReader JavaDoc parser) {
1115        if (styleParserPool == null) {
1116            styleParserPool = new ArrayList(10);
1117        }
1118        styleParserPool.add(parser);
1119    }
1120
1121    /**
1122     * Read a schema from a given schema location
1123     * @return the target namespace of the schema
1124     * <p>
1125     * This method is intended for internal use.
1126     */

1127
1128    public String JavaDoc readSchema(PipelineConfiguration pipe, String JavaDoc baseURI, String JavaDoc schemaLocation, String JavaDoc expected)
1129    throws TransformerConfigurationException {
1130        needSchemaAwareVersion();
1131        return null;
1132    }
1133
1134    /**
1135     * Read schemas from a list of schema locations.
1136     * <p>
1137     * This method is intended for internal use.
1138     */

1139
1140    public void readMultipleSchemas(PipelineConfiguration pipe, String JavaDoc baseURI, List schemaLocations, String JavaDoc expected)
1141            throws SchemaException {
1142        needSchemaAwareVersion();
1143    }
1144
1145
1146    /**
1147     * Read an inline schema from a stylesheet.
1148     * <p>
1149     * This method is intended for internal use.
1150     * @param pipe
1151     * @param root the xs:schema element in the stylesheet
1152     * @param expected the target namespace expected; null if there is no
1153     * expectation.
1154     * @return the actual target namespace of the schema
1155     *
1156     */

1157
1158    public String JavaDoc readInlineSchema(PipelineConfiguration pipe, NodeInfo root, String JavaDoc expected)
1159            throws SchemaException {
1160        needSchemaAwareVersion();
1161        return null;
1162    }
1163
1164    private void needSchemaAwareVersion() {
1165        throw new UnsupportedOperationException JavaDoc(
1166                "You need the schema-aware version of Saxon for this operation");
1167    }
1168
1169    /**
1170     * Load a schema, which will be available for use by all subsequent operations using
1171     * this Configuration.
1172     * @param schemaSource the JAXP Source object identifying the schema document to be loaded
1173     * @throws SchemaException if the schema cannot be read or parsed or if it is invalid
1174     * @since 8.4
1175     */

1176
1177    public void addSchemaSource(Source JavaDoc schemaSource) throws SchemaException {
1178        needSchemaAwareVersion();
1179    }
1180
1181    /**
1182     * Add a schema to the cache.
1183     * <p>
1184     * This method is intended for internal use
1185     * @param schema an object of class javax.xml.validation.schema, which is not declared as such
1186     * to avoid creating a dependency on this JDK 1.5 class
1187     */

1188
1189    public void addSchema(Object JavaDoc schema)
1190    throws TransformerConfigurationException {
1191        needSchemaAwareVersion();
1192    }
1193
1194    /**
1195     * Get a schema from the cache. Return null if not found.
1196     * <p>
1197     * This method is intended for internal use.
1198     * @return an object of class javax.xml.validation.schema, which is not declared as such
1199     * to avoid creating a dependency on this JDK 1.5 class
1200     */

1201
1202    public Object JavaDoc getSchema(String JavaDoc namespace) {
1203        return null;
1204    }
1205
1206    /**
1207     * Get a global element declaration.
1208     * <p>
1209     * This method is intended for internal use.
1210     * @return the element declaration whose name matches the given
1211     * fingerprint, or null if no element declaration with this name has
1212     * been registered.
1213     */

1214
1215    public SchemaDeclaration getElementDeclaration(int fingerprint) {
1216        return null;
1217    }
1218
1219    /**
1220     * Get a global attribute declaration.
1221     * <p>
1222     * This method is intended for internal use
1223     * @return the attribute declaration whose name matches the given
1224     * fingerprint, or null if no element declaration with this name has
1225     * been registered.
1226     */

1227
1228    public SchemaDeclaration getAttributeDeclaration(int fingerprint) {
1229        return null;
1230    }
1231
1232    /**
1233      * Get the top-level schema type definition with a given fingerprint.
1234     * <p>
1235     * This method is intended for internal use and for use by advanced
1236     * applications. (The SchemaType object returned cannot yet be considered
1237     * a stable API, and may be superseded when a JAXP API for schema information
1238     * is defined.)
1239      * @param fingerprint the fingerprint of the schema type
1240      * @return the schema type , or null if there is none
1241      * with this name.
1242      */

1243
1244     public SchemaType getSchemaType(int fingerprint) {
1245        if (fingerprint < 1023) {
1246            return BuiltInSchemaFactory.getSchemaType(fingerprint);
1247        }
1248        return null;
1249     }
1250
1251    /**
1252     * Get a document-level validator to add to a Receiver pipeline.
1253     * <p>
1254     * This method is intended for internal use.
1255     * @param receiver The receiver to which events should be sent after validation
1256     * @param systemId the base URI of the document being validated
1257     * @param namePool the namePool to be used by the validator
1258     * @param validationMode for example Validation.STRICT or Validation.STRIP. The integer may
1259     * also have the bit Validation.VALIDATE_OUTPUT set, indicating that the strean being validated
1260     * is to be treated as a final output stream (which means multiple errors can be reported)
1261     * @param schemaType The type against which the outermost element of the document must be validated
1262     * (null if there is no constraint)
1263     * @return A Receiver to which events can be sent for validation
1264     */

1265
1266    public Receiver getDocumentValidator(Receiver receiver,
1267                                         String JavaDoc systemId,
1268                                         NamePool namePool,
1269                                         int validationMode,
1270                                         SchemaType schemaType) {
1271        // non-schema-aware version
1272
return receiver;
1273    }
1274
1275    /**
1276     * Get a Receiver that can be used to validate an element, and that passes the validated
1277     * element on to a target receiver. If validation is not supported, the returned receiver
1278     * will be the target receiver.
1279     * <p>
1280     * This method is intended for internal use.
1281     * @param receiver the target receiver tp receive the validated element
1282     * @param nameCode the nameCode of the element to be validated. This must correspond to the
1283     * name of an element declaration in a loaded schema
1284     * @param schemaType the schema type (typically a complex type) against which the element is to
1285     * be validated
1286     * @param validation The validation mode, for example Validation.STRICT or Validation.LAX
1287     * @param pool The name pool
1288     * @return The target receiver, indicating that with this configuration, no validation
1289     * is performed.
1290     */

1291    public Receiver getElementValidator(Receiver receiver,
1292                                        int nameCode,
1293                                        int locationId,
1294                                        SchemaType schemaType,
1295                                        int validation,
1296                                        NamePool pool)
1297            throws XPathException {
1298        return receiver;
1299    }
1300
1301    /**
1302     * Validate an attribute value.
1303     * <p>
1304     * This method is intended for internal use.
1305     * @param nameCode the name of the attribute
1306     * @param value the value of the attribute as a string
1307     * @param validation STRICT or LAX
1308     * @return the type annotation to apply to the attribute node
1309     * @throws ValidationException if the value is invalid
1310     */

1311
1312    public int validateAttribute(int nameCode, CharSequence JavaDoc value, int validation)
1313    throws ValidationException {
1314        return -1;
1315    }
1316
1317    /**
1318     * Add to a pipeline a receiver that strips all type annotations. This
1319     * has a null implementation in the Saxon-B product, because type annotations
1320     * can never arise.
1321     * <p>
1322     * This method is intended for internal use.
1323     */

1324
1325    public Receiver getAnnotationStripper(Receiver destination) {
1326        return destination;
1327    }
1328
1329    /**
1330     * Make a test for elements corresponding to a give element declaration.
1331     * <p>
1332     * This method is intended for internal use.
1333     */

1334
1335    public NodeTest makeSubstitutionGroupTest(SchemaDeclaration elementDecl) {
1336        needSchemaAwareVersion();
1337        return null;
1338    }
1339
1340
1341    /**
1342    * Create a new SAX XMLReader object using the class name provided. <br>
1343    * <p>
1344    * The named class must exist and must implement the
1345    * org.xml.sax.XMLReader or Parser interface. <br>
1346    * <p>
1347    * This method returns an instance of the parser named.
1348     * <p>
1349     * This method is intended for internal use.
1350    *
1351    * @param className A string containing the name of the
1352    * SAX parser class, for example "com.microstar.sax.LarkDriver"
1353    * @return an instance of the Parser class named, or null if it is not
1354    * loadable or is not a Parser.
1355    *
1356    */

1357    public XMLReader JavaDoc makeParser (String JavaDoc className)
1358    throws TransformerFactoryConfigurationError
1359    {
1360        Object JavaDoc obj;
1361        try {
1362            obj = getInstance(className, null);
1363        } catch (XPathException err) {
1364            throw new TransformerFactoryConfigurationError(err);
1365        }
1366        if (obj instanceof XMLReader JavaDoc) {
1367            return (XMLReader JavaDoc)obj;
1368        }
1369        throw new TransformerFactoryConfigurationError("Class " + className +
1370                                 " is not a SAX2 XMLReader");
1371    }
1372
1373    /**
1374    * Get a locale given a language code in XML format.
1375     * <p>
1376     * This method is intended for internal use.
1377    */

1378
1379    public static Locale getLocale(String JavaDoc lang) {
1380        int hyphen = lang.indexOf("-");
1381        String JavaDoc language, country;
1382        if (hyphen < 1) {
1383            language = lang;
1384            country = "";
1385        } else {
1386            language = lang.substring(1, hyphen);
1387            country = lang.substring(hyphen+1);
1388        }
1389        return new Locale(language, country);
1390    }
1391
1392    /**
1393     * Set the debugger to be used.
1394     * <p>
1395     * This method is provided for advanced users only, and is subject to change.
1396     */

1397
1398    public void setDebugger(Debugger debugger) {
1399        this.debugger = debugger;
1400    }
1401
1402    /**
1403     * Get the debugger in use. This will be null if no debugger has been registered.
1404     * <p>
1405     * This method is provided for advanced users only, and is subject to change.
1406     */

1407
1408    public Debugger getDebugger() {
1409        return debugger;
1410    }
1411
1412    /**
1413     * Factory method to create a SlotManager.
1414     * <p>
1415     * This method is provided for advanced users only, and is subject to change.
1416     */

1417
1418    public SlotManager makeSlotManager() {
1419        if (debugger == null) {
1420            return new SlotManager();
1421        } else {
1422            return debugger.makeSlotManager();
1423        }
1424    }
1425
1426    /**
1427     * Factory method to get an Optimizer.
1428     * <p>
1429     * This method is intended for internal use only.
1430     */

1431
1432    public Optimizer getOptimizer() {
1433        if (optimizer == null) {
1434            optimizer = new Optimizer(this);
1435        }
1436        return optimizer;
1437    }
1438
1439    /**
1440     * Set a ClassLoader to be used when loading external classes. Examples of classes that are
1441     * loaded include SAX parsers, localization modules for formatting numbers and dates,
1442     * extension functions, external object models. In an environment such as Eclipse that uses
1443     * its own ClassLoader, this ClassLoader should be nominated to ensure that any class loaded
1444     * by Saxon is identical to a class of the same name loaded by the external environment.
1445     * <p>
1446     * This method is intended for external use by advanced users, but should be regarded as
1447     * experimental.
1448     */

1449
1450    public void setClassLoader(ClassLoader JavaDoc loader) {
1451        this.classLoader = loader;
1452    }
1453
1454    /**
1455     * Get the ClassLoader supplied using the method {@link #setClassLoader}.
1456     * If none has been supplied, return null.
1457     * <p>
1458     * This method is intended for external use by advanced users, but should be regarded as
1459     * experimental.
1460     */

1461
1462    public ClassLoader JavaDoc getClassLoader() {
1463        return classLoader;
1464    }
1465
1466    /**
1467    * Load a class using the class name provided.
1468    * Note that the method does not check that the object is of the right class.
1469     * <p>
1470     * This method is intended for internal use only.
1471     *
1472    * @param className A string containing the name of the
1473    * class, for example "com.microstar.sax.LarkDriver"
1474    * @param classLoader The ClassLoader to be used to load the class. If this is null, then
1475     * the classLoader used will be the first one available of: the classLoader registered
1476     * with the Configuration using {@link #setClassLoader}; the context class loader for
1477     * the current thread; or failing that, the class loader invoked implicitly by a call
1478     * of Class.forName() (which is the ClassLoader that was used to load the Configuration
1479     * object itself).
1480     * @return an instance of the class named, or null if it is not
1481    * loadable.
1482    * @throws XPathException if the class cannot be loaded.
1483    *
1484    */

1485
1486    public Class JavaDoc getClass(String JavaDoc className, boolean tracing, ClassLoader JavaDoc classLoader) throws XPathException {
1487        if (tracing) {
1488            System.err.println("Loading " + className);
1489        }
1490
1491        try {
1492            ClassLoader JavaDoc loader = classLoader;
1493            if (loader == null) {
1494                loader = this.classLoader;
1495            }
1496            if (loader == null) {
1497                loader = Thread.currentThread().getContextClassLoader();
1498            }
1499            if (loader != null) {
1500                try {
1501                    return loader.loadClass(className);
1502                } catch (Exception JavaDoc ex) {
1503                    return Class.forName(className);
1504                }
1505            } else {
1506                return Class.forName(className);
1507            }
1508        }
1509        catch (Exception JavaDoc e) {
1510            if (tracing) {
1511                // The exception is often masked, especially when calling extension
1512
// functions
1513
System.err.println("No Java class " + className + " could be loaded");
1514            }
1515            throw new DynamicError("Failed to load " + className, e );
1516        }
1517
1518    }
1519
1520  /**
1521    * Instantiate a class using the class name provided.
1522    * Note that the method does not check that the object is of the right class.
1523   * <p>
1524   * This method is intended for internal use only.
1525   *
1526    * @param className A string containing the name of the
1527    * class, for example "com.microstar.sax.LarkDriver"
1528    * @param classLoader The ClassLoader to be used to load the class. If this is null, then
1529     * the classLoader used will be the first one available of: the classLoader registered
1530     * with the Configuration using {@link #setClassLoader}; the context class loader for
1531     * the current thread; or failing that, the class loader invoked implicitly by a call
1532     * of Class.forName() (which is the ClassLoader that was used to load the Configuration
1533     * object itself).
1534    * @return an instance of the class named, or null if it is not
1535    * loadable.
1536    * @throws XPathException if the class cannot be loaded.
1537    *
1538    */

1539
1540    public Object JavaDoc getInstance(String JavaDoc className, ClassLoader JavaDoc classLoader) throws XPathException {
1541        Class JavaDoc theclass = getClass(className, false, classLoader);
1542        try {
1543            return theclass.newInstance();
1544        } catch (Exception JavaDoc err) {
1545            throw new DynamicError("Failed to instantiate class " + className, err);
1546        }
1547    }
1548
1549    /**
1550    * Load a named collator class and check it is OK.
1551     * <p>
1552     * This method is intended for internal use only.
1553    */

1554
1555    public Comparator makeCollator (String JavaDoc className) throws XPathException
1556    {
1557        Object JavaDoc handler = getInstance(className, null);
1558
1559        if (handler instanceof Comparator ) {
1560            return (Comparator )handler;
1561        } else {
1562            throw new DynamicError("Failed to load collation class " + className +
1563                        ": it is not an instance of java.util.Comparator");
1564        }
1565
1566    }
1567
1568    /**
1569     * Set lazy construction mode on or off. In lazy construction mode, element constructors
1570     * are not evaluated until the content of the tree is required. Lazy construction mode
1571     * is currently experimental and is therefore off by default.
1572     * @param lazy true to switch lazy construction mode on, false to switch it off.
1573     */

1574
1575    public void setLazyConstructionMode(boolean lazy) {
1576        lazyConstructionMode = lazy;
1577    }
1578
1579    /**
1580     * Determine whether lazy construction mode is on or off. In lazy construction mode, element constructors
1581     * are not evaluated until the content of the tree is required. Lazy construction mode
1582     * is currently experimental and is therefore off by default.
1583     * @return true if lazy construction mode is enabled
1584     */

1585
1586    public boolean isLazyConstructionMode() {
1587        return lazyConstructionMode;
1588    }
1589
1590
1591    /**
1592     * Register the standard Saxon-supplied object models.
1593     * <p>
1594     * This method is intended for internal use only.
1595     */

1596
1597    public void registerStandardObjectModels() {
1598        // Try to load the support classes for various object models, registering
1599
// them in the Configuration. We require both the Saxon object model definition
1600
// and an implementation of the object model itself to be loadable before
1601
// the object model is registered.
1602
String JavaDoc[] models = {"net.sf.saxon.dom.DOMEnvelope",
1603                           "net.sf.saxon.dom.DOMObjectModel",
1604                           "net.sf.saxon.jdom.JDOMObjectModel",
1605                           "net.sf.saxon.xom.XOMObjectModel"};
1606        String JavaDoc[] nodes = {"net.sf.saxon.dom.NodeOverNodeInfo",
1607                           "org.w3c.dom.Node",
1608                           "org.jdom.Element",
1609                           "nu.xom.Node"};
1610
1611        for (int i=0; i<models.length; i++) {
1612            try {
1613                getClass(nodes[i], false, null);
1614                ExternalObjectModel model = (ExternalObjectModel)getInstance(models[i], null);
1615                registerExternalObjectModel(model);
1616            } catch (XPathException err) {
1617                // ignore the failure. We can't report an exception here, and in any case a failure
1618
// is legitimate if the object model isn't on the class path. We'll fail later when
1619
// we try to process a node in the chosen object model: the node simply won't be
1620
// recognized as one that Saxon can handle
1621
} catch (ClassCastException JavaDoc err) {
1622                // we've loaded the class, but it isn't an ExternalObjectModel. This can apparently
1623
// happen if there's more than one ClassLoader involved. We'll output a simple warning,
1624
// and then continue as if the external object model wasn't on the class path
1625
System.err.println("Warning: external object model " + models[i] +
1626                        " has been loaded, but is not an instance of net.sf.saxon.om.ExternalObjectModel");
1627            }
1628        }
1629    }
1630
1631
1632    /**
1633     * Register an external object model.
1634     * <p>
1635     * This method is intended for advanced users only, and is subject to change.
1636     */

1637
1638    public void registerExternalObjectModel(ExternalObjectModel model) {
1639        externalObjectModels.add(model);
1640    }
1641
1642    /**
1643     * Find the external object model corresponding to a given node.
1644     * <p>
1645     * This method is intended for internal use only.
1646     *
1647     * @param node a Node as implemented in some external object model
1648     * @return the first registered external object model that recognizes
1649     * this node; or null if no-one will own up to it.
1650     */

1651
1652    public ExternalObjectModel findExternalObjectModel(Object JavaDoc node) {
1653        Iterator it = externalObjectModels.iterator();
1654        while (it.hasNext()) {
1655            final ExternalObjectModel model = (ExternalObjectModel)it.next();
1656            if (model.isRecognizedNode(node)) {
1657                return model;
1658            }
1659        }
1660        return null;
1661    }
1662
1663    /**
1664     * Get all the registered external object models.
1665     * <p>
1666     * This method is intended for internal use only.
1667     */

1668
1669    public List getExternalObjectModels() {
1670        return externalObjectModels;
1671    }
1672
1673    /**
1674     * Make a PipelineConfiguration from the properties of this Configuration
1675     * @since 8.4
1676     */

1677
1678    public PipelineConfiguration makePipelineConfiguration() {
1679        PipelineConfiguration pipe = new PipelineConfiguration();
1680        pipe.setConfiguration(this);
1681        pipe.setErrorListener(getErrorListener());
1682        pipe.setURIResolver(getURIResolver());
1683        return pipe;
1684    }
1685
1686    /**
1687     * Set the implicit timezone, as a positive or negative offset from UTC in minutes.
1688     * The range is -14hours to +14hours
1689     */

1690    public void setImplicitTimezone(int minutes) {
1691        if (minutes < -14*60 || minutes > +14*60) {
1692            throw new IllegalArgumentException JavaDoc("Implicit timezone is out of range: range is " + (-14*60)
1693                            + " to +" + (+14*60) + " minutes");
1694        }
1695        implicitTimezone = minutes;
1696    }
1697
1698    /**
1699     * Get the implicit timezone, as a positive or negative offset from UTC in minutes.
1700     * The range is -14hours to +14hours
1701     * @return the value set using {@link #setImplicitTimezone}, or failing that
1702     * the timezone from the system clock at the time the Configuration was created.
1703     */

1704    public int getImplicitTimezone() {
1705        return implicitTimezone;
1706    }
1707
1708    /**
1709     * Get the configuration, given the context. This is provided as a static method to make it accessible
1710     * as an extension function.
1711     */

1712
1713    public static Configuration getConfiguration(XPathContext context) {
1714        return context.getController().getConfiguration();
1715    }
1716
1717    /**
1718     * Supply a SourceResolver
1719     */

1720
1721    public void setSourceResolver(SourceResolver resolver) {
1722        sourceResolver = resolver;
1723    }
1724
1725    /**
1726     * Get the current SourceResolver. If none has been supplied, a system-defined SourceResolver
1727     * is returned.
1728     * @return the current SourceResolver
1729     */

1730
1731    public SourceResolver getSourceResolver() {
1732        return sourceResolver;
1733    }
1734
1735    /**
1736     * Implement the SourceResolver interface
1737     */

1738
1739    public Source JavaDoc resolveSource(Source JavaDoc source, Configuration config) throws XPathException {
1740        if (source instanceof AugmentedSource) return source;
1741        if (source instanceof StreamSource JavaDoc) return source;
1742        if (source instanceof SAXSource JavaDoc) return source;
1743        if (source instanceof DOMSource JavaDoc) return source;
1744        if (source instanceof NodeInfo) return source;
1745        if (source instanceof PullProvider) return source;
1746        return null;
1747    }
1748
1749    /**
1750     * Get a configuration-defined output method.
1751     * @return a Receiver that implements the method, or null if the method name is not recognized
1752     */

1753
1754    public Receiver getOutputMethod(String JavaDoc clarkName) {
1755        return null;
1756    }
1757}
1758
1759//
1760
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
1761
// you may not use this file except in compliance with the License. You may obtain a copy of the
1762
// License at http://www.mozilla.org/MPL/
1763
//
1764
// Software distributed under the License is distributed on an "AS IS" basis,
1765
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
1766
// See the License for the specific language governing rights and limitations under the License.
1767
//
1768
// The Original Code is: all this file.
1769
//
1770
// The Initial Developer of the Original Code is Michael H. Kay.
1771
//
1772
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
1773
//
1774
// Contributor(s): none.
1775
//
Popular Tags