Package client.net.sf.saxon.ce

Source Code of client.net.sf.saxon.ce.Configuration

package client.net.sf.saxon.ce;

import client.net.sf.saxon.ce.dom.HTMLDocumentWrapper;
import client.net.sf.saxon.ce.dom.HTMLDocumentWrapper.DocType;
import client.net.sf.saxon.ce.dom.XMLDOM;
import client.net.sf.saxon.ce.event.PipelineConfiguration;
import client.net.sf.saxon.ce.expr.EarlyEvaluationContext;
import client.net.sf.saxon.ce.expr.Optimizer;
import client.net.sf.saxon.ce.expr.XPathContext;
import client.net.sf.saxon.ce.expr.number.Numberer_en;
import client.net.sf.saxon.ce.expr.sort.CaseInsensitiveCollator;
import client.net.sf.saxon.ce.expr.sort.CodepointCollator;
import client.net.sf.saxon.ce.lib.*;
import client.net.sf.saxon.ce.om.DocumentInfo;
import client.net.sf.saxon.ce.om.DocumentPool;
import client.net.sf.saxon.ce.om.NamePool;
import client.net.sf.saxon.ce.om.StructuredQName;
import client.net.sf.saxon.ce.trans.CompilerInfo;
import client.net.sf.saxon.ce.trans.XPathException;
import client.net.sf.saxon.ce.tree.util.DocumentNumberAllocator;
import client.net.sf.saxon.ce.tree.util.URI;
import client.net.sf.saxon.ce.type.BuiltInType;
import client.net.sf.saxon.ce.type.SchemaType;
import client.net.sf.saxon.ce.type.TypeHierarchy;
import client.net.sf.saxon.ce.value.Whitespace;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Node;
import com.google.gwt.user.client.Window;

import java.util.logging.Logger;
//import com.google.gwt.xml.client.Document;
//import com.google.gwt.xml.client.XMLParser;
//import com.google.gwt.xml.client.impl.*;


/**
* This class holds details of user-selected configuration options for a set of transformations
* and/or queries. When running XSLT, the preferred way of setting configuration options is via
* the JAXP TransformerFactory interface, but the Configuration object provides a finer
* level of control. As yet there is no standard API for XQuery, so the only way of setting
* Configuration information is to use the methods on this class directly.
* <p/>
* <p>As well as holding configuration settings, this class acts as a factory for classes
* providing service in particular areas: error handling, URI resolution, and the like. Some
* of these services are chosen on the basis of the current platform (Java or .NET), some vary
* depending whether the environment is schema-aware or not.</p>
* <p/>
* <p>The <code>Configuration</code> provides access to a {@link NamePool} which is used to manage
* all the names used in stylesheets, queries, schemas, and source and documents: the NamePool
* allocates integer codes to these names allowing efficient storage and comparison. Normally
* there will be a one-to-one relationship between a <code>NamePool</code> and a <code>Configuration</code>.
* It is possible, however, for several <code>Configuration</code> objects to share the same
* <code>NamePool</code>. Until Saxon 8.9, by default all <code>Configuration</code> objects
* shared a single <code>NamePool</code> unless configured otherwise; this changed in 8.9 so that
* the default is to allocate a new <code>NamePool</code> for each <code>Configuration</code>.</p>
* <p/>
* <p>The <code>Configuration</code> establishes the scope within which node identity is managed.
* Every document belongs to a <code>Configuration</code>, and every node has a distinct identity
* within that <code>Configuration</code>. In consequence, it is not possible for any query or
* transformation to manipulate multiple documents unless they all belong to the same
* <code>Configuration</code>.</p>
* <p/>
* <p>Since Saxon 8.4, the JavaDoc documentation for Saxon attempts to identify interfaces
* that are considered stable, and will only be changed in a backwards-incompatible way
* if there is an overriding reason to do so. These interfaces and methods are labelled
* with the JavaDoc "since" tag. The value 8.n indicates a method in this category that
* was introduced in Saxon version 8.n: or in the case of 8.4, that was present in Saxon 8.4
* and possibly in earlier releases. (In some cases, these methods have been unchanged for
* a long time.) Methods without a "since" tag, although public, are provided for internal
* use or for use by advanced users, and are subject to change from one release to the next.
* The presence of a "since" tag on a class or interface indicates that there are one or more
* methods in the class that are considered stable; it does not mean that all methods are
* stable.
*
* @since 8.4
*/


