use of org.exist.xquery.parser.XQueryLexer in project exist by eXist-db.
the class Compile method eval.
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
// get the query expression
final String expr = args[0].getStringValue();
if (expr.trim().isEmpty()) {
return new EmptySequence();
}
context.pushNamespaceContext();
logger.debug("eval: {}", expr);
// TODO(pkaminsk2): why replicate XQuery.compile here?
String error = null;
ErrorCodes.ErrorCode code = null;
int line = -1;
int column = -1;
final XQueryContext pContext = new XQueryContext(context.getBroker().getBrokerPool());
if (getArgumentCount() == 2 && args[1].hasOne()) {
pContext.setModuleLoadPath(args[1].getStringValue());
}
final XQueryLexer lexer = new XQueryLexer(pContext, new StringReader(expr));
final XQueryParser parser = new XQueryParser(lexer);
// shares the context of the outer expression
final XQueryTreeParser astParser = new XQueryTreeParser(pContext);
try {
parser.xpath();
if (parser.foundErrors()) {
logger.debug(parser.getErrorMessage());
throw new XPathException(this, "error found while executing expression: " + parser.getErrorMessage());
}
final AST ast = parser.getAST();
final PathExpr path = new PathExpr(pContext);
astParser.xpath(ast, path);
if (astParser.foundErrors()) {
throw astParser.getLastException();
}
path.analyze(new AnalyzeContextInfo());
} catch (final RecognitionException | TokenStreamException e) {
error = e.toString();
} catch (final XPathException e) {
line = e.getLine();
column = e.getColumn();
code = e.getCode();
error = e.getDetailMessage();
} catch (final Exception e) {
error = e.getMessage();
} finally {
context.popNamespaceContext();
pContext.reset(false);
}
if (isCalledAs("compile")) {
return error == null ? Sequence.EMPTY_SEQUENCE : new StringValue(error);
} else {
return response(pContext, error, code, line, column);
}
}
use of org.exist.xquery.parser.XQueryLexer in project exist by eXist-db.
the class XUpdateProcessor method processQuery.
private Sequence processQuery(String select) throws SAXException {
XQueryContext context = null;
try {
context = new XQueryContext(broker.getBrokerPool());
context.setStaticallyKnownDocuments(documentSet);
Map.Entry<String, String> namespaceEntry;
for (Map.Entry<String, String> stringStringEntry : namespaces.entrySet()) {
namespaceEntry = stringStringEntry;
context.declareNamespace(namespaceEntry.getKey(), namespaceEntry.getValue());
}
Map.Entry<String, Object> entry;
for (Map.Entry<String, Object> stringObjectEntry : variables.entrySet()) {
entry = stringObjectEntry;
context.declareVariable(entry.getKey(), entry.getValue());
}
// TODO(pkaminsk2): why replicate XQuery.compile here?
final XQueryLexer lexer = new XQueryLexer(context, new StringReader(select));
final XQueryParser parser = new XQueryParser(lexer);
final XQueryTreeParser treeParser = new XQueryTreeParser(context);
parser.xpath();
if (parser.foundErrors()) {
throw new SAXException(parser.getErrorMessage());
}
final AST ast = parser.getAST();
if (LOG.isDebugEnabled()) {
LOG.debug("generated AST: {}", ast.toStringTree());
}
final PathExpr expr = new PathExpr(context);
treeParser.xpath(ast, expr);
if (treeParser.foundErrors()) {
throw new SAXException(treeParser.getErrorMessage());
}
expr.analyze(new AnalyzeContextInfo());
final Sequence seq = expr.eval(null, null);
return seq;
} catch (final RecognitionException | TokenStreamException e) {
LOG.warn("error while creating variable", e);
throw new SAXException(e);
} catch (final XPathException e) {
throw new SAXException(e);
} finally {
if (context != null) {
context.reset(false);
}
}
}
use of org.exist.xquery.parser.XQueryLexer in project exist by eXist-db.
the class LexerTest method query.
@Test
public void query() throws EXistException, PermissionDeniedException, IOException, SAXException, LockException, RecognitionException, XPathException, TokenStreamException {
String query = "//p[. = '\u4ED6\u4E3A\u8FD9\u9879\u5DE5\u7A0B\u6295" + "\u5165\u4E86\u5341\u4E09\u5E74\u65F6\u95F4\u3002']";
// get a BrokerPool for access to the database engine
BrokerPool pool = BrokerPool.getInstance();
final TransactionManager transact = pool.getTransactionManager();
try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
try (final Txn transaction = transact.beginTransaction()) {
// parse the xml source
Collection collection = broker.getOrCreateCollection(transaction, TestConstants.TEST_COLLECTION_URI);
broker.saveCollection(transaction, collection);
broker.storeDocument(transaction, XmldbURI.create("test.xml"), new StringInputSource(xml), MimeType.XML_TYPE, collection);
// TODO : unlock the collection here ?
transact.commit(transaction);
}
// parse the query into the internal syntax tree
XQueryContext context = new XQueryContext(broker.getBrokerPool());
XQueryLexer lexer = new XQueryLexer(context, new StringReader(query));
XQueryParser xparser = new XQueryParser(lexer);
XQueryTreeParser treeParser = new XQueryTreeParser(context);
xparser.xpath();
if (xparser.foundErrors()) {
fail(xparser.getErrorMessage());
return;
}
AST ast = xparser.getAST();
PathExpr expr = new PathExpr(context);
treeParser.xpath(ast, expr);
if (treeParser.foundErrors()) {
fail(treeParser.getErrorMessage());
return;
}
expr.analyze(new AnalyzeContextInfo());
// execute the query
Sequence result = expr.eval(null, null);
// check results
int count = result.getItemCount();
}
}
use of org.exist.xquery.parser.XQueryLexer in project exist by eXist-db.
the class AbstractSource method guessXQueryEncoding.
/**
* Check if the XQuery file declares a content encoding in the
* XQuery declaration.
*
* @param is the input stream
* @return The guessed encoding.
*/
protected static String guessXQueryEncoding(final InputStream is) {
final XQueryLexer lexer = new XQueryLexer(null, new InputStreamReader(is));
final DeclScanner scanner = new DeclScanner(lexer);
try {
scanner.versionDecl();
} catch (final RecognitionException | XPathException | TokenStreamException e) {
// Nothing to do
}
return scanner.getEncoding();
}
use of org.exist.xquery.parser.XQueryLexer 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);
}
}
}
Aggregations