use of org.exist.xquery.value.FunctionReference in project exist by eXist-db.
the class InspectFunction method eval.
@Override
public Sequence eval(final Sequence[] args, final Sequence contextSequence) throws XPathException {
final FunctionReference ref = (FunctionReference) args[0].itemAt(0);
final FunctionSignature sig = ref.getSignature();
try {
context.pushDocumentContext();
final MemTreeBuilder builder = context.getDocumentBuilder();
final int nodeNr = InspectFunctionHelper.generateDocs(sig, null, builder);
return builder.getDocument().getNode(nodeNr);
} finally {
context.popDocumentContext();
}
}
use of org.exist.xquery.value.FunctionReference in project exist by eXist-db.
the class ResourceFunctionExecutorImpl method execute.
@Override
public Sequence execute(final ResourceFunction resourceFunction, final Iterable<TypedArgumentValue> arguments, final HttpRequest request) throws RestXqServiceException {
final RestXqServiceCompiledXQueryCache cache = RestXqServiceCompiledXQueryCacheImpl.getInstance();
CompiledXQuery xquery = null;
ProcessMonitor processMonitor = null;
try (final DBBroker broker = getBrokerPool().getBroker()) {
// ensure we can execute the function before going any further
checkSecurity(broker, resourceFunction.getXQueryLocation());
// get a compiled query service from the cache
xquery = cache.getCompiledQuery(broker, resourceFunction.getXQueryLocation());
// find the function that we will execute
final UserDefinedFunction fn = findFunction(xquery, resourceFunction.getFunctionSignature());
final XQueryContext xqueryContext = xquery.getContext();
// set the request object - can later be used by the EXQuery Request Module
xqueryContext.setAttribute(EXQ_REQUEST_ATTR, request);
// TODO this is a workaround?
declareVariables(xqueryContext);
// START workaround: evaluate global variables in modules, as they are reset by XQueryContext.reset()
final Expression rootExpr = xqueryContext.getRootExpression();
for (int i = 0; i < rootExpr.getSubExpressionCount(); i++) {
final Expression subExpr = rootExpr.getSubExpression(i);
if (subExpr instanceof VariableDeclaration) {
subExpr.eval(null);
}
}
// END workaround
// setup monitoring
processMonitor = broker.getBrokerPool().getProcessMonitor();
xqueryContext.getProfiler().traceQueryStart();
processMonitor.queryStarted(xqueryContext.getWatchDog());
// create a function call
try (final FunctionReference fnRef = new FunctionReference(new FunctionCall(xqueryContext, fn))) {
// convert the arguments
final org.exist.xquery.value.Sequence[] fnArgs = convertToExistFunctionArguments(xqueryContext, fn, arguments);
// execute the function call
fnRef.analyze(new AnalyzeContextInfo());
// if setUid/setGid, determine the effectiveSubject to use for execution
final Optional<EffectiveSubject> effectiveSubject = getEffectiveSubject(xquery);
try {
// switch to effective user if setUid/setGid
effectiveSubject.ifPresent(broker::pushSubject);
final org.exist.xquery.value.Sequence result = fnRef.evalFunction(null, null, fnArgs);
// copy for closure
final CompiledXQuery xquery1 = xquery;
// return a sequence adapter which returns the query when it is finished with the results
return new SequenceAdapter(result, () -> {
if (xquery1 != null) {
// return the compiled query to the pool
cache.returnCompiledQuery(resourceFunction.getXQueryLocation(), xquery1);
}
});
} finally {
// switch back from effective user if setUid/setGid
if (effectiveSubject.isPresent()) {
broker.popSubject();
}
}
}
} catch (final URISyntaxException | EXistException | XPathException | PermissionDeniedException use) {
// if an error occurred we should return the compiled query
if (xquery != null) {
// return the compiled query to the pool
cache.returnCompiledQuery(resourceFunction.getXQueryLocation(), xquery);
}
throw new RestXqServiceException(use.getMessage(), use);
} finally {
// clear down monitoring
if (processMonitor != null) {
xquery.getContext().getProfiler().traceQueryEnd(xquery.getContext());
processMonitor.queryCompleted(xquery.getContext().getWatchDog());
}
}
}
use of org.exist.xquery.value.FunctionReference in project exist by eXist-db.
the class FunOnFunctions method eval.
@Override
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
try {
if (isCalledAs("function-lookup")) {
final QName fname = ((QNameValue) args[0].itemAt(0)).getQName();
final int arity = ((IntegerValue) args[1].itemAt(0)).getInt();
FunctionCall call;
try {
call = NamedFunctionReference.lookupFunction(this, context, fname, arity);
} catch (final XPathException e) {
if (e.getErrorCode() == ErrorCodes.XPST0017) {
// return empty sequence for all "function not found" related errors
return Sequence.EMPTY_SEQUENCE;
}
throw e;
}
return call == null ? Sequence.EMPTY_SEQUENCE : new FunctionReference(call);
} else if (isCalledAs("function-name")) {
final FunctionReference ref = (FunctionReference) args[0].itemAt(0);
final QName qname = ref.getSignature().getName();
if (qname == null || qname == InlineFunction.INLINE_FUNCTION_QNAME) {
return Sequence.EMPTY_SEQUENCE;
} else {
return new QNameValue(context, qname);
}
} else {
// isCalledAs("function-arity")
final FunctionReference ref = (FunctionReference) args[0].itemAt(0);
return new IntegerValue(ref.getSignature().getArgumentCount());
}
} catch (final Exception e) {
if (e instanceof XPathException) {
throw (XPathException) e;
} else {
throw new XPathException(this, ErrorCodes.XPST0017, e.getMessage());
}
}
}
use of org.exist.xquery.value.FunctionReference in project exist by eXist-db.
the class XMLTestRunner method run.
@Override
public void run(final RunNotifier notifier) {
try {
final String pkgName = getClass().getPackage().getName().replace('.', '/');
final Source query = new ClassLoaderSource(pkgName + "/xml-test-runner.xq");
final List<java.util.function.Function<XQueryContext, Tuple2<String, Object>>> externalVariableDeclarations = Arrays.asList(context -> new Tuple2<>("doc", doc), context -> new Tuple2<>("id", Sequence.EMPTY_SEQUENCE), // set callback functions for notifying junit!
context -> new Tuple2<>("test-ignored-function", new FunctionReference(new FunctionCall(context, new ExtTestIgnoredFunction(context, getSuiteName(), notifier)))), context -> new Tuple2<>("test-started-function", new FunctionReference(new FunctionCall(context, new ExtTestStartedFunction(context, getSuiteName(), notifier)))), context -> new Tuple2<>("test-failure-function", new FunctionReference(new FunctionCall(context, new ExtTestFailureFunction(context, getSuiteName(), notifier)))), context -> new Tuple2<>("test-assumption-failed-function", new FunctionReference(new FunctionCall(context, new ExtTestAssumptionFailedFunction(context, getSuiteName(), notifier)))), context -> new Tuple2<>("test-error-function", new FunctionReference(new FunctionCall(context, new ExtTestErrorFunction(context, getSuiteName(), notifier)))), context -> new Tuple2<>("test-finished-function", new FunctionReference(new FunctionCall(context, new ExtTestFinishedFunction(context, getSuiteName(), notifier)))));
// NOTE: at this stage EXIST_EMBEDDED_SERVER_CLASS_INSTANCE in XSuite will be usable
final BrokerPool brokerPool = XSuite.EXIST_EMBEDDED_SERVER_CLASS_INSTANCE.getBrokerPool();
executeQuery(brokerPool, query, externalVariableDeclarations);
} catch (final DatabaseConfigurationException | IOException | EXistException | PermissionDeniedException | XPathException e) {
// TODO(AR) what to do here?
throw new RuntimeException(e);
}
}
use of org.exist.xquery.value.FunctionReference in project exist by eXist-db.
the class XQueryTestRunner method run.
@Override
public void run(final RunNotifier notifier) {
try {
final String pkgName = getClass().getPackage().getName().replace('.', '/');
final Source query = new ClassLoaderSource(pkgName + "/xquery-test-runner.xq");
final URI testModuleUri = path.toAbsolutePath().toUri();
final String suiteName = getSuiteName();
final List<java.util.function.Function<XQueryContext, Tuple2<String, Object>>> externalVariableDeclarations = Arrays.asList(context -> new Tuple2<>("test-module-uri", new AnyURIValue(testModuleUri)), // set callback functions for notifying junit!
context -> new Tuple2<>("test-ignored-function", new FunctionReference(new FunctionCall(context, new ExtTestIgnoredFunction(context, suiteName, notifier)))), context -> new Tuple2<>("test-started-function", new FunctionReference(new FunctionCall(context, new ExtTestStartedFunction(context, suiteName, notifier)))), context -> new Tuple2<>("test-failure-function", new FunctionReference(new FunctionCall(context, new ExtTestFailureFunction(context, suiteName, notifier)))), context -> new Tuple2<>("test-assumption-failed-function", new FunctionReference(new FunctionCall(context, new ExtTestAssumptionFailedFunction(context, suiteName, notifier)))), context -> new Tuple2<>("test-error-function", new FunctionReference(new FunctionCall(context, new ExtTestErrorFunction(context, suiteName, notifier)))), context -> new Tuple2<>("test-finished-function", new FunctionReference(new FunctionCall(context, new ExtTestFinishedFunction(context, suiteName, notifier)))));
// NOTE: at this stage EXIST_EMBEDDED_SERVER_CLASS_INSTANCE in XSuite will be usable
final BrokerPool brokerPool = XSuite.EXIST_EMBEDDED_SERVER_CLASS_INSTANCE.getBrokerPool();
executeQuery(brokerPool, query, externalVariableDeclarations);
} catch (final DatabaseConfigurationException | IOException | EXistException | PermissionDeniedException | XPathException e) {
// TODO(AR) what to do here?
throw new RuntimeException(e);
}
}
Aggregations