public class Configuration {

    private ErrorListener errorListener = new StandardErrorListener();

    private boolean timing = false;
    private boolean allowExternalFunctions = true;
    private boolean useTypedValueCache = true;
    private boolean useDisableOutputEscaping = false;
    private NamePool namePool = new NamePool();
    private DocumentNumberAllocator documentNumberAllocator = new DocumentNumberAllocator();
    private DocumentPool globalDocumentPool = new DocumentPool();
    private transient XPathContext conversionContext = null;
    private transient TypeHierarchy typeHierarchy;

    private ParseOptions defaultParseOptions = new ParseOptions();
    protected Optimizer optimizer = null;
    protected int optimizationLevel = Optimizer.FULL_OPTIMIZATION;

    private CompilerInfo defaultXsltCompilerInfo = new CompilerInfo();
    private DocumentPool sourceDocumentPool = new DocumentPool();
    private Logger logger = Logger.getLogger("Configuration");



    /**
     * Constant indicating that the processor should take the recovery action
     * when a recoverable error occurs, with no warning message.
     */
    public static final int RECOVER_SILENTLY = 0;
    /**
     * Constant indicating that the processor should produce a warning
     * when a recoverable error occurs, and should then take the recovery
     * action and continue.
     */
    public static final int RECOVER_WITH_WARNINGS = 1;
    /**
     * Constant indicating that when a recoverable error occurs, the
     * processor should not attempt to take the defined recovery action,
     * but should terminate with an error.
     */
    public static final int DO_NOT_RECOVER = 2;

    /**
     * Constant indicating the XML Version 1.0
     */

    public static final int XML10 = 10;

    /**
     * Constant indicating the XML Version 1.1
     */

    public static final int XML11 = 11;

    /**
     * Constant indicating that the host language is XSLT
     */
    public static final int XSLT = 50;

    /**
     * Constant indicating that the host language is XPATH itself - that is, a free-standing XPath environment
     */
    public static final int XPATH = 54;

    /**
     * Create a non-schema-aware configuration object with default settings for all options.
     *
     * @since 8.4
     */
   
    public Configuration() {
    }

     /**
     * Get the edition code identifying this configuration: "CE" for "client edition"
     */

    public static String getEditionCode() {
        return "CE";
    }
   
    public DocumentInfo getHostPage(){
      // attempt to initialise this only once - in the Configuration constructor led
      // to NamePool exception
        Document page = Document.get();
        return new HTMLDocumentWrapper(page, page.getURL(), this, DocType.UNKNOWN);
    }

    /**
     * Get an XPathContext object with sufficient capability to perform comparisons and conversions
     *
     * @return a dynamic context for performing conversions
     */

    public XPathContext getConversionContext() {
        if (conversionContext == null) {
            conversionContext = new EarlyEvaluationContext(this);
        }
        return conversionContext;
    }
   
    public static URI getLocation() {
      URI location = null;
      try {
        location = new URI(Window.Location.getHref());
      } catch(Exception err) {}
      return location;
    }

    /**
     * Get the collation with a given collation name. If the collation name has
     * not been registered in this CollationMap, the CollationURIResolver registered
     * with the Configuration is called. If this cannot resolve the collation name,
     * it should return null.
     * @param name the collation name (should be an absolute URI)
     * @return the StringCollator with this name if known, or null if not known
     */

    public StringCollator getNamedCollation(String name) {
        if (name.equals(NamespaceConstant.CODEPOINT_COLLATION_URI)) {
            return CodepointCollator.getInstance();
        } else if (name.equals(NamespaceConstant.CASE_INSENSITIVE_COLLATION_URI)) {
            return CaseInsensitiveCollator.getInstance();
        } else {
            return null;
        }
    }

