All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.saxon.query.StaticQueryContext Maven / Gradle / Ivy

There is a newer version: 12.5
Show newest version
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2015 Saxonica Limited.
// 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.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

package net.sf.saxon.query;

import net.sf.saxon.Configuration;
import net.sf.saxon.expr.Literal;
import net.sf.saxon.expr.instruct.Executable;
import net.sf.saxon.expr.instruct.GlobalParam;
import net.sf.saxon.expr.instruct.GlobalVariable;
import net.sf.saxon.expr.parser.CodeInjector;
import net.sf.saxon.expr.parser.Location;
import net.sf.saxon.expr.sort.SimpleCollation;
import net.sf.saxon.functions.FunctionLibrary;
import net.sf.saxon.lib.*;
import net.sf.saxon.om.*;
import net.sf.saxon.trace.TraceCodeInjector;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.type.AnyItemType;
import net.sf.saxon.type.ItemType;
import net.sf.saxon.value.SequenceType;

import javax.xml.transform.ErrorListener;
import javax.xml.transform.Source;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.*;

/**
 * StaticQueryContext contains information used to build a StaticContext for use when processing XQuery
 * expressions.
 * 

*

Despite its name, StaticQueryContext no longer implements the StaticContext * interface, which means it cannot be used directly by Saxon when parsing a query. Instead it is first copied * to create a QueryModule object, which does implement the StaticContext interface. *

*

The application constructs a StaticQueryContext * and initializes it with information about the context, for example, default namespaces, base URI, and so on. * When a query is compiled using this StaticQueryContext, the query parser makes a copy of the StaticQueryContext * and uses this internally, modifying it with information obtained from the query prolog, as well as information * such as namespace and variable declarations that can occur at any point in the query. The query parser does * not modify the original StaticQueryContext supplied by the calling application, which may therefore be used * for compiling multiple queries, serially or even in multiple threads.

*

*

This class forms part of Saxon's published XQuery API. Methods that * are considered stable are labelled with the JavaDoc "since" tag. * The value 8.4 indicates a method introduced at or before Saxon 8.4; other * values indicate the version at which the method was introduced.

*

*

In the longer term, this entire API may at some stage be superseded by a proposed * standard Java API for XQuery.

* * @since 8.4 */ public class StaticQueryContext { private Configuration config; private NamePool namePool; private String baseURI; private HashMap userDeclaredNamespaces; /*@Nullable*/ private Set userDeclaredVariables; private boolean inheritNamespaces = true; private boolean preserveNamespaces = true; private int constructionMode = Validation.PRESERVE; /*@Nullable*/ private NamespaceResolver externalNamespaceResolver = null; private String defaultFunctionNamespace; /*@Nullable*/ private String defaultElementNamespace = NamespaceConstant.NULL; private ItemType requiredContextItemType = AnyItemType.getInstance(); private boolean preserveSpace = false; private boolean defaultEmptyLeast = true; /*@Nullable*/ private ModuleURIResolver moduleURIResolver; private UnfailingErrorListener errorListener; /*@Nullable*/ private CodeInjector codeInjector; private boolean isUpdating = false; private int languageVersion = 30; private String defaultCollationName; private Location moduleLocation; /** * Private constructor used when copying a context */ protected StaticQueryContext() { } /** * Create a StaticQueryContext using a given Configuration. This creates a StaticQueryContext for a main module * (that is, a module that is not a library module). * * @param config the Saxon Configuration * @since 8.4 * @deprecated since 9.2. Use config.newStaticQueryContext(). This will create a StaticQueryContext with * capabilities appropriate to the configuration (for example, offering XQuery 1.1 support). */ public StaticQueryContext(/*@NotNull*/ Configuration config) { this(config.getDefaultStaticQueryContext()); this.config = config; namePool = config.getNamePool(); errorListener = config.getErrorListener(); if (errorListener instanceof StandardErrorListener) { errorListener = ((StandardErrorListener) errorListener).makeAnother(Configuration.XQUERY); ((StandardErrorListener) errorListener).setRecoveryPolicy(Configuration.DO_NOT_RECOVER); } defaultCollationName = config.getDefaultCollationName(); reset(); } /** * Create a StaticQueryContext using a given Configuration. This creates a StaticQueryContext for a main module * (that is, a module that is not a library module). *

*

This method is primarily for internal use. The recommended way to create a StaticQueryContext is by * using the factory method Configuration.newStaticQueryContext().

* * @param config the Saxon Configuration * @param initial if set, this is the StaticQueryContext owned by the Configuration */ public StaticQueryContext(/*@NotNull*/ Configuration config, boolean initial) { if (initial) { this.config = config; namePool = config.getNamePool(); errorListener = config.getErrorListener(); //moduleURIResolver = config.getModuleURIResolver(); if (errorListener instanceof StandardErrorListener) { errorListener = ((StandardErrorListener) errorListener).makeAnother(Configuration.XQUERY); ((StandardErrorListener) errorListener).setRecoveryPolicy(Configuration.DO_NOT_RECOVER); } //collationMap = new CollationMap(config.getCollationMap()); //locationMap = new LocationMap(); //schemaAware = (Boolean)config.getConfigurationProperty(FeatureKeys.XQUERY_SCHEMA_AWARE); // executable = new Executable(config); // executable.setCollationTable(new CollationMap(config.getCollationMap())); // executable.setHostLanguage(Configuration.XQUERY); // executable.setLocationMap(new LocationMap()); reset(); } else { copyFrom(config.getDefaultStaticQueryContext()); } } /** * Create a copy of a supplied StaticQueryContext * * @param c the StaticQueryContext to be copied */ public StaticQueryContext(/*@NotNull*/ StaticQueryContext c) { copyFrom(c); } protected void copyFrom(/*@NotNull*/ StaticQueryContext c) { config = c.config; namePool = c.namePool; baseURI = c.baseURI; moduleURIResolver = c.moduleURIResolver; if (c.userDeclaredNamespaces != null) { userDeclaredNamespaces = new HashMap(c.userDeclaredNamespaces); } if (c.userDeclaredVariables != null) { userDeclaredVariables = new HashSet(c.userDeclaredVariables); } inheritNamespaces = c.inheritNamespaces; preserveNamespaces = c.preserveNamespaces; constructionMode = c.constructionMode; externalNamespaceResolver = c.externalNamespaceResolver; defaultElementNamespace = c.defaultElementNamespace; defaultFunctionNamespace = c.defaultFunctionNamespace; requiredContextItemType = c.requiredContextItemType; preserveSpace = c.preserveSpace; defaultEmptyLeast = c.defaultEmptyLeast; moduleURIResolver = c.moduleURIResolver; errorListener = c.errorListener; codeInjector = c.codeInjector; isUpdating = c.isUpdating; languageVersion = c.languageVersion; //collationMap = new CollationMap(c.collationMap); //locationMap = new LocationMap(); //schemaAware = c.schemaAware; //streaming = c.streaming; // executable = new Executable(config); // executable.setCollationTable(new CollationMap(c.executable.getCollationTable())); // executable.setHostLanguage(Configuration.XQUERY); // executable.setLocationMap(new LocationMap()); // executable.setSchemaAware(c.executable.isSchemaAware()); } /** * Reset the state of this StaticQueryContext to an uninitialized state * * @since 8.4 */ public void reset() { userDeclaredNamespaces = new HashMap(10); externalNamespaceResolver = null; errorListener = config.getErrorListener(); if (errorListener instanceof StandardErrorListener) { errorListener = ((StandardErrorListener) errorListener).makeAnother(Configuration.XQUERY); ((StandardErrorListener) errorListener).setRecoveryPolicy(Configuration.DO_NOT_RECOVER); } constructionMode = getConfiguration().isLicensedFeature(Configuration.LicenseFeature.ENTERPRISE_XQUERY) ? Validation.PRESERVE : Validation.STRIP; preserveSpace = false; defaultEmptyLeast = true; requiredContextItemType = AnyItemType.getInstance(); defaultFunctionNamespace = NamespaceConstant.FN; defaultElementNamespace = NamespaceConstant.NULL; moduleURIResolver = null; clearNamespaces(); isUpdating = false; languageVersion = 30; } /** * Set the Configuration options * * @param config the Saxon Configuration * @throws IllegalArgumentException if the configuration supplied is different from the existing * configuration * @since 8.4 */ public void setConfiguration(/*@NotNull*/ Configuration config) { if (this.config != null && this.config != config) { throw new IllegalArgumentException("Configuration cannot be changed dynamically"); } this.config = config; namePool = config.getNamePool(); } /** * Get the Configuration options * * @return the Saxon configuration * @since 8.4 */ public Configuration getConfiguration() { return config; } /** * Get the executable containing this query * * @return the executable (which is newly created by this method) */ /*@NotNull*/ public Executable makeExecutable() { Executable executable = new Executable(config); executable.setSchemaAware(isSchemaAware()); executable.setHostLanguage(Configuration.XQUERY, getLanguageVersion() >= 30); return executable; } /** * Say whether this query is schema-aware * * @param aware true if this query is schema-aware * @since 9.2.1.2 */ public void setSchemaAware(boolean aware) { if (aware) { throw new UnsupportedOperationException("Schema-awareness requires Saxon-EE"); } } /** * Ask whether this query is schema-aware * * @return true if this query is schema-aware * @since 9.2.1.2 */ public boolean isSchemaAware() { return false; } /** * Say whether the query should be compiled and evaluated to use streaming. * This affects subsequent calls on the compile() methods. This option requires * Saxon-EE. * @param option if true, the compiler will attempt to compile a query to be * capable of executing in streaming mode. If the query cannot be streamed, * a compile-time exception is reported. In streaming mode, the source * document is supplied as a stream, and no tree is built in memory. The default * is false. Setting the value to true has the side-effect of setting the required * context item type to "document node"; this is to ensure that expresions such as * //BOOK are streamable. * @since 9.6 */ public void setStreaming(boolean option) { if (option) { throw new UnsupportedOperationException("Streaming requires Saxon-EE"); } } /** * Ask whether the streaming option has been set, that is, whether * subsequent calls on compile() will compile queries to be capable * of executing in streaming mode. * @return true if the streaming option has been set. * @since 9.6 */ public boolean isStreaming() { return false; } /** * Set the Base URI of the query * * @param baseURI the base URI of the query, or null to indicate that no base URI is available * @since 8.4 */ public void setBaseURI(String baseURI) { this.baseURI = baseURI; } /** * Convenience method for building Saxon's internal representation of a source XML * document. The document will be built using Configuration (and NamePool) associated * with this StaticQueryContext. *

*

This method is retained for backwards compatibility; however, it is merely a wrapper * around the method {@link Configuration#buildDocumentTree}, which should be called in preference.

* * @param source Any javax.xml.transform.Source object representing the document against * which queries will be executed. Note that a Saxon {@link net.sf.saxon.om.NodeInfo} * can be used as a Source. To use a third-party DOM Document as a source, create an instance of * {@link javax.xml.transform.dom.DOMSource DOMSource} to wrap it. *

For additional control over the way in which the source document is processed, * supply an {@link net.sf.saxon.lib.AugmentedSource AugmentedSource} object and set appropriate * options on the object.

* @return the DocumentInfo representing the root node of the resulting document object. * @throws XPathException if building the document fails * @since 8.4 * @deprecated since 9.2: use {@link Configuration#buildDocumentTree(javax.xml.transform.Source)} */ /*@NotNull*/ public TreeInfo buildDocument(Source source) throws XPathException { return config.buildDocumentTree(source); } /** * Set the language version. * * @param version The XQuery language version. Must be 10 (="1.0") or 30 (="3.0") or 31 (="3.1"). * @since 9.2; changed in 9.3 to expect a DecimalValue rather than a string. Changed in 9.7 to * accept an int (30 = "3.0") and to allow "3.1". */ public void setLanguageVersion(int version) { if (version==10 || version==30 || version==31) { languageVersion = version; } else { throw new IllegalArgumentException("languageVersion = " + version); } } /** * Get the language version * * @return the language version. Either "1.0" or "1.1". Default is "1.0". * @since 9.2; changed in 9.3 to return a DecimalValue rather than a string; * changed in 9.7 to return an int (30 = "3.0" and so on) */ public int getLanguageVersion() { return languageVersion; } /** * Get any extension function library that was previously set. * * @return the extension function library, or null if none has been set. The result will always be null if called * in Saxon-HE; setting an extension function library requires the Saxon-PE or Saxon-EE versions of this class. * @since 9.4 */ /*@Nullable*/ public FunctionLibrary getExtensionFunctionLibrary() { return null; } /** * Ask whether compile-time generation of trace code was requested * * @return true if compile-time generation of code was requested * @since 9.0 */ public boolean isCompileWithTracing() { return codeInjector instanceof TraceCodeInjector; } /** * Request compile-time generation of trace code (or not) * * @param trace true if compile-time generation of trace code is required * @since 9.0 */ public void setCompileWithTracing(boolean trace) { if (trace) { codeInjector = new TraceCodeInjector(); } else { codeInjector = null; } } /** * Request that the parser should insert custom code into the expression tree * by calling a supplied CodeInjector to process each expression as it is parsed, * for example for tracing or performance measurement * * @param injector the CodeInjector to be used. May be null, in which case * no code is injected * @since 9.4 */ public void setCodeInjector( /*@Nullable*/ CodeInjector injector) { this.codeInjector = injector; } /** * Get any CodeInjector that has been registered * * @return the registered CodeInjector, or null * @since 9.4 */ /*@Nullable*/ public CodeInjector getCodeInjector() { return codeInjector; } /** * Ask whether XQuery Update is allowed * * @return true if XQuery update is supported by queries using this context */ public boolean isUpdating() { return isUpdating; } /** * Set the namespace inheritance mode * * @param inherit true if namespaces are inherited, false if not * @since 8.4 */ public void setInheritNamespaces(boolean inherit) { inheritNamespaces = inherit; } /** * Get the namespace inheritance mode * * @return true if namespaces are inherited, false if not * @since 8.4 */ public boolean isInheritNamespaces() { return inheritNamespaces; } /** * Set the namespace copy mode * * @param inherit true if namespaces are preserved, false if not * @since 8.4 */ public void setPreserveNamespaces(boolean inherit) { preserveNamespaces = inherit; } /** * Get the namespace copy mode * * @return true if namespaces are preserved, false if not * @since 8.4 */ public boolean isPreserveNamespaces() { return preserveNamespaces; } /** * Set the construction mode for this module * * @param mode one of {@link net.sf.saxon.lib.Validation#STRIP}, {@link net.sf.saxon.lib.Validation#PRESERVE} * @since 8.4 */ public void setConstructionMode(int mode) { constructionMode = mode; } /** * Get the current construction mode * * @return one of {@link net.sf.saxon.lib.Validation#STRIP}, {@link net.sf.saxon.lib.Validation#PRESERVE} * @since 8.4 */ public int getConstructionMode() { return constructionMode; } /** * Set the module location. Normally the module location is assumed to be line 1, column 1 of the * resource identified by the base URI. But a different location can be set, for example if the query * is embedded in an XML document, and this information will be available in diagnostics. * @param location the module location * @since 9.7 */ public void setModuleLocation(Location location) { this.moduleLocation = location; } /** * Get the module location. Normally the module location is assumed to be line 1, column 1 of the * resource identified by the base URI. But a different location can be set, for example if the query * is embedded in an XML document, and this information will be available in diagnostics. * @return the module location * @since 9.7 */ public Location getModuleLocation() { return moduleLocation; } /** * Prepare an XQuery query for subsequent evaluation. The source text of the query * is supplied as a String. The base URI of the query is taken from the static context, * and defaults to the current working directory. *

*

Note that this interface makes the caller responsible for decoding the query and * presenting it as a string of characters. This means it is likely that any encoding * specified in the query prolog will be ignored.

* * @param query The XQuery query to be evaluated, supplied as a string. * @return an XQueryExpression object representing the prepared expression * @throws net.sf.saxon.trans.XPathException * if the syntax of the expression is wrong, * or if it references namespaces, variables, or functions that have not been declared, * or contains other static errors. * @since 8.4 */ /*@NotNull*/ public XQueryExpression compileQuery(/*@NotNull*/ String query) throws XPathException { XQueryParser qp = (XQueryParser) config.newExpressionParser("XQ", isUpdating, languageVersion); if (codeInjector != null) { qp.setCodeInjector(codeInjector); } else if (config.isCompileWithTracing()) { qp.setCodeInjector(new TraceCodeInjector()); } qp.setStreaming(isStreaming()); QueryModule mainModule = new QueryModule(this); if (languageVersion >= 30) { qp.setDisableCycleChecks(true); } return qp.makeXQueryExpression(query, mainModule, config); } /** * Prepare an XQuery query for subsequent evaluation. The Query is supplied * in the form of a Reader. The base URI of the query is taken from the static context, * and defaults to the current working directory. *

*

Note that this interface makes the Reader responsible for decoding the query and * presenting it as a stream of characters. This means it is likely that any encoding * specified in the query prolog will be ignored. Also, some implementations of Reader * cannot handle a byte order mark.

* * @param source A Reader giving access to the text of the XQuery query to be compiled. * @return an XPathExpression object representing the prepared expression. * @throws net.sf.saxon.trans.XPathException * if the syntax of the expression is wrong, or if it references namespaces, * variables, or functions that have not been declared, or any other static error is reported. * @throws java.io.IOException if a failure occurs reading the supplied input. * @since 8.4 */ /*@Nullable*/ public XQueryExpression compileQuery(/*@NotNull*/ Reader source) throws XPathException, IOException { char[] buffer = new char[4096]; StringBuilder sb = new StringBuilder(4096); while (true) { int n = source.read(buffer); if (n > 0) { sb.append(buffer, 0, n); } else { break; } } return compileQuery(sb.toString()); } /** * Prepare an XQuery query for subsequent evaluation. The Query is supplied * in the form of a InputStream, with an optional encoding. If the encoding is not specified, * the query parser attempts to obtain the encoding by inspecting the input stream: it looks specifically * for a byte order mark, and for the encoding option in the version declaration of an XQuery prolog. * The encoding defaults to UTF-8. * The base URI of the query is taken from the static context, * and defaults to the current working directory. * * @param source An InputStream giving access to the text of the XQuery query to be compiled, as a stream * of octets * @param encoding The encoding used to translate characters to octets in the query source. The parameter * may be null: in this case the query parser attempts to infer the encoding by inspecting the source, * and if that fails, it assumes UTF-8 encoding * @return an XPathExpression object representing the prepared expression. * @throws net.sf.saxon.trans.XPathException * if the syntax of the expression is wrong, or if it references namespaces, * variables, or functions that have not been declared, or any other static error is reported. * @throws java.io.IOException if a failure occurs reading the supplied input. * @since 8.5 */ /*@Nullable*/ public XQueryExpression compileQuery(/*@NotNull*/ InputStream source, /*@Nullable*/ String encoding) throws XPathException, IOException { String query = QueryReader.readInputStream(source, encoding, config.getValidCharacterChecker()); return compileQuery(query); } /** * Compile an XQuery library module for subsequent evaluation. This method is supported * only in Saxon-EE * * @param query the content of the module, as a string * @throws XPathException if a static error exists in the query * @throws UnsupportedOperationException if not using Saxon-EE * @since 9.2 (changed in 9.3 to return void) */ public void compileLibrary(String query) throws XPathException { throw new XPathException("Separate compilation of query libraries requires Saxon-EE"); } /** * Prepare an XQuery library module for subsequent evaluation. This method is supported * only in Saxon-EE. The effect of the method is that subsequent query compilations using this static * context can import the module URI without specifying a location hint; the import then takes effect * without requiring the module to be compiled each time it is imported. * * @param source the content of the module, as a Reader which supplies the source code * @throws XPathException if a static error exists in the query * @throws IOException if the input cannot be read * @throws UnsupportedOperationException if not using Saxon-EE * @since 9.2 (changed in 9.3 to return void) */ public void compileLibrary(Reader source) throws XPathException, IOException { throw new XPathException("Separate compilation of query libraries requires Saxon-EE"); } /** * Prepare an XQuery library module for subsequent evaluation. This method is supported * only in Saxon-EE. The effect of the method is that subsequent query compilations using this static * context can import the module URI without specifying a location hint; the import then takes effect * without requiring the module to be compiled each time it is imported. * * @param source the content of the module, as an InputStream which supplies the source code * @param encoding the character encoding of the input stream. May be null, in which case the encoding * is inferred, for example by looking at the query declaration * @throws XPathException if a static error exists in the query * @throws IOException if the input cannot be read * @throws UnsupportedOperationException if not using Saxon-EE * @since 9.2 (changed in 9.3 to return void) */ public void compileLibrary(InputStream source, /*@Nullable*/ String encoding) throws XPathException, IOException { throw new UnsupportedOperationException("Separate compilation of query libraries requires Saxon-EE"); } /** * Get a previously compiled library module * * @param namespace the module namespace * @return the QueryLibrary if a module with this namespace has been compiled as a library module; * otherwise null. Always null when not using Saxon-EE. * @since 9.3 */ /*@Nullable*/ public QueryLibrary getCompiledLibrary(String namespace) { return null; } /** * Declare a namespace whose prefix can be used in expressions. This is * equivalent to declaring a prefix in the Query prolog. * Any namespace declared in the Query prolog overrides a namespace declared using * this API. * * @param prefix The namespace prefix. Must not be null. Setting this to "" means that the * namespace will be used as the default namespace for elements and types. * @param uri The namespace URI. Must not be null. The value "" (zero-length string) is used * to undeclare a namespace; it is not an error if there is no existing binding for * the namespace prefix. * @throws NullPointerException if either the prefix or URI is null * @throws IllegalArgumentException if the prefix is "xml" and the namespace is not the XML namespace, or vice * versa; or if the prefix is "xmlns", or the URI is "http://www.w3.org/2000/xmlns/" * @since 9.0 */ public void declareNamespace( /*@Nullable*/ String prefix, /*@Nullable*/ String uri) { if (prefix == null) { throw new NullPointerException("Null prefix supplied to declareNamespace()"); } if (uri == null) { throw new NullPointerException("Null namespace URI supplied to declareNamespace()"); } if (prefix.equals("xml") != uri.equals(NamespaceConstant.XML)) { throw new IllegalArgumentException("Misdeclaration of XML namespace"); } if (prefix.equals("xmlns") || uri.equals(NamespaceConstant.XMLNS)) { throw new IllegalArgumentException("Misdeclaration of xmlns namespace"); } if (prefix.isEmpty()) { defaultElementNamespace = uri; } if (uri.isEmpty()) { userDeclaredNamespaces.remove(prefix); } else { userDeclaredNamespaces.put(prefix, uri); } } /** * Clear all the user-declared namespaces * * @since 9.0 */ public void clearNamespaces() { userDeclaredNamespaces.clear(); declareNamespace("xml", NamespaceConstant.XML); declareNamespace("xs", NamespaceConstant.SCHEMA); declareNamespace("xsi", NamespaceConstant.SCHEMA_INSTANCE); declareNamespace("fn", NamespaceConstant.FN); declareNamespace("local", NamespaceConstant.LOCAL); declareNamespace("err", NamespaceConstant.ERR); declareNamespace("saxon", NamespaceConstant.SAXON); declareNamespace("", ""); } /** * Get the map of user-declared namespaces * * @return the user-declared namespaces */ protected HashMap getUserDeclaredNamespaces() { return userDeclaredNamespaces; } /** * Get the namespace prefixes that have been declared using the method {@link #declareNamespace} * * @return an iterator that returns the namespace prefixes that have been explicitly declared, as * strings. The default namespace for elements and types will be included, using the prefix "". * @since 9.0 */ public Iterator iterateDeclaredPrefixes() { return userDeclaredNamespaces.keySet().iterator(); } /** * Get the namespace URI for a given prefix, which must have been declared using the method * {@link #declareNamespace}. Note that this method will not call the external namespace resolver * to resolve the prefix. * * @param prefix the namespace prefix, or "" to represent the null prefix * @return the namespace URI. Returns "" to represent the non-namespace, * null to indicate that the prefix has not been declared */ public String getNamespaceForPrefix(String prefix) { return userDeclaredNamespaces.get(prefix); } /** * Set an external namespace resolver. If a namespace prefix cannot be resolved using any * other mechanism, then as a last resort the external namespace resolver is called to * obtain a URI for the given prefix. *

*

Changed in Saxon 9.0 so that the namespaces resolved by the external namespace resolver * are available at run-time, just like namespaces declared in the query prolog. In consequence, * the supplied NamespaceResolver must now implement the * {@link net.sf.saxon.om.NamespaceResolver#iteratePrefixes()} method.

* * @param resolver the external namespace resolver */ public void setExternalNamespaceResolver(NamespaceResolver resolver) { externalNamespaceResolver = resolver; } /** * Get the external namespace resolver that has been registered using * setExternalNamespaceResolver(), if any. * * @return the external namespace resolver */ /*@Nullable*/ public NamespaceResolver getExternalNamespaceResolver() { return externalNamespaceResolver; } /** * Get the default function namespace * * @return the default function namespace (defaults to the fn: namespace) * @since 8.4 */ public String getDefaultFunctionNamespace() { return defaultFunctionNamespace; } /** * Set the default function namespace * * @param defaultFunctionNamespace The namespace to be used for unprefixed function calls * @since 8.4 */ public void setDefaultFunctionNamespace(String defaultFunctionNamespace) { this.defaultFunctionNamespace = defaultFunctionNamespace; } /** * Set the default element namespace * * @param uri the namespace URI to be used as the default namespace for elements and types * @since 8.4 */ public void setDefaultElementNamespace(String uri) { defaultElementNamespace = uri; declareNamespace("", uri); } /** * Get the default namespace for elements and types * * @return the namespace URI to be used as the default namespace for elements and types * @since 8.9 Modified in 8.9 to return the namespace URI as a string rather than an integer code */ /*@Nullable*/ public String getDefaultElementNamespace() { return defaultElementNamespace; } /** * Declare a global variable. This has the same effect as including a global variable declaration * in the Query Prolog of the main query module. A static error occurs when compiling the query if the * query prolog contains a declaration of the same variable. * * @param qName the qualified name of the variable * @param type the declared type of the variable * @param value the initial value of the variable. May be null if the variable is external. * @param external true if the variable is external, that is, if its value may be set at run-time. * @throws NullPointerException if the value is null, unless the variable is external * @throws XPathException if the value of the variable is not consistent with its type. * @since 9.1 */ public void declareGlobalVariable( StructuredQName qName, /*@NotNull*/ SequenceType type, /*@Nullable*/ Sequence value, boolean external) throws XPathException { if (value == null && !external) { throw new NullPointerException("No initial value for declared variable"); } if (value != null && !type.matches(value, getConfiguration().getTypeHierarchy())) { throw new XPathException("Value of declared variable does not match its type"); } GlobalVariable var = external ? new GlobalParam() : new GlobalVariable(); // PackageData pd = new PackageData(config); // pd.setXPathVersion(getLanguageVersion()); // pd.setHostLanguage(Configuration.XQUERY); // pd.setSchemaAware(isSchemaAware()); // var.setPackageData(pd); var.setVariableQName(qName); var.setRequiredType(type); if (value != null) { var.setSelectExpression(Literal.makeLiteral(SequenceTool.toGroundedValue(value))); } if (userDeclaredVariables == null) { userDeclaredVariables = new HashSet(); } userDeclaredVariables.add(var); } /** * Iterate over all the declared global variables * * @return an iterator over all the global variables that have been declared. They are returned * as instances of class {@link GlobalVariable} * @since 9.1 */ public Iterator iterateDeclaredGlobalVariables() { if (userDeclaredVariables == null) { List empty = Collections.emptyList(); return empty.iterator(); } else { return userDeclaredVariables.iterator(); } } /** * Clear all declared global variables * * @since 9.1 */ public void clearDeclaredGlobalVariables() { userDeclaredVariables = null; } /** * Set a user-defined ModuleURIResolver for resolving URIs used in "import module" * declarations in the XQuery prolog. * This will be used for resolving URIs in XQuery "import module" declarations, overriding * any ModuleURIResolver that was specified as part of the configuration. * * @param resolver the ModuleURIResolver to be used */ public void setModuleURIResolver(ModuleURIResolver resolver) { moduleURIResolver = resolver; } /** * Get the user-defined ModuleURIResolver for resolving URIs used in "import module" * declarations in the XQuery prolog; returns null if none has been explicitly set either * on the StaticQueryContext or on the Configuration. * * @return the registered ModuleURIResolver */ /*@Nullable*/ public ModuleURIResolver getModuleURIResolver() { return moduleURIResolver; } /** * Declare a named collation. Collations are only available in a query if this method * has been called externally to declare the collation and associate it with an * implementation, in the form of a Java Comparator. The default collation is the * Unicode codepoint collation, unless otherwise specified. * * @param name The name of the collation (technically, a URI) * @param comparator The Java Comparator used to implement the collating sequence * @since 8.4. * @deprecated since 9.6. All collations are now registered at the level of the * Configuration. If this method is called, the effect is that the supplied collation * is registered with the configuration */ public void declareCollation(String name, Comparator comparator) { getConfiguration().registerCollation(name, new SimpleCollation(name, comparator)); } /** * Declare a named collation. Collations are only available in a query if this method * has been called externally to declare the collation and associate it with an * implementation, in the form of a Java StringCollator. The default collation is the * Unicode codepoint collation, unless otherwise specified. * * @param name The name of the collation (technically, a URI) * @param collation The Java Comparator used to implement the collating sequence * @since 8.9. * @deprecated since 9.6. All collations are now registered at the level of the * Configuration. If this method is called, the effect is that the supplied collation * is registered with the configuration */ public void declareCollation(String name, StringCollator collation) { getConfiguration().registerCollation(name, collation); } /** * Set the default collation. * * @param name The collation name, as specified in the query prolog. The name * is not validated until it is used. * @throws NullPointerException if the supplied value is null * @since 8.4. Changed in 8.6 so it no longer validates the collation name: this is * because the base URI is not necessarily known at the point where the default * collation is declared. */ public void declareDefaultCollation(String name) { this.defaultCollationName = name; } /** * Get a named collation. * * @param name the name of the collation, as an absolute URI * @return the collation identified by the given name, as set previously using declareCollation. * If no collation with this name has been declared, the method calls the CollationURIResolver * to locate a collation with this name. * Return null if no collation with this name is found. * @throws NullPointerException if the collation name argument is null. * @since 8.4 * @deprecated since 9.6. Collations are now all held globally at the level of the * Configuration. Calling this method will get the relevant collation held in the Configuration. */ public StringCollator getCollation(String name) { try { return getConfiguration().getCollation(name); } catch (XPathException e) { getErrorListener().warning(e); return null; } } /** * Get the name of the default collation. * * @return the name of the default collation; or the name of the codepoint collation * if no default collation has been defined. The name is returned in the form * it was specified; that is, it is not yet resolved against the base URI. (This * is because the base URI declaration can follow the default collation declaration * in the query prolog.) If no default collation has been specified, the "default default" * (that is, the Unicode codepoint collation) is returned. * @since 8.4 */ /*@Nullable*/ public String getDefaultCollationName() { return defaultCollationName; } /** * Declare the static type of the context item. If this type is declared, and if a context item * is supplied when the query is invoked, then the context item must conform to this type (no * type conversion will take place to force it into this type). * * @param type the required type of the context item */ public void setRequiredContextItemType(ItemType type) { requiredContextItemType = type; } /** * Get the required type of the context item. If no type has been explicitly declared for the context * item, an instance of AnyItemType (representing the type item()) is returned. * * @return the required type of the context item */ public ItemType getRequiredContextItemType() { return requiredContextItemType; } /** * Get the NamePool used for compiling expressions * * @return the name pool * @since 8.4 */ public NamePool getNamePool() { return namePool; } /** * Get the system ID of the container of the expression. Used to construct error messages. * Note that the systemID and the Base URI are currently identical, but they might be distinguished * in the future. * * @return the Base URI * @since 8.4 */ public String getSystemId() { return baseURI; } /** * Get the Base URI of the query, for resolving any relative URI's used * in the expression. * Note that the systemID and the Base URI are currently identical, but they might be distinguished * in the future. * Used by the document() function. * * @return the base URI of the query * @since 8.4 */ public String getBaseURI() { return baseURI; } /** * Set the policy for preserving boundary space * * @param preserve true if boundary space is to be preserved, false if it is to be stripped * @since 9.0 */ public void setPreserveBoundarySpace(boolean preserve) { preserveSpace = preserve; } /** * Ask whether the policy for boundary space is "preserve" or "strip" * * @return true if the policy is to preserve boundary space, false if it is to strip it * @since 9.0 */ public boolean isPreserveBoundarySpace() { return preserveSpace; } /** * Set the option for where an empty sequence appears in the collation order, if not otherwise * specified in the "order by" clause * * @param least true if the empty sequence is considered less than any other value (the default), * false if it is considered greater than any other value * @since 9.0 */ public void setEmptyLeast(boolean least) { defaultEmptyLeast = least; } /** * Ask where an empty sequence should appear in the collation order, if not otherwise * specified in the "order by" clause * * @return true if the empty sequence is considered less than any other value (the default), * false if it is considered greater than any other value * @since 9.0 */ public boolean isEmptyLeast() { return defaultEmptyLeast; } /** * Set the ErrorListener to be used to report compile-time errors in a query. This will also * be the default for the run-time error listener used to report dynamic errors. *

*

If the supplied listener is a StandardErrorListener, then a new copy will be made * using {@link StandardErrorListener#makeAnother(int)}

*

*

If the supplied listener is not an {@link UnfailingErrorListener}, then it will be wrapped * in a {@link DelegatingErrorListener}.

* * @param listener the ErrorListener to be used */ public void setErrorListener(ErrorListener listener) { if (listener instanceof StandardErrorListener) { errorListener = ((StandardErrorListener) listener).makeAnother(Configuration.XQUERY); ((StandardErrorListener) errorListener).setRecoveryPolicy(Configuration.DO_NOT_RECOVER); } else if (listener instanceof UnfailingErrorListener) { errorListener = (UnfailingErrorListener) listener; } else { errorListener = new DelegatingErrorListener(listener); } } /** * Get the ErrorListener in use for this static context * * @return the registered ErrorListener */ public UnfailingErrorListener getErrorListener() { if (errorListener == null) { errorListener = config.getErrorListener(); } return errorListener; } /** * Say whether the query is allowed to be updating. XQuery update syntax will be rejected * during query compilation unless this flag is set. * * @param updating true if the query is allowed to use the XQuery Update facility * (requires Saxon-EE). If set to false, the query must not be an updating query. If set * to true, it may be either an updating or a non-updating query. * @since 9.1 */ public void setUpdatingEnabled(boolean updating) { isUpdating = updating; } /** * Ask whether the query is allowed to be updating * * @return true if the query is allowed to use the XQuery Update facility. Note that this * does not necessarily mean that the query is an updating query; but if the value is false, * the it must definitely be non-updating. * @since 9.1 */ public boolean isUpdatingEnabled() { return isUpdating; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy