use of org.exist.source.Source in project exist by eXist-db.
the class XQueryStartupTrigger method executeQuery.
/**
* Execute xquery on path
*
* @param broker eXist database broker
* @param path path to query, formatted as xmldb:exist:///db/...
*/
private void executeQuery(DBBroker broker, String path) {
XQueryContext context = null;
try {
// Get path to xquery
Source source = SourceFactory.getSource(broker, null, path, false);
if (source == null) {
LOG.info("No XQuery found at '{}'", path);
} else {
// Setup xquery service
XQuery service = broker.getBrokerPool().getXQueryService();
context = new XQueryContext(broker.getBrokerPool());
// Allow use of modules with relative paths
String moduleLoadPath = StringUtils.substringBeforeLast(path, "/");
context.setModuleLoadPath(moduleLoadPath);
// Compile query
CompiledXQuery compiledQuery = service.compile(context, source);
LOG.info("Starting XQuery at '{}'", path);
// Finish preparation
context.prepareForExecution();
// Execute
Sequence result = service.execute(broker, compiledQuery, null);
// Log results
LOG.info("Result XQuery: '{}'", result.getStringValue());
}
} catch (Throwable t) {
// Dirty, catch it all
LOG.error("An error occurred during preparation/execution of the XQuery script {}: {}", path, t.getMessage(), t);
} finally {
if (context != null) {
context.runCleanupTasks();
}
}
}
use of org.exist.source.Source in project exist by eXist-db.
the class XQueryTrigger method finish.
private void finish(int event, DBBroker broker, Txn transaction, XmldbURI src, XmldbURI dst, boolean isCollection) {
// get the query
final Source query = getQuerySource(broker);
if (query == null) {
return;
}
// avoid infinite recursion by allowing just one trigger per thread
if (!TriggerStatePerThread.verifyUniqueTriggerPerThreadBeforeFinish(this, src)) {
return;
}
final XQueryContext context = new XQueryContext(broker.getBrokerPool());
CompiledXQuery compiledQuery = null;
try {
// compile the XQuery
compiledQuery = service.compile(context, query);
// declare external variables
context.declareVariable(bindingPrefix + "type", EVENT_TYPE_FINISH);
context.declareVariable(bindingPrefix + "event", new StringValue(eventToString(event)));
if (isCollection) {
context.declareVariable(bindingPrefix + "collection", new AnyURIValue(src));
} else {
context.declareVariable(bindingPrefix + "collection", new AnyURIValue(src.removeLastSegment()));
}
context.declareVariable(bindingPrefix + "uri", new AnyURIValue(src));
if (dst == null) {
context.declareVariable(bindingPrefix + "new-uri", Sequence.EMPTY_SEQUENCE);
} else {
context.declareVariable(bindingPrefix + "new-uri", new AnyURIValue(dst));
}
// For backward compatibility
context.declareVariable(bindingPrefix + "eventType", EVENT_TYPE_FINISH);
context.declareVariable(bindingPrefix + "triggerEvent", new StringValue(eventToString(event)));
if (isCollection) {
context.declareVariable(bindingPrefix + "collectionName", new AnyURIValue(src));
} else {
context.declareVariable(bindingPrefix + "collectionName", new AnyURIValue(src.removeLastSegment()));
context.declareVariable(bindingPrefix + "documentName", new AnyURIValue(src));
}
// declare user defined parameters as external variables
for (Object o : userDefinedVariables.keySet()) {
final String varName = (String) o;
final String varValue = userDefinedVariables.getProperty(varName);
context.declareVariable(bindingPrefix + varName, new StringValue(varValue));
}
} catch (final XPathException | IOException | PermissionDeniedException e) {
// Should never be reached
LOG.error(e);
}
// execute the XQuery
try {
// TODO : should we provide another contextSet ?
final NodeSet contextSet = NodeSet.EMPTY_SET;
service.execute(broker, compiledQuery, contextSet);
// TODO : should we have a special processing ?
} catch (final XPathException e) {
// Should never be reached
LOG.error("Error during trigger finish", e);
} catch (final PermissionDeniedException e) {
// Should never be reached
LOG.error(e);
}
TriggerStatePerThread.setTriggerRunningState(TriggerStatePerThread.NO_TRIGGER_RUNNING, this, null);
TriggerStatePerThread.setTransaction(null);
LOG.debug("Trigger fired for finish");
}
use of org.exist.source.Source in project exist by eXist-db.
the class XQueryTrigger method prepare.
private void prepare(int event, DBBroker broker, Txn transaction, XmldbURI src, XmldbURI dst, boolean isCollection) throws TriggerException {
// get the query
final Source query = getQuerySource(broker);
if (query == null) {
return;
}
// avoid infinite recursion by allowing just one trigger per thread
if (!TriggerStatePerThread.verifyUniqueTriggerPerThreadBeforePrepare(this, src)) {
return;
}
TriggerStatePerThread.setTransaction(transaction);
final XQueryContext context = new XQueryContext(broker.getBrokerPool());
// TODO : further initialisations ?
CompiledXQuery compiledQuery;
try {
// compile the XQuery
compiledQuery = service.compile(context, query);
// declare external variables
context.declareVariable(bindingPrefix + "type", EVENT_TYPE_PREPARE);
context.declareVariable(bindingPrefix + "event", new StringValue(eventToString(event)));
if (isCollection) {
context.declareVariable(bindingPrefix + "collection", new AnyURIValue(src));
} else {
context.declareVariable(bindingPrefix + "collection", new AnyURIValue(src.removeLastSegment()));
}
context.declareVariable(bindingPrefix + "uri", new AnyURIValue(src));
if (dst == null) {
context.declareVariable(bindingPrefix + "new-uri", Sequence.EMPTY_SEQUENCE);
} else {
context.declareVariable(bindingPrefix + "new-uri", new AnyURIValue(dst));
}
// For backward compatibility
context.declareVariable(bindingPrefix + "eventType", EVENT_TYPE_PREPARE);
context.declareVariable(bindingPrefix + "triggerEvent", new StringValue(eventToString(event)));
if (isCollection) {
context.declareVariable(bindingPrefix + "collectionName", new AnyURIValue(src));
} else {
context.declareVariable(bindingPrefix + "collectionName", new AnyURIValue(src.removeLastSegment()));
context.declareVariable(bindingPrefix + "documentName", new AnyURIValue(src));
}
// declare user defined parameters as external variables
for (Object o : userDefinedVariables.keySet()) {
final String varName = (String) o;
final String varValue = userDefinedVariables.getProperty(varName);
context.declareVariable(bindingPrefix + varName, new StringValue(varValue));
}
} catch (final XPathException | IOException | PermissionDeniedException e) {
TriggerStatePerThread.setTriggerRunningState(TriggerStatePerThread.NO_TRIGGER_RUNNING, this, null);
TriggerStatePerThread.setTransaction(null);
throw new TriggerException(PREPARE_EXCEPTION_MESSAGE, e);
}
// execute the XQuery
try {
// TODO : should we provide another contextSet ?
final NodeSet contextSet = NodeSet.EMPTY_SET;
service.execute(broker, compiledQuery, contextSet);
// TODO : should we have a special processing ?
LOG.debug("Trigger fired for prepare");
} catch (final XPathException | PermissionDeniedException e) {
TriggerStatePerThread.setTriggerRunningState(TriggerStatePerThread.NO_TRIGGER_RUNNING, this, null);
TriggerStatePerThread.setTransaction(null);
throw new TriggerException(PREPARE_EXCEPTION_MESSAGE, e);
}
}
use of org.exist.source.Source in project exist by eXist-db.
the class RESTServer method executeXQuery.
/**
* Directly execute an XQuery stored as a binary document in the database.
*
* @throws PermissionDeniedException
*/
private void executeXQuery(final DBBroker broker, final Txn transaction, final DocumentImpl resource, final HttpServletRequest request, final HttpServletResponse response, final Properties outputProperties, final String servletPath, final String pathInfo) throws XPathException, BadRequestException, PermissionDeniedException {
final Source source = new DBSource(broker, (BinaryDocument) resource, true);
final XQueryPool pool = broker.getBrokerPool().getXQueryPool();
CompiledXQuery compiled = null;
try {
final XQuery xquery = broker.getBrokerPool().getXQueryService();
compiled = pool.borrowCompiledXQuery(broker, source);
XQueryContext context;
if (compiled == null) {
// special header to indicate that the query is not returned from
// cache
response.setHeader("X-XQuery-Cached", "false");
context = new XQueryContext(broker.getBrokerPool());
} else {
response.setHeader("X-XQuery-Cached", "true");
context = compiled.getContext();
context.prepareForReuse();
}
// TODO: don't hardcode this?
context.setModuleLoadPath(XmldbURI.EMBEDDED_SERVER_URI.append(resource.getCollection().getURI()).toString());
context.setStaticallyKnownDocuments(new XmldbURI[] { resource.getCollection().getURI() });
final HttpRequestWrapper reqw = declareVariables(context, null, request, response);
reqw.setServletPath(servletPath);
reqw.setPathInfo(pathInfo);
final long compilationTime;
if (compiled == null) {
try {
final long compilationStart = System.currentTimeMillis();
compiled = xquery.compile(context, source);
compilationTime = System.currentTimeMillis() - compilationStart;
} catch (final IOException e) {
throw new BadRequestException("Failed to read query from " + resource.getURI(), e);
}
} else {
compilationTime = 0;
}
DebuggeeFactory.checkForDebugRequest(request, context);
boolean wrap = outputProperties.getProperty("_wrap") != null && "yes".equals(outputProperties.getProperty("_wrap"));
try {
final long executeStart = System.currentTimeMillis();
final Sequence result = xquery.execute(broker, compiled, null, outputProperties);
writeResults(response, broker, transaction, result, -1, 1, false, outputProperties, wrap, compilationTime, System.currentTimeMillis() - executeStart);
} finally {
context.runCleanupTasks();
}
} finally {
if (compiled != null) {
pool.returnCompiledXQuery(source, compiled);
}
}
}
use of org.exist.source.Source in project exist by eXist-db.
the class XQueryPool method isCompiledQueryValid.
/**
* Determines if a compiled XQuery is still valid.
*
* @param broker the database broker
* @param source the source of the query
* @param compiledXQuery the compiled query
*
* @return true if the compiled query is still valid, false otherwise.
*/
private static boolean isCompiledQueryValid(final DBBroker broker, final Source source, final CompiledXQuery compiledXQuery) {
final Source cachedSource = compiledXQuery.getSource();
Source.Validity validity = cachedSource.isValid(broker);
if (validity == Source.Validity.UNKNOWN) {
validity = cachedSource.isValid(source);
}
if (validity == Source.Validity.INVALID || validity == Source.Validity.UNKNOWN) {
// returning null will remove the entry from the cache
return false;
}
// modules may have changed
return compiledXQuery.isValid();
}
Aggregations