    /**
     * Load a Numberer class for a given language and check it is OK.
     * This method is provided primarily for internal use.
     * @param language the language for which a Numberer is required. May be null,
     * indicating default language
     * @param country the country for which a Numberer is required. May be null,
     * indicating default country
     * @return a suitable numberer. If no specific numberer is available
     * for the language, the default numberer (normally English) is used.
     */

    public Numberer makeNumberer(String language, String country) {
        return new Numberer_en();
    }



   /**
     * Get the default options for XSLT compilation
     * @return the default options for XSLT compilation. The CompilerInfo object will reflect any options
     * set using other methods available for this Configuration object
     */

    public CompilerInfo getDefaultXsltCompilerInfo() {
        return defaultXsltCompilerInfo;
    }

    /**
     * Determine how recoverable run-time errors are to be handled. This applies
     * only if the standard ErrorListener is used.
     *
     * @return the current recovery policy. The options are {@link #RECOVER_SILENTLY},
     *         {@link #RECOVER_WITH_WARNINGS}, or {@link #DO_NOT_RECOVER}.
     * @since 8.4
     */

    public int getRecoveryPolicy() {
        return defaultXsltCompilerInfo.getRecoveryPolicy();
    }

    public ErrorListener getErrorListener() {
        return errorListener;
    }

    public void setErrorListener(ErrorListener listener) {
        this.errorListener = listener;
    }

    /**
     * Determine how recoverable run-time errors are to be handled. This applies
     * only if the standard ErrorListener is used. The recovery policy applies to
     * errors classified in the XSLT 2.0 specification as recoverable dynamic errors,
     * but only in those cases where Saxon provides a choice over how the error is handled:
     * in some cases, Saxon makes the decision itself.
     *
     * @param recoveryPolicy the recovery policy to be used. The options are {@link #RECOVER_SILENTLY},
     *                       {@link #RECOVER_WITH_WARNINGS}, or {@link #DO_NOT_RECOVER}.
     * @since 8.4
     */

    public void setRecoveryPolicy(int recoveryPolicy) {
        defaultXsltCompilerInfo.setRecoveryPolicy(recoveryPolicy);
    }

    /**
     * Determine whether brief progress messages and timing information will be output
     * to System.err.
     * <p/>
     * This method is provided largely for internal use. Progress messages are normally
     * controlled directly from the command line interfaces, and are not normally used when
     * driving Saxon from the Java API.
     *
     * @return true if these messages are to be output.
     */

    public boolean isTiming() {
        return timing;
    }

    /**
     * Determine whether brief progress messages and timing information will be output
     * to System.err.
     * <p/>
     * This method is provided largely for internal use. Progress messages are normally
     * controlled directly from the command line interfaces, and are not normally used when
     *
     * @param timing true if these messages are to be output.
     */

    public void setTiming(boolean timing) {
        this.timing = timing;
    }

    /**
     * Determine whether a warning is to be output when running against a stylesheet labelled
     * as version="1.0". The XSLT specification requires such a warning unless the user disables it.
     *
     * @return true if these messages are to be output.
     * @since 8.4
     */

    public boolean isVersionWarning() {
        return defaultXsltCompilerInfo.isVersionWarning();
    }

    /**
     * Determine whether a warning is to be output when the version attribute of the stylesheet does
     * not match the XSLT processor version. (In the case where the stylesheet version is "1.0",
     * the XSLT specification requires such a warning unless the user disables it.)
     *
     * @param warn true if these warning messages are to be output.
     * @since 8.4
     */

    public void setVersionWarning(boolean warn) {
        defaultXsltCompilerInfo.setVersionWarning(warn);
    }

    /**
     * Determine whether calls to external Java functions are permitted.
     *
     * @return true if such calls are permitted.
     * @since 8.4
     */

    public boolean isAllowExternalFunctions() {
        return allowExternalFunctions;
    }

