}
@Override
public Sequence execute(final ResourceFunction resourceFunction, final Iterable<TypedArgumentValue> arguments, final HttpRequest request) throws RestXqServiceException {
final RestXqServiceCompiledXQueryCache cache = RestXqServiceCompiledXQueryCacheImpl.getInstance();
DBBroker broker = null;
CompiledXQuery xquery = null;
ProcessMonitor processMonitor = null;
try {
broker = getBrokerPool().get(getBrokerPool().getSubject());
//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
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());
final org.exist.xquery.value.Sequence result = fnRef.evalFunction(null, null, fnArgs);
return new SequenceAdapter(result);
} catch(final URISyntaxException use) {
throw new RestXqServiceException(use.getMessage(), use);
} catch(final PermissionDeniedException pde) {
throw new RestXqServiceException(pde.getMessage(), pde);
} catch(final XPathException xpe) {
throw new RestXqServiceException(xpe.getMessage(), xpe);
} catch(final EXistException ee) {
throw new RestXqServiceException(ee.getMessage(), ee);
} finally {
//clear down monitoring
if(processMonitor != null) {
xquery.getContext().getProfiler().traceQueryEnd(xquery.getContext());
processMonitor.queryCompleted(xquery.getContext().getWatchDog());
}
//return the broker
if(broker != null) {
getBrokerPool().release(broker);
}
if(xquery != null) {
//return the compiled query to the pool
cache.returnCompiledQuery(resourceFunction.getXQueryLocation(), xquery);
}
}
}