0001: package net.sf.saxon;
0002:
0003: import net.sf.saxon.event.Builder;
0004: import net.sf.saxon.event.PipelineConfiguration;
0005: import net.sf.saxon.event.Receiver;
0006: import net.sf.saxon.event.StandardOutputResolver;
0007: import net.sf.saxon.expr.Optimizer;
0008: import net.sf.saxon.expr.XPathContext;
0009: import net.sf.saxon.functions.*;
0010: import net.sf.saxon.instruct.Debugger;
0011: import net.sf.saxon.instruct.SlotManager;
0012: import net.sf.saxon.om.*;
0013: import net.sf.saxon.pattern.NodeTest;
0014: import net.sf.saxon.pull.PullProvider;
0015: import net.sf.saxon.query.ModuleURIResolver;
0016: import net.sf.saxon.query.StandardModuleURIResolver;
0017: import net.sf.saxon.sort.CollationURIResolver;
0018: import net.sf.saxon.sort.StandardCollationURIResolver;
0019: import net.sf.saxon.trace.TraceListener;
0020: import net.sf.saxon.trans.DynamicError;
0021: import net.sf.saxon.trans.IndependentContext;
0022: import net.sf.saxon.trans.XPathException;
0023: import net.sf.saxon.type.*;
0024: import net.sf.saxon.value.Whitespace;
0025: import org.xml.sax.SAXException;
0026: import org.xml.sax.SAXNotRecognizedException;
0027: import org.xml.sax.SAXNotSupportedException;
0028: import org.xml.sax.XMLReader;
0029:
0030: import javax.xml.parsers.ParserConfigurationException;
0031: import javax.xml.parsers.SAXParserFactory;
0032: import javax.xml.transform.*;
0033: import javax.xml.transform.dom.DOMSource;
0034: import javax.xml.transform.sax.SAXSource;
0035: import javax.xml.transform.stream.StreamSource;
0036: import java.io.Serializable;
0037: import java.util.*;
0038:
0039: /**
0040: * This class holds details of user-selected configuration options for a transformation
0041: * or query. When running XSLT, the preferred way of setting configuration options is via
0042: * the JAXP TransformerFactory interface, but the Configuration object provides a finer
0043: * level of control. As yet there is no standard API for XQuery, so the only way of setting
0044: * Configuration information is to use the methods on this class directly.
0045: * <p>
0046: * Since Saxon 8.4, the JavaDoc documentation for Saxon attempts to identify interfaces
0047: * that are considered stable, and will only be changed in a backwards-incompatible way
0048: * if there is an overriding reason to do so. These interfaces and methods are labelled
0049: * with the JavaDoc "since" tag. The value 8.n indicates a method in this category that
0050: * was introduced in Saxon version 8.n: or in the case of 8.4, that was present in Saxon 8.4
0051: * and possibly in earlier releases. (In some cases, these methods have been unchanged for
0052: * a long time.) Methods without a "since" tag, although public, are provided for internal
0053: * use or for use by advanced users, and are subject to change from one release to the next.
0054: * The presence of a "since" tag on a class or interface indicates that there are one or more
0055: * methods in the class that are considered stable; it does not mean that all methods are
0056: * stable.
0057: *
0058: * @since 8.4
0059: */
0060:
0061: public class Configuration implements Serializable, SourceResolver {
0062:
0063: private transient URIResolver uriResolver;
0064: private StandardURIResolver systemURIResolver = new StandardURIResolver(
0065: this );
0066: protected transient ErrorListener listener;
0067: private int xmlVersion = XML10;
0068: private int treeModel = Builder.TINY_TREE;
0069: private boolean lineNumbering = false;
0070: private boolean checkForXml11Input = false;
0071: private TraceListener traceListener = null;
0072: private FunctionLibrary extensionBinder;
0073: private CollationURIResolver collationResolver = StandardCollationURIResolver
0074: .getInstance();
0075: private CollectionURIResolver collectionResolver = new StandardCollectionURIResolver();
0076: private ModuleURIResolver moduleURIResolver = null;
0077: private ModuleURIResolver standardModuleURIResolver = new StandardModuleURIResolver();
0078: private SourceResolver sourceResolver = this ;
0079: protected VendorFunctionLibrary vendorFunctionLibrary;
0080: protected int recoveryPolicy = RECOVER_WITH_WARNINGS;
0081: private String messageEmitterClass = "net.sf.saxon.event.MessageEmitter";
0082: private String sourceParserClass;
0083: private String styleParserClass;
0084: private transient OutputURIResolver outputURIResolver;
0085: private boolean timing = false;
0086: private boolean versionWarning = true;
0087: private boolean allowExternalFunctions = true;
0088: private boolean traceExternalFunctions = false;
0089: private boolean validation = false;
0090: private boolean allNodesUntyped = false;
0091: private boolean lazyConstructionMode = false;
0092: private boolean allowMultiThreading = false;
0093: private int stripsWhiteSpace = Whitespace.IGNORABLE;
0094: private NamePool targetNamePool = null;
0095: private DocumentNumberAllocator documentNumberAllocator = new DocumentNumberAllocator();
0096: private XPathContext conversionContext = null;
0097:
0098: private int hostLanguage = XSLT;
0099: private int schemaValidationMode = Validation.PRESERVE;
0100: private boolean validationWarnings = false;
0101: private boolean retainDTDattributeTypes = false;
0102: private Debugger debugger = null;
0103: protected Optimizer optimizer = null;
0104: private ExtensionFunctionFactory extensionFunctionFactory = new ExtensionFunctionFactory(
0105: this );
0106:
0107: private transient ClassLoader classLoader;
0108: private int implicitTimezone;
0109: private transient List sourceParserPool = new ArrayList(5);
0110: private transient List styleParserPool = new ArrayList(5);
0111:
0112: /**
0113: * The external object models are held in static so they are only loaded once in an application
0114: * that creates many Configurations repeatedly. This saves expensive searches of the classpath
0115: */
0116:
0117: private static List sharedExternalObjectModels = null;
0118: private List externalObjectModels = null;
0119:
0120: /**
0121: * Constant indicating that the processor should take the recovery action
0122: * when a recoverable error occurs, with no warning message.
0123: */
0124: public static final int RECOVER_SILENTLY = 0;
0125: /**
0126: * Constant indicating that the processor should produce a warning
0127: * when a recoverable error occurs, and should then take the recovery
0128: * action and continue.
0129: */
0130: public static final int RECOVER_WITH_WARNINGS = 1;
0131: /**
0132: * Constant indicating that when a recoverable error occurs, the
0133: * processor should not attempt to take the defined recovery action,
0134: * but should terminate with an error.
0135: */
0136: public static final int DO_NOT_RECOVER = 2;
0137:
0138: /**
0139: * Constant indicating the XML Version 1.0
0140: */
0141:
0142: public static final int XML10 = 10;
0143:
0144: /**
0145: * Constant indicating the XML Version 1.1
0146: */
0147:
0148: public static final int XML11 = 11;
0149:
0150: /**
0151: * Constant indicating that the host language is XSLT
0152: */
0153: public static final int XSLT = 50;
0154:
0155: /**
0156: * Constant indicating that the host language is XQuery
0157: */
0158: public static final int XQUERY = 51;
0159:
0160: /**
0161: * Constant indicating that the "host language" is XML Schema
0162: */
0163: public static final int XML_SCHEMA = 52;
0164:
0165: /**
0166: * Constant indicating that the host language is Java: that is, this is a free-standing
0167: * Java application with no XSLT or XQuery content
0168: */
0169: public static final int JAVA_APPLICATION = 53;
0170:
0171: /**
0172: * Constant indicating that the host language is XPATH itself - that is, a free-standing XPath environment
0173: */
0174: public static final int XPATH = 54;
0175:
0176: /**
0177: * Create a configuration object with default settings for all options. This is equivalent to
0178: * calling <code>new Configuration(true)</code>.
0179: * @since 8.4
0180: */
0181:
0182: public Configuration() {
0183: init();
0184: synchronized (Configuration.class) {
0185: if (sharedExternalObjectModels == null) {
0186: registerStandardObjectModels();
0187: }
0188: externalObjectModels = new ArrayList(
0189: sharedExternalObjectModels);
0190: }
0191: }
0192:
0193: private void init() {
0194: targetNamePool = NamePool.getDefaultNamePool();
0195: extensionBinder = new JavaExtensionLibrary(this );
0196:
0197: // Get the implicit timezone from the current system clock
0198: GregorianCalendar calendar = new GregorianCalendar();
0199: int tzmsecs = (calendar.get(Calendar.ZONE_OFFSET) + calendar
0200: .get(Calendar.DST_OFFSET));
0201: implicitTimezone = tzmsecs / 60000;
0202: }
0203:
0204: /**
0205: * Get a message used to identify this product when a transformation is run using the -t option
0206: * @return A string containing both the product name and the product
0207: * version
0208: * @since 8.4
0209: */
0210:
0211: public String getProductTitle() {
0212: return "Saxon " + Version.getProductVersion()
0213: + " from Saxonica";
0214: }
0215:
0216: /**
0217: * Determine if the configuration is schema-aware, for the given host language
0218: * @param language the required host language: XSLT, XQUERY, or XML_SCHEMA
0219: * @since 8.4
0220: */
0221:
0222: public boolean isSchemaAware(int language) {
0223: return false;
0224: // changing this to true will do no good!
0225: }
0226:
0227: /**
0228: * Display a message about the license status
0229: */
0230:
0231: public void displayLicenseMessage() {
0232: }
0233:
0234: /**
0235: * Get the host language used in this configuration. The typical values
0236: * are XSLT and XQUERY. The values XML_SCHEMA and JAVA_APPLICATION may also
0237: * be encountered.
0238: * <p>
0239: * This method is problematic because it is possible to run multiple transformations
0240: * or queries within the same configuration. The method is therefore best avoided.
0241: * Instead, use {@link net.sf.saxon.instruct.Executable#getHostLanguage}.
0242: * Internally its only use is in deciding (in Saxon-SA only) which error listener to
0243: * use by default at compile time, and since the standard XSLT and XQuery listeners have
0244: * no differences when used for static errors, the choice is immaterial.
0245: * @return Configuration.XSLT or Configuration.XQUERY
0246: */
0247:
0248: public int getHostLanguage() {
0249: return hostLanguage;
0250: }
0251:
0252: /**
0253: * Set the host language used in this configuration. The possible values
0254: * are XSLT and XQUERY.
0255: * @param hostLanguage Configuration.XSLT or Configuration.XQUERY
0256: */
0257:
0258: public void setHostLanguage(int hostLanguage) {
0259: this .hostLanguage = hostLanguage;
0260: }
0261:
0262: /**
0263: * Get the URIResolver used in this configuration
0264: * @return the URIResolver. If no URIResolver has been set explicitly, the
0265: * default URIResolver is used.
0266: * @since 8.4
0267: */
0268:
0269: public URIResolver getURIResolver() {
0270: if (uriResolver == null) {
0271: return systemURIResolver;
0272: }
0273: return uriResolver;
0274: }
0275:
0276: /**
0277: * Set the URIResolver to be used in this configuration. This will be used to
0278: * resolve the URIs used statically (e.g. by xsl:include) and also the URIs used
0279: * dynamically by functions such as document() and doc(). Note that the URIResolver
0280: * does not resolve the URI in the sense of RFC 2396 (which is also the sense in which
0281: * the resolve-uri() function uses the term): rather it dereferences an absolute URI
0282: * to obtain an actual resource, which is returned as a Source object.
0283: * @param resolver The URIResolver to be used.
0284: * @since 8.4
0285: */
0286:
0287: public void setURIResolver(URIResolver resolver) {
0288: this .uriResolver = resolver;
0289: }
0290:
0291: /**
0292: * Get the system-defined URI Resolver. This is used when the user-defined URI resolver
0293: * returns null as the result of the resolve() method
0294: */
0295:
0296: public StandardURIResolver getSystemURIResolver() {
0297: return systemURIResolver;
0298: }
0299:
0300: /**
0301: * Create an instance of a URIResolver with a specified class name
0302: *
0303: * @exception TransformerException if the requested class does not
0304: * implement the javax.xml.transform.URIResolver interface
0305: * @param className The fully-qualified name of the URIResolver class
0306: * @return The newly created URIResolver
0307: */
0308: public URIResolver makeURIResolver(String className)
0309: throws TransformerException {
0310: Object obj = getInstance(className, null);
0311: if (obj instanceof URIResolver) {
0312: return (URIResolver) obj;
0313: }
0314: throw new DynamicError("Class " + className
0315: + " is not a URIResolver");
0316: }
0317:
0318: /**
0319: * Get the ErrorListener used in this configuration. If no ErrorListener
0320: * has been supplied explicitly, the default ErrorListener is used.
0321: * @return the ErrorListener.
0322: * @since 8.4
0323: */
0324:
0325: public ErrorListener getErrorListener() {
0326: if (listener == null) {
0327: listener = new StandardErrorListener();
0328: ((StandardErrorListener) listener)
0329: .setRecoveryPolicy(recoveryPolicy);
0330: }
0331: return listener;
0332: }
0333:
0334: /**
0335: * Set the ErrorListener to be used in this configuration. The ErrorListener
0336: * is informed of all static and dynamic errors detected, and can decide whether
0337: * run-time warnings are to be treated as fatal.
0338: * @param listener the ErrorListener to be used
0339: * @since 8.4
0340: */
0341:
0342: public void setErrorListener(ErrorListener listener) {
0343: this .listener = listener;
0344: }
0345:
0346: /**
0347: * Report a fatal error
0348: */
0349:
0350: public void reportFatalError(XPathException err) {
0351: if (!err.hasBeenReported()) {
0352: try {
0353: getErrorListener().fatalError(err);
0354: } catch (TransformerException e) {
0355: //
0356: }
0357: err.setHasBeenReported();
0358: }
0359: }
0360:
0361: /**
0362: * Set whether multithreading optimizations are allowed
0363: */
0364:
0365: public void setMultiThreading(boolean multithreading) {
0366: allowMultiThreading = multithreading;
0367: }
0368:
0369: /**
0370: * Determine whether multithreading optimizations are allowed
0371: */
0372:
0373: public boolean isMultiThreading() {
0374: return allowMultiThreading;
0375: }
0376:
0377: /**
0378: * Set the XML version to be used by default for validating characters and names
0379: * @param version one of the constants XML10 or XML11
0380: * @since 8.6
0381: */
0382:
0383: public void setXMLVersion(int version) {
0384: this .xmlVersion = version;
0385: }
0386:
0387: /**
0388: * Get the XML version to be used by default for validating characters and names
0389: * @return one of the constants XML10 or XML11
0390: * @since 8.6
0391: */
0392:
0393: public int getXMLVersion() {
0394: return this .xmlVersion;
0395: }
0396:
0397: /**
0398: * Determine whether it is necessary to check for XML 1.1 input when parsing. This
0399: * check is necessary if (a) the configuration is set to XML 1.0, and (b) some loaded
0400: * parser has indicated that it can handle XML 1.1.
0401: */
0402:
0403: public boolean mustCheckForXML11Input() {
0404: return checkForXml11Input;
0405: }
0406:
0407: /**
0408: * Get a class that can be used to check names against the selected XML version
0409: * @return a class that can be used for name checking
0410: * @since 8.6
0411: */
0412:
0413: public NameChecker getNameChecker() {
0414: return (xmlVersion == XML10 ? (NameChecker) Name10Checker
0415: .getInstance() : (NameChecker) Name11Checker
0416: .getInstance());
0417: }
0418:
0419: /**
0420: * Get an XPathContext object with sufficient capability to perform comparisons and conversions
0421: */
0422:
0423: public XPathContext getConversionContext() {
0424: if (conversionContext == null) {
0425: conversionContext = new IndependentContext(this )
0426: .makeEarlyEvaluationContext();
0427: }
0428: return conversionContext;
0429: }
0430:
0431: /**
0432: * Get the Tree Model used by this Configuration. This is either
0433: * Builder.STANDARD_TREE or Builder.TINY_TREE. The default (confusingly)
0434: * is Builder.TINY_TREE.
0435: * @return the selected Tree Model
0436: * @since 8.4
0437: */
0438:
0439: public int getTreeModel() {
0440: return treeModel;
0441: }
0442:
0443: /**
0444: * Set the Tree Model used by this Configuration. This is either
0445: * Builder.STANDARD_TREE or Builder.TINY_TREE. The default (confusingly)
0446: * is Builder.TINY_TREE.
0447: * @param treeModel the selected Tree Model
0448: * @since 8.4
0449: */
0450:
0451: public void setTreeModel(int treeModel) {
0452: this .treeModel = treeModel;
0453: }
0454:
0455: /**
0456: * Determine whether source documents will maintain line numbers, for the
0457: * benefit of the saxon:line-number() extension function as well as run-time
0458: * tracing.
0459: * @return true if line numbers are maintained in source documents
0460: * @since 8.4
0461: */
0462:
0463: public boolean isLineNumbering() {
0464: return lineNumbering;
0465: }
0466:
0467: /**
0468: * Determine whether source documents will maintain line numbers, for the
0469: * benefit of the saxon:line-number() extension function as well as run-time
0470: * tracing.
0471: * @param lineNumbering true if line numbers are maintained in source documents
0472: * @since 8.4
0473: */
0474:
0475: public void setLineNumbering(boolean lineNumbering) {
0476: this .lineNumbering = lineNumbering;
0477: }
0478:
0479: /**
0480: * Get the TraceListener used for run-time tracing of instruction execution.
0481: * @return the TraceListener, or null if none is in use.
0482: * @since 8.4
0483: */
0484:
0485: public TraceListener getTraceListener() {
0486: return traceListener;
0487: }
0488:
0489: /**
0490: * Set the TraceListener to be used for run-time tracing of instruction execution.
0491: * @param traceListener The TraceListener to be used.
0492: * @since 8.4
0493: */
0494:
0495: public void setTraceListener(TraceListener traceListener) {
0496: this .traceListener = traceListener;
0497: setMultiThreading(false);
0498: }
0499:
0500: /** Create an instance of a TraceListener with a specified class name
0501: *
0502: * @exception net.sf.saxon.trans.XPathException if the requested class does not
0503: * implement the net.sf.saxon.trace.TraceListener interface
0504: * @param className The fully qualified class name of the TraceListener to
0505: * be constructed
0506: * @return the newly constructed TraceListener
0507: */
0508:
0509: public TraceListener makeTraceListener(String className)
0510: throws XPathException {
0511: Object obj = getInstance(className, null);
0512: if (obj instanceof TraceListener) {
0513: return (TraceListener) obj;
0514: }
0515: throw new DynamicError("Class " + className
0516: + " is not a TraceListener");
0517: }
0518:
0519: /**
0520: * Set the FunctionLibrary used to bind calls on extension functions. This allows the
0521: * rules for identifying extension functions to be customized (in principle, it would
0522: * allow support for extension functions in other languages to be provided).
0523: * <p>
0524: * When an application supplies its own FunctionLibrary for binding extension functions,
0525: * this replaces the default binding mechanism for Java extension functions, namely
0526: * {@link JavaExtensionLibrary}. It thus disables the function libraries
0527: * for built-in Saxon extensions and for EXSLT extensions. It is possible to create a
0528: * function library that adds to the existing mechanisms, rather than replacing them,
0529: * by supplying as the FunctionLibrary a {@link net.sf.saxon.functions.FunctionLibraryList}
0530: * that itself contains two FunctionLibrary objects: a JavaExtensionLibrary, and a user-written
0531: * FunctionLibrary.
0532: * @param binder The FunctionLibrary object used to locate implementations of extension
0533: * functions, based on their name and arity
0534: * @see #setExtensionFunctionFactory
0535: */
0536:
0537: public void setExtensionBinder(FunctionLibrary binder) {
0538: extensionBinder = binder;
0539: }
0540:
0541: /**
0542: * Get the FunctionLibrary used to bind calls on extension functions.
0543: * <p>
0544: * This mechanism is for advanced users only, and the details are subject to change.
0545: * @return the registered FunctionLibrary for extension functions if one has been
0546: * registered; or the default FunctionLibrary for extension functions otherwise
0547: */
0548:
0549: public FunctionLibrary getExtensionBinder() {
0550: return extensionBinder;
0551: }
0552:
0553: /**
0554: * Get the FunctionLibrary used to bind calls on Saxon-defined extension functions.
0555: * <p>
0556: * This method is intended for internal use only.
0557: */
0558:
0559: public VendorFunctionLibrary getVendorFunctionLibrary() {
0560: if (vendorFunctionLibrary == null) {
0561: vendorFunctionLibrary = new VendorFunctionLibrary();
0562: }
0563: return vendorFunctionLibrary;
0564: }
0565:
0566: /**
0567: * Set a CollationURIResolver to be used to resolve collation URIs (that is,
0568: * to take a URI identifying a collation, and return the corresponding collation).
0569: * Note that Saxon attempts first to resolve a collation URI using the resolver
0570: * registered with the Controller; if that returns null, it tries again using the
0571: * resolver registered with the Configuration.
0572: * <p>
0573: * Note that it is undefined whether collation URIs are resolved at compile time
0574: * or at run-time. It is therefore inadvisable to change the CollationURIResolver after
0575: * compiling a query or stylesheet and before running it.
0576: * @param resolver the collation URI resolver to be used. This replaces any collation
0577: * URI resolver previously registered.
0578: * @since 8.5
0579: */
0580:
0581: public void setCollationURIResolver(CollationURIResolver resolver) {
0582: collationResolver = resolver;
0583: }
0584:
0585: /**
0586: * Get the collation URI resolver associated with this configuration. This will
0587: * return the CollationURIResolver previously set using the {@link #setCollationURIResolver}
0588: * method; if this has not been called, it returns the system-defined collation URI resolver
0589: * @return the registered CollationURIResolver
0590: * @since 8.5
0591: */
0592:
0593: public CollationURIResolver getCollationURIResolver() {
0594: return collationResolver;
0595: }
0596:
0597: /**
0598: * Set a CollectionURIResolver to be used to resolve collection URIs (that is,
0599: * the URI supplied in a call to the collection() function).
0600: * <p>
0601: * Collection URIs are always resolved at run-time, using the CollectionURIResolver
0602: * in force at the time the collection() function is called.
0603: * @param resolver the collection URI resolver to be used. This replaces any collection
0604: * URI resolver previously registered.
0605: * @since 8.5
0606: */
0607:
0608: public void setCollectionURIResolver(CollectionURIResolver resolver) {
0609: collectionResolver = resolver;
0610: }
0611:
0612: /**
0613: * Get the collection URI resolver associated with this configuration. This will
0614: * return the CollectionURIResolver previously set using the {@link #setCollectionURIResolver}
0615: * method; if this has not been called, it returns the system-defined collection URI resolver
0616: * @return the registered CollationURIResolver
0617: * @since 8.5
0618: */
0619:
0620: public CollectionURIResolver getCollectionURIResolver() {
0621: return collectionResolver;
0622: }
0623:
0624: /**
0625: * Set a user-defined ModuleURIResolver for resolving URIs used in "import module"
0626: * declarations in the XQuery prolog
0627: */
0628:
0629: public void setModuleURIResolver(ModuleURIResolver resolver) {
0630: moduleURIResolver = resolver;
0631: }
0632:
0633: /**
0634: * Create and register an instance of a ModuleURIResolver with a specified class name
0635: *
0636: * @exception TransformerException if the requested class does not
0637: * implement the net.sf.saxon.query.ModuleURIResolver interface
0638: * @param className The fully-qualified name of the ModuleURIResolver class
0639: */
0640: public void setModuleURIResolver(String className)
0641: throws TransformerException {
0642: Object obj = getInstance(className, null);
0643: if (obj instanceof ModuleURIResolver) {
0644: setModuleURIResolver((ModuleURIResolver) obj);
0645: } else {
0646: throw new DynamicError("Class " + className
0647: + " is not a ModuleURIResolver");
0648: }
0649: }
0650:
0651: /**
0652: * Get the user-defined ModuleURIResolver for resolving URIs used in "import module"
0653: * declarations in the XQuery prolog; returns null if none has been explicitly set.
0654: */
0655:
0656: public ModuleURIResolver getModuleURIResolver() {
0657: return moduleURIResolver;
0658: }
0659:
0660: /**
0661: * Get the standard system-defined ModuleURIResolver for resolving URIs used in "import module"
0662: * declarations in the XQuery prolog.
0663: */
0664:
0665: public ModuleURIResolver getStandardModuleURIResolver() {
0666: return standardModuleURIResolver;
0667: }
0668:
0669: /**
0670: * Determine how recoverable run-time errors are to be handled. This applies
0671: * only if the standard ErrorListener is used.
0672: * @return the current recovery policy. The options are {@link #RECOVER_SILENTLY},
0673: * {@link #RECOVER_WITH_WARNINGS}, or {@link #DO_NOT_RECOVER}.
0674: * @since 8.4
0675: */
0676:
0677: public int getRecoveryPolicy() {
0678: return recoveryPolicy;
0679: }
0680:
0681: /**
0682: * Determine how recoverable run-time errors are to be handled. This applies
0683: * only if the standard ErrorListener is used. The recovery policy applies to
0684: * errors classified in the XSLT 2.0 specification as recoverable dynamic errors,
0685: * but only in those cases where Saxon provides a choice over how the error is handled:
0686: * in some cases, Saxon makes the decision itself.
0687: * @param recoveryPolicy the recovery policy to be used. The options are {@link #RECOVER_SILENTLY},
0688: * {@link #RECOVER_WITH_WARNINGS}, or {@link #DO_NOT_RECOVER}.
0689: * @since 8.4
0690: */
0691:
0692: public void setRecoveryPolicy(int recoveryPolicy) {
0693: this .recoveryPolicy = recoveryPolicy;
0694: }
0695:
0696: /**
0697: * Get the name of the class that will be instantiated to create a MessageEmitter,
0698: * to process the output of xsl:message instructions in XSLT.
0699: * @return the full class name of the message emitter class.
0700: * @since 8.4
0701: */
0702:
0703: public String getMessageEmitterClass() {
0704: return messageEmitterClass;
0705: }
0706:
0707: /**
0708: * Set the name of the class that will be instantiated to create a MessageEmitter,
0709: * to process the output of xsl:message instructions in XSLT.
0710: * @param messageEmitterClass the full class name of the message emitter class. This
0711: * must implement net.sf.saxon.event.Emitter.
0712: * @since 8.4
0713: */
0714:
0715: public void setMessageEmitterClass(String messageEmitterClass) {
0716: this .messageEmitterClass = messageEmitterClass;
0717: }
0718:
0719: /**
0720: * Get the name of the class that will be instantiated to create an XML parser
0721: * for parsing source documents (for example, documents loaded using the document()
0722: * or doc() functions).
0723: * <p>
0724: * This method is retained in Saxon for backwards compatibility, but the preferred way
0725: * of choosing an XML parser is to use JAXP interfaces, for example by supplying a
0726: * JAXP Source object initialized with an appropriate implementation of org.xml.sax.XMLReader.
0727: * @return the fully qualified name of the XML parser class
0728: */
0729:
0730: public String getSourceParserClass() {
0731: return sourceParserClass;
0732: }
0733:
0734: /**
0735: * Set the name of the class that will be instantiated to create an XML parser
0736: * for parsing source documents (for example, documents loaded using the document()
0737: * or doc() functions).
0738: * <p>
0739: * This method is retained in Saxon for backwards compatibility, but the preferred way
0740: * of choosing an XML parser is to use JAXP interfaces, for example by supplying a
0741: * JAXP Source object initialized with an appropriate implementation of org.xml.sax.XMLReader.
0742: *
0743: * @param sourceParserClass the fully qualified name of the XML parser class. This must implement
0744: * the SAX2 XMLReader interface.
0745: */
0746:
0747: public void setSourceParserClass(String sourceParserClass) {
0748: this .sourceParserClass = sourceParserClass;
0749: }
0750:
0751: /**
0752: * Get the name of the class that will be instantiated to create an XML parser
0753: * for parsing stylesheet modules.
0754: * <p>
0755: * This method is retained in Saxon for backwards compatibility, but the preferred way
0756: * of choosing an XML parser is to use JAXP interfaces, for example by supplying a
0757: * JAXP Source object initialized with an appropriate implementation of org.xml.sax.XMLReader.
0758: *
0759: * @return the fully qualified name of the XML parser class
0760: */
0761:
0762: public String getStyleParserClass() {
0763: return styleParserClass;
0764: }
0765:
0766: /**
0767: * Set the name of the class that will be instantiated to create an XML parser
0768: * for parsing stylesheet modules.
0769: * <p>
0770: * This method is retained in Saxon for backwards compatibility, but the preferred way
0771: * of choosing an XML parser is to use JAXP interfaces, for example by supplying a
0772: * JAXP Source object initialized with an appropriate implementation of org.xml.sax.XMLReader.
0773: *
0774: * @param styleParserClass the fully qualified name of the XML parser class
0775: */
0776:
0777: public void setStyleParserClass(String styleParserClass) {
0778: this .styleParserClass = styleParserClass;
0779: }
0780:
0781: /**
0782: * Get the OutputURIResolver that will be used to resolve URIs used in the
0783: * href attribute of the xsl:result-document instruction.
0784: * @return the OutputURIResolver. If none has been supplied explicitly, the
0785: * default OutputURIResolver is returned.
0786: * @since 8.4
0787: */
0788:
0789: public OutputURIResolver getOutputURIResolver() {
0790: if (outputURIResolver == null) {
0791: outputURIResolver = StandardOutputResolver.getInstance();
0792: }
0793: return outputURIResolver;
0794: }
0795:
0796: /**
0797: * Set the OutputURIResolver that will be used to resolve URIs used in the
0798: * href attribute of the xsl:result-document instruction.
0799: * @param outputURIResolver the OutputURIResolver to be used.
0800: * @since 8.4
0801: */
0802:
0803: public void setOutputURIResolver(OutputURIResolver outputURIResolver) {
0804: this .outputURIResolver = outputURIResolver;
0805: }
0806:
0807: /**
0808: * Determine whether brief progress messages and timing information will be output
0809: * to System.err.
0810: * <p>
0811: * This method is provided largely for internal use. Progress messages are normally
0812: * controlled directly from the command line interfaces, and are not normally used when
0813: * driving Saxon from the Java API.
0814: *
0815: * @return true if these messages are to be output.
0816: */
0817:
0818: public boolean isTiming() {
0819: return timing;
0820: }
0821:
0822: /**
0823: * Determine whether brief progress messages and timing information will be output
0824: * to System.err.
0825: * <p>
0826: * This method is provided largely for internal use. Progress messages are normally
0827: * controlled directly from the command line interfaces, and are not normally used when
0828: *
0829: * @param timing true if these messages are to be output.
0830: */
0831:
0832: public void setTiming(boolean timing) {
0833: this .timing = timing;
0834: }
0835:
0836: /**
0837: * Determine whether a warning is to be output when running against a stylesheet labelled
0838: * as version="1.0". The XSLT specification requires such a warning unless the user disables it.
0839: * @return true if these messages are to be output.
0840: * @since 8.4
0841: */
0842:
0843: public boolean isVersionWarning() {
0844: return versionWarning;
0845: }
0846:
0847: /**
0848: * Determine whether a warning is to be output when running against a stylesheet labelled
0849: * as version="1.0". The XSLT specification requires such a warning unless the user disables it.
0850: * @param warn true if these messages are to be output.
0851: * @since 8.4
0852: */
0853:
0854: public void setVersionWarning(boolean warn) {
0855: this .versionWarning = warn;
0856: }
0857:
0858: /**
0859: * Determine whether calls to external Java functions are permitted.
0860: * @return true if such calls are permitted.
0861: * @since 8.4
0862: */
0863:
0864: public boolean isAllowExternalFunctions() {
0865: return allowExternalFunctions;
0866: }
0867:
0868: /**
0869: * Determine whether calls to external Java functions are permitted. Allowing
0870: * external function calls is potentially a security risk if the stylesheet or
0871: * Query is untrusted, as it allows arbitrary Java methods to be invoked, which can
0872: * examine or modify the contents of filestore and other resources on the machine
0873: * where the query/stylesheet is executed
0874: *
0875: * @param allowExternalFunctions true if external function calls are to be
0876: * permitted.
0877: * @since 8.4
0878: */
0879:
0880: public void setAllowExternalFunctions(boolean allowExternalFunctions) {
0881: this .allowExternalFunctions = allowExternalFunctions;
0882: }
0883:
0884: /**
0885: * Determine whether calls on external functions are to be traced for diagnostic
0886: * purposes.
0887: * @return true if tracing is enabled for calls to external Java functions
0888: */
0889:
0890: public boolean isTraceExternalFunctions() {
0891: return traceExternalFunctions;
0892: }
0893:
0894: /**
0895: * Determine whether attribute types obtained from a DTD are to be used to set type annotations
0896: * on the resulting nodes.
0897: *
0898: * @param useTypes set to true if DTD types are to be taken into account
0899: * @since 8.4
0900: */
0901:
0902: public void setRetainDTDAttributeTypes(boolean useTypes)
0903: throws TransformerFactoryConfigurationError {
0904: if (useTypes && !isSchemaAware(Configuration.XML_SCHEMA)) {
0905: throw new TransformerFactoryConfigurationError(
0906: "Retaining DTD attribute types requires the schema-aware product");
0907: }
0908: retainDTDattributeTypes = useTypes;
0909: }
0910:
0911: /**
0912: * Determine whether attribute types obtained from a DTD are to be used to set type annotations
0913: * on the resulting nodes
0914: *
0915: * @return true if DTD types are to be taken into account
0916: * @since 8.4
0917: */
0918:
0919: public boolean isRetainDTDAttributeTypes() {
0920: return retainDTDattributeTypes;
0921: }
0922:
0923: /**
0924: * Determine whether calls on external functions are to be traced for diagnostic
0925: * purposes.
0926: * @param traceExternalFunctions true if tracing is to be enabled
0927: * for calls to external Java functions
0928: */
0929:
0930: public void setTraceExternalFunctions(boolean traceExternalFunctions) {
0931: this .traceExternalFunctions = traceExternalFunctions;
0932: }
0933:
0934: /**
0935: * Get an ExtensionFunctionFactory. This is used at compile time for generating
0936: * the code that calls Java extension functions. It is possible to supply a user-defined
0937: * ExtensionFunctionFactory to customize the way extension functions are bound.
0938: * <p>
0939: * This mechanism is intended for advanced use only, and is subject to change.
0940: *
0941: * @return the factory object registered to generate calls on extension functions,
0942: * if one has been registered; if not, the default factory used by Saxon.
0943: */
0944:
0945: public ExtensionFunctionFactory getExtensionFunctionFactory() {
0946: return extensionFunctionFactory;
0947: }
0948:
0949: /**
0950: * Set an ExtensionFunctionFactory. This is used at compile time for generating
0951: * the code that calls Java extension functions. It is possible to supply a user-defined
0952: * ExtensionFunctionFactory to customize the way extension functions are called. The
0953: * ExtensionFunctionFactory determines how external methods are called, but is not
0954: * involved in binding the external method corresponding to a given function name or URI.
0955: * <p>
0956: * This mechanism is intended for advanced use only, and is subject to change.
0957: * @see #setExtensionBinder
0958: */
0959:
0960: public void setExtensionFunctionFactory(
0961: ExtensionFunctionFactory factory) {
0962: extensionFunctionFactory = factory;
0963: }
0964:
0965: /**
0966: * Determine whether the XML parser for source documents will be asked to perform
0967: * DTD validation of source documents
0968: * @return true if DTD validation is requested.
0969: * @since 8.4
0970: */
0971:
0972: public boolean isValidation() {
0973: return validation;
0974: }
0975:
0976: /**
0977: * Determine whether the XML parser for source documents will be asked to perform
0978: * DTD validation of source documents
0979: * @param validation true if DTD validation is to be requested.
0980: * @since 8.4
0981: */
0982:
0983: public void setValidation(boolean validation) {
0984: this .validation = validation;
0985: }
0986:
0987: /**
0988: * Specify that all nodes encountered within this query or transformation will be untyped
0989: */
0990:
0991: public void setAllNodesUntyped(boolean allUntyped) {
0992: allNodesUntyped = allUntyped;
0993: }
0994:
0995: /**
0996: * Determine whether all nodes encountered within this query or transformation are guaranteed to be
0997: * untyped
0998: */
0999:
1000: public boolean areAllNodesUntyped() {
1001: return allNodesUntyped;
1002: }
1003:
1004: /**
1005: * Determine whether source documents (supplied as a StreamSource or SAXSource)
1006: * should be subjected to schema validation
1007: * @return the schema validation mode previously set using setSchemaValidationMode(),
1008: * or the default mode {@link Validation#STRIP} otherwise.
1009: */
1010:
1011: public int getSchemaValidationMode() {
1012: return schemaValidationMode;
1013: }
1014:
1015: /**
1016: * Indicate whether source documents (supplied as a StreamSource or SAXSource)
1017: * should be subjected to schema validation
1018: * @param validationMode the validation (or construction) mode to be used for source documents.
1019: * One of {@link Validation#STRIP}, {@link Validation#PRESERVE}, {@link Validation#STRICT},
1020: * {@link Validation#LAX}
1021: * @since 8.4
1022: */
1023:
1024: public void setSchemaValidationMode(int validationMode) {
1025: switch (validationMode) {
1026: case Validation.STRIP:
1027: case Validation.PRESERVE:
1028: break;
1029: case Validation.LAX:
1030: case Validation.STRICT:
1031: if (!isSchemaAware(XML_SCHEMA)) {
1032: needSchemaAwareVersion();
1033: }
1034: break;
1035: default:
1036: throw new IllegalArgumentException(
1037: "Unsupported validation mode " + validationMode);
1038: }
1039: schemaValidationMode = validationMode;
1040: }
1041:
1042: /**
1043: * Indicate whether schema validation failures on result documents are to be treated
1044: * as fatal errors or as warnings.
1045: *
1046: * @param warn true if schema validation failures are to be treated as warnings; false if they
1047: * are to be treated as fatal errors.
1048: * @since 8.4
1049: */
1050:
1051: public void setValidationWarnings(boolean warn) {
1052: validationWarnings = warn;
1053: }
1054:
1055: /**
1056: * Determine whether schema validation failures on result documents are to be treated
1057: * as fatal errors or as warnings.
1058: * @return true if validation errors are to be treated as warnings (that is, the
1059: * validation failure is reported but processing continues as normal); false
1060: * if validation errors are fatal.
1061: * @since 8.4
1062: */
1063:
1064: public boolean isValidationWarnings() {
1065: return validationWarnings;
1066: }
1067:
1068: /**
1069: * Get the target namepool to be used for stylesheets/queries and for source documents.
1070: * @return the target name pool. If no NamePool has been specified explicitly, the
1071: * default NamePool is returned.
1072: * @since 8.4
1073: */
1074:
1075: public NamePool getNamePool() {
1076: return targetNamePool;
1077: }
1078:
1079: /**
1080: * Set the NamePool to be used for stylesheets/queries and for source documents.
1081: * <p>
1082: * Normally all transformations and queries run under a single Java VM share the same
1083: * NamePool. This creates a potential bottleneck, since changes to the namepool are
1084: * synchronized. It is possible therefore to allocate a distinct NamePool to each
1085: * Configuration. This requires considerable care and should only be done when the
1086: * default arrangement is found to cause problems. There is a basic rule to follow:
1087: * any compiled stylesheet or query must use the same NamePool as its source and
1088: * result documents.
1089: *
1090: * @param targetNamePool The NamePool to be used.
1091: * @since 8.4
1092: */
1093:
1094: public void setNamePool(NamePool targetNamePool) {
1095: this .targetNamePool = targetNamePool;
1096: }
1097:
1098: /**
1099: * Get the document number allocator.
1100: * <p>
1101: * This is intended primarily for internal use
1102: */
1103:
1104: public DocumentNumberAllocator getDocumentNumberAllocator() {
1105: return documentNumberAllocator;
1106: }
1107:
1108: /**
1109: * Determine whether whitespace-only text nodes are to be stripped unconditionally
1110: * from source documents.
1111: * @return true if all whitespace-only text nodes are stripped.
1112: * @since 8.4
1113: */
1114:
1115: public boolean isStripsAllWhiteSpace() {
1116: return stripsWhiteSpace == Whitespace.ALL;
1117: }
1118:
1119: /**
1120: * Determine whether whitespace-only text nodes are to be stripped unconditionally
1121: * from source documents.
1122: * @param stripsAllWhiteSpace if all whitespace-only text nodes are to be stripped.
1123: * @since 8.4
1124: */
1125:
1126: public void setStripsAllWhiteSpace(boolean stripsAllWhiteSpace) {
1127: if (stripsAllWhiteSpace) {
1128: this .stripsWhiteSpace = Whitespace.ALL;
1129: }
1130: }
1131:
1132: /**
1133: * Set which kinds of whitespace-only text node should be stripped.
1134: * @param kind the kind of whitespace-only text node that should be stripped when building
1135: * a source tree. One of {@link Whitespace.NONE} (none), {@link Whitespace.ALL} (all),
1136: * or {@link Whitespace.IGNORABLE} (element-content whitespace as defined in a DTD or schema)
1137: */
1138:
1139: public void setStripsWhiteSpace(int kind) {
1140: stripsWhiteSpace = kind;
1141: }
1142:
1143: /**
1144: * Set which kinds of whitespace-only text node should be stripped.
1145: * @return kind the kind of whitespace-only text node that should be stripped when building
1146: * a source tree. One of {@link Whitespace.NONE} (none), {@link Whitespace.ALL} (all),
1147: * or {@link Whitespace.IGNORABLE} (element-content whitespace as defined in a DTD or schema)
1148: */
1149:
1150: public int getStripsWhiteSpace() {
1151: return stripsWhiteSpace;
1152: }
1153:
1154: /**
1155: * Get a parser for source documents. The parser is allocated from a pool if any are available
1156: * from the pool: the client should ideally return the parser to the pool after use, so that it
1157: * can be reused.
1158: * <p>
1159: * This method is intended primarily for internal use.
1160: */
1161:
1162: public synchronized XMLReader getSourceParser()
1163: throws TransformerFactoryConfigurationError {
1164: if (sourceParserPool == null) {
1165: sourceParserPool = new ArrayList(10);
1166: }
1167: if (sourceParserPool.size() > 0) {
1168: int n = sourceParserPool.size() - 1;
1169: XMLReader parser = (XMLReader) sourceParserPool.get(n);
1170: sourceParserPool.remove(n);
1171: return parser;
1172: }
1173: XMLReader parser;
1174: if (getSourceParserClass() != null) {
1175: parser = makeParser(getSourceParserClass());
1176: } else {
1177: parser = loadParser();
1178: }
1179: if (isValidation()) {
1180: try {
1181: parser.setFeature(
1182: "http://xml.org/sax/features/validation", true);
1183: } catch (SAXException err) {
1184: throw new TransformerFactoryConfigurationError(
1185: "The XML parser does not support validation");
1186: }
1187: }
1188:
1189: return parser;
1190: }
1191:
1192: /**
1193: * Return a source parser to the pool, for reuse
1194: * @param parser The parser: the caller must not supply a parser that was obtained by any
1195: * mechanism other than calling the getSourceParser() method.
1196: */
1197:
1198: public synchronized void reuseSourceParser(XMLReader parser) {
1199: if (sourceParserPool == null) {
1200: sourceParserPool = new ArrayList(10);
1201: }
1202: sourceParserPool.add(parser);
1203: }
1204:
1205: /**
1206: * Get a parser by instantiating the SAXParserFactory
1207: * @return the parser (XMLReader)
1208: */
1209:
1210: private XMLReader loadParser() {
1211: XMLReader parser;
1212: try {
1213: parser = SAXParserFactory.newInstance().newSAXParser()
1214: .getXMLReader();
1215: } catch (ParserConfigurationException err) {
1216: throw new TransformerFactoryConfigurationError(err);
1217: } catch (SAXException err) {
1218: throw new TransformerFactoryConfigurationError(err);
1219: }
1220: if (xmlVersion == XML10 && !checkForXml11Input) {
1221: try {
1222: boolean value = parser
1223: .getFeature("http://xml.org/sax/features/xml-1.1");
1224: if (value) {
1225: checkForXml11Input = true;
1226: }
1227: } catch (SAXNotRecognizedException e) {
1228: //
1229: } catch (SAXNotSupportedException e) {
1230: //
1231: }
1232: }
1233: return parser;
1234: }
1235:
1236: /**
1237: * Get the parser for stylesheet documents. This parser is also used for schema documents.
1238: * <p>
1239: * This method is intended for internal use only.
1240: *
1241: */
1242:
1243: public synchronized XMLReader getStyleParser()
1244: throws TransformerFactoryConfigurationError {
1245: if (styleParserPool == null) {
1246: styleParserPool = new ArrayList(10);
1247: }
1248: if (styleParserPool.size() > 0) {
1249: int n = styleParserPool.size() - 1;
1250: XMLReader parser = (XMLReader) styleParserPool.get(n);
1251: styleParserPool.remove(n);
1252: return parser;
1253: }
1254: XMLReader parser;
1255: if (getStyleParserClass() != null) {
1256: parser = makeParser(getStyleParserClass());
1257: } else {
1258: parser = loadParser();
1259: }
1260: try {
1261: parser.setFeature("http://xml.org/sax/features/namespaces",
1262: true);
1263: parser.setFeature(
1264: "http://xml.org/sax/features/namespace-prefixes",
1265: false);
1266: } catch (SAXNotRecognizedException e) {
1267: throw new TransformerFactoryConfigurationError(e);
1268: } catch (SAXNotSupportedException e) {
1269: throw new TransformerFactoryConfigurationError(e);
1270: }
1271: return parser;
1272: }
1273:
1274: /**
1275: * Return a stylesheet (or schema) parser to the pool, for reuse
1276: * @param parser The parser: the caller must not supply a parser that was obtained by any
1277: * mechanism other than calling the getStyleParser() method.
1278: */
1279:
1280: public synchronized void reuseStyleParser(XMLReader parser) {
1281: if (styleParserPool == null) {
1282: styleParserPool = new ArrayList(10);
1283: }
1284: styleParserPool.add(parser);
1285: }
1286:
1287: /**
1288: * Read a schema from a given schema location
1289: * @return the target namespace of the schema
1290: * <p>
1291: * This method is intended for internal use.
1292: */
1293:
1294: public String readSchema(PipelineConfiguration pipe,
1295: String baseURI, String schemaLocation, String expected)
1296: throws TransformerConfigurationException {
1297: needSchemaAwareVersion();
1298: return null;
1299: }
1300:
1301: /**
1302: * Read schemas from a list of schema locations.
1303: * <p>
1304: * This method is intended for internal use.
1305: */
1306:
1307: public void readMultipleSchemas(PipelineConfiguration pipe,
1308: String baseURI, List schemaLocations, String expected)
1309: throws SchemaException {
1310: needSchemaAwareVersion();
1311: }
1312:
1313: /**
1314: * Read an inline schema from a stylesheet.
1315: * <p>
1316: * This method is intended for internal use.
1317: * @param pipe
1318: * @param root the xs:schema element in the stylesheet
1319: * @param expected the target namespace expected; null if there is no
1320: * expectation.
1321: * @return the actual target namespace of the schema
1322: *
1323: */
1324:
1325: public String readInlineSchema(PipelineConfiguration pipe,
1326: NodeInfo root, String expected) throws SchemaException {
1327: needSchemaAwareVersion();
1328: return null;
1329: }
1330:
1331: private void needSchemaAwareVersion() {
1332: throw new UnsupportedOperationException(
1333: "You need the schema-aware version of Saxon for this operation");
1334: }
1335:
1336: /**
1337: * Load a schema, which will be available for use by all subsequent operations using
1338: * this Configuration.
1339: * @param schemaSource the JAXP Source object identifying the schema document to be loaded
1340: * @throws SchemaException if the schema cannot be read or parsed or if it is invalid
1341: * @throws UnsupportedOperationException if the configuration is not schema-aware
1342: * @since 8.4
1343: */
1344:
1345: public void addSchemaSource(Source schemaSource)
1346: throws SchemaException {
1347: needSchemaAwareVersion();
1348: }
1349:
1350: /**
1351: * Add a schema to the cache.
1352: * <p>
1353: * This method is intended for internal use
1354: * @param schema an object of class javax.xml.validation.schema, which is not declared as such
1355: * to avoid creating a dependency on this JDK 1.5 class
1356: */
1357:
1358: public void addSchema(Object schema)
1359: throws TransformerConfigurationException {
1360: needSchemaAwareVersion();
1361: }
1362:
1363: /**
1364: * Get a schema from the cache. Return null if not found.
1365: * <p>
1366: * This method is intended for internal use.
1367: * @return an object of class javax.xml.validation.schema, which is not declared as such
1368: * to avoid creating a dependency on this JDK 1.5 class
1369: */
1370:
1371: public Object getSchema(String namespace) {
1372: return null;
1373: }
1374:
1375: /**
1376: * Get the set of namespaces of imported schemas
1377: */
1378:
1379: public Set getImportedNamespaces() {
1380: return Collections.EMPTY_SET;
1381: }
1382:
1383: /**
1384: * Mark a schema namespace as being sealed. This is done when components from this namespace
1385: * are first used for validating a source document or compiling a source document or query. Once
1386: * a namespace has been sealed, it is not permitted to change the schema components in that namespace
1387: * by redefining them, deriving new types by extension, or adding to their substitution groups.
1388: * @param namespace the namespace URI of the components to be sealed
1389: */
1390:
1391: public void sealNamespace(String namespace) {
1392: //
1393: }
1394:
1395: /**
1396: * Test whether a schema namespace is sealed. Once
1397: * a namespace has been sealed, it is not permitted to change the schema components in that namespace
1398: * by redefining them, deriving new types by extension, or adding to their substitution groups.
1399: * @param namespace the namespace URI of the components to be tested
1400: * @return true if this namespace has been sealed, otherwise false
1401: */
1402:
1403: public boolean isSealedNamespace(String namespace) {
1404: return false;
1405: }
1406:
1407: /**
1408: * Get a global element declaration.
1409: * <p>
1410: * This method is intended for internal use.
1411: * @return the element declaration whose name matches the given
1412: * fingerprint, or null if no element declaration with this name has
1413: * been registered.
1414: */
1415:
1416: public SchemaDeclaration getElementDeclaration(int fingerprint) {
1417: return null;
1418: }
1419:
1420: /**
1421: * Get a global attribute declaration.
1422: * <p>
1423: * This method is intended for internal use
1424: * @return the attribute declaration whose name matches the given
1425: * fingerprint, or null if no element declaration with this name has
1426: * been registered.
1427: */
1428:
1429: public SchemaDeclaration getAttributeDeclaration(int fingerprint) {
1430: return null;
1431: }
1432:
1433: /**
1434: * Get the top-level schema type definition with a given fingerprint.
1435: * <p>
1436: * This method is intended for internal use and for use by advanced
1437: * applications. (The SchemaType object returned cannot yet be considered
1438: * a stable API, and may be superseded when a JAXP API for schema information
1439: * is defined.)
1440: * @param fingerprint the fingerprint of the schema type
1441: * @return the schema type , or null if there is none
1442: * with this name.
1443: */
1444:
1445: public SchemaType getSchemaType(int fingerprint) {
1446: if (fingerprint < 1023) {
1447: return BuiltInSchemaFactory.getSchemaType(fingerprint);
1448: }
1449: return null;
1450: }
1451:
1452: /**
1453: * Get a document-level validator to add to a Receiver pipeline.
1454: * <p>
1455: * This method is intended for internal use.
1456: * @param receiver The receiver to which events should be sent after validation
1457: * @param systemId the base URI of the document being validated
1458: * @param namePool the namePool to be used by the validator
1459: * @param validationMode for example Validation.STRICT or Validation.STRIP. The integer may
1460: * also have the bit Validation.VALIDATE_OUTPUT set, indicating that the strean being validated
1461: * is to be treated as a final output stream (which means multiple errors can be reported)
1462: * @param stripSpace
1463: * @param schemaType The type against which the outermost element of the document must be validated
1464: * (null if there is no constraint)
1465: * @return A Receiver to which events can be sent for validation
1466: */
1467:
1468: public Receiver getDocumentValidator(Receiver receiver,
1469: String systemId, NamePool namePool, int validationMode,
1470: int stripSpace, SchemaType schemaType) {
1471: // non-schema-aware version
1472: return receiver;
1473: }
1474:
1475: /**
1476: * Get a Receiver that can be used to validate an element, and that passes the validated
1477: * element on to a target receiver. If validation is not supported, the returned receiver
1478: * will be the target receiver.
1479: * <p>
1480: * This method is intended for internal use.
1481: * @param receiver the target receiver tp receive the validated element
1482: * @param nameCode the nameCode of the element to be validated. This must correspond to the
1483: * name of an element declaration in a loaded schema
1484: * @param schemaType the schema type (typically a complex type) against which the element is to
1485: * be validated
1486: * @param validation The validation mode, for example Validation.STRICT or Validation.LAX
1487: * @param pool The name pool
1488: * @return The target receiver, indicating that with this configuration, no validation
1489: * is performed.
1490: */
1491: public Receiver getElementValidator(Receiver receiver,
1492: int nameCode, int locationId, SchemaType schemaType,
1493: int validation, NamePool pool) throws XPathException {
1494: return receiver;
1495: }
1496:
1497: /**
1498: * Validate an attribute value.
1499: * <p>
1500: * This method is intended for internal use.
1501: * @param nameCode the name of the attribute
1502: * @param value the value of the attribute as a string
1503: * @param validation STRICT or LAX
1504: * @return the type annotation to apply to the attribute node
1505: * @throws ValidationException if the value is invalid
1506: */
1507:
1508: public int validateAttribute(int nameCode, CharSequence value,
1509: int validation) throws ValidationException {
1510: return -1;
1511: }
1512:
1513: /**
1514: * Add to a pipeline a receiver that strips all type annotations. This
1515: * has a null implementation in the Saxon-B product, because type annotations
1516: * can never arise.
1517: * <p>
1518: * This method is intended for internal use.
1519: */
1520:
1521: public Receiver getAnnotationStripper(Receiver destination) {
1522: return destination;
1523: }
1524:
1525: /**
1526: * Make a test for elements corresponding to a give element declaration.
1527: * <p>
1528: * This method is intended for internal use.
1529: */
1530:
1531: public NodeTest makeSubstitutionGroupTest(
1532: SchemaDeclaration elementDecl) {
1533: needSchemaAwareVersion();
1534: return null;
1535: }
1536:
1537: /**
1538: * Create a new SAX XMLReader object using the class name provided. <br>
1539: * <p>
1540: * The named class must exist and must implement the
1541: * org.xml.sax.XMLReader or Parser interface. <br>
1542: * <p>
1543: * This method returns an instance of the parser named.
1544: * <p>
1545: * This method is intended for internal use.
1546: *
1547: * @param className A string containing the name of the
1548: * SAX parser class, for example "com.microstar.sax.LarkDriver"
1549: * @return an instance of the Parser class named, or null if it is not
1550: * loadable or is not a Parser.
1551: *
1552: */
1553: public XMLReader makeParser(String className)
1554: throws TransformerFactoryConfigurationError {
1555: Object obj;
1556: try {
1557: obj = getInstance(className, null);
1558: } catch (XPathException err) {
1559: throw new TransformerFactoryConfigurationError(err);
1560: }
1561: if (obj instanceof XMLReader) {
1562: return (XMLReader) obj;
1563: }
1564: throw new TransformerFactoryConfigurationError("Class "
1565: + className + " is not a SAX2 XMLReader");
1566: }
1567:
1568: /**
1569: * Get a locale given a language code in XML format.
1570: * <p>
1571: * This method is intended for internal use.
1572: */
1573:
1574: public static Locale getLocale(String lang) {
1575: int hyphen = lang.indexOf("-");
1576: String language, country;
1577: if (hyphen < 1) {
1578: language = lang;
1579: country = "";
1580: } else {
1581: language = lang.substring(1, hyphen);
1582: country = lang.substring(hyphen + 1);
1583: }
1584: return new Locale(language, country);
1585: }
1586:
1587: /**
1588: * Set the debugger to be used.
1589: * <p>
1590: * This method is provided for advanced users only, and is subject to change.
1591: */
1592:
1593: public void setDebugger(Debugger debugger) {
1594: this .debugger = debugger;
1595: }
1596:
1597: /**
1598: * Get the debugger in use. This will be null if no debugger has been registered.
1599: * <p>
1600: * This method is provided for advanced users only, and is subject to change.
1601: */
1602:
1603: public Debugger getDebugger() {
1604: return debugger;
1605: }
1606:
1607: /**
1608: * Factory method to create a SlotManager.
1609: * <p>
1610: * This method is provided for advanced users only, and is subject to change.
1611: */
1612:
1613: public SlotManager makeSlotManager() {
1614: if (debugger == null) {
1615: return new SlotManager();
1616: } else {
1617: return debugger.makeSlotManager();
1618: }
1619: }
1620:
1621: /**
1622: * Factory method to get an Optimizer.
1623: * <p>
1624: * This method is intended for internal use only.
1625: */
1626:
1627: public Optimizer getOptimizer() {
1628: if (optimizer == null) {
1629: optimizer = new Optimizer(this );
1630: }
1631: return optimizer;
1632: }
1633:
1634: /**
1635: * Set a ClassLoader to be used when loading external classes. Examples of classes that are
1636: * loaded include SAX parsers, localization modules for formatting numbers and dates,
1637: * extension functions, external object models. In an environment such as Eclipse that uses
1638: * its own ClassLoader, this ClassLoader should be nominated to ensure that any class loaded
1639: * by Saxon is identical to a class of the same name loaded by the external environment.
1640: * <p>
1641: * This method is intended for external use by advanced users, but should be regarded as
1642: * experimental.
1643: */
1644:
1645: public void setClassLoader(ClassLoader loader) {
1646: this .classLoader = loader;
1647: }
1648:
1649: /**
1650: * Get the ClassLoader supplied using the method {@link #setClassLoader}.
1651: * If none has been supplied, return null.
1652: * <p>
1653: * This method is intended for external use by advanced users, but should be regarded as
1654: * experimental.
1655: */
1656:
1657: public ClassLoader getClassLoader() {
1658: return classLoader;
1659: }
1660:
1661: /**
1662: * Load a class using the class name provided.
1663: * Note that the method does not check that the object is of the right class.
1664: * <p>
1665: * This method is intended for internal use only.
1666: *
1667: * @param className A string containing the name of the
1668: * class, for example "com.microstar.sax.LarkDriver"
1669: * @param classLoader The ClassLoader to be used to load the class. If this is null, then
1670: * the classLoader used will be the first one available of: the classLoader registered
1671: * with the Configuration using {@link #setClassLoader}; the context class loader for
1672: * the current thread; or failing that, the class loader invoked implicitly by a call
1673: * of Class.forName() (which is the ClassLoader that was used to load the Configuration
1674: * object itself).
1675: * @return an instance of the class named, or null if it is not
1676: * loadable.
1677: * @throws XPathException if the class cannot be loaded.
1678: *
1679: */
1680:
1681: public Class getClass(String className, boolean tracing,
1682: ClassLoader classLoader) throws XPathException {
1683: if (tracing) {
1684: System.err.println("Loading " + className);
1685: }
1686:
1687: try {
1688: ClassLoader loader = classLoader;
1689: if (loader == null) {
1690: loader = this .classLoader;
1691: }
1692: if (loader == null) {
1693: loader = Thread.currentThread().getContextClassLoader();
1694: }
1695: if (loader != null) {
1696: try {
1697: return loader.loadClass(className);
1698: } catch (Exception ex) {
1699: return Class.forName(className);
1700: }
1701: } else {
1702: return Class.forName(className);
1703: }
1704: } catch (Exception e) {
1705: if (tracing) {
1706: // The exception is often masked, especially when calling extension
1707: // functions
1708: System.err.println("No Java class " + className
1709: + " could be loaded");
1710: }
1711: throw new DynamicError("Failed to load " + className, e);
1712: }
1713:
1714: }
1715:
1716: /**
1717: * Instantiate a class using the class name provided.
1718: * Note that the method does not check that the object is of the right class.
1719: * <p>
1720: * This method is intended for internal use only.
1721: *
1722: * @param className A string containing the name of the
1723: * class, for example "com.microstar.sax.LarkDriver"
1724: * @param classLoader The ClassLoader to be used to load the class. If this is null, then
1725: * the classLoader used will be the first one available of: the classLoader registered
1726: * with the Configuration using {@link #setClassLoader}; the context class loader for
1727: * the current thread; or failing that, the class loader invoked implicitly by a call
1728: * of Class.forName() (which is the ClassLoader that was used to load the Configuration
1729: * object itself).
1730: * @return an instance of the class named, or null if it is not
1731: * loadable.
1732: * @throws XPathException if the class cannot be loaded.
1733: *
1734: */
1735:
1736: public Object getInstance(String className, ClassLoader classLoader)
1737: throws XPathException {
1738: Class theclass = getClass(className, false, classLoader);
1739: try {
1740: return theclass.newInstance();
1741: } catch (Exception err) {
1742: throw new DynamicError("Failed to instantiate class "
1743: + className, err);
1744: }
1745: }
1746:
1747: /**
1748: * Load a named collator class and check it is OK.
1749: * <p>
1750: * This method is intended for internal use only.
1751: */
1752:
1753: public Comparator makeCollator(String className)
1754: throws XPathException {
1755: Object handler = getInstance(className, null);
1756:
1757: if (handler instanceof Comparator) {
1758: return (Comparator) handler;
1759: } else {
1760: throw new DynamicError("Failed to load collation class "
1761: + className
1762: + ": it is not an instance of java.util.Comparator");
1763: }
1764:
1765: }
1766:
1767: /**
1768: * Set lazy construction mode on or off. In lazy construction mode, element constructors
1769: * are not evaluated until the content of the tree is required. Lazy construction mode
1770: * is currently experimental and is therefore off by default.
1771: * @param lazy true to switch lazy construction mode on, false to switch it off.
1772: */
1773:
1774: public void setLazyConstructionMode(boolean lazy) {
1775: lazyConstructionMode = lazy;
1776: }
1777:
1778: /**
1779: * Determine whether lazy construction mode is on or off. In lazy construction mode, element constructors
1780: * are not evaluated until the content of the tree is required. Lazy construction mode
1781: * is currently experimental and is therefore off by default.
1782: * @return true if lazy construction mode is enabled
1783: */
1784:
1785: public boolean isLazyConstructionMode() {
1786: return lazyConstructionMode;
1787: }
1788:
1789: /**
1790: * Register the standard Saxon-supplied object models.
1791: * <p>
1792: * This method is intended for internal use only.
1793: */
1794:
1795: private void registerStandardObjectModels() {
1796: // Try to load the support classes for various object models, registering
1797: // them in the Configuration. We require both the Saxon object model definition
1798: // and an implementation of the object model itself to be loadable before
1799: // the object model is registered.
1800: String[] models = { "net.sf.saxon.dom.DOMEnvelope",
1801: "net.sf.saxon.dom.DOMObjectModel",
1802: "net.sf.saxon.jdom.JDOMObjectModel",
1803: "net.sf.saxon.xom.XOMObjectModel" };
1804: String[] nodes = { "net.sf.saxon.dom.NodeOverNodeInfo",
1805: "org.w3c.dom.Node", "org.jdom.Element", "nu.xom.Node" };
1806:
1807: sharedExternalObjectModels = new ArrayList(4);
1808: for (int i = 0; i < models.length; i++) {
1809: try {
1810: getClass(nodes[i], false, null);
1811: ExternalObjectModel model = (ExternalObjectModel) getInstance(
1812: models[i], null);
1813: sharedExternalObjectModels.add(model);
1814: //registerExternalObjectModel(model);
1815: } catch (XPathException err) {
1816: // ignore the failure. We can't report an exception here, and in any case a failure
1817: // is legitimate if the object model isn't on the class path. We'll fail later when
1818: // we try to process a node in the chosen object model: the node simply won't be
1819: // recognized as one that Saxon can handle
1820: } catch (ClassCastException err) {
1821: // we've loaded the class, but it isn't an ExternalObjectModel. This can apparently
1822: // happen if there's more than one ClassLoader involved. We'll output a simple warning,
1823: // and then continue as if the external object model wasn't on the class path
1824: System.err
1825: .println("Warning: external object model "
1826: + models[i]
1827: + " has been loaded, but is not an instance of net.sf.saxon.om.ExternalObjectModel");
1828:
1829: }
1830: }
1831: }
1832:
1833: /**
1834: * Register an external object model with this Configuration.
1835: * @param model The external object model.
1836: * This can either be one of the system-supplied external
1837: * object models for JDOM, XOM, or DOM, or a user-supplied external object model.
1838: * <p>
1839: * This method is intended for advanced users only, and is subject to change.
1840: */
1841:
1842: public void registerExternalObjectModel(ExternalObjectModel model) {
1843: if (externalObjectModels == null) {
1844: externalObjectModels = new ArrayList(4);
1845: }
1846: if (!externalObjectModels.contains(model)) {
1847: externalObjectModels.add(model);
1848: }
1849: }
1850:
1851: /**
1852: * Find the external object model corresponding to a given node.
1853: * <p>
1854: * This method is intended for internal use only.
1855: *
1856: * @param node a Node as implemented in some external object model
1857: * @return the first registered external object model that recognizes
1858: * this node; or null if no-one will own up to it.
1859: */
1860:
1861: public ExternalObjectModel findExternalObjectModel(Object node) {
1862: if (externalObjectModels == null) {
1863: return null;
1864: }
1865: Iterator it = externalObjectModels.iterator();
1866: while (it.hasNext()) {
1867: final ExternalObjectModel model = (ExternalObjectModel) it
1868: .next();
1869: if (model.isRecognizedNode(node)) {
1870: return model;
1871: }
1872: }
1873: return null;
1874: }
1875:
1876: /**
1877: * Get all the registered external object models.
1878: * <p>
1879: * This method is intended for internal use only.
1880: */
1881:
1882: public List getExternalObjectModels() {
1883: return externalObjectModels;
1884: }
1885:
1886: /**
1887: * Make a PipelineConfiguration from the properties of this Configuration
1888: * @since 8.4
1889: */
1890:
1891: public PipelineConfiguration makePipelineConfiguration() {
1892: PipelineConfiguration pipe = new PipelineConfiguration();
1893: pipe.setConfiguration(this );
1894: pipe.setErrorListener(getErrorListener());
1895: pipe.setURIResolver(getURIResolver());
1896: return pipe;
1897: }
1898:
1899: /**
1900: * Set the implicit timezone, as a positive or negative offset from UTC in minutes.
1901: * The range is -14hours to +14hours
1902: */
1903: public void setImplicitTimezone(int minutes) {
1904: if (minutes < -14 * 60 || minutes > +14 * 60) {
1905: throw new IllegalArgumentException(
1906: "Implicit timezone is out of range: range is "
1907: + (-14 * 60) + " to +" + (+14 * 60)
1908: + " minutes");
1909: }
1910: implicitTimezone = minutes;
1911: }
1912:
1913: /**
1914: * Get the implicit timezone, as a positive or negative offset from UTC in minutes.
1915: * The range is -14hours to +14hours
1916: * @return the value set using {@link #setImplicitTimezone}, or failing that
1917: * the timezone from the system clock at the time the Configuration was created.
1918: */
1919: public int getImplicitTimezone() {
1920: return implicitTimezone;
1921: }
1922:
1923: /**
1924: * Get the configuration, given the context. This is provided as a static method to make it accessible
1925: * as an extension function.
1926: */
1927:
1928: public static Configuration getConfiguration(XPathContext context) {
1929: return context.getConfiguration();
1930: }
1931:
1932: /**
1933: * Supply a SourceResolver
1934: */
1935:
1936: public void setSourceResolver(SourceResolver resolver) {
1937: sourceResolver = resolver;
1938: }
1939:
1940: /**
1941: * Get the current SourceResolver. If none has been supplied, a system-defined SourceResolver
1942: * is returned.
1943: * @return the current SourceResolver
1944: */
1945:
1946: public SourceResolver getSourceResolver() {
1947: return sourceResolver;
1948: }
1949:
1950: /**
1951: * Implement the SourceResolver interface
1952: */
1953:
1954: public Source resolveSource(Source source, Configuration config)
1955: throws XPathException {
1956: if (source instanceof AugmentedSource)
1957: return source;
1958: if (source instanceof StreamSource)
1959: return source;
1960: if (source instanceof SAXSource)
1961: return source;
1962: if (source instanceof DOMSource)
1963: return source;
1964: if (source instanceof NodeInfo)
1965: return source;
1966: if (source instanceof PullProvider)
1967: return source;
1968: return null;
1969: }
1970:
1971: /**
1972: * Get a configuration-defined output method.
1973: * @return a Receiver that implements the method, or null if the method name is not recognized
1974: */
1975:
1976: public Receiver getOutputMethod(String clarkName) {
1977: return null;
1978: }
1979:
1980: /**
1981: * Set a property of the configuration. This method underpins the setAttribute() method of the
1982: * TransformerFactory implementation, and is provided
1983: * to enable setting of Configuration properties using URIs without instantiating a TransformerFactory:
1984: * specifically, this may be useful when running XQuery, and it is also used by the Validator API
1985: * @param name the URI identifying the property to be set
1986: * @param value the value of the property
1987: * @throws IllegalArgumentException if the property name is not recognized
1988: */
1989:
1990: public void setConfigurationProperty(String name, Object value) {
1991: final Configuration config = this ;
1992: if (name.equals(FeatureKeys.TREE_MODEL)) {
1993: if (!(value instanceof Integer)) {
1994: throw new IllegalArgumentException(
1995: "Tree model must be an Integer");
1996: }
1997: config.setTreeModel(((Integer) value).intValue());
1998:
1999: } else if (name.equals(FeatureKeys.ALLOW_EXTERNAL_FUNCTIONS)) {
2000: if (!(value instanceof Boolean)) {
2001: throw new IllegalArgumentException(
2002: "ALLOW_EXTERNAL_FUNCTIONS must be a boolean");
2003: }
2004: config.setAllowExternalFunctions(((Boolean) value)
2005: .booleanValue());
2006:
2007: } else if (name
2008: .equals(FeatureKeys.RECOGNIZE_URI_QUERY_PARAMETERS)) {
2009: if (!(value instanceof Boolean)) {
2010: throw new IllegalArgumentException(
2011: "RECOGNIZE_QUERY_URI_PARAMETERS must be a boolean");
2012: }
2013: config.getSystemURIResolver().setRecognizeQueryParameters(
2014: ((Boolean) value).booleanValue());
2015:
2016: } else if (name.equals(FeatureKeys.TRACE_EXTERNAL_FUNCTIONS)) {
2017: if (!(value instanceof Boolean)) {
2018: throw new IllegalArgumentException(
2019: "TRACE_EXTERNAL_FUNCTIONS must be a boolean");
2020: }
2021: config.setTraceExternalFunctions(((Boolean) value)
2022: .booleanValue());
2023:
2024: } else if (name.equals(FeatureKeys.TIMING)) {
2025: if (!(value instanceof Boolean)) {
2026: throw new IllegalArgumentException(
2027: "TIMING must be a boolean");
2028: }
2029: config.setTiming(((Boolean) value).booleanValue());
2030:
2031: } else if (name.equals(FeatureKeys.DTD_VALIDATION)) {
2032: if (!(value instanceof Boolean)) {
2033: throw new IllegalArgumentException(
2034: "DTD_VALIDATION must be a boolean");
2035: }
2036: config.setValidation(((Boolean) value).booleanValue());
2037:
2038: } else if (name.equals(FeatureKeys.STRIP_WHITESPACE)) {
2039: if (!(value instanceof String)) {
2040: throw new IllegalArgumentException(
2041: "STRIP_WHITESPACE must be a string");
2042: }
2043: int ival;
2044: if (value.equals("all")) {
2045: ival = Whitespace.ALL;
2046: } else if (value.equals("none")) {
2047: ival = Whitespace.NONE;
2048: } else if (value.equals("ignorable")) {
2049: ival = Whitespace.IGNORABLE;
2050: } else {
2051: throw new IllegalArgumentException(
2052: "Unrecognized value STRIP_WHITESPACE = '"
2053: + value
2054: + "': must be 'all', 'none', or 'ignorable'");
2055: }
2056: config.setStripsWhiteSpace(ival);
2057:
2058: } else if (name.equals(FeatureKeys.SCHEMA_VALIDATION)) {
2059: if (!(value instanceof Integer)) {
2060: throw new IllegalArgumentException(
2061: "SCHEMA_VALIDATION must be an integer");
2062: }
2063: config
2064: .setSchemaValidationMode(((Integer) value)
2065: .intValue());
2066:
2067: } else if (name.equals(FeatureKeys.VALIDATION_WARNINGS)) {
2068: if (!(value instanceof Boolean)) {
2069: throw new IllegalArgumentException(
2070: "VALIDATION_WARNINGS must be a boolean");
2071: }
2072: config.setValidationWarnings(((Boolean) value)
2073: .booleanValue());
2074:
2075: } else if (name.equals(FeatureKeys.VERSION_WARNING)) {
2076: if (!(value instanceof Boolean)) {
2077: throw new IllegalArgumentException(
2078: "VERSION_WARNING must be a boolean");
2079: }
2080: config.setVersionWarning(((Boolean) value).booleanValue());
2081:
2082: } else if (name.equals(FeatureKeys.TRACE_LISTENER)) {
2083: if (!(value instanceof TraceListener)) {
2084: throw new IllegalArgumentException(
2085: "TRACE_LISTENER is of wrong class");
2086: }
2087: config.setTraceListener((TraceListener) value);
2088:
2089: } else if (name.equals(FeatureKeys.LINE_NUMBERING)) {
2090: if (!(value instanceof Boolean)) {
2091: throw new IllegalArgumentException(
2092: "LINE_NUMBERING value must be Boolean");
2093: }
2094: config.setLineNumbering(((Boolean) value).booleanValue());
2095:
2096: } else if (name.equals(FeatureKeys.RECOVERY_POLICY)) {
2097: if (!(value instanceof Integer)) {
2098: throw new IllegalArgumentException(
2099: "RECOVERY_POLICY value must be Integer");
2100: }
2101: config.setRecoveryPolicy(((Integer) value).intValue());
2102:
2103: } else if (name.equals(FeatureKeys.MESSAGE_EMITTER_CLASS)) {
2104: if (!(value instanceof String)) {
2105: throw new IllegalArgumentException(
2106: "MESSAGE_EMITTER class must be a String");
2107: }
2108: config.setMessageEmitterClass((String) value);
2109:
2110: } else if (name.equals(FeatureKeys.SOURCE_PARSER_CLASS)) {
2111: if (!(value instanceof String)) {
2112: throw new IllegalArgumentException(
2113: "SOURCE_PARSER class must be a String");
2114: }
2115: config.setSourceParserClass((String) value);
2116:
2117: } else if (name.equals(FeatureKeys.STYLE_PARSER_CLASS)) {
2118: if (!(value instanceof String)) {
2119: throw new IllegalArgumentException(
2120: "STYLE_PARSER class must be a String");
2121: }
2122: config.setStyleParserClass((String) value);
2123:
2124: } else if (name.equals(FeatureKeys.OUTPUT_URI_RESOLVER)) {
2125: if (!(value instanceof OutputURIResolver)) {
2126: throw new IllegalArgumentException(
2127: "OUTPUT_URI_RESOLVER value must be an instance of net.sf.saxon.OutputURIResolver");
2128: }
2129: config.setOutputURIResolver((OutputURIResolver) value);
2130:
2131: } else if (name.equals(FeatureKeys.NAME_POOL)) {
2132: if (!(value instanceof NamePool)) {
2133: throw new IllegalArgumentException(
2134: "NAME_POOL value must be an instance of net.sf.saxon.om.NamePool");
2135: }
2136: config.setNamePool((NamePool) value);
2137:
2138: } else if (name.equals(FeatureKeys.COLLATION_URI_RESOLVER)) {
2139: if (!(value instanceof CollationURIResolver)) {
2140: throw new IllegalArgumentException(
2141: "COLLATION_URI_RESOLVER value must be an instance of net.sf.saxon.sort.CollationURIResolver");
2142: }
2143: config
2144: .setCollationURIResolver((CollationURIResolver) value);
2145:
2146: } else if (name.equals(FeatureKeys.COLLECTION_URI_RESOLVER)) {
2147: if (!(value instanceof CollectionURIResolver)) {
2148: throw new IllegalArgumentException(
2149: "COLLECTION_URI_RESOLVER value must be an instance of net.sf.saxon.CollectionURIResolver");
2150: }
2151: config
2152: .setCollectionURIResolver((CollectionURIResolver) value);
2153:
2154: } else if (name.equals(FeatureKeys.XML_VERSION)) {
2155: if (!(value instanceof String && (value.equals("1.0") || value
2156: .equals("1.1")))) {
2157: throw new IllegalArgumentException(
2158: "XML_VERSION value must be \"1.0\" or \"1.1\" as a String");
2159:
2160: }
2161: config.setXMLVersion((value.equals("1.0") ? XML10 : XML11));
2162:
2163: } else {
2164: throw new IllegalArgumentException("Unknown attribute "
2165: + name);
2166: }
2167: }
2168:
2169: /**
2170: * Get a property of the configuration
2171: * @param name the name of the required property
2172: * @return the value of the property
2173: * @throws IllegalArgumentException thrown if the property is not one that Saxon recognizes.
2174: */
2175:
2176: public Object getConfigurationProperty(String name) {
2177: final Configuration config = this ;
2178: if (name.equals(FeatureKeys.TREE_MODEL)) {
2179: return new Integer(config.getTreeModel());
2180:
2181: } else if (name.equals(FeatureKeys.TIMING)) {
2182: return Boolean.valueOf(config.isTiming());
2183:
2184: } else if (name.equals(FeatureKeys.DTD_VALIDATION)) {
2185: return Boolean.valueOf(config.isValidation());
2186:
2187: } else if (name.equals(FeatureKeys.SCHEMA_VALIDATION)) {
2188: return new Integer(config.getSchemaValidationMode());
2189:
2190: } else if (name.equals(FeatureKeys.VALIDATION_WARNINGS)) {
2191: return Boolean.valueOf(config.isValidationWarnings());
2192:
2193: } else if (name.equals(FeatureKeys.ALLOW_EXTERNAL_FUNCTIONS)) {
2194: return Boolean.valueOf(config.isAllowExternalFunctions());
2195:
2196: } else if (name
2197: .equals(FeatureKeys.RECOGNIZE_URI_QUERY_PARAMETERS)) {
2198: return Boolean.valueOf(config.getSystemURIResolver()
2199: .queryParametersAreRecognized());
2200:
2201: } else if (name.equals(FeatureKeys.TRACE_EXTERNAL_FUNCTIONS)) {
2202: return Boolean.valueOf(config.isTraceExternalFunctions());
2203:
2204: } else if (name.equals(FeatureKeys.VERSION_WARNING)) {
2205: return Boolean.valueOf(config.isVersionWarning());
2206:
2207: } else if (name.equals(FeatureKeys.TRACE_LISTENER)) {
2208: return config.getTraceListener();
2209:
2210: } else if (name.equals(FeatureKeys.LINE_NUMBERING)) {
2211: return Boolean.valueOf(config.isLineNumbering());
2212:
2213: } else if (name.equals(FeatureKeys.RECOVERY_POLICY)) {
2214: return new Integer(config.getRecoveryPolicy());
2215:
2216: } else if (name.equals(FeatureKeys.MESSAGE_EMITTER_CLASS)) {
2217: return config.getMessageEmitterClass();
2218:
2219: } else if (name.equals(FeatureKeys.SOURCE_PARSER_CLASS)) {
2220: return config.getSourceParserClass();
2221:
2222: } else if (name.equals(FeatureKeys.STYLE_PARSER_CLASS)) {
2223: return config.getStyleParserClass();
2224:
2225: } else if (name.equals(FeatureKeys.OUTPUT_URI_RESOLVER)) {
2226: return config.getOutputURIResolver();
2227:
2228: } else if (name.equals(FeatureKeys.NAME_POOL)) {
2229: return config.getNamePool();
2230:
2231: } else if (name.equals(FeatureKeys.COLLATION_URI_RESOLVER)) {
2232: return config.getCollationURIResolver();
2233:
2234: } else if (name.equals(FeatureKeys.COLLECTION_URI_RESOLVER)) {
2235: return config.getCollectionURIResolver();
2236:
2237: } else {
2238: throw new IllegalArgumentException("Unknown attribute "
2239: + name);
2240: }
2241: }
2242: }
2243:
2244: //
2245: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
2246: // you may not use this file except in compliance with the License. You may obtain a copy of the
2247: // License at http://www.mozilla.org/MPL/
2248: //
2249: // Software distributed under the License is distributed on an "AS IS" basis,
2250: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
2251: // See the License for the specific language governing rights and limitations under the License.
2252: //
2253: // The Original Code is: all this file.
2254: //
2255: // The Initial Developer of the Original Code is Michael H. Kay.
2256: //
2257: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
2258: //
2259: // Contributor(s): none.
2260: //
|