package client.net.sf.saxon.ce.style; import client.net.sf.saxon.ce.Configuration; import client.net.sf.saxon.ce.expr.Container; import client.net.sf.saxon.ce.expr.Expression; import client.net.sf.saxon.ce.expr.StaticContext; import client.net.sf.saxon.ce.expr.instruct.Executable; import client.net.sf.saxon.ce.functions.*; import client.net.sf.saxon.ce.lib.NamespaceConstant; import client.net.sf.saxon.ce.lib.StringCollator; import client.net.sf.saxon.ce.om.NameChecker; import client.net.sf.saxon.ce.om.NamespaceResolver; import client.net.sf.saxon.ce.om.QNameException; import client.net.sf.saxon.ce.om.StructuredQName; import client.net.sf.saxon.ce.sxpath.AbstractStaticContext; import client.net.sf.saxon.ce.trans.DecimalFormatManager; import client.net.sf.saxon.ce.trans.XPathException; import client.net.sf.saxon.ce.tree.util.SourceLocator; import client.net.sf.saxon.ce.type.BuiltInAtomicType; /** * This class implements the static context used for evaluating use-when expressions in XSLT 2.0 * A new instance of this class is created for each use-when expression encountered; there are * therefore no issues with reusability. The class provides a Container for the expression as well * as the static context information; the Executable contains the single XPath expression only, and * is created for the purpose. */ public class UseWhenStaticContext extends AbstractStaticContext implements StaticContext, Container { private NamespaceResolver namespaceContext; private FunctionLibrary functionLibrary; private Executable executable; private SourceLocator sourceLocator; /** * Create a static context for evaluating use-when expressions * @param config the Saxon configuration * @param namespaceContext the namespace context in which the use-when expression appears */ public UseWhenStaticContext(Configuration config, NamespaceResolver namespaceContext, SourceLocator sourceLocator) { setConfiguration(config); this.namespaceContext = namespaceContext; this.sourceLocator = sourceLocator; FunctionLibraryList lib = new FunctionLibraryList(); lib.addFunctionLibrary(SystemFunctionLibrary.getSystemFunctionLibrary( StandardFunction.CORE|StandardFunction.USE_WHEN)); lib.addFunctionLibrary(ConstructorFunctionLibrary.getInstance()); functionLibrary = lib; executable = new Executable(config); } /** * Get the Executable representing the containing XSLT stylesheet * @return the Executable */ public Executable getExecutable() { return executable; } public SourceLocator getSourceLocator() { return sourceLocator; } /** * Issue a compile-time warning */ public void issueWarning(String s, SourceLocator locator) { getConfiguration().issueWarning(s); } /** * Get the System ID of the container of the expression. This is the containing * entity (file) and is therefore useful for diagnostics. Use getBaseURI() to get * the base URI, which may be different. */ public String getSystemId() { return getBaseURI(); } /** * Get the granularity of the container. * @return 0 for a temporary container created during parsing; 1 for a container * that operates at the level of an XPath expression; 2 for a container at the level * of a global function or template */ public int getContainerGranularity() { return 1; } /** * Get the URI for a namespace prefix. The default namespace is NOT used * when the prefix is empty. * * @param prefix The prefix * @throws client.net.sf.saxon.ce.trans.XPathException * if the prefix is not declared */ public String getURIForPrefix(String prefix) throws XPathException { String uri = namespaceContext.getURIForPrefix(prefix, false); if (uri == null) { XPathException err = new XPathException("Namespace prefix '" + prefix + "' has not been declared"); err.setErrorCode("XTDE0290"); throw err; } return uri; } /** * Bind a variable used in this element to the XSLVariable element in which it is declared * @param qName the name of the variable */ public Expression bindVariable(StructuredQName qName) throws XPathException { XPathException err = new XPathException("Variables cannot be used in a use-when expression"); err.setErrorCode("XPST0008"); err.setIsStaticError(true); throw err; } /** * Get the function library containing all the in-scope functions available in this static * context */ public FunctionLibrary getFunctionLibrary() { return functionLibrary; } /** * Get a named collation. * * @param name The name of the required collation. Supply null to get the default collation. * @return the collation; or null if the required collation is not found. */ public StringCollator getCollation(String name) { 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 */ public String getDefaultCollationName() { return NamespaceConstant.CODEPOINT_COLLATION_URI; } /** * Get the default function namespace */ public String getDefaultFunctionNamespace() { return NamespaceConstant.FN; } /** * Determine whether Backwards Compatible Mode is used */ public boolean isInBackwardsCompatibleMode() { return false; } /** * Determine whether a built-in type is available in this context. This method caters for differences * between host languages as to which set of types are built in. * * @param type the supposedly built-in type. This will always be a type in the * XS or XDT namespace. * @return true if this type can be used in this static context */ public boolean isAllowedBuiltInType(BuiltInAtomicType type) { return true; } /** * Get a namespace resolver to resolve the namespaces declared in this static context. * * @return a namespace resolver. */ public NamespaceResolver getNamespaceResolver() { return namespaceContext; } /** * Get a DecimalFormatManager to resolve the names of decimal formats used in calls * to the format-number() function. * @return the decimal format manager for this static context, or null if named decimal * formats are not supported in this environment. */ public DecimalFormatManager getDecimalFormatManager() { return null; } /** * Determine if an extension element is available * @throws client.net.sf.saxon.ce.trans.XPathException if the name is invalid or the prefix is not declared */ public boolean isElementAvailable(String qname) throws XPathException { try { String[] parts = NameChecker.getQNameParts(qname); String uri; if (parts[0].length() == 0) { uri = getDefaultElementNamespace(); } else { uri = getURIForPrefix(parts[0]); } StyleNodeFactory factory = new StyleNodeFactory(getConfiguration()); return factory.isElementAvailable(uri, parts[1]); } catch (QNameException e) { XPathException err = new XPathException("Invalid element name. " + e.getMessage()); err.setErrorCode("XTDE1440"); throw err; } } } // 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.