    /**
     * Determine whether calls to external Java functions are permitted. Allowing
     * external function calls is potentially a security risk if the stylesheet or
     * Query is untrusted, as it allows arbitrary Java methods to be invoked, which can
     * examine or modify the contents of filestore and other resources on the machine
     * where the query/stylesheet is executed.
     * <p/>
     * <p>Setting the value to false disallows all of the following:</p>
     * <p/>
     * <ul>
     * <li>Calls to Java extension functions</li>
     * <li>Use of the XSLT system-property() function to access Java system properties</li>
     * <li>Use of a relative URI in the <code>xsl:result-document</code> instruction</li>
     * <li>Calls to XSLT extension instructions</li>
     * </ul>
     * <p/>
     * <p>Note that this option does not disable use of the <code>doc()</code> function or similar
     * functions to access the filestore of the machine where the transformation or query is running.
     * That should be done using a user-supplied <code>URIResolver</code></p>
     *
     * @param allowExternalFunctions true if external function calls are to be
     *                               permitted.
     * @since 8.4
     */

    public void setAllowExternalFunctions(boolean allowExternalFunctions) {
        this.allowExternalFunctions = allowExternalFunctions;
    }


    /**
     * Determine whether the XML parser for source documents will be asked to perform
     * validation of source documents
     *
     * @return true if DTD validation is requested.
     * @since 8.4
     */

    public boolean isValidation() {
        return defaultParseOptions.getDTDValidationMode() == Validation.STRICT ||
                defaultParseOptions.getDTDValidationMode() == Validation.LAX;
    }

    /**
     * Get the document pool. This is used only for source documents, not for stylesheet modules.
     * <p>
     * This method is intended for internal use only.
     *
     * @return the source document pool
     */

    public DocumentPool getDocumentPool() {
        return sourceDocumentPool;
    }


    /**
     * Determine whether the XML parser for source documents will be asked to perform
     * DTD validation of source documents
     *
     * @param validation true if DTD validation is to be requested.
     * @since 8.4
     */

    public void setValidation(boolean validation) {
        defaultParseOptions.setDTDValidationMode(validation ? Validation.STRICT : Validation.STRIP);
    }

    /**
     * Get the target namepool to be used for stylesheets/queries and for source documents.
     *
     * @return the target name pool. If no NamePool has been specified explicitly, the
     *         default NamePool is returned.
     * @since 8.4
     */

    public NamePool getNamePool() {
        return namePool;
    }

    /**
     * Set the NamePool to be used for stylesheets/queries and for source documents.
     * <p/>
     * <p> Using this method allows several Configurations to share the same NamePool. This
     * was the normal default arrangement until Saxon 8.9, which changed the default so
     * that each Configuration uses its own NamePool.</p>
     * <p/>
     * <p>Sharing a NamePool creates a potential bottleneck, since changes to the namepool are
     * synchronized.</p>
     *
     * @param targetNamePool The NamePool to be used.
     * @since 8.4
     */

    public void setNamePool(NamePool targetNamePool) {
        namePool = targetNamePool;
    }

    /**
     * Get the TypeHierarchy: a cache holding type information
     *
     * @return the type hierarchy cache
     */

    public final TypeHierarchy getTypeHierarchy() {
        if (typeHierarchy == null) {
            typeHierarchy = new TypeHierarchy(this);
        }
        return typeHierarchy;
    }

    /**
     * Get the document number allocator.
     * <p/>
     * The document number allocator is used to allocate a unique number to each document built under this
     * configuration. The document number forms the basis of all tests for node identity; it is therefore essential
     * that when two documents are accessed in the same XPath expression, they have distinct document numbers.
     * Normally this is ensured by building them under the same Configuration. Using this method together with
     * {@link #setDocumentNumberAllocator}, however, it is possible to have two different Configurations that share
     * a single DocumentNumberAllocator
     *
     * @return the current DocumentNumberAllocator
     * @since 9.0
     */

    public DocumentNumberAllocator getDocumentNumberAllocator() {
        return documentNumberAllocator;
    }

