Implemented initial Federated Content Search Query Language (FCSQL)
serialization (term query).
Change-Id: I5da3916a785f854c2760c76a92d27bddcc3e0b03
diff --git a/pom.xml b/pom.xml
index 2516d11..71d1be5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -48,7 +48,7 @@
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
- <version>4.2</version>
+ <version>4.5.1</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
@@ -117,6 +117,26 @@
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
+ <dependency>
+ <groupId>eu.clarin.sru.fcs</groupId>
+ <artifactId>fcs-simple-endpoint</artifactId>
+ <version>1.3.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.lucene</groupId>
+ <artifactId>lucene-core</artifactId>
+ <version>5.2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.lucene</groupId>
+ <artifactId>lucene-analyzers-common</artifactId>
+ <version>5.2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.lucene</groupId>
+ <artifactId>lucene-queryparser</artifactId>
+ <version>5.2.1</version>
+ </dependency>
</dependencies>
<build>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
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 b06731c..e2070bf 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
@@ -22,16 +22,12 @@
private static final String INDEX_WORDS = "words";
private static final String TERM_RELATION_CQL_1_1 = "scr";
private static final String TERM_RELATION_CQL_1_2 = "=";
- private static final String SUPPORTED_RELATION_EXACT = "exact"; // not
- // in
- // the
- // doc
+ private static final String SUPPORTED_RELATION_EXACT = "exact"; // not in the doc
private static final String OPERATION_OR = "operation:or";
private static final String OPERATION_SEQUENCE = "operation:sequence";
private static final String OPERATION_POSITION = "operation:position";
private static final String KORAP_CONTEXT = "http://ids-mannheim.de/ns/KorAP/json-ld/v0.1/context.jsonld";
- private LinkedHashMap<String, Object> requestMap;
private String version;
private boolean isCaseSensitive; // default true
@@ -40,12 +36,10 @@
this(query, VERSION_1_2, true);
}
-
public CqlQueryProcessor (String query, String version) {
this(query, version, true);
}
-
public CqlQueryProcessor (String query, String version,
boolean isCaseSensitive) {
this.version = version;
@@ -55,13 +49,11 @@
process(query);
}
-
@Override
public Map<String, Object> getRequestMap () {
return this.requestMap;
}
-
@Override
public void process (String query) {
if ((query == null) || query.isEmpty())
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/FCSQLQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/FCSQLQueryProcessor.java
new file mode 100644
index 0000000..7e0c199
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/FCSQLQueryProcessor.java
@@ -0,0 +1,269 @@
+package de.ids_mannheim.korap.query.serialize;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import de.ids_mannheim.korap.query.serialize.util.StatusCodes;
+import eu.clarin.sru.server.SRUQueryBase;
+import eu.clarin.sru.server.SRUVersion;
+import eu.clarin.sru.server.fcs.Constants;
+import eu.clarin.sru.server.fcs.parser.Expression;
+import eu.clarin.sru.server.fcs.parser.Operator;
+import eu.clarin.sru.server.fcs.parser.QueryNode;
+import eu.clarin.sru.server.fcs.parser.QueryParser;
+import eu.clarin.sru.server.fcs.parser.QueryParserException;
+import eu.clarin.sru.server.fcs.parser.QuerySegment;
+import eu.clarin.sru.server.fcs.parser.RegexFlag;
+
+public class FCSQLQueryProcessor extends AbstractQueryProcessor {
+
+ public static final class FCSQuery extends SRUQueryBase<QueryNode> {
+
+ private FCSQuery(String rawQuery, QueryNode parsedQuery) {
+ super(rawQuery, parsedQuery);
+ }
+
+ @Override
+ public String getQueryType() {
+ return Constants.FCS_QUERY_TYPE_FCS;
+ }
+ }
+
+ public enum Foundry {
+ CNX, OPENNLP, TT, MATE, XIP;
+ }
+
+ private static final String KORAP_CONTEXT = "http://ids-mannheim.de/ns/KorAP/json-ld/v0.1/context.jsonld";
+ private String version;
+ private List<Foundry> supportedFoundries;
+ private final QueryParser parser = new QueryParser();
+
+ public FCSQLQueryProcessor(String query, String version) {
+ if (version == null) {
+ addError(StatusCodes.MISSING_VERSION,
+ "SRU Diagnostic 7: Version number is missing.");
+ } else if (!version.equals(SRUVersion.VERSION_2_0)) {
+ addError(StatusCodes.MISSING_VERSION,
+ "SRU Diagnostic 5: Only supports SRU version 2.0.");
+ }
+ this.version = version;
+
+ this.requestMap = new LinkedHashMap<>();
+ requestMap.put("@context", KORAP_CONTEXT);
+
+ this.supportedFoundries = new ArrayList<Foundry>(5);
+ supportedFoundries.add(Foundry.CNX);
+ supportedFoundries.add(Foundry.OPENNLP);
+ supportedFoundries.add(Foundry.TT);
+ supportedFoundries.add(Foundry.MATE);
+ supportedFoundries.add(Foundry.XIP);
+
+ process(query);
+ }
+
+ @Override
+ public Map<String, Object> getRequestMap() {
+ return this.requestMap;
+ }
+
+ @Override
+ public void process(String query) {
+ FCSQuery fcsQuery = parseQueryStringtoFCSQuery(query);
+ QueryNode fcsQueryNode = fcsQuery.getParsedQuery();
+ Map<String, Object> queryMap = parseFCSQuery(fcsQueryNode);
+ requestMap.put("query", queryMap);
+ }
+
+ private FCSQuery parseQueryStringtoFCSQuery(String query) {
+ if ((query == null) || query.isEmpty())
+ addError(StatusCodes.MALFORMED_QUERY,
+ "SRU diagnostic 1: No query has been passed.");
+ FCSQuery fcsQuery = null;
+ try {
+ QueryNode parsedQuery = parser.parse(query);
+ fcsQuery = new FCSQuery(query, parsedQuery);
+ } catch (QueryParserException e) {
+ addError(StatusCodes.UNKNOWN_QUERY_ERROR, "FCS Diagnostic 10: +"
+ + e.getMessage());
+ }
+ catch (Exception e) {
+ addError(StatusCodes.UNKNOWN_QUERY_ERROR, "FCS Diagnostic 10: +"
+ + "Unexpected error while parsing query.");
+ }
+ return fcsQuery;
+ }
+
+ private Map<String, Object> parseFCSQuery(QueryNode queryNode) {
+ Map<String, Object> queryMap = parseQueryNode(queryNode);
+ if (queryMap == null) {
+ addError(StatusCodes.UNKNOWN_QUERY_ERROR, "SRU diagnostic 47:"
+ + " Failed parsing query for unknown reasons.");
+ }
+ return queryMap;
+
+ }
+
+ private Map<String, Object> parseQueryNode(QueryNode queryNode) {
+ Map<String, Object> queryMap = null;
+
+ if (queryNode instanceof QuerySegment) {
+ queryMap = parseQuerySegment((QuerySegment) queryNode);
+// } else if (queryNode instanceof QueryGroup) {
+//
+// } else if (queryNode instanceof QuerySequence) {
+//
+// } else if (queryNode instanceof QueryDisjunction) {
+//
+// } else if (queryNode instanceof QueryWithWithin) {
+
+ }else {
+ addError(StatusCodes.QUERY_TOO_COMPLEX, "FCS diagnostic 11:"
+ + queryNode.getNodeType().name()
+ + " is currently unsupported.");
+ }
+
+ return queryMap;
+ }
+
+ private Map<String, Object> parseQuerySegment(QuerySegment segment) {
+ Map<String, Object> queryMap = null;
+
+ if ((segment.getMinOccurs() == 1) && (segment.getMaxOccurs() == 1)) {
+ queryMap = parseExpression(segment.getExpression());
+ } else {
+ addError(StatusCodes.QUERY_TOO_COMPLEX, "FCS diagnostic 11:"
+ + "Query is too complex.");
+ }
+ return queryMap;
+ }
+
+ private Map<String, Object> parseExpression(QueryNode queryNode) {
+ Map<String, Object> queryMap = null;
+
+ if (queryNode instanceof Expression) {
+ Expression expression = (Expression) queryNode;
+ queryMap = parseLayer(expression);
+ }
+ // else if (queryNode instanceof ExpressionAnd) {
+ //
+ // }
+ // else if (queryNode instanceof ExpressionGroup) {
+ //
+ // }
+ // else if (queryNode instanceof ExpressionNot) {
+ //
+ // }
+ // else if (queryNode instanceof ExpressionOr) {
+ //
+ // }
+ // else if (queryNode instanceof ExpressionWildcard) {
+ //
+ // }
+ else {
+ addError(StatusCodes.QUERY_TOO_COMPLEX, "FCS diagnostic 11:"
+ + "Query is too complex.");
+ }
+ return queryMap;
+ }
+
+ private Map<String, Object> parseLayer(Expression expression) {
+ String layer = parseLayerIdentifier(expression.getLayerIdentifier());
+ String foundry = parseQualifier(expression.getLayerQualifier(), layer);
+ String operator = parseOperator(expression.getOperator());
+ boolean isCaseSensitive = parseRegexFlags(expression.getRegexFlags());
+ String term = expression.getRegexValue();
+
+ return writeTerm(term, foundry, layer, operator, isCaseSensitive);
+ }
+ private String parseLayerIdentifier(String identifier) {
+ String layer = null;
+ if (identifier == null) {
+ // throw exception
+ } else if (identifier.equals("text")) {
+ layer = "orth";
+ } else if (identifier.equals("pos")) {
+ layer = "p";
+ } else if (identifier.equals("lemma")) {
+ layer = "l";
+ } else {
+ addError(StatusCodes.UNKNOWN_QUERY_ELEMENT, "SRU diagnostic 48:"
+ + identifier + " is unsupported.");
+ }
+
+ return layer;
+ }
+
+ private String parseQualifier(String qualifier, String layer) {
+ // Set default foundry
+ if (qualifier == null) {
+ if (layer.equals("orth")) {
+ qualifier = Foundry.OPENNLP.name().toLowerCase();
+ } else {
+ qualifier = Foundry.TT.name().toLowerCase();
+ }
+ } else if (qualifier.equals(Foundry.OPENNLP.name().toLowerCase())
+ && layer.equals("lemma")) {
+ addError(StatusCodes.UNKNOWN_QUERY_ELEMENT, "SRU diagnostic 48:"
+ + "Layer lemma with qualifier opennlp is unsupported.");
+ } else if (!supportedFoundries.contains(qualifier)) {
+ addError(StatusCodes.UNKNOWN_QUERY_ELEMENT, "SRU diagnostic 48:"
+ + "Layer " + layer + " with qualifier" + qualifier
+ + " is unsupported.");
+ }
+ return qualifier;
+ }
+
+ private String parseOperator(Operator operator) {
+ String matchOperator = null;
+ if (operator == null || operator == Operator.EQUALS) {
+ matchOperator = "match:eq";
+ } else if (operator == Operator.NOT_EQUALS) {
+ matchOperator = "match:ne";
+ } else {
+ addError(StatusCodes.UNKNOWN_QUERY_ELEMENT, "SRU diagnostic 37:"
+ + operator.name() + " is unsupported.");
+ }
+ return matchOperator;
+ }
+
+ private boolean parseRegexFlags(Set<RegexFlag> set) {
+ // default case sensitive
+ boolean flag = true;
+ if (set != null) {
+ for (RegexFlag f : set) {
+ if (f == RegexFlag.CASE_SENSITVE) {
+ continue;
+ } else if (f == RegexFlag.CASE_INSENSITVE) {
+ flag = false;
+ } else {
+ addError(StatusCodes.UNKNOWN_QUERY_ELEMENT,
+ "SRU diagnostic 48:" + f.name()
+ + " is unsupported.");
+ }
+ }
+ }
+ return flag;
+ }
+
+ private Map<String, Object> writeTerm(String term, String foundry,
+ String layer, String operator, boolean isCaseSensitive) {
+ Map<String, Object> map = new LinkedHashMap<String, Object>();
+ map.put("@type", "koral:term");
+ if (!isCaseSensitive) {
+ map.put("caseInsensitive", "true");
+ }
+ map.put("key", term);
+ map.put("foundry", foundry);
+ map.put("layer", layer);
+ map.put("match", operator);
+
+ Map<String, Object> tokenMap = new LinkedHashMap<String, Object>();
+ tokenMap.put("@type", "koral:token");
+ tokenMap.put("wrap", map);
+ return tokenMap;
+ }
+
+}
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 dcf0d3d..d4cb27e 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
@@ -12,11 +12,10 @@
import java.util.*;
/**
- * Main class for Koral, serializes queries from concrete QLs to
- * KoralQuery
+ * Main class for Koral, serializes queries from concrete QLs to KoralQuery
*
- * @author Joachim Bingel (bingel@ids-mannheim.de),
- * Michael Hanl (hanl@ids-mannheim.de)
+ * @author Joachim Bingel (bingel@ids-mannheim.de), Michael Hanl
+ * (hanl@ids-mannheim.de), Eliza Margaretha (margaretha@ids-mannheim.de)
* @version 0.3.0
* @since 0.1.0
*/
@@ -28,10 +27,11 @@
+
static {
qlProcessorAssignment = new HashMap<String, Class<? extends AbstractQueryProcessor>>();
- qlProcessorAssignment.put("poliqarpplus",
- PoliqarpPlusQueryProcessor.class);
+ qlProcessorAssignment.put("poliqarpplus",
+ PoliqarpPlusQueryProcessor.class);
qlProcessorAssignment.put("cosmas2", Cosmas2QueryProcessor.class);
qlProcessorAssignment.put("annis", AnnisQueryProcessor.class);
qlProcessorAssignment.put("cql", CqlQueryProcessor.class);
@@ -50,18 +50,16 @@
private org.slf4j.Logger log = LoggerFactory
.getLogger(QuerySerializer.class);
-
- public QuerySerializer () {
+ public QuerySerializer() {
this.errors = new LinkedList<>();
this.warnings = new LinkedList<>();
this.messages = new LinkedList<>();
}
-
/**
* @param args
*/
- public static void main (String[] args) {
+ public static void main(String[] args) {
/*
* just for testing...
*/
@@ -74,8 +72,7 @@
System.err
.println("Usage: QuerySerializer \"query\" queryLanguage");
System.exit(1);
- }
- else {
+ } else {
queries = new String[] { args[0] };
ql = args[1];
}
@@ -84,141 +81,118 @@
try {
jg.run(q, ql);
System.out.println();
- }
- catch (NullPointerException npe) {
+ } catch (NullPointerException npe) {
npe.printStackTrace();
System.out.println("null\n");
- }
- catch (IOException e) {
+ } catch (IOException e) {
e.printStackTrace();
}
}
}
-
/**
- * Runs the QuerySerializer by initializing the relevant
- * AbstractSyntaxTree implementation (depending on specified query
- * language) and transforms and writes the tree's requestMap to
- * the specified output file.
- *
- * @param query
- * The query string
- * @param queryLanguage
- * The query language. As of 17 Dec 2014, this must be
- * one of 'poliqarpplus', 'cosmas2', 'annis' or 'cql'.
- * @throws IOException
- */
- public void run (String query, String queryLanguage) throws IOException {
+ * Runs the QuerySerializer by initializing the relevant AbstractSyntaxTree
+ * implementation (depending on specified query language) and transforms and
+ * writes the tree's requestMap to the specified output file.
+ *
+ * @param query
+ * The query string
+ * @param queryLanguage
+ * The query language. As of 17 Dec 2014, this must be one of
+ * 'poliqarpplus', 'cosmas2', 'annis' or 'cql'.
+ * @throws IOException
+ */
+ public void run(String query, String queryLanguage) throws IOException {
if (queryLanguage.equalsIgnoreCase("poliqarp")) {
ast = new PoliqarpPlusQueryProcessor(query);
- }
- else if (queryLanguage.equalsIgnoreCase("cosmas2")) {
+ } else if (queryLanguage.equalsIgnoreCase("cosmas2")) {
ast = new Cosmas2QueryProcessor(query);
- }
- else if (queryLanguage.equalsIgnoreCase("poliqarpplus")) {
+ } else if (queryLanguage.equalsIgnoreCase("poliqarpplus")) {
ast = new PoliqarpPlusQueryProcessor(query);
- }
- else if (queryLanguage.equalsIgnoreCase("cql")) {
+ } else if (queryLanguage.equalsIgnoreCase("cql")) {
ast = new CqlQueryProcessor(query);
- }
- else if (queryLanguage.equalsIgnoreCase("annis")) {
+ } else if (queryLanguage.equalsIgnoreCase("fcsql")) {
+ ast = new FCSQLQueryProcessor(query, "2.0");
+ }else if (queryLanguage.equalsIgnoreCase("annis")) {
ast = new AnnisQueryProcessor(query);
- }
- else {
- throw new IllegalArgumentException(queryLanguage
- + " is not a supported query language!");
+ } else {
+ throw new IllegalArgumentException(queryLanguage
+ + " is not a supported query language!");
}
toJSON();
}
-
- public QuerySerializer setQuery (String query, String ql, String version) {
+ 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()) {
+ } else if (ql == null || ql.isEmpty()) {
ast.addError(StatusCodes.NO_QUERY,
"You did not specify any query language!");
- }
- else if (ql.equalsIgnoreCase("poliqarp")) {
+ } else if (ql.equalsIgnoreCase("poliqarp")) {
ast = new PoliqarpPlusQueryProcessor(query);
- }
- else if (ql.equalsIgnoreCase("cosmas2")) {
+ } else if (ql.equalsIgnoreCase("cosmas2")) {
ast = new Cosmas2QueryProcessor(query);
- }
- else if (ql.equalsIgnoreCase("poliqarpplus")) {
+ } else if (ql.equalsIgnoreCase("poliqarpplus")) {
ast = new PoliqarpPlusQueryProcessor(query);
- }
- else if (ql.equalsIgnoreCase("cql")) {
- if (version == null)
+ }else if (ql.equalsIgnoreCase("cql")) {
+ if (version == null) {
ast = new CqlQueryProcessor(query);
- else
+ } else {
ast = new CqlQueryProcessor(query, version);
- }
- else if (ql.equalsIgnoreCase("annis")) {
+ }
+ } else if (ql.equalsIgnoreCase("fcsql")) {
+ if (version == null) {
+ ast.addError(StatusCodes.MISSING_VERSION,
+ "SRU Version is missing!");
+ } else {
+ ast = new FCSQLQueryProcessor(query, version);
+ }
+ } else if (ql.equalsIgnoreCase("annis")) {
ast = new AnnisQueryProcessor(query);
- }
- else {
- ast.addError(StatusCodes.UNKNOWN_QL, ql
- + " is not a supported query language!");
+ }else {
+ ast.addError(StatusCodes.UNKNOWN_QUERY_LANGUAGE,
+ ql + " is not a supported query language!");
}
return this;
}
-
- public QuerySerializer setQuery (String query, String ql) {
+ public QuerySerializer setQuery(String query, String ql) {
return setQuery(query, ql, "");
}
-
- public void setVerbose (boolean verbose) {
+ public void setVerbose(boolean verbose) {
AbstractQueryProcessor.verbose = verbose;
}
-
- public final String toJSON () {
+ public final String toJSON() {
String ser;
try {
ser = mapper.writeValueAsString(raw());
qllogger.info("Serialized query: " + ser);
- }
- catch (JsonProcessingException e) {
+ } catch (JsonProcessingException e) {
return "";
}
return ser;
}
-
- public final Map build () {
+ public final Map build() {
return raw();
}
-
- private Map raw () {
+ private Map raw() {
if (ast != null) {
- Map<String, Object> requestMap = new HashMap<>(ast.getRequestMap());
+ Map<String, Object> requestMap = ast.getRequestMap();
Map meta = (Map) requestMap.get("meta");
Map collection = (Map) requestMap.get("collection");
List errors = (List) requestMap.get("errors");
List warnings = (List) requestMap.get("warnings");
List messages = (List) requestMap.get("messages");
- collection = mergeCollection(collection, this.collection);
- requestMap.put("collection", collection);
-
- if (meta == null)
- meta = new HashMap();
- if (errors == null)
- errors = new LinkedList();
- if (warnings == null)
- warnings = new LinkedList();
- if (messages == null)
- messages = new LinkedList();
-
+ this.collection = mergeCollection(collection, this.collection);
+ requestMap.put("collection", this.collection);
if (this.meta != null) {
- meta.putAll(this.meta);
- requestMap.put("meta", meta);
+ this.meta.putAll(meta);
+ requestMap.put("meta", this.meta);
}
if (this.errors != null && !this.errors.isEmpty()) {
errors.addAll(this.errors);
@@ -232,43 +206,37 @@
messages.addAll(this.messages);
requestMap.put("messages", messages);
}
+
return cleanup(requestMap);
}
return new HashMap<>();
}
-
- private Map<String, Object> cleanup (Map<String, Object> requestMap) {
+ private Map<String, Object> cleanup(Map<String, Object> requestMap) {
Iterator<Map.Entry<String, Object>> set = requestMap.entrySet()
.iterator();
while (set.hasNext()) {
Map.Entry<String, Object> entry = set.next();
- if (entry.getValue() instanceof List
- && ((List) entry.getValue()).isEmpty())
+ if (entry.getValue() instanceof List
+ && ((List) entry.getValue()).isEmpty())
set.remove();
- else if (entry.getValue() instanceof Map
- && ((Map) entry.getValue()).isEmpty())
+ else if (entry.getValue() instanceof Map
+ && ((Map) entry.getValue()).isEmpty())
set.remove();
- else if (entry.getValue() instanceof String
- && ((String) entry.getValue()).isEmpty())
+ else if (entry.getValue() instanceof String
+ && ((String) entry.getValue()).isEmpty())
set.remove();
}
return requestMap;
}
-
- private Map<String, Object> mergeCollection (
- Map<String, Object> collection1, Map<String, Object> collection2) {
+ private Map<String, Object> mergeCollection(
+ Map<String, Object> collection1, Map<String, Object> collection2) {
if (collection1 == null || collection1.isEmpty()) {
return collection2;
- }
- else if (collection2 == null || collection2.isEmpty()) {
+ } else if (collection2 == null || collection2.isEmpty()) {
return collection1;
- }
- else if (collection1.equals(collection2)) {
- return collection1;
- }
- else {
+ } else {
LinkedHashMap<String, Object> docGroup = KoralObjectGenerator
.makeDocGroup("and");
ArrayList<Object> operands = (ArrayList<Object>) docGroup
@@ -279,9 +247,8 @@
}
}
-
@Deprecated
- public QuerySerializer addMeta (String cli, String cri, int cls, int crs,
+ public QuerySerializer addMeta(String cli, String cri, int cls, int crs,
int num, int pageIndex) {
MetaQueryBuilder meta = new MetaQueryBuilder();
meta.setSpanContext(cls, cli, crs, cri);
@@ -291,14 +258,17 @@
return this;
}
-
- public QuerySerializer setMeta (Map<String, Object> meta) {
+ public QuerySerializer setMeta(Map<String, Object> meta) {
this.meta = meta;
return this;
}
+ public QuerySerializer setMeta(MetaQueryBuilder meta) {
+ this.meta = meta.raw();
+ return this;
+ }
- public QuerySerializer setCollection (String collection) {
+ public QuerySerializer setCollection(String collection) {
CollectionQueryProcessor tree = new CollectionQueryProcessor();
tree.process(collection);
Map<String, Object> collectionRequest = tree.getRequestMap();
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 10614ea..1f896b3 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,7 +7,9 @@
public final static int INVALID_CLASS_REFERENCE = 304;
public final static int INCOMPATIBLE_OPERATOR_AND_OPERAND = 305;
public final static int UNKNOWN_QUERY_ELEMENT = 306;
- public final static int UNKNOWN_QL = 307;
+ public final static int UNKNOWN_QUERY_LANGUAGE = 307;
public final static int UNBOUND_ANNIS_RELATION = 308;
- public final static int UNKNOWN_QUERY_ERROR = 399;
-}
+ public final static int MISSING_VERSION = 309;
+ public final static int QUERY_TOO_COMPLEX = 310;
+ public final static int UNKNOWN_QUERY_ERROR = 399;
+}
\ No newline at end of file
diff --git a/src/test/java/de/ids_mannheim/korap/query/serialize/FcsqlQueryProcessorTest.java b/src/test/java/de/ids_mannheim/korap/query/serialize/FcsqlQueryProcessorTest.java
new file mode 100644
index 0000000..729381e
--- /dev/null
+++ b/src/test/java/de/ids_mannheim/korap/query/serialize/FcsqlQueryProcessorTest.java
@@ -0,0 +1,90 @@
+package de.ids_mannheim.korap.query.serialize;
+
+import static org.junit.Assert.assertEquals;
+
+
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class FcsqlQueryProcessorTest {
+ ObjectMapper mapper = new ObjectMapper();
+
+ private void runAndValidate(String query, String jsonLD)
+ throws JsonProcessingException {
+ FCSQLQueryProcessor tree = new FCSQLQueryProcessor(query, "2.0");
+ String serializedQuery = mapper.writeValueAsString(tree.getRequestMap()
+ .get("query"));
+ assertEquals(jsonLD.replace(" ", ""), serializedQuery.replace("\"", ""));
+ }
+
+ @Test
+ public void testTermQuery() throws JsonProcessingException {
+ String query = "\"Sonne\"";
+ String jsonLd = "{@type:koral:token, wrap:{@type:koral:term, key:Sonne, "
+ + "foundry:opennlp, layer:orth, match:match:eq}}";
+ runAndValidate(query, jsonLd);
+ }
+
+ @Test
+ public void testTermQueryWithRegexFlag() throws JsonProcessingException {
+ String query = "\"Fliegen\" /c";
+ String jsonLd = "{@type:koral:token, wrap:{@type:koral:term, caseInsensitive:true, "
+ + "key:Fliegen, foundry:opennlp, layer:orth, match:match:eq}}";
+ runAndValidate(query, jsonLd);
+ }
+
+ @Test
+ public void testTermQueryWithSpecificLayer() throws JsonProcessingException {
+ String query = "[text = \"Sonne\"]";
+ String jsonLd = "{@type:koral:token, wrap:{@type:koral:term, key:Sonne, "
+ + "foundry:opennlp, layer:orth, match:match:eq}}";
+ runAndValidate(query, jsonLd);
+
+ query = "[lemma = \"sein\"]";
+ jsonLd = "{@type:koral:token, wrap:{@type:koral:term, key:sein, "
+ + "foundry:tt, layer:l, match:match:eq}}";
+ runAndValidate(query, jsonLd);
+
+ query = "[pos = \"NN\"]";
+ jsonLd = "{@type:koral:token, wrap:{@type:koral:term, key:NN, "
+ + "foundry:tt, layer:p, match:match:eq}}";
+ runAndValidate(query, jsonLd);
+ }
+
+ @Test
+ public void testTermQueryWithQualifier() throws JsonProcessingException {
+ String query = "[mate:lemma = \"sein\"]";
+ String jsonLd = "{@type:koral:token, wrap:{@type:koral:term, key:sein, "
+ + "foundry:mate, layer:l, match:match:eq}}";
+ runAndValidate(query, jsonLd);
+
+ query = "[cnx:pos = \"N\"]";
+ jsonLd = "{@type:koral:token, wrap:{@type:koral:term, key:N, "
+ + "foundry:cnx, layer:p, match:match:eq}}";
+ runAndValidate(query, jsonLd);
+ }
+
+ @Test
+ public void testMatchOperation() throws JsonProcessingException {
+ String query = "[cnx:pos != \"N\"]";
+ String jsonLd = "{@type:koral:token, wrap:{@type:koral:term, key:N, "
+ + "foundry:cnx, layer:p, match:match:ne}}";
+ runAndValidate(query, jsonLd);
+ }
+
+ // @Test
+ // public void testSequenceQuery() throws JsonProcessingException {
+ // String query = "\"blaue\" [pos = \"NN\"]";
+ // String jsonLd =
+ // "{@type:koral:group, operation:operation:sequence, operands:["
+ // +
+ // "{@type:koral:token, wrap:{@type:koral:term, key:blaue, foundry:opennlp, layer:orth, match:match:eq}},"
+ // +
+ // "{@type:koral:token, wrap:{@type:koral:term, key:NN, foundry:tt, layer:p, match:match:eq}}"
+ // + "]}";
+ // runAndValidate(query, jsonLd);
+ // }
+
+}