removed all thrown errors from query serialisation workflow. all errors are reported via the field in the serialisation.
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractQueryProcessor.java
index 5e3ef4f..e6c4b4b 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractQueryProcessor.java
@@ -10,12 +10,9 @@
import org.antlr.v4.runtime.tree.ParseTree;
import org.slf4j.Logger;
-import de.ids_mannheim.korap.query.serialize.util.StatusCodes;
-import de.ids_mannheim.korap.query.serialize.util.QueryException;
-
public abstract class AbstractQueryProcessor {
- public abstract void process(String query) throws QueryException;
+ public abstract void process(String query);
Logger log;
/**
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/AnnisQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/AnnisQueryProcessor.java
index 07fe43e..a823f9d 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/AnnisQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/AnnisQueryProcessor.java
@@ -24,7 +24,6 @@
import de.ids_mannheim.korap.query.parse.annis.AqlParser;
import de.ids_mannheim.korap.query.serialize.util.Antlr4DescriptiveErrorListener;
import de.ids_mannheim.korap.query.serialize.util.CqlfObjectGenerator;
-import de.ids_mannheim.korap.query.serialize.util.QueryException;
/**
* Map representation of ANNIS QL syntax tree as returned by ANTLR
@@ -88,16 +87,12 @@
*/
public AnnisQueryProcessor(String query) {
CqlfObjectGenerator.setQueryProcessor(this);
- try {
- process(query);
- } catch (QueryException e) {
- e.printStackTrace();
- }
+ process(query);
System.out.println(">>> "+requestMap.get("query")+" <<<");
}
@Override
- public void process(String query) throws QueryException {
+ public void process(String query) {
ParseTree tree = parseAnnisQuery(query);
if (this.parser != null) {
super.parser = this.parser;
@@ -713,7 +708,7 @@
}
}
- private ParserRuleContext parseAnnisQuery (String query) throws QueryException {
+ private ParserRuleContext parseAnnisQuery (String query) {
Lexer lexer = new AqlLexer((CharStream)null);
ParserRuleContext tree = null;
Antlr4DescriptiveErrorListener errorListener = new Antlr4DescriptiveErrorListener(query);
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr3AbstractQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr3AbstractQueryProcessor.java
index 4f0775f..4faa5e8 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr3AbstractQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr3AbstractQueryProcessor.java
@@ -44,13 +44,13 @@
return false;
}
- protected boolean hasDescendant(Tree node, String childCat) {
+ protected static boolean hasDescendantWithCat(Tree node, String childCat) {
for (int i = 0; i < node.getChildCount(); i++) {
Tree child = node.getChild(i);
if (getNodeCat(child).equals(childCat)) {
return true;
}
- if (hasDescendant(child, childCat)) {
+ if (hasDescendantWithCat(child, childCat)) {
return true;
}
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr4AbstractQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr4AbstractQueryProcessor.java
index 6873678..aecc928 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr4AbstractQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr4AbstractQueryProcessor.java
@@ -47,13 +47,13 @@
return false;
}
- protected boolean hasDescendant(ParseTree node, String childCat) {
+ protected boolean hasDescendantWithCat(ParseTree node, String childCat) {
for (int i = 0; i < node.getChildCount(); i++) {
ParseTree child = node.getChild(i);
if (getNodeCat(child).equals(childCat)) {
return true;
}
- if (hasDescendant(child, childCat)) {
+ if (hasDescendantWithCat(child, childCat)) {
return true;
}
}
@@ -61,7 +61,7 @@
}
- protected static List<ParseTree> getChildren(ParseTree node) {
+ protected List<ParseTree> getChildren(ParseTree node) {
ArrayList<ParseTree> children = new ArrayList<ParseTree>();
for (int i = 0; i < node.getChildCount(); i++) {
children.add(node.getChild(i));
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder2.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder2.java
index 324a939..3d62b52 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder2.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder2.java
@@ -1,7 +1,6 @@
package de.ids_mannheim.korap.query.serialize;
import com.fasterxml.jackson.databind.JsonNode;
-import de.ids_mannheim.korap.query.serialize.util.QueryException;
import de.ids_mannheim.korap.utils.JsonUtils;
import java.io.IOException;
@@ -47,7 +46,7 @@
return this;
}
- public CollectionQueryBuilder2 setQuery(String query) throws QueryException {
+ public CollectionQueryBuilder2 setQuery(String query) {
CollectionQueryProcessor tree = new CollectionQueryProcessor();
tree.process(query);
this.groups = tree.getRequestMap();
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder3.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder3.java
index d87da4a..285f14b 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder3.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder3.java
@@ -1,6 +1,5 @@
package de.ids_mannheim.korap.query.serialize;
-import de.ids_mannheim.korap.query.serialize.util.QueryException;
import de.ids_mannheim.korap.utils.JsonUtils;
import java.io.IOException;
@@ -63,7 +62,7 @@
return this;
}
- public List getRequest() throws QueryException {
+ public List getRequest() {
List list = new ArrayList();
if (!this.rq.isEmpty())
list.addAll(this.rq);
@@ -74,7 +73,7 @@
return list;
}
- public String toJSON() throws QueryException {
+ public String toJSON() {
return JsonUtils.toJSON(getRequest());
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessor.java
index 26e86e3..0cd2768 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessor.java
@@ -5,7 +5,6 @@
import de.ids_mannheim.korap.query.serialize.util.Antlr4DescriptiveErrorListener;
import de.ids_mannheim.korap.query.serialize.util.CqlfObjectGenerator;
import de.ids_mannheim.korap.query.serialize.util.StatusCodes;
-import de.ids_mannheim.korap.query.serialize.util.QueryException;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
@@ -51,13 +50,13 @@
CollectionQueryProcessor.verbose = verbose;
}
- public CollectionQueryProcessor(String query) throws QueryException {
+ public CollectionQueryProcessor(String query) {
CqlfObjectGenerator.setQueryProcessor(this);
process(query);
}
@Override
- public void process(String query) throws QueryException {
+ public void process(String query) {
ParseTree tree = parseCollectionQuery(query);
if (this.parser != null) {
super.parser = this.parser;
@@ -66,7 +65,12 @@
}
log.info("Processing collection query: "+query);
if (verbose) System.out.println(tree.toStringTree(parser));
- processNode(tree);
+ if (tree != null) {
+ log.debug("ANTLR parse tree: "+tree.toStringTree(parser));
+ processNode(tree);
+ } else {
+ addError(StatusCodes.MALFORMED_QUERY, "Could not parse query >>> "+query+" <<<.");
+ }
}
private void processNode(ParseTree node) {
@@ -446,7 +450,7 @@
}
}
- private ParserRuleContext parseCollectionQuery(String query) throws QueryException {
+ private ParserRuleContext parseCollectionQuery(String query) {
Lexer lexer = new CollectionQueryLexer((CharStream) null);
ParserRuleContext tree = null;
Antlr4DescriptiveErrorListener errorListener = new Antlr4DescriptiveErrorListener(query);
@@ -474,9 +478,6 @@
System.err.println("ERROR: "+errorListener.generateFullErrorMsg());
System.err.println("Parsing exception message: " + e);
}
- if (tree == null) {
- throw new QueryException("Could not parse query. Make sure it is correct syntax.");
- }
// Return the generated tree
return tree;
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/Cosmas2QueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/Cosmas2QueryProcessor.java
index f119b08..2ab4ddb 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/Cosmas2QueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/Cosmas2QueryProcessor.java
@@ -6,7 +6,6 @@
import de.ids_mannheim.korap.query.serialize.util.CqlfObjectGenerator;
import de.ids_mannheim.korap.query.serialize.util.ResourceMapper;
import de.ids_mannheim.korap.query.serialize.util.StatusCodes;
-import de.ids_mannheim.korap.query.serialize.util.QueryException;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.RecognitionException;
@@ -77,7 +76,7 @@
/**
* A list of node categories that can be sequenced (i.e. which can be in a sequence with any number of other nodes in this list)
*/
- private final List<String> sequentiableCats = Arrays.asList(new String[]{"OPWF", "OPLEM", "OPMORPH", "OPBEG", "OPEND", "OPIN", "OPBED", "OPELEM", "OPOR", "OPAND"});
+ private final List<String> sequentiableNodeTypes = Arrays.asList(new String[]{"OPWF", "OPLEM", "OPMORPH", "OPBEG", "OPEND", "OPIN", "OPBED", "OPELEM", "OPOR", "OPAND"});
/**
* Keeps track of sequenced nodes, i.e. nodes that implicitly govern a sequence, as in (C2PQ (OPWF der) (OPWF Mann)).
* This is necessary in order to know when to take the sequence off the object stack, as the sequence is introduced by the
@@ -97,7 +96,7 @@
* @param parser The ANTLR parser instance that generated the parse tree
* @throws QueryException
*/
- public Cosmas2QueryProcessor(String query) throws QueryException {
+ public Cosmas2QueryProcessor(String query) {
CqlfObjectGenerator.setQueryProcessor(this);
this.query = query;
process(query);
@@ -105,7 +104,7 @@
}
@Override
- public void process(String query) throws QueryException {
+ public void process(String query) {
Tree tree = null;
tree = parseCosmasQuery(query);
log.info("Processing CosmasII query: "+query);
@@ -115,8 +114,7 @@
}
}
- private void processNode(Tree node) throws QueryException {
-
+ private void processNode(Tree node) {
// Top-down processing
if (visited.contains(node)) return;
else visited.add(node);
@@ -141,7 +139,7 @@
// Check for potential implicit sequences as in (C2PQ (OPWF der) (OPWF Mann)). The sequence is introduced
// by the first child if it (and its siblings) is sequentiable.
- if (sequentiableCats.contains(nodeCat)) {
+ if (sequentiableNodeTypes.contains(nodeCat)) {
// for each node, check if parent has more than one child (-> could be implicit sequence)
Tree parent = node.getParent();
if (parent.getChildCount() > 1) {
@@ -149,7 +147,7 @@
if (node == parent.getChild(0)) {
nodeHasSequentiableSiblings = false;
for (int i = 1; i < parent.getChildCount(); i++) {
- if (sequentiableCats.contains(getNodeCat(parent.getChild(i)))) {
+ if (sequentiableNodeTypes.contains(getNodeCat(parent.getChild(i)))) {
nodeHasSequentiableSiblings = true;
continue;
}
@@ -172,7 +170,6 @@
}
}
}
-
if (nodeCat.equals("OPWF") || nodeCat.equals("OPLEM")) {
processOPWF_OPLEM(node);
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CqlQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CqlQueryProcessor.java
index 5a06c1a..7e76964 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CqlQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/CqlQueryProcessor.java
@@ -1,6 +1,7 @@
package de.ids_mannheim.korap.query.serialize;
-import de.ids_mannheim.korap.query.serialize.util.QueryException;
+import de.ids_mannheim.korap.query.serialize.util.StatusCodes;
+
import org.z3950.zing.cql.*;
import java.io.IOException;
@@ -31,15 +32,15 @@
private String version;
private boolean isCaseSensitive; // default true
- public CqlQueryProcessor(String query) throws QueryException {
+ public CqlQueryProcessor(String query) {
this(query, VERSION_1_2, true);
}
- public CqlQueryProcessor(String query, String version) throws QueryException {
+ public CqlQueryProcessor(String query, String version) {
this(query, version, true);
}
- public CqlQueryProcessor(String query, String version, boolean isCaseSensitive) throws QueryException {
+ public CqlQueryProcessor(String query, String version, boolean isCaseSensitive) {
this.version = version;
this.isCaseSensitive = isCaseSensitive;
this.requestMap = new LinkedHashMap<>();
@@ -54,9 +55,9 @@
}
@Override
- public void process(String query) throws QueryException {
+ public void process(String query) {
if ((query == null) || query.isEmpty())
- throw new QueryException(301, "SRU diagnostic 27: An empty query is unsupported.");
+ addError(StatusCodes.MALFORMED_QUERY, "SRU diagnostic 27: An empty query is unsupported.");
CQLNode cqlNode = parseQuerytoCQLNode(query);
Map<String,Object> queryMap = parseCQLNode(cqlNode);
@@ -82,7 +83,7 @@
return map;
}
- private CQLNode parseQuerytoCQLNode(String query) throws QueryException {
+ private CQLNode parseQuerytoCQLNode(String query) {
try {
int compat = -1;
switch (version) {
@@ -95,11 +96,12 @@
return new CQLParser(compat).parse(query);
} catch (CQLParseException | IOException e) {
- throw new QueryException("Error parsing CQL");
+ addError(StatusCodes.MALFORMED_QUERY, "Error parsing CQL");
+ return null;
}
}
- private Map<String,Object> parseCQLNode(CQLNode node) throws QueryException {
+ private Map<String,Object> parseCQLNode(CQLNode node) {
if (node instanceof CQLTermNode) {
return parseTermNode((CQLTermNode) node);
@@ -108,16 +110,18 @@
} else if (node instanceof CQLOrNode) {
return parseOrNode((CQLOrNode) node);
} else {
- throw new QueryException(105, "SRU diagnostic 48: Only basic search including term-only " +
+ addError(StatusCodes.UNKNOWN_QUERY_ELEMENT, "SRU diagnostic 48: Only basic search including term-only " +
"and boolean (AND,OR) operator queries are currently supported.");
+ return new LinkedHashMap<String,Object>();
}
}
- private Map<String,Object> parseTermNode(CQLTermNode node) throws QueryException {
+ private Map<String,Object> parseTermNode(CQLTermNode node) {
checkTermNode(node);
final String term = node.getTerm();
if ((term == null) || term.isEmpty()) {
- throw new QueryException(301, "SRU diagnostic 27: An empty term is unsupported.");
+ addError(StatusCodes.NO_QUERY, "SRU diagnostic 27: An empty term is unsupported.");
+ return new LinkedHashMap<String,Object>();
} else if (term.contains(" ")) {
return writeSequence(term);
} else {
@@ -125,7 +129,7 @@
}
}
- private Map<String,Object> parseAndNode(CQLAndNode node) throws QueryException {
+ private Map<String,Object> parseAndNode(CQLAndNode node) {
checkBooleanModifier(node);
Map<String, Object> map = new LinkedHashMap<String,Object>();
@@ -150,7 +154,7 @@
return map;
}
- private Map<String,Object> parseOrNode(CQLOrNode node) throws QueryException {
+ private Map<String,Object> parseOrNode(CQLOrNode node) {
checkBooleanModifier(node);
Map<String, Object> map = new LinkedHashMap<String,Object>();
@@ -196,20 +200,20 @@
return tokenMap;
}
- private void checkBooleanModifier(CQLBooleanNode node) throws QueryException {
+ private void checkBooleanModifier(CQLBooleanNode node) {
List<Modifier> modifiers = node.getModifiers();
if ((modifiers != null) && !modifiers.isEmpty()) {
Modifier modifier = modifiers.get(0);
- throw new QueryException(105, "SRU diagnostic 20: Relation modifier " +
+ addError(105, "SRU diagnostic 20: Relation modifier " +
modifier.toCQL() + " is not supported.");
}
}
- private void checkTermNode(CQLTermNode node) throws QueryException {
+ private void checkTermNode(CQLTermNode node) {
// only allow "cql.serverChoice" and "words" index
if (!(INDEX_CQL_SERVERCHOICE.equals(node.getIndex()) ||
INDEX_WORDS.equals(node.getIndex()))) {
- throw new QueryException(105, "SRU diagnostic 16: Index " + node.getIndex() + " is not supported.");
+ addError(105, "SRU diagnostic 16: Index " + node.getIndex() + " is not supported.");
}
// only allow "=" relation without any modifiers
CQLRelation relation = node.getRelation();
@@ -217,13 +221,13 @@
if (!(TERM_RELATION_CQL_1_1.equals(baseRel) ||
TERM_RELATION_CQL_1_2.equals(baseRel) ||
SUPPORTED_RELATION_EXACT.equals(baseRel))) {
- throw new QueryException(105, "SRU diagnostic 19: Relation " +
+ addError(105, "SRU diagnostic 19: Relation " +
relation.getBase() + " is not supported.");
}
List<Modifier> modifiers = relation.getModifiers();
if ((modifiers != null) && !modifiers.isEmpty()) {
Modifier modifier = modifiers.get(0);
- throw new QueryException(105, "SRU diagnostic 20: Relation modifier " +
+ addError(105, "SRU diagnostic 20: Relation modifier " +
modifier.getValue() + " is not supported.");
}
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/DummyQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/DummyQueryProcessor.java
new file mode 100644
index 0000000..6c49737
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/DummyQueryProcessor.java
@@ -0,0 +1,16 @@
+package de.ids_mannheim.korap.query.serialize;
+
+/**
+ * This class serves as a dummy class for reporting errors when the query or query language as specified
+ * in the {@link #QuerySerializer} are empty or erroneous. Without instatiating a class, errors/warnings cannot
+ * be reported.
+ * @author bingel
+ *
+ */
+public final class DummyQueryProcessor extends AbstractQueryProcessor {
+
+ @Override
+ public void process(String query) {
+ // This is just a dummy class. Do nothing!
+ }
+}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessor.java
index 458e976..0da9e5c 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessor.java
@@ -5,7 +5,6 @@
import de.ids_mannheim.korap.query.serialize.util.Antlr4DescriptiveErrorListener;
import de.ids_mannheim.korap.query.serialize.util.CqlfObjectGenerator;
import de.ids_mannheim.korap.query.serialize.util.StatusCodes;
-import de.ids_mannheim.korap.query.serialize.util.QueryException;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.ParseTree;
@@ -34,14 +33,14 @@
* @param query The syntax tree as returned by ANTLR
* @throws QueryException
*/
- public PoliqarpPlusQueryProcessor(String query) throws QueryException {
+ public PoliqarpPlusQueryProcessor(String query) {
CqlfObjectGenerator.setQueryProcessor(this);
process(query);
log.info(">>> " + requestMap.get("query") + " <<<");
}
@Override
- public void process(String query) throws QueryException {
+ public void process(String query) {
ParseTree tree;
tree = parsePoliqarpQuery(query);
super.parser = this.parser;
@@ -49,6 +48,8 @@
if (tree != null) {
log.debug("ANTLR parse tree: "+tree.toStringTree(parser));
processNode(tree);
+ } else {
+ addError(StatusCodes.MALFORMED_QUERY, "Could not parse query >>> "+query+" <<<.");
}
}
@@ -62,7 +63,7 @@
* @param node The currently processed node. The process(String query) method calls this method with the root.
* @throws QueryException
*/
- private void processNode(ParseTree node) throws QueryException {
+ private void processNode(ParseTree node) {
// Top-down processing
if (visited.contains(node)) return;
else visited.add(node);
@@ -748,7 +749,7 @@
}
- private ParserRuleContext parsePoliqarpQuery(String query) throws QueryException {
+ private ParserRuleContext parsePoliqarpQuery(String query) {
Lexer lexer = new PoliqarpPlusLexer((CharStream) null);
ParserRuleContext tree = null;
Antlr4DescriptiveErrorListener errorListener = new Antlr4DescriptiveErrorListener(query);
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/QuerySerializer.java b/src/main/java/de/ids_mannheim/korap/query/serialize/QuerySerializer.java
index e590957..9760854 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/QuerySerializer.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/QuerySerializer.java
@@ -4,7 +4,6 @@
import com.fasterxml.jackson.databind.JsonMappingException;
import de.ids_mannheim.korap.query.serialize.util.StatusCodes;
-import de.ids_mannheim.korap.query.serialize.util.QueryException;
import de.ids_mannheim.korap.utils.JsonUtils;
import de.ids_mannheim.korap.utils.KorAPLogger;
@@ -82,8 +81,6 @@
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
- } catch (QueryException e) {
- e.printStackTrace();
}
}
}
@@ -99,56 +96,49 @@
* @throws QueryException
*/
public void run(String query, String queryLanguage, String outFile)
- throws IOException, QueryException {
- if (queryLanguage.equals("poliqarp")) {
+ throws IOException {
+ if (queryLanguage.equalsIgnoreCase("poliqarp")) {
ast = new PoliqarpPlusQueryProcessor(query);
- } else if (queryLanguage.toLowerCase().equals("cosmas2")) {
+ } else if (queryLanguage.equalsIgnoreCase("cosmas2")) {
ast = new Cosmas2QueryProcessor(query);
- } else if (queryLanguage.toLowerCase().equals("poliqarpplus")) {
+ } else if (queryLanguage.equalsIgnoreCase("poliqarpplus")) {
ast = new PoliqarpPlusQueryProcessor(query);
- } else if (queryLanguage.toLowerCase().equals("cql")) {
+ } else if (queryLanguage.equalsIgnoreCase("cql")) {
ast = new CqlQueryProcessor(query);
- } else if (queryLanguage.toLowerCase().equals("annis")) {
+ } else if (queryLanguage.equalsIgnoreCase("annis")) {
ast = new AnnisQueryProcessor(query);
} else {
- throw new QueryException(queryLanguage + " is not a supported query language!");
+ throw new IllegalArgumentException(queryLanguage + " is not a supported query language!");
}
toJSON();
}
- public QuerySerializer setQuery(String query, String ql, String version)
- throws QueryException {
-
- if (query == null || query.isEmpty())
- throw new QueryException(StatusCodes.NO_QUERY, "No Content!");
-
- try {
- if (ql.equalsIgnoreCase("poliqarp")) {
- ast = new PoliqarpPlusQueryProcessor(query);
- } else if (ql.equalsIgnoreCase("cosmas2")) {
- ast = new Cosmas2QueryProcessor(query);
- } else if (ql.equalsIgnoreCase("poliqarpplus")) {
- ast = new PoliqarpPlusQueryProcessor(query);
- } else if (ql.equalsIgnoreCase("cql")) {
- if (version == null)
- ast = new CqlQueryProcessor(query);
- else
- ast = new CqlQueryProcessor(query, version);
- } else if (ql.equalsIgnoreCase("annis")) {
- ast = new AnnisQueryProcessor(query);
- } else {
- throw new QueryException(ql + " is not a supported query language!");
- }
- } catch (QueryException e) {
- throw e;
- } catch (Exception e) {
- e.printStackTrace();
- throw new QueryException("UNKNOWN: Query could not be parsed (" + query + ")");
+ public QuerySerializer setQuery(String query, String ql, String version) {
+ ast = new DummyQueryProcessor();
+ if (query == null || query.isEmpty()) {
+ ast.addError(StatusCodes.NO_QUERY, "You did not specify a query!");
+ } else if (ql == null || ql.isEmpty()){
+ ast.addError(StatusCodes.NO_QUERY, "You did not specify any query language!");
+ } else if (ql.equalsIgnoreCase("poliqarp")) {
+ ast = new PoliqarpPlusQueryProcessor(query);
+ } else if (ql.equalsIgnoreCase("cosmas2")) {
+ ast = new Cosmas2QueryProcessor(query);
+ } else if (ql.equalsIgnoreCase("poliqarpplus")) {
+ ast = new PoliqarpPlusQueryProcessor(query);
+ } else if (ql.equalsIgnoreCase("cql")) {
+ if (version == null)
+ ast = new CqlQueryProcessor(query);
+ else
+ ast = new CqlQueryProcessor(query, version);
+ } else if (ql.equalsIgnoreCase("annis")) {
+ ast = new AnnisQueryProcessor(query);
+ } else {
+ ast.addError(StatusCodes.UNKNOWN_QL, ql + " is not a supported query language!");
}
return this;
}
- public QuerySerializer setQuery(String query, String ql) throws QueryException {
+ public QuerySerializer setQuery(String query, String ql) {
return setQuery(query, ql, "");
}
@@ -228,7 +218,7 @@
return this;
}
- public QuerySerializer setCollection(String collection) throws QueryException {
+ public QuerySerializer setCollection(String collection) {
CollectionQueryProcessor tree = new CollectionQueryProcessor();
Map collectionRequest = tree.getRequestMap();
tree.process(collection);
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/TreeTemplate.java b/src/main/java/de/ids_mannheim/korap/query/serialize/TreeTemplate.java
index 1c20f96..9c74336 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/TreeTemplate.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/TreeTemplate.java
@@ -3,92 +3,63 @@
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.BailErrorStrategy;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.Lexer;
-import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ParseTree;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+//TODO replace AqlLexer with lexer for your Antlr4 grammar!
import de.ids_mannheim.korap.query.parse.annis.AqlLexer;
+//TODO replace AqlParser with parser for your Antlr4 grammar!
import de.ids_mannheim.korap.query.parse.annis.AqlParser;
-import de.ids_mannheim.korap.query.serialize.util.QueryException;
+import de.ids_mannheim.korap.query.serialize.util.CqlfObjectGenerator;
+import de.ids_mannheim.korap.query.serialize.util.StatusCodes;
/**
* Map representation of syntax tree as returned by ANTLR
- * @author bingel
+ * @author Joachim Bingel (bingel@ids-mannheim.de)
*
*/
public class TreeTemplate extends Antlr4AbstractQueryProcessor {
- /**
- * Keeps track of open node categories
- */
- LinkedList<String> openNodeCats = new LinkedList<String>();
- /**
- * Flag that indicates whether token fields or meta fields are currently being processed
- */
- boolean inMeta = false;
- /**
- * Parser object deriving the ANTLR parse tree.
- */
- static Parser qlParser;
- /**
- * Keeps track of all visited nodes in a tree
- */
- List<ParseTree> visited = new ArrayList<ParseTree>();
- /**
- * Keeps track of active object.
- */
- LinkedList<LinkedHashMap<String,Object>> objectStack = new LinkedList<LinkedHashMap<String,Object>>();
- /**
- * Marks the currently active token in order to know where to add flags (might already have been taken away from token stack).
- */
- LinkedHashMap<String,Object> curToken = new LinkedHashMap<String,Object>();
-
- private LinkedList<ArrayList<ArrayList<Object>>> distributedOperandsLists = new LinkedList<ArrayList<ArrayList<Object>>>();
-
- /**
- * Keeps track of how many objects there are to pop after every recursion of {@link #processNode(ParseTree)}
- */
- LinkedList<Integer> objectsToPop = new LinkedList<Integer>();
- Integer stackedObjects = 0;
- public static boolean verbose = false;
-
+ private static Logger log = LoggerFactory.getLogger(TreeTemplate.class);
/**
*
* @param tree The syntax tree as returned by ANTLR
* @param parser The ANTLR parser instance that generated the parse tree
*/
public TreeTemplate(String query) {
- try {
- process(query);
- } catch (QueryException e) {
- e.printStackTrace();
+ CqlfObjectGenerator.setQueryProcessor(this);
+ process(query);
+ }
+
+ @Override
+ public void process(String query) {
+ ParseTree tree = parseQuery(query);
+ super.parser = this.parser;
+ if (tree != null) {
+ log.debug("ANTLR parse tree: "+tree.toStringTree(parser));
+ processNode(tree);
+ } else {
+ addError(StatusCodes.MALFORMED_QUERY, "Could not parse query >>> "+query+" <<<.");
}
}
-
- @Override
- public void process(String query) throws QueryException {
- ParseTree tree = parseQuery(query);
- System.out.println("Processing Annis QL");
- processNode(tree);
- }
-
+
private void processNode(ParseTree node) {
// Top-down processing
if (visited.contains(node)) return;
else visited.add(node);
-
+
String nodeCat = getNodeCat(node);
openNodeCats.push(nodeCat);
-
+
stackedObjects = 0;
-
+
if (verbose) {
System.err.println(" "+objectStack);
System.out.println(openNodeCats);
@@ -103,7 +74,7 @@
*/
objectsToPop.push(stackedObjects);
-
+
/*
****************************************************************
****************************************************************
@@ -115,76 +86,69 @@
ParseTree child = node.getChild(i);
processNode(child);
}
-
-
+
+
/*
**************************************************************
* Stuff that happens after processing the children of a node *
**************************************************************
*/
-
-
+
+
for (int i=0; i<objectsToPop.pop(); i++) {
objectStack.pop();
}
-
+
openNodeCats.pop();
-
+
}
@SuppressWarnings("unused")
private void putIntoSuperObject(LinkedHashMap<String, Object> object) {
putIntoSuperObject(object, 0);
}
-
+
@SuppressWarnings({ "unchecked" })
private void putIntoSuperObject(LinkedHashMap<String, Object> object, int objStackPosition) {
- if (distributedOperandsLists.size()>0) {
- ArrayList<ArrayList<Object>> distributedOperands = distributedOperandsLists.pop();
- for (ArrayList<Object> operands : distributedOperands) {
- operands.add(object);
- }
- } else if (objectStack.size()>objStackPosition) {
+ if (objectStack.size()>objStackPosition) {
ArrayList<Object> topObjectOperands = (ArrayList<Object>) objectStack.get(objStackPosition).get("operands");
topObjectOperands.add(0, object);
-
+
} else {
requestMap.put("query", object);
}
}
-
- private static ParserRuleContext parseQuery (String q) throws QueryException {
- Lexer qlLexer = new AqlLexer((CharStream)null);
- ParserRuleContext tree = null;
- // Like p. 111
- try {
- // Tokenize input data
- ANTLRInputStream input = new ANTLRInputStream(q);
- qlLexer.setInputStream(input);
- CommonTokenStream tokens = new CommonTokenStream(qlLexer);
- qlParser = new AqlParser(tokens);
+ private ParserRuleContext parseQuery (String q) {
+ //TODO replace AqlLexer with lexer for your Antlr4 grammar!
+ Lexer qlLexer = new AqlLexer((CharStream)null);
+ ParserRuleContext tree = null;
+ // Like p. 111
+ try {
+ // Tokenize input data
+ ANTLRInputStream input = new ANTLRInputStream(q);
+ qlLexer.setInputStream(input);
+ CommonTokenStream tokens = new CommonTokenStream(qlLexer);
+ //TODO replace AqlParser with parser for your Antlr4 grammar!
+ parser = new AqlParser(tokens);
- // Don't throw out erroneous stuff
- qlParser.setErrorHandler(new BailErrorStrategy());
- qlParser.removeErrorListeners();
+ // Don't throw out erroneous stuff
+ parser.setErrorHandler(new BailErrorStrategy());
+ parser.removeErrorListeners();
- // Get starting rule from parser
- Method startRule = AqlParser.class.getMethod("start");
- tree = (ParserRuleContext) startRule.invoke(qlParser, (Object[])null);
- }
+ // Get starting rule from parser
+ //TODO replace AqlParser with parser for your Antlr4 grammar!
+ Method startRule = AqlParser.class.getMethod("start");
+ tree = (ParserRuleContext) startRule.invoke(parser, (Object[])null);
+ }
- // Some things went wrong ...
- catch (Exception e) {
- System.err.println( e.getMessage() );
- }
-
- if (tree == null) {
- throw new QueryException("Could not parse query. Make sure it is correct QL syntax.");
- }
+ // Some things went wrong ...
+ catch (Exception e) {
+ System.err.println( e.getMessage() );
+ }
- // Return the generated tree
- return tree;
- }
+ // Return the generated tree
+ return tree;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/util/CqlfObjectGenerator.java b/src/main/java/de/ids_mannheim/korap/query/serialize/util/CqlfObjectGenerator.java
index b03959d..abc4511 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/util/CqlfObjectGenerator.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/util/CqlfObjectGenerator.java
@@ -269,4 +269,4 @@
}
return number;
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/util/QueryException.java b/src/main/java/de/ids_mannheim/korap/query/serialize/util/QueryException.java
deleted file mode 100644
index ff63f79..0000000
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/util/QueryException.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package de.ids_mannheim.korap.query.serialize.util;
-
-public class QueryException extends Exception {
-
- int errorCode;
-
- public QueryException() {
- super();
- }
-
- public QueryException(String message) {
- super(message);
- }
-
- public QueryException(String message, Throwable cause) {
- super(message, cause);
- };
-
- public QueryException(Throwable cause) {
- super(cause);
- };
-
- public QueryException(int code, String message) {
- super(message);
- setErrorCode(code);
- }
-
- public int getErrorCode() {
- return errorCode;
- }
-
- public void setErrorCode(int errorCode) {
- this.errorCode = errorCode;
- }
-
-};
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/util/StatusCodes.java b/src/main/java/de/ids_mannheim/korap/query/serialize/util/StatusCodes.java
index 6fe6afd..ffdedf0 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/util/StatusCodes.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/util/StatusCodes.java
@@ -7,5 +7,6 @@
public final static int UNDEFINED_CLASS_REFERENCE = 304;
public final static int INCOMPATIBLE_OPERATOR_AND_OPERAND = 305;
public final static int UNKNOWN_QUERY_ELEMENT = 306;
+ public static final int UNKNOWN_QL = 307;
public final static int UNKNOWN_QUERY_ERROR = 399;
}