package client.net.sf.saxon.ce.style;
import client.net.sf.saxon.ce.Configuration;
import client.net.sf.saxon.ce.expr.*;
import client.net.sf.saxon.ce.expr.instruct.Executable;
import client.net.sf.saxon.ce.functions.FunctionLibrary;
import client.net.sf.saxon.ce.lib.NamespaceConstant;
import client.net.sf.saxon.ce.om.*;
import client.net.sf.saxon.ce.trans.DecimalFormatManager;
import client.net.sf.saxon.ce.trans.Err;
import client.net.sf.saxon.ce.trans.XPathException;
import client.net.sf.saxon.ce.tree.util.SourceLocator;
/**
* An ExpressionContext represents the context for an XPath expression written
* in the stylesheet.
*/
public class ExpressionContext implements StaticContext {
private StyleElement element;
private NamePool namePool;
private NamespaceResolver namespaceResolver = null;
/**
* Create a static context for XPath expressions in an XSLT stylesheet
* @param styleElement the element on which the XPath expression appears
*/
public ExpressionContext(StyleElement styleElement) {
element = styleElement;
namePool = styleElement.getNamePool();
}
/**
* Get the system configuration
*/
public Configuration getConfiguration() {
return element.getConfiguration();
}
/**
* Get the executable
* @return the executable
*/
public Executable getExecutable() {
return element.getExecutable();
}
/**
* Construct a dynamic context for early evaluation of constant subexpressions
*/
public XPathContext makeEarlyEvaluationContext() {
return new EarlyEvaluationContext(getConfiguration());
}
/**
* Issue a compile-time warning
*/
public void issueWarning(String s, SourceLocator locator) {
element.issueWarning(s, locator);
}
/**
* Get the NamePool used for compiling expressions
*/
public NamePool getNamePool() {
return namePool;
}
/**
* Get the System ID of the entity containing the expression (used for diagnostics)
*/
public String getSystemId() {
return element.getSystemId();
}
/**
* Get the Base URI of the element containing the expression, for resolving any
* relative URI's used in the expression.
* Used by the document() function.
*/
public String getBaseURI() {
return element.getBaseURI();
}
/**
* Get the URI for a prefix, using this Element as the context for namespace resolution.
* The default namespace will not be used when the prefix is empty.
* @param prefix The prefix
* @throws XPathException if the prefix is not declared
*/
public String getURIForPrefix(String prefix) throws XPathException {
String uri = element.getURIForPrefix(prefix, false);
if (uri == null) {
XPathException err = new XPathException("Undeclared namespace prefix " + Err.wrap(prefix));
err.setErrorCode("XPST0081");
err.setIsStaticError(true);
throw err;
}
return uri;
}
/**
* Get a copy of the NamespaceResolver suitable for saving in the executable code
* @return a NamespaceResolver
*/
public NamespaceResolver getNamespaceResolver() {
return element;
}
/**
* 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 element.getPreparedStylesheet().getDecimalFormatManager();
}
/**
* Get a fingerprint for a name, using this as the context for namespace resolution
* @param qname The name as written, in the form "[prefix:]localname"
* @param useDefault Defines the action when there is no prefix. If true, use
* the default namespace URI (as for element names). If false, use no namespace URI
* (as for attribute names).
* @return -1 if the name is not already present in the name pool
*/
public int getFingerprint(String qname, boolean useDefault) throws XPathException {
String[] parts;
try {
parts = NameChecker.getQNameParts(qname);
} catch (QNameException err) {
throw new XPathException(err.getMessage());
}
String prefix = parts[0];
if (prefix.length() == 0) {
String uri = "";
if (useDefault) {
uri = getURIForPrefix(prefix);
}
return namePool.getFingerprint(uri, qname);
} else {
String uri = getURIForPrefix(prefix);
return namePool.getFingerprint(uri, parts[1]);
}
}
/**
* Get a StructuredQName for a name, using this as the context for namespace resolution
* @param qname The name as written, in the form "[prefix:]localname"
* @param useDefault Defines the action when there is no prefix. If true, use
* the default namespace URI (as for element names). If false, use no namespace URI
* (as for attribute names).
* @return -1 if the name is not already present in the name pool
*/
public StructuredQName getStructuredQName(String qname, boolean useDefault) throws XPathException {
String[] parts;
try {
parts = NameChecker.getQNameParts(qname);
} catch (QNameException err) {
throw new XPathException(err.getMessage());
}
String prefix = parts[0];
if (prefix.length() == 0) {
String uri = "";
if (useDefault) {
uri = getURIForPrefix(prefix);
}
return new StructuredQName("", uri, qname);
} else {
String uri = getURIForPrefix(prefix);
return new StructuredQName(prefix, uri, parts[1]);
}
}
private static StructuredQName[] errorVariables = {
new StructuredQName("err", NamespaceConstant.ERR, "code"),
new StructuredQName("err", NamespaceConstant.ERR, "description"),
new StructuredQName("err", NamespaceConstant.ERR, "value"),
new StructuredQName("err", NamespaceConstant.ERR, "module"),
new StructuredQName("err", NamespaceConstant.ERR, "line-number"),
new StructuredQName("err", NamespaceConstant.ERR, "column-number")
};
/**
* Bind a variable to an object that can be used to refer to it
* @param qName the name of the variable
* @return a VariableDeclaration object that can be used to identify it in the Bindery,
* @throws XPathException if the variable has not been declared
*/
public Expression bindVariable(StructuredQName qName) throws XPathException {
XSLVariableDeclaration xslVariableDeclaration = element.bindVariable(qName);
if (xslVariableDeclaration == null) {
XPathException err = new XPathException("Variable " + qName.getDisplayName() +
" has not been declared");
err.setErrorCode("XPST0008");
err.setIsStaticError(true);
throw err;
}
VariableReference var = (xslVariableDeclaration.isGlobal()
? new VariableReference()
: new LocalVariableReference());
xslVariableDeclaration.registerReference(var);
return var;
}
/**
* Get the function library containing all the in-scope functions available in this static
* context
*/
public FunctionLibrary getFunctionLibrary() {
return element.getPrincipalStylesheetModule().getFunctionLibrary();
}
/**
* Determine if an extension element is available
* @throws 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]);
}
return element.getPreparedStylesheet().getStyleNodeFactory().isElementAvailable(uri, parts[1]);
} catch (QNameException e) {
XPathException err = new XPathException("Invalid element name. " + e.getMessage());
err.setErrorCode("XTDE1440");
throw err;
}
}
/**
* Get the default collation. Return null if no default collation has been defined
*/
public String getDefaultCollationName() {
return element.getDefaultCollationName();
}
/**
* Get the default XPath namespace for elements and types
* Return NamespaceConstant.NULL for the non-namespace
*/
public String getDefaultElementNamespace() {
return element.getDefaultXPathNamespace();
}
/**
* Get the default function namespace
*/
public String getDefaultFunctionNamespace() {
return NamespaceConstant.FN;
}
/**
* Determine whether Backwards Compatible Mode is used
*/
public boolean isInBackwardsCompatibleMode() {
return element.xPath10ModeIsEnabled();
}
/**
* Get the containing element in the stylesheet
* @return the stylesheet element
*/
public StyleElement getStyleElement() {
return element;
}
}
// 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.