use of org.exist.source.DBSource in project exist by eXist-db.
the class RpcConnection method execute.
@Deprecated
@Override
public Map<String, Object> execute(final String pathToQuery, final Map<String, Object> parameters) throws EXistException, PermissionDeniedException {
final long startTime = System.currentTimeMillis();
final Optional<String> sortBy = Optional.ofNullable(parameters.get(RpcAPI.SORT_EXPR)).map(Object::toString);
return this.<Map<String, Object>>readDocument(XmldbURI.createInternal(pathToQuery)).apply((document, broker, transaction) -> {
final BinaryDocument xquery = (BinaryDocument) document;
if (xquery.getResourceType() != DocumentImpl.BINARY_FILE) {
throw new EXistException("Document " + pathToQuery + " is not a binary resource");
}
if (!xquery.getPermissions().validate(user, Permission.READ | Permission.EXECUTE)) {
throw new PermissionDeniedException("Insufficient privileges to access resource");
}
final Source source = new DBSource(broker, xquery, true);
try {
final Map<String, Object> rpcResponse = this.<Map<String, Object>>compileQuery(broker, transaction, source, parameters).apply(compiledQuery -> queryResultToRpcResponse(startTime, doQuery(broker, compiledQuery, null, parameters), sortBy));
return rpcResponse;
} catch (final XPathException e) {
throw new EXistException(e);
}
});
}
use of org.exist.source.DBSource in project exist by eXist-db.
the class UserXQueryJob method executeXQuery.
private void executeXQuery(final BrokerPool pool, final DBBroker broker, final Source source, final Properties params) throws PermissionDeniedException, XPathException, JobExecutionException {
XQueryPool xqPool = null;
CompiledXQuery compiled = null;
XQueryContext context = null;
try {
// execute the xquery
final XQuery xquery = pool.getXQueryService();
xqPool = pool.getXQueryPool();
// try and get a pre-compiled query from the pool
compiled = xqPool.borrowCompiledXQuery(broker, source);
if (compiled == null) {
context = new XQueryContext(pool);
} else {
context = compiled.getContext();
context.prepareForReuse();
}
if (source instanceof DBSource) {
final XmldbURI collectionUri = ((DBSource) source).getDocumentPath().removeLastSegment();
context.setModuleLoadPath(XmldbURI.EMBEDDED_SERVER_URI.append(collectionUri.getCollectionPath()).toString());
context.setStaticallyKnownDocuments(new XmldbURI[] { collectionUri });
}
if (compiled == null) {
try {
compiled = xquery.compile(context, source);
} catch (final IOException e) {
abort("Failed to read query from " + xqueryResource);
}
}
// declare any parameters as external variables
if (params != null) {
String bindingPrefix = params.getProperty("bindingPrefix");
if (bindingPrefix == null) {
bindingPrefix = "local";
}
for (final Entry param : params.entrySet()) {
final String key = (String) param.getKey();
final String value = (String) param.getValue();
context.declareVariable(bindingPrefix + ":" + key, new StringValue(value));
}
}
xquery.execute(broker, compiled, null);
} finally {
if (context != null) {
context.runCleanupTasks();
}
// return the compiled query to the pool
if (xqPool != null && source != null && compiled != null) {
xqPool.returnCompiledXQuery(source, compiled);
}
}
}
use of org.exist.source.DBSource in project exist by eXist-db.
the class XQuery method compile.
/**
* Compiles an XQuery from a Source.
*
* @param context the XQuery context
* @param reader the reader to use for obtaining theXQuery to compile
* @param xpointer true if the query is part of an XPointer, false otherwise
*
* @return the compiled XQuery
*
* @throws XPathException if an error occurs during compilation
* @throws PermissionDeniedException if the caller is not permitted to compile the XQuery
*/
private CompiledXQuery compile(final XQueryContext context, final Reader reader, final boolean xpointer) throws XPathException, PermissionDeniedException {
// check read permission
if (context.getSource() instanceof DBSource) {
((DBSource) context.getSource()).validate(Permission.READ);
}
// TODO: move XQueryContext.getUserFromHttpSession() here, have to check if servlet.jar is in the classpath
// before compiling/executing that code though to avoid a dependency on servlet.jar - reflection? - deliriumsky
// how about - if(XQuery.class.getResource("servlet.jar") != null) do load my class with dependency and call method?
/*
<|wolf77|> I think last time I checked, I already had problems with the call to
<|wolf77|> HTTPUtils.addLastModifiedHeader( result, context );
<|wolf77|> in line 184 of XQuery.java, because it introduces another dependency on HTTP.
*/
final long start = System.currentTimeMillis();
final XQueryLexer lexer = new XQueryLexer(context, reader);
final XQueryParser parser = new XQueryParser(lexer);
final XQueryTreeParser treeParser = new XQueryTreeParser(context);
try {
if (xpointer) {
parser.xpointer();
} else {
parser.xpath();
}
if (parser.foundErrors()) {
LOG.debug(parser.getErrorMessage());
throw new StaticXQueryException(parser.getErrorMessage());
}
final AST ast = parser.getAST();
if (ast == null) {
throw new XPathException("Unknown XQuery parser error: the parser returned an empty syntax tree.");
}
// LOG.debug("Generated AST: " + ast.toStringTree());
final PathExpr expr = new PathExpr(context);
if (xpointer) {
treeParser.xpointer(ast, expr);
} else {
treeParser.xpath(ast, expr);
}
if (treeParser.foundErrors()) {
// AST treeAst = treeParser.getAST();
throw new StaticXQueryException(ast.getLine(), ast.getColumn(), treeParser.getErrorMessage(), treeParser.getLastException());
}
context.getRootContext().resolveForwardReferences();
context.analyzeAndOptimizeIfModulesChanged(expr);
// dumping huge queries to the log
if (LOG.isDebugEnabled()) {
if (context.getExpressionCount() < 150) {
LOG.debug("Query diagnostics:\n{}", ExpressionDumper.dump(expr));
} else {
LOG.debug("Query diagnostics:\n" + "[skipped: more than 150 expressions]");
}
}
if (LOG.isDebugEnabled()) {
final NumberFormat nf = NumberFormat.getNumberInstance();
LOG.debug("Compilation took {} ms", nf.format(System.currentTimeMillis() - start));
}
return expr;
} catch (final RecognitionException e) {
LOG.debug("Error compiling query: {}", e.getMessage(), e);
String msg = e.getMessage();
if (msg.endsWith(", found 'null'")) {
msg = msg.substring(0, msg.length() - ", found 'null'".length());
}
throw new StaticXQueryException(e.getLine(), e.getColumn(), msg);
} catch (final TokenStreamException e) {
final String es = e.toString();
if (es.matches("^line \\d+:\\d+:.+")) {
LOG.debug("Error compiling query: {}", e.getMessage(), e);
final int line = Integer.parseInt(es.substring(5, es.indexOf(':')));
final String tmpColumn = es.substring(es.indexOf(':') + 1);
final int column = Integer.parseInt(tmpColumn.substring(0, tmpColumn.indexOf(':')));
throw new StaticXQueryException(line, column, e.getMessage(), e);
} else {
LOG.debug("Error compiling query: {}", e.getMessage(), e);
throw new StaticXQueryException(e.getMessage(), e);
}
}
}
use of org.exist.source.DBSource in project exist by eXist-db.
the class XQuery method execute.
public Sequence execute(final DBBroker broker, final CompiledXQuery expression, Sequence contextSequence, final Properties outputProperties, final boolean resetContext) throws XPathException, PermissionDeniedException {
// check execute permissions
if (expression.getContext().getSource() instanceof DBSource) {
((DBSource) expression.getContext().getSource()).validate(Permission.EXECUTE);
}
final long start = System.currentTimeMillis();
final XQueryContext context = expression.getContext();
expression.reset();
if (resetContext) {
// context.setBroker(broker);
context.getWatchDog().reset();
}
if (context.requireDebugMode()) {
final Debuggee debuggee = broker.getBrokerPool().getDebuggee();
if (debuggee != null) {
debuggee.joint(expression);
}
}
// do any preparation before execution
context.prepareForExecution();
final Subject callingUser = broker.getCurrentSubject();
// if setUid or setGid, become Effective User
EffectiveSubject effectiveSubject = null;
final Source src = expression.getContext().getSource();
if (src instanceof DBSource) {
final DBSource dbSrc = (DBSource) src;
final Permission perm = dbSrc.getPermissions();
if (perm.isSetUid()) {
if (perm.isSetGid()) {
// setUid and SetGid
effectiveSubject = new EffectiveSubject(perm.getOwner(), perm.getGroup());
} else {
// just setUid
effectiveSubject = new EffectiveSubject(perm.getOwner());
}
} else if (perm.isSetGid()) {
// just setGid, so we use the current user as the effective user
effectiveSubject = new EffectiveSubject(callingUser, perm.getGroup());
}
}
try {
if (effectiveSubject != null) {
// switch to effective user (e.g. setuid/setgid)
broker.pushSubject(effectiveSubject);
}
context.getProfiler().traceQueryStart();
broker.getBrokerPool().getProcessMonitor().queryStarted(context.getWatchDog());
try {
// support for XQuery 3.0 - declare context item :=
if (contextSequence == null) {
if (context.getContextItemDeclartion() != null) {
contextSequence = context.getContextItemDeclartion().eval(null, null);
}
}
final Sequence result = expression.eval(contextSequence);
if (LOG.isDebugEnabled()) {
final NumberFormat nf = NumberFormat.getNumberInstance();
LOG.debug("Execution took {} ms", nf.format(System.currentTimeMillis() - start));
}
if (outputProperties != null) {
// must be done before context.reset!
context.checkOptions(outputProperties);
}
return result;
} finally {
context.getProfiler().traceQueryEnd(context);
// track query stats before context is reset
broker.getBrokerPool().getProcessMonitor().queryCompleted(context.getWatchDog());
expression.reset();
if (resetContext) {
context.reset();
}
}
} finally {
if (effectiveSubject != null) {
broker.popSubject();
}
}
}
use of org.exist.source.DBSource in project exist by eXist-db.
the class XQueryURLRewrite method findSourceFromDb.
@Nullable
private SourceInfo findSourceFromDb(final DBBroker broker, final String basePath, final String path, final String[] components) {
LockedDocument lockedControllerDoc = null;
try {
final XmldbURI locationUri = XmldbURI.xmldbUriFor(basePath);
XmldbURI resourceUri = locationUri;
for (final String component : components) {
resourceUri = resourceUri.append(component);
}
lockedControllerDoc = findDbControllerXql(broker, locationUri, resourceUri);
if (lockedControllerDoc == null) {
LOG.warn("XQueryURLRewrite controller could not be found for path: {}", path);
return null;
}
final DocumentImpl controllerDoc = lockedControllerDoc.getDocument();
if (LOG.isTraceEnabled()) {
LOG.trace("Found controller file: {}", controllerDoc.getURI());
}
if (controllerDoc.getResourceType() != DocumentImpl.BINARY_FILE || !"application/xquery".equals(controllerDoc.getMimeType())) {
LOG.warn("XQuery resource: {} is not an XQuery or declares a wrong mime-type", query);
return null;
}
final String controllerPath = controllerDoc.getCollection().getURI().getRawCollectionPath();
return new SourceInfo(new DBSource(broker, (BinaryDocument) controllerDoc, true), "xmldb:exist://" + controllerPath, controllerPath.substring(locationUri.getCollectionPath().length()));
} catch (final URISyntaxException e) {
LOG.warn("Bad URI for base path: {}", e.getMessage(), e);
return null;
} finally {
if (lockedControllerDoc != null) {
lockedControllerDoc.close();
}
}
}
Aggregations