    /**
     * Set the document number allocator.
     * <p/>
     * The document number allocator is used to allocate a unique number to each document built under this
     * configuration. The document number forms the basis of all tests for node identity; it is therefore essential
     * that when two documents are accessed in the same XPath expression, they have distinct document numbers.
     * Normally this is ensured by building them under the same Configuration. Using this method together with
     * {@link #getDocumentNumberAllocator}, however, it is possible to have two different Configurations that share
     * a single DocumentNumberAllocator</p>
     * <p>This method is for advanced applications only. Misuse of the method can cause problems with node identity.
     * The method should not be used except while initializing a Configuration, and it should be used only to
     * arrange for two different configurations to share the same DocumentNumberAllocators. In this case they
     * should also share the same NamePool.
     *
     * @param allocator the DocumentNumberAllocator to be used
     * @since 9.0
     */

    public void setDocumentNumberAllocator(DocumentNumberAllocator allocator) {
        documentNumberAllocator = allocator;
    }

    /**
     * Determine whether two Configurations are compatible. When queries, transformations, and path expressions
     * are run, all the Configurations used to build the documents and to compile the queries and stylesheets
     * must be compatible. Two Configurations are compatible if they share the same NamePool and the same
     * DocumentNumberAllocator.
     *
     * @param other the other Configuration to be compared with this one
     * @return true if the two configurations are compatible
     */

    public boolean isCompatible(Configuration other) {
        return namePool == other.namePool && documentNumberAllocator == other.documentNumberAllocator;
    }

    /**
     * Get the global document pool. This is used for documents preloaded during query or stylesheet
     * compilation. The user application can preload documents into the global pool, where they will be found
     * if any query or stylesheet requests the specified document using the doc() or document() function.
     *
     * @return the global document pool
     * @since 9.1
     */

    public DocumentPool getGlobalDocumentPool() {
        return globalDocumentPool;
    }

    /**
     * Set which kinds of whitespace-only text node should be stripped.
     *
     * @param kind the kind of whitespace-only text node that should be stripped when building
     *             a source tree. One of {@link Whitespace#NONE} (none), {@link Whitespace#ALL} (all),
     *             or {@link Whitespace#IGNORABLE} (element-content whitespace as defined in a DTD or schema)
     */

    public void setStripsWhiteSpace(int kind) {
        defaultParseOptions.setStripSpace(kind);
    }

    /**
     * Set which kinds of whitespace-only text node should be stripped.
     *
     * @return kind the kind of whitespace-only text node that should be stripped when building
     *         a source tree. One of {@link client.net.sf.saxon.ce.value.Whitespace#NONE} (none), {@link Whitespace#ALL} (all),
     *         or {@link Whitespace#IGNORABLE} (element-content whitespace as defined in a DTD or schema)
     */

    public int getStripsWhiteSpace() {
        return defaultParseOptions.getStripSpace();
    }


     /**
     * Get the top-level schema type definition with a given fingerprint.
     * <p/>
     * This method is intended for internal use and for use by advanced
     * applications. (The SchemaType object returned cannot yet be considered
     * a stable API, and may be superseded when a JAXP API for schema information
     * is defined.)
     *
     * @param fingerprint the fingerprint of the schema type
     * @return the schema type , or null if there is none
     *         with this name.
     */

    public SchemaType getSchemaType(int fingerprint) {
        if (fingerprint < 1023) {
            return BuiltInType.getSchemaType(fingerprint);
        }
        return null;
    }

    /**
     * Factory method to get an Optimizer.
     * <p/>
     * This method is intended for internal use only.
     *
     * @return the optimizer used in this configuration
     */

    public Optimizer getOptimizer() {
        if (optimizer == null) {
            optimizer = new Optimizer(this);
            optimizer.setOptimizationLevel(optimizationLevel);
        }
        return optimizer;
    }


    /**
     * Make a PipelineConfiguration from the properties of this Configuration
     *
     * @return a new PipelineConfiguration
     * @since 8.4
     */

    public PipelineConfiguration makePipelineConfiguration() {
        PipelineConfiguration pipe = new PipelineConfiguration();
        pipe.setConfiguration(this);
        return pipe;
    }

