net.sf.saxon.xpath.XPathFactoryImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of saxon-he Show documentation
Show all versions of saxon-he Show documentation
An OSGi bundle for Saxon-HE
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2013 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.xpath;
import net.sf.saxon.Configuration;
import net.sf.saxon.lib.FeatureKeys;
import net.sf.saxon.lib.NamespaceConstant;
import net.sf.saxon.lib.Validation;
import javax.xml.XMLConstants;
import javax.xml.xpath.*;
/**
* Saxon implementation of the JAXP 1.3 XPathFactory
*/
public class XPathFactoryImpl extends XPathFactory {
private Configuration config;
private XPathVariableResolver variableResolver;
private XPathFunctionResolver functionResolver;
/**
* Default constructor: this creates a Configuration as well as creating the XPathFactory. Any documents
* accessed using this XPathFactory must be built using this same Configuration.
*/
public XPathFactoryImpl() {
config = Configuration.newConfiguration();
setConfiguration(config);
Configuration.getPlatform().registerAllBuiltInObjectModels(config);
}
/**
* Constructor using a user-supplied Configuration.
* This constructor is useful if the document to be queried already exists, as it allows the configuration
* associated with the document to be used with this XPathFactory.
* @param config the Saxon configuration
*/
public XPathFactoryImpl(Configuration config) {
this.config = config;
config.setProcessor(this);
}
/**
* Set the Configuration for the factory
* @param config the Saxon Configuration to be used
*/
public void setConfiguration(Configuration config) {
this.config = config;
config.setProcessor(this);
}
/**
* Get the Configuration object used by this XPathFactory
* @return the Saxon configuration
*/
public Configuration getConfiguration() {
return config;
}
/**
* Test whether a given object model is supported. Returns true if the object model
* is the Saxon object model, DOM, JDOM, DOM4J, or XOM
* @param model The URI identifying the object model.
* @return true if the object model is one of the following (provided that the supporting
* JAR file is available on the classpath)
* {@link net.sf.saxon.lib.NamespaceConstant#OBJECT_MODEL_SAXON},
* {@link XPathConstants#DOM_OBJECT_MODEL},
* {@link net.sf.saxon.lib.NamespaceConstant#OBJECT_MODEL_JDOM}, or
* {@link NamespaceConstant#OBJECT_MODEL_XOM}, or
* {@link net.sf.saxon.lib.NamespaceConstant#OBJECT_MODEL_DOM4J}.
* Saxon also allows user-defined external object models to be registered with the Configuration, and
* this method will return true in respect of any such model.
*/
public boolean isObjectModelSupported(String model) {
boolean debug = System.getProperty("jaxp.debug") != null;
if (debug) {
System.err.println("JAXP: Calling " + getClass().getName() + ".isObjectModelSupported(\"" + model + "\")");
System.err.println("JAXP: -- returning " + silentIsObjectModelSupported(model));
}
return silentIsObjectModelSupported(model);
}
private boolean silentIsObjectModelSupported(String model) {
return model.equals(NamespaceConstant.OBJECT_MODEL_SAXON) || config.getExternalObjectModel(model) != null;
}
/**
* Set a feature of this XPath implementation. The features currently
* recognized are:
*
* - {@link XMLConstants#FEATURE_SECURE_PROCESSING}
* - {@link net.sf.saxon.lib.FeatureKeys#SCHEMA_VALIDATION}: requests schema validation of source documents.
* The property is rejected if the configuration is not schema-aware.
*
* In addition, any Saxon configuration feature (listed in {@link FeatureKeys} can be used
* provided the value is a boolean. (For non-boolean configuration properties, drop down to the underlying
* Saxon {@link Configuration} object and call setConfigurationProperty()
)
* @param feature a URI identifying the feature
* @param b true to set the feature on, false to set it off
* @throws XPathFactoryConfigurationException if the feature name is not recognized
*/
public void setFeature(String feature, boolean b) throws XPathFactoryConfigurationException {
if (feature.equals(FEATURE_SECURE_PROCESSING)) {
config.setBooleanProperty(FeatureKeys.ALLOW_EXTERNAL_FUNCTIONS, !b);
} else if (feature.equals(FeatureKeys.SCHEMA_VALIDATION)) {
config.setSchemaValidationMode(b ? Validation.STRICT : Validation.STRIP);
} else {
try {
config.setBooleanProperty(feature, b);
} catch (IllegalArgumentException err) {
throw new XPathFactoryConfigurationException("Unknown or non-boolean feature: " + feature);
}
}
}
/**
* Get a feature of this XPath implementation. The only features currently
* recognized are:
*
* - {@link #FEATURE_SECURE_PROCESSING}
* - {@link net.sf.saxon.lib.FeatureKeys#SCHEMA_VALIDATION}: requests schema validation of source documents.
*
* In addition, any Saxon configuration feature (listed in {@link FeatureKeys} can be used
* provided the value is a boolean. (For non-boolean configuration properties, drop down to the underlying
* Saxon {@link Configuration} object and call getConfigurationProperty()
)
* @param feature a URI identifying the feature
* @return true if the feature is on, false if it is off
* @throws XPathFactoryConfigurationException if the feature name is not recognized
*/
public boolean getFeature(String feature) throws XPathFactoryConfigurationException {
if (feature.equals(FEATURE_SECURE_PROCESSING)) {
return !config.getBooleanProperty(FeatureKeys.ALLOW_EXTERNAL_FUNCTIONS);
} else if (feature.equals(FeatureKeys.SCHEMA_VALIDATION)) {
return config.getSchemaValidationMode() == Validation.STRICT;
} else {
try {
Object o = config.getConfigurationProperty(feature);
if (o instanceof Boolean) {
return ((Boolean)o);
} else {
throw new XPathFactoryConfigurationException(
"Configuration property " + feature + " is not a boolean (it is an instance of " + o.getClass() + ")");
}
} catch (IllegalArgumentException e) {
throw new XPathFactoryConfigurationException("Unknown feature: " + feature);
}
}
}
/**
* Set a resolver for XPath variables. This will be used to obtain the value of
* any variable referenced in an XPath expression. The variable resolver must be allocated
* before the expression is compiled, but it will only be called when the expression
* is evaluated.
* @param xPathVariableResolver The object used to resolve references to variables.
*/
public void setXPathVariableResolver(XPathVariableResolver xPathVariableResolver) {
variableResolver = xPathVariableResolver;
}
/**
* Set a resolver for XPath functions. This will be used to obtain an implementation
* of any external function referenced in an XPath expression. This is not required for
* system functions, Saxon extension functions, constructor functions named after types,
* or extension functions bound using a namespace that maps to a Java class.
* @param xPathFunctionResolver The object used to resolve references to external functions.
*/
public void setXPathFunctionResolver(XPathFunctionResolver xPathFunctionResolver) {
functionResolver = xPathFunctionResolver;
}
/**
* Create an XPath evaluator
* @return an XPath object, which can be used to compile and execute XPath expressions.
*/
/*@NotNull*/ public XPath newXPath() {
XPathEvaluator xpath = new XPathEvaluator(config);
xpath.setXPathFunctionResolver(functionResolver);
xpath.setXPathVariableResolver(variableResolver);
return xpath;
}
private static String FEATURE_SECURE_PROCESSING = XMLConstants.FEATURE_SECURE_PROCESSING;
// "http://javax.xml.XMLConstants/feature/secure-processing";
}