
net.sf.saxon.xqj.SaxonXQPreparedExpression Maven / Gradle / Ivy
package net.sf.saxon.xqj;
import net.sf.saxon.expr.Expression;
import net.sf.saxon.expr.instruct.GlobalParam;
import net.sf.saxon.expr.instruct.GlobalVariable;
import net.sf.saxon.lib.NamespaceConstant;
import net.sf.saxon.om.SequenceIterator;
import net.sf.saxon.om.StructuredQName;
import net.sf.saxon.query.DynamicQueryContext;
import net.sf.saxon.query.XQueryExpression;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.type.ItemType;
import net.sf.saxon.value.SequenceExtent;
import net.sf.saxon.value.SequenceType;
import net.sf.saxon.z.IntHashSet;
import net.sf.saxon.z.IntIterator;
import javax.xml.namespace.QName;
import javax.xml.xquery.*;
import java.util.HashMap;
import java.util.HashSet;
/**
* Saxon implementation of the XQJ interface XQPreparedExpression. This represents a compiled XQuery
* expression, together with the dynamic context for its evaluation. Note that this means the object
* should not be used in more than one thread concurrently.
*
* Note that an expression is scrollable or not depending on the scrollability property of the XQConnection
* that was used to compile this expression (at the time it was compiled). If the expression is scrollable then
* its results are delivered in an XQSequence that supports scrolling backwards as well as forwards.
*
* For full Javadoc details, see the XQJ interface specification.
*/
public class SaxonXQPreparedExpression extends SaxonXQDynamicContext implements XQPreparedExpression {
private XQueryExpression expression;
private SaxonXQStaticContext staticContext;
private DynamicQueryContext context;
private boolean scrollable;
protected SaxonXQPreparedExpression(SaxonXQConnection connection,
XQueryExpression expression,
/*@NotNull*/ SaxonXQStaticContext sqc,
DynamicQueryContext context)
throws XQException {
this.connection = connection;
this.expression = expression;
this.staticContext = new SaxonXQStaticContext(sqc); // take a snapshot of the supplied static context
this.context = context;
scrollable = sqc.getScrollability() == XQConstants.SCROLLTYPE_SCROLLABLE;
setClosableContainer(connection);
}
protected DynamicQueryContext getDynamicContext() {
return context;
}
protected SaxonXQConnection getConnection() {
return connection;
}
protected SaxonXQDataFactory getDataFactory() throws XQException {
if (connection.isClosed()) {
close();
}
checkNotClosed();
return connection;
}
protected XQueryExpression getXQueryExpression() {
return expression;
}
protected SaxonXQStaticContext getSaxonXQStaticContext() {
return staticContext;
}
public void cancel() throws XQException {
checkNotClosed();
}
/*@NotNull*/ public XQResultSequence executeQuery() throws XQException {
checkNotClosed();
try {
SequenceIterator iter = expression.iterator(context);
if (scrollable) {
SequenceExtent value = new SequenceExtent(iter);
return new SaxonXQSequence(value, this);
} else {
return new SaxonXQForwardSequence(iter, this);
}
} catch (XPathException de) {
XQException xqe = new XQException(de.getMessage());
xqe.initCause(de);
throw xqe;
}
}
/*@NotNull*/ public QName[] getAllExternalVariables() throws XQException {
checkNotClosed();
HashMap vars = expression.getExecutable().getCompiledGlobalVariables();
if (vars == null || vars.isEmpty()) {
return EMPTY_QNAME_ARRAY;
} else {
HashSet params = new HashSet(vars.size());
for (GlobalVariable var : vars.values()) {
if (var instanceof GlobalParam) {
StructuredQName q = var.getVariableQName();
if (!(q.getURI().equals(NamespaceConstant.SAXON) && q.getLocalPart().equals("context-item"))) {
params.add(q);
}
}
}
QName[] qnames = new QName[params.size()];
int q=0;
for (StructuredQName name : params) {
qnames[q++] = new QName(name.getURI(), name.getLocalPart(), name.getPrefix());
}
return qnames;
}
}
/*@NotNull*/ private static QName[] EMPTY_QNAME_ARRAY = new QName[0];
/*@NotNull*/ public QName[] getAllUnboundExternalVariables() throws XQException {
checkNotClosed();
java.util.Collection boundParameters = getDynamicContext().getParameters().getKeys();
IntHashSet unbound = new IntHashSet(boundParameters.size());
QName[] all = getAllExternalVariables();
for (int i=0; i