use of org.exist.xquery.value.FunctionReference in project exist by eXist-db.
the class CallFunction method eval.
/* (non-Javadoc)
* @see org.exist.xquery.BasicFunction#eval(org.exist.xquery.value.Sequence[], org.exist.xquery.value.Sequence)
*/
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
final Sequence arg0 = getArgument(0).eval(contextSequence, contextItem);
if (arg0.getCardinality() != Cardinality.EXACTLY_ONE) {
throw new XPathException(this, "Expected exactly one item for first argument");
}
final Item item0 = arg0.itemAt(0);
if (item0.getType() != Type.FUNCTION_REFERENCE) {
throw new XPathException(this, "Type error: expected function, got " + Type.getTypeName(item0.getType()));
}
try (final FunctionReference ref = (FunctionReference) item0) {
// pass the remaining parameters to the function call
final List<Expression> params = new ArrayList<>(getArgumentCount() - 1);
for (int i = 1; i < getArgumentCount(); i++) {
params.add(getArgument(i));
}
ref.setArguments(params);
ref.analyze(new AnalyzeContextInfo(this, 0));
// Evaluate the function
return ref.eval(contextSequence);
}
}
use of org.exist.xquery.value.FunctionReference in project exist by eXist-db.
the class CleanupTest method resetStateOfInlineFunc.
@Test
public void resetStateOfInlineFunc() throws XMLDBException, EXistException, PermissionDeniedException, XPathException {
final BrokerPool pool = BrokerPool.getInstance();
final XQuery xquery = pool.getXQueryService();
try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
// execute query to get a function item
final Sequence result = xquery.execute(broker, TEST_INLINE, Sequence.EMPTY_SEQUENCE);
assertEquals(result.getItemCount(), 1);
final FunctionCall call = ((FunctionReference) result.itemAt(0)).getCall();
// closure variables are set when function item is created, but should be cleared after query
final List<ClosureVariable> closure = call.getFunction().getClosureVariables();
assertNull(closure);
}
}
use of org.exist.xquery.value.FunctionReference in project exist by eXist-db.
the class ArrowOperator method eval.
@Override
public Sequence eval(Sequence contextSequence, final Item contextItem) throws XPathException {
if (contextItem != null) {
contextSequence = contextItem.toSequence();
}
contextSequence = leftExpr.eval(contextSequence);
final FunctionReference fref;
if (fcall != null) {
fref = new FunctionReference(fcall);
} else {
final Sequence funcSeq = funcSpec.eval(contextSequence, contextItem);
if (funcSeq.getCardinality() != Cardinality.EXACTLY_ONE) {
throw new XPathException(this, ErrorCodes.XPTY0004, "Expected exactly one item for the function to be called, got " + funcSeq.getItemCount() + ". Expression: " + ExpressionDumper.dump(funcSpec));
}
final Item item0 = funcSeq.itemAt(0);
if (!Type.subTypeOf(item0.getType(), Type.FUNCTION_REFERENCE)) {
throw new XPathException(this, ErrorCodes.XPTY0004, "Type error: expected function, got " + Type.getTypeName(item0.getType()));
}
fref = (FunctionReference) item0;
}
try {
final List<Expression> fparams = new ArrayList<>(parameters.size() + 1);
fparams.add(new ContextParam(context, contextSequence));
fparams.addAll(parameters);
fref.setArguments(fparams);
// need to create a new AnalyzeContextInfo to avoid memory leak
// cachedContextInfo will stay in memory
fref.analyze(new AnalyzeContextInfo(cachedContextInfo));
// Evaluate the function
return fref.eval(null);
} finally {
fref.close();
}
}
use of org.exist.xquery.value.FunctionReference in project exist by eXist-db.
the class DynamicFunctionCall method eval.
@Override
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
context.proceed(this);
final Sequence funcSeq = functionExpr.eval(contextSequence, contextItem);
if (funcSeq.getCardinality() != Cardinality.EXACTLY_ONE) {
throw new XPathException(this, ErrorCodes.XPTY0004, "Expected exactly one item for the function to be called, got " + funcSeq.getItemCount() + ". Expression: " + ExpressionDumper.dump(functionExpr));
}
final Item item0 = funcSeq.itemAt(0);
if (!Type.subTypeOf(item0.getType(), Type.FUNCTION_REFERENCE)) {
throw new XPathException(this, ErrorCodes.XPTY0004, "Type error: expected function, got " + Type.getTypeName(item0.getType()));
}
final FunctionReference ref = (FunctionReference) item0;
// if the call is a partial application, create a new function
if (isPartial) {
try {
final FunctionCall call = ref.getCall();
call.setArguments(arguments);
final PartialFunctionApplication partialApp = new PartialFunctionApplication(context, call);
partialApp.analyze(new AnalyzeContextInfo(cachedContextInfo));
return partialApp.eval(contextSequence, contextItem);
} catch (final XPathException e) {
e.setLocation(line, column, getSource());
throw e;
}
} else {
ref.setArguments(arguments);
// need to create a new AnalyzeContextInfo to avoid memory leak
// cachedContextInfo will stay in memory
ref.analyze(new AnalyzeContextInfo(cachedContextInfo));
// Evaluate the function
try {
return ref.eval(contextSequence);
} catch (XPathException e) {
if (e.getLine() <= 0) {
e.setLocation(getLine(), getColumn(), getSource());
}
throw e;
} finally {
ref.close();
}
}
}
use of org.exist.xquery.value.FunctionReference in project exist by eXist-db.
the class HighlightMatches method eval.
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
if (args[0].isEmpty())
return Sequence.EMPTY_SEQUENCE;
context.pushDocumentContext();
final Serializer serializer = context.getBroker().borrowSerializer();
try (FunctionReference func = (FunctionReference) args[1].itemAt(0)) {
MemTreeBuilder builder = context.getDocumentBuilder();
NGramIndexWorker index = (NGramIndexWorker) context.getBroker().getIndexController().getWorkerByIndexId(NGramIndex.ID);
DocumentBuilderReceiver docBuilder = new DocumentBuilderReceiver(builder);
MatchCallback matchCb = new MatchCallback(func, docBuilder);
ValueSequence result = new ValueSequence();
for (SequenceIterator i = args[0].iterate(); i.hasNext(); ) {
NodeValue v = (NodeValue) i.nextItem();
try {
int nodeNr = builder.getDocument().getLastNode();
if (v.getImplementationType() == NodeValue.IN_MEMORY_NODE) {
((NodeImpl) v).copyTo(context.getBroker(), docBuilder);
} else {
NodeProxy p = (NodeProxy) v;
MatchListener ml = index.getMatchListener(context.getBroker(), p, matchCb);
Receiver receiver;
if (ml == null)
receiver = docBuilder;
else {
ml.setNextInChain(docBuilder);
receiver = ml;
}
serializer.setReceiver(receiver);
serializer.toReceiver((NodeProxy) v, false);
}
result.add(builder.getDocument().getNode(++nodeNr));
} catch (SAXException e) {
LOG.warn(e.getMessage(), e);
throw new XPathException(this, e.getMessage());
}
}
return result;
} finally {
context.getBroker().returnSerializer(serializer);
context.popDocumentContext();
}
}
Aggregations