    /**
     * Issue a warning
     */

    public void issueWarning(String message) {
        logger.warning(message);
    }
   
    /**
     * Build a document, using specified options for parsing and building.
     * @param url the URL of the document to be fetched and parsed.
     * @throws XPathException if the URL cannot be dereferenced or if parsing fails
     */
    public DocumentInfo buildDocument(final String url) throws XPathException {
        if (url.equals("html:document")) {
            // special case this URI
          return getHostPage();
        }
       
        String xml;
        try {
            xml = XMLDOM.makeHTTPRequest(url);
        } catch (Exception err) {
            throw new XPathException("HTTPRequest error: " + err.getMessage());
        }
        Document jsDoc;
        try {
          jsDoc = (Document)XMLDOM.parseXML(xml);
          if (jsDoc.getDocumentElement() == null) {
            throw new XPathException("null returned for " + url);
          }
        } catch (Exception ec) {
          throw new XPathException("XML parser error: " + ec.getMessage());
        }
        return new HTMLDocumentWrapper(jsDoc, url, Configuration.this, DocType.NONHTML);
    }
   
  
    public DocumentInfo wrapHTMLDocument(com.google.gwt.dom.client.Document doc, String uri) {
      return new HTMLDocumentWrapper(doc, uri, Configuration.this, DocType.UNKNOWN);
    }
   
    public DocumentInfo wrapXMLDocument(Node doc, String uri) {
      return new HTMLDocumentWrapper(doc, uri, Configuration.this, DocType.NONHTML);
    }
   
    private static int ieVersion = 0;
   
    /**
     * Returns -1 if host is not IE or the version number when IE is found
     */
    public static int getIeVersion(){
      if (ieVersion == 0){
        ieVersion = getNativeIEVersion();
      }
      return ieVersion;   
    }
   
    public static native int getNativeIEVersion() /*-{
      var rv = -1;
      if (navigator.appName == 'Microsoft Internet Explorer')
      {       
          var ua = navigator.userAgent;
          var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
          if (re.exec(ua) != null)
             rv = parseFloat( RegExp.$1 );
      }
      return rv;
    }-*/;
 
    /**
     * Set a property of the configuration. This method underpins the setAttribute() method of the
     * TransformerFactory implementation, and is provided
     * to enable setting of Configuration properties using URIs without instantiating a TransformerFactory:
     * specifically, this may be useful when running XQuery, and it is also used by the Validator API
     *
     * @param name  the URI identifying the property to be set. See the class {@link FeatureKeys} for
     *              constants representing the property names that can be set.
     * @param value the value of the property
     * @throws IllegalArgumentException if the property name is not recognized or if the value is not
     * a valid value for the named property
     */

    public void setConfigurationProperty(String name, Object value) {

        if (name.equals(FeatureKeys.ALLOW_EXTERNAL_FUNCTIONS)) {
            boolean b = requireBoolean(name, value);
            setAllowExternalFunctions(b);

        } else if (name.equals(FeatureKeys.DTD_VALIDATION)) {
            boolean b = requireBoolean(name, value);
            setValidation(b);

        } else if (name.equals(FeatureKeys.DTD_VALIDATION_RECOVERABLE)) {
            boolean b = requireBoolean(name, value);
            if (b) {
                defaultParseOptions.setDTDValidationMode(Validation.LAX);
            } else {
                defaultParseOptions.setDTDValidationMode(isValidation() ? Validation.STRICT : Validation.SKIP);
            }

        } else if (name.equals(FeatureKeys.NAME_POOL)) {
            if (!(value instanceof NamePool)) {
                throw new IllegalArgumentException("NAME_POOL value must be an instance of client.net.sf.saxon.ce.om.NamePool");
            }
            setNamePool((NamePool)value);

        } else if (name.equals(FeatureKeys.OPTIMIZATION_LEVEL)) {
            String s = requireString(name, value);
            try {
                optimizationLevel = Integer.parseInt(s);
                if (optimizationLevel < Optimizer.NO_OPTIMIZATION || optimizationLevel > Optimizer.FULL_OPTIMIZATION) {
                    throw new IllegalArgumentException("OPTIMIZATION_LEVEL must be in the range " +
                            Optimizer.NO_OPTIMIZATION + " to " + Optimizer.FULL_OPTIMIZATION);
                }
                if (optimizer != null) {
                    optimizer.setOptimizationLevel(optimizationLevel);
                }
            } catch (NumberFormatException e) {
                throw new IllegalArgumentException("OPTIMIZATION_LEVEL value must be a number represented as a string");
            }

        } else if (name.equals(FeatureKeys.RECOVERY_POLICY)) {
            if (!(value instanceof Integer)) {
                throw new IllegalArgumentException("RECOVERY_POLICY value must be an Integer");
            }
            setRecoveryPolicy(((Integer)value).intValue());

        } else if (name.equals(FeatureKeys.RECOVERY_POLICY_NAME)) {
            if (!(value instanceof String)) {
                throw new IllegalArgumentException("RECOVERY_POLICY_NAME value must be a String");
            }
            int rval;
            if (value.equals("recoverSilently")) {
                rval = RECOVER_SILENTLY;
            } else if (value.equals("recoverWithWarnings")) {
                rval = RECOVER_WITH_WARNINGS;
            } else if (value.equals("doNotRecover")) {
                rval = DO_NOT_RECOVER;
            } else {
                throw new IllegalArgumentException(
                        "Unrecognized value of RECOVERY_POLICY_NAME = '" + value +
                                "': must be 'recoverSilently', 'recoverWithWarnings', or 'doNotRecover'");
            }
            setRecoveryPolicy(rval);

        } else if (name.equals(FeatureKeys.STRIP_WHITESPACE)) {
            String s = requireString(name, value);
            int ival;
            if (s.equals("all")) {
                ival = Whitespace.ALL;
            } else if (s.equals("none")) {
                ival = Whitespace.NONE;
            } else if (s.equals("ignorable")) {
                ival = Whitespace.IGNORABLE;
            } else {
                throw new IllegalArgumentException(
                        "Unrecognized value STRIP_WHITESPACE = '" + value +
                                "': must be 'all', 'none', or 'ignorable'");
            }
            setStripsWhiteSpace(ival);


        } else if (name.equals(FeatureKeys.TIMING)) {
            setTiming(requireBoolean(name, value));

        } else if (name.equals(FeatureKeys.USE_PI_DISABLE_OUTPUT_ESCAPING)) {
            useDisableOutputEscaping = requireBoolean(name, value);

        } else if (name.equals(FeatureKeys.USE_TYPED_VALUE_CACHE)) {
            useTypedValueCache = requireBoolean(name, value);

        } else if (name.equals(FeatureKeys.VERSION_WARNING)) {
            setVersionWarning(requireBoolean(name, value));

        } else if (name.equals(FeatureKeys.XSLT_INITIAL_MODE)) {
            String s = requireString(name, value);
            getDefaultXsltCompilerInfo().setDefaultInitialMode(StructuredQName.fromClarkName(s));

        } else if (name.equals(FeatureKeys.XSLT_INITIAL_TEMPLATE)) {
            String s = requireString(name, value);
            getDefaultXsltCompilerInfo().setDefaultInitialTemplate(StructuredQName.fromClarkName(s));

        } else {
            new IllegalArgumentException("Unknown configuration option " + name).printStackTrace();
            throw new IllegalArgumentException("Unknown configuration option " + name);
        }
    }

    /**
     * Validate a property value where the required type is boolean
     * @param propertyName the name of the property
     * @param value the supplied value of the property. This may be either a java.lang.Boolean, or a string
     * taking one of the values on|off, true|false, yes|no, or 1|0 (suited to the conventions of different
     * configuration APIs that end up calling this method)
     * @return the value as a boolean
     * @throws IllegalArgumentException if the supplied value cannot be validated as a recognized boolean value
     */

    protected boolean requireBoolean(String propertyName, Object value) {
        if (value instanceof Boolean) {
            return ((Boolean)value).booleanValue();
        } else if (value instanceof String) {
            if ("true".equals(value) || "on".equals(value) || "yes".equals(value) || "1".equals(value)) {
                return true;
            } else if ("false".equals(value) || "off".equals(value) || "no".equals(value) || "0".equals(value)) {
                return false;
            } else {
                throw new IllegalArgumentException(propertyName + " must be 'true' or 'false' (or on|off, yes|no, 1|0)");
            }
        } else {
            throw new IllegalArgumentException(propertyName + " must be a boolean (or a string representing a boolean)");
        }
    }

    protected String requireString(String propertyName, Object value) {
        if (value instanceof String) {
            return ((String)value);
        } else {
            throw new IllegalArgumentException("The value of " + propertyName + " must be a string");
        }
    }

    /**
     * Get a property of the configuration
     *
     * @param name the name of the required property. See the class {@link FeatureKeys} for
     *             constants representing the property names that can be requested.
     * @return the value of the property
     * @throws IllegalArgumentException thrown if the property is not one that Saxon recognizes.
     */

    public Object getConfigurationProperty(String name) {
        if (name.equals(FeatureKeys.ALLOW_EXTERNAL_FUNCTIONS)) {
            return Boolean.valueOf(isAllowExternalFunctions());

        } else if (name.equals(FeatureKeys.DTD_VALIDATION)) {
            return Boolean.valueOf(isValidation());

        } else if (name.equals(FeatureKeys.DTD_VALIDATION_RECOVERABLE)) {
            return Boolean.valueOf(defaultParseOptions.getDTDValidationMode() == Validation.LAX);

        } else if (name.equals(FeatureKeys.NAME_POOL)) {
            return getNamePool();

        } else if (name.equals(FeatureKeys.OPTIMIZATION_LEVEL)) {
            return "" + optimizationLevel;

        } else if (name.equals(FeatureKeys.RECOVERY_POLICY)) {
            return Integer.valueOf(getRecoveryPolicy());

        } else if (name.equals(FeatureKeys.RECOVERY_POLICY_NAME)) {
            switch (getRecoveryPolicy()) {
                case RECOVER_SILENTLY: return "recoverSilently";
                case RECOVER_WITH_WARNINGS: return "recoverWithWarnings";
                case DO_NOT_RECOVER: return "doNotRecover";
                default: return null;
            }

        } else if (name.equals(FeatureKeys.STRIP_WHITESPACE)) {
            int s = getStripsWhiteSpace();
            if (s == Whitespace.ALL) {
                return "all";
            } else if (s == Whitespace.IGNORABLE) {
                return "ignorable";
            } else {
                return "none";
            }

        } else if (name.equals(FeatureKeys.TIMING)) {
            return Boolean.valueOf(isTiming());

        } else if (name.equals(FeatureKeys.USE_PI_DISABLE_OUTPUT_ESCAPING)) {
            return Boolean.valueOf(useDisableOutputEscaping);
           
        } else if (name.equals(FeatureKeys.USE_TYPED_VALUE_CACHE)) {
            return Boolean.valueOf(useTypedValueCache);

        } else if (name.equals(FeatureKeys.VERSION_WARNING)) {
            return Boolean.valueOf(isVersionWarning());

        } else if (name.equals(FeatureKeys.XSLT_INITIAL_MODE)) {
            return getDefaultXsltCompilerInfo().getDefaultInitialMode().getClarkName();

        } else if (name.equals(FeatureKeys.XSLT_INITIAL_TEMPLATE)) {
            return getDefaultXsltCompilerInfo().getDefaultInitialTemplate().getClarkName();

        } else if (name.equals(FeatureKeys.XSLT_STATIC_ERROR_LISTENER_CLASS)) {
            return getDefaultXsltCompilerInfo().getErrorListener().getClass().getName();

        } else {
            throw new IllegalArgumentException("Unknown attribute " + name);
        }
    }

}

// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.

// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.
TOP

Related Classes of client.net.sf.saxon.ce.Configuration

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.