Added FCSAndQuery serialization.
Change-Id: I5a1bc12a5e308a6ae6a040f6492a0d479da7aceb
diff --git a/src/main/java/de/ids_mannheim/korap/query/parse/fcsql/FCSSRUQueryParser.java b/src/main/java/de/ids_mannheim/korap/query/parse/fcsql/FCSSRUQueryParser.java
new file mode 100644
index 0000000..1ca4edd
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/parse/fcsql/FCSSRUQueryParser.java
@@ -0,0 +1,217 @@
+package de.ids_mannheim.korap.query.parse.fcsql;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import de.ids_mannheim.korap.query.parse.fcsql.KoralSequence.Distance;
+import de.ids_mannheim.korap.query.serialize.FCSQLQueryProcessor;
+import de.ids_mannheim.korap.query.serialize.util.StatusCodes;
+import eu.clarin.sru.server.fcs.parser.Expression;
+import eu.clarin.sru.server.fcs.parser.ExpressionAnd;
+import eu.clarin.sru.server.fcs.parser.Operator;
+import eu.clarin.sru.server.fcs.parser.QueryNode;
+import eu.clarin.sru.server.fcs.parser.QuerySegment;
+import eu.clarin.sru.server.fcs.parser.RegexFlag;
+
+public class FCSSRUQueryParser {
+
+ private static final String FOUNDRY_CNX = "cnx";
+ private static final String FOUNDRY_OPENNLP = "opennlp";
+ private static final String FOUNDRY_TT = "tt";
+ private static final String FOUNDRY_MATE = "mate";
+ private static final String FOUNDRY_XIP = "xip";
+
+ private List<String> supportedFoundries = Arrays
+ .asList(new String[] { FOUNDRY_CNX, FOUNDRY_OPENNLP, FOUNDRY_TT,
+ FOUNDRY_MATE, FOUNDRY_XIP });
+
+ private FCSQLQueryProcessor processor;
+
+ public FCSSRUQueryParser (FCSQLQueryProcessor processor) {
+ this.processor = processor;
+ }
+
+ public Object parseQueryNode(QueryNode queryNode) {
+
+ if (queryNode instanceof QuerySegment) {
+ return parseQuerySegment((QuerySegment) queryNode);
+ // } else if (queryNode instanceof QueryGroup) {
+ //
+ // } else if (queryNode instanceof QuerySequence) {
+ //
+ // } else if (queryNode instanceof QueryDisjunction) {
+ //
+ // } else if (queryNode instanceof QueryWithWithin) {
+
+ }
+ else {
+ processor.addError(StatusCodes.QUERY_TOO_COMPLEX,
+ "FCS diagnostic 11:" + queryNode.getNodeType().name()
+ + " is currently unsupported.");
+ return null;
+ }
+ }
+
+ private Object parseQuerySegment(QuerySegment segment) {
+ if ((segment.getMinOccurs() == 1) && (segment.getMaxOccurs() == 1)) {
+ return parseExpression(segment.getExpression());
+ }
+ else {
+ processor.addError(StatusCodes.QUERY_TOO_COMPLEX,
+ "FCS diagnostic 11: Query is too complex.");
+ return null;
+ }
+ }
+
+ private Object parseExpression(QueryNode queryNode) {
+ if (queryNode instanceof Expression) {
+ Expression expression = (Expression) queryNode;
+ return parseSimpleExpression(expression);
+ }
+ else if (queryNode instanceof ExpressionAnd) {
+ ExpressionAnd expressionAnd = (ExpressionAnd) queryNode;
+ return parseExpressionAnd(expressionAnd);
+ }
+ // else if (queryNode instanceof ExpressionGroup) {
+ //
+ // }
+ // else if (queryNode instanceof ExpressionNot) {
+ //
+ // }
+ // else if (queryNode instanceof ExpressionOr) {
+ //
+ // }
+ // else if (queryNode instanceof ExpressionWildcard) {
+ //
+ // }
+ else {
+ processor.addError(StatusCodes.QUERY_TOO_COMPLEX,
+ "FCS diagnostic 11: Query is too complex.");
+ return null;
+ }
+ }
+
+ private Object parseExpressionAnd(ExpressionAnd expressionAnd) {
+ KoralSequence koralSequence = new KoralSequence();
+ List<Object> operands = new ArrayList<Object>();
+ for (QueryNode child : expressionAnd.getChildren()) {
+ operands.add(parseExpression(child));
+ }
+
+ List<Distance> distances = new ArrayList<Distance>();
+ Distance d = koralSequence.new Distance("s", 0, 0);
+ distances.add(d);
+
+ koralSequence.setOperands(operands);
+ koralSequence.setDistances(distances);
+ return koralSequence;
+ }
+
+ private Object parseSimpleExpression(Expression expression) {
+ KoralTerm koralTerm = new KoralTerm();
+ koralTerm.setQueryTerm(expression.getRegexValue());
+ parseLayerIdentifier(koralTerm, expression.getLayerIdentifier());
+ parseQualifier(koralTerm, expression.getLayerQualifier());
+ parseOperator(koralTerm, expression.getOperator());
+ parseRegexFlags(koralTerm, expression.getRegexFlags());
+ return koralTerm;
+ }
+
+ private void parseLayerIdentifier(KoralTerm koralTerm, String identifier) {
+ String layer = null;
+ if (identifier == null) {
+ processor.addError(StatusCodes.MALFORMED_QUERY,
+ "FCS diagnostic 10: Layer identifier is missing.");
+ koralTerm.setInvalid(true);
+ }
+ else if (identifier.equals("text")) {
+ layer = "orth";
+ }
+ else if (identifier.equals("pos")) {
+ layer = "p";
+ }
+ else if (identifier.equals("lemma")) {
+ layer = "l";
+ }
+ else {
+ processor.addError(StatusCodes.UNKNOWN_QUERY_ELEMENT,
+ "SRU diagnostic 48: Layer " + identifier
+ + " is unsupported.");
+ koralTerm.setInvalid(true);
+ }
+
+ koralTerm.setLayer(layer);
+ }
+
+ private void parseQualifier(KoralTerm koralTerm, String qualifier) {
+ String layer = koralTerm.getLayer();
+ if (layer == null) {
+ koralTerm.setInvalid(true);
+ return;
+ }
+ // Set default foundry
+ if (qualifier == null) {
+ if (layer.equals("orth")) {
+ qualifier = FOUNDRY_OPENNLP;
+ }
+ else {
+ qualifier = FOUNDRY_TT;
+ }
+ }
+ else if (qualifier.equals(FOUNDRY_OPENNLP) && layer.equals("l")) {
+ processor
+ .addError(StatusCodes.UNKNOWN_QUERY_ELEMENT,
+ "SRU diagnostic 48: Layer lemma with qualifier opennlp is unsupported.");
+ koralTerm.setInvalid(true);
+ }
+ else if (!supportedFoundries.contains(qualifier)) {
+ processor.addError(StatusCodes.UNKNOWN_QUERY_ELEMENT,
+ "SRU diagnostic 48: Qualifier " + qualifier
+ + " is unsupported.");
+ koralTerm.setInvalid(true);
+ }
+
+ koralTerm.setFoundry(qualifier);
+ }
+
+ private void parseOperator(KoralTerm koralTerm, Operator operator) {
+ String matchOperator = null;
+ if (operator == null || operator == Operator.EQUALS) {
+ matchOperator = "match:eq";
+ }
+ else if (operator == Operator.NOT_EQUALS) {
+ matchOperator = "match:ne";
+ }
+ else {
+ processor
+ .addError(StatusCodes.UNKNOWN_QUERY_ELEMENT,
+ "SRU diagnostic 37:" + operator.name()
+ + " is unsupported.");
+ koralTerm.setInvalid(true);
+ }
+ koralTerm.setOperator(matchOperator);
+ }
+
+ private void parseRegexFlags(KoralTerm koralTerm, Set<RegexFlag> set) {
+ // default case sensitive
+ if (set != null) {
+ for (RegexFlag f : set) {
+ if (f == RegexFlag.CASE_SENSITVE) {
+ koralTerm.setCaseSensitive(true);
+ }
+ else if (f == RegexFlag.CASE_INSENSITVE) {
+ koralTerm.setCaseSensitive(false);
+ }
+ else {
+ processor.addError(StatusCodes.UNKNOWN_QUERY_ELEMENT,
+ "SRU diagnostic 48:" + f.name()
+ + " is unsupported.");
+ koralTerm.setInvalid(true);
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/query/parse/fcsql/KoralSequence.java b/src/main/java/de/ids_mannheim/korap/query/parse/fcsql/KoralSequence.java
new file mode 100644
index 0000000..31bd159
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/parse/fcsql/KoralSequence.java
@@ -0,0 +1,71 @@
+package de.ids_mannheim.korap.query.parse.fcsql;
+
+import java.util.List;
+
+public class KoralSequence {
+
+ private boolean inOrder = false;
+ private List<Object> operands;
+ private List<Distance> distances;
+
+ public boolean isInOrder() {
+ return inOrder;
+ }
+
+ public void setInOrder(boolean inOrder) {
+ this.inOrder = inOrder;
+ }
+
+ public List<Object> getOperands() {
+ return operands;
+ }
+
+ public void setOperands(List<Object> operands) {
+ this.operands = operands;
+ }
+
+ public List<Distance> getDistances() {
+ return distances;
+ }
+
+ public void setDistances(List<Distance> distances) {
+ this.distances = distances;
+ }
+
+ public class Distance {
+ private String key;
+ private String min;
+ private String max;
+
+ public Distance (String key, int min, int max) {
+ this.key = key;
+ this.min = String.valueOf(min);
+ this.max = String.valueOf(max);
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public String getMin() {
+ return min;
+ }
+
+ public void setMin(String min) {
+ this.min = min;
+ }
+
+ public String getMax() {
+ return max;
+ }
+
+ public void setMax(String max) {
+ this.max = max;
+ }
+
+ }
+}
diff --git a/src/main/java/de/ids_mannheim/korap/query/parse/fcsql/KoralTerm.java b/src/main/java/de/ids_mannheim/korap/query/parse/fcsql/KoralTerm.java
new file mode 100644
index 0000000..1ae2e09
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/parse/fcsql/KoralTerm.java
@@ -0,0 +1,61 @@
+package de.ids_mannheim.korap.query.parse.fcsql;
+
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import de.ids_mannheim.korap.query.serialize.FCSQLQueryProcessor;
+import de.ids_mannheim.korap.query.serialize.util.StatusCodes;
+import eu.clarin.sru.server.fcs.parser.Operator;
+import eu.clarin.sru.server.fcs.parser.RegexFlag;
+
+public class KoralTerm {
+
+ private String layer;
+ private String foundry;
+ private String operator;
+ private String queryTerm;
+ private boolean caseSensitive = true;
+ private boolean invalid = false;
+
+
+ public String getLayer() {
+ return layer;
+ }
+ public void setLayer(String layer) {
+ this.layer = layer;
+ }
+ public String getFoundry() {
+ return foundry;
+ }
+ public void setFoundry(String foundry) {
+ this.foundry = foundry;
+ }
+ public String getOperator() {
+ return operator;
+ }
+ public void setOperator(String operator) {
+ this.operator = operator;
+ }
+ public String getQueryTerm() {
+ return queryTerm;
+ }
+ public void setQueryTerm(String queryTerm) {
+ this.queryTerm = queryTerm;
+ }
+ public boolean isCaseSensitive() {
+ return caseSensitive;
+ }
+ public void setCaseSensitive(boolean isCaseSensitive) {
+ this.caseSensitive = isCaseSensitive;
+ }
+ public boolean isInvalid() {
+ return invalid;
+ }
+ public void setInvalid(boolean invalid) {
+ this.invalid = invalid;
+ }
+
+}
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
index 7e0c199..0785237 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/FCSQLQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/FCSQLQueryProcessor.java
@@ -4,266 +4,168 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.Set;
+import de.ids_mannheim.korap.query.parse.fcsql.FCSSRUQueryParser;
+import de.ids_mannheim.korap.query.parse.fcsql.KoralSequence;
+import de.ids_mannheim.korap.query.parse.fcsql.KoralSequence.Distance;
+import de.ids_mannheim.korap.query.parse.fcsql.KoralTerm;
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;
+/**
+ * @author margaretha
+ *
+ */
public class FCSQLQueryProcessor extends AbstractQueryProcessor {
- public static final class FCSQuery extends SRUQueryBase<QueryNode> {
+ public static final class FCSSRUQuery extends SRUQueryBase<QueryNode> {
- private FCSQuery(String rawQuery, QueryNode parsedQuery) {
- super(rawQuery, parsedQuery);
- }
+ private FCSSRUQuery (String rawQuery, QueryNode parsedQuery) {
+ super(rawQuery, parsedQuery);
+ }
- @Override
- public String getQueryType() {
- return Constants.FCS_QUERY_TYPE_FCS;
- }
- }
+ @Override
+ public String getQueryType() {
+ return Constants.FCS_QUERY_TYPE_FCS;
+ }
+ }
- public enum Foundry {
- CNX, OPENNLP, TT, MATE, XIP;
- }
+ private static final String VERSION_2_0 = "2.0";
+ 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 String version;
- private List<Foundry> supportedFoundries;
- private final QueryParser parser = new QueryParser();
+ private final QueryParser fcsParser = new QueryParser();
+ private String version;
- 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;
+ public FCSQLQueryProcessor (String query, String version) {
+ super();
+ this.version = version;
+ process(query);
+ }
- this.requestMap = new LinkedHashMap<>();
- requestMap.put("@context", KORAP_CONTEXT);
+ @Override
+ public Map<String, Object> getRequestMap() {
+ return this.requestMap;
+ }
- 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);
+ @Override
+ public void process(String query) {
+ if (isVersionValid()) {
+ FCSSRUQuery fcsSruQuery = parseQueryStringtoFCSQuery(query);
+ QueryNode fcsQueryNode = fcsSruQuery.getParsedQuery();
+ parseFCSQueryToKoralQuery(fcsQueryNode);
+ }
+ }
- process(query);
- }
+ private boolean isVersionValid() {
+ if (version == null || version.isEmpty()) {
+ addError(StatusCodes.MISSING_VERSION,
+ "SRU diagnostic 7: Version number is missing.");
+ return false;
+ }
+ else if (!version.equals(VERSION_2_0)) {
+ addError(StatusCodes.MISSING_VERSION,
+ "SRU diagnostic 5: Only supports SRU version 2.0.");
+ return false;
+ }
+ return true;
+ }
- @Override
- public Map<String, Object> getRequestMap() {
- return this.requestMap;
- }
+ private FCSSRUQuery parseQueryStringtoFCSQuery(String query) {
+ if ((query == null) || query.isEmpty())
+ addError(StatusCodes.NO_QUERY,
+ "SRU diagnostic 1: No query has been passed.");
+ FCSSRUQuery fcsQuery = null;
+ try {
+ QueryNode parsedQuery = fcsParser.parse(query);
+ fcsQuery = new FCSSRUQuery(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;
+ }
- @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 void parseFCSQueryToKoralQuery(QueryNode queryNode) {
+ FCSSRUQueryParser parser = new FCSSRUQueryParser(this);
+ Object o = parser.parseQueryNode(queryNode);
+ Map<String, Object> queryMap = buildQueryMap(o);
+ if (queryMap != null) 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> buildQueryMap(Object o) {
+ if (o != null) {
+ if (o instanceof KoralTerm) {
+ KoralTerm koralTerm = (KoralTerm) o;
+ if (!koralTerm.isInvalid()) {
+ return createTermMap(koralTerm);
+ }
+ }
+ else if (o instanceof KoralSequence) {
+ KoralSequence koralSequence = (KoralSequence) o;
+ return createSequenceMap(koralSequence);
+ }
+ }
+ return null;
+ }
- 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> createSequenceMap(KoralSequence koralSequence) {
+ Map<String, Object> map = new LinkedHashMap<String, Object>();
+ map.put("@type", "koral:group");
+ map.put("operation", OPERATION_SEQUENCE);
+ map.put("inOrder", koralSequence.isInOrder());
- }
+ if (koralSequence.getDistances() != null) {
+ List<Map<String, Object>> distanceList = new ArrayList<Map<String, Object>>();
+ for (Distance d : koralSequence.getDistances()) {
+ distanceList.add(createDistanceMap(d));
+ }
+ map.put("distances", distanceList);
+ }
- private Map<String, Object> parseQueryNode(QueryNode queryNode) {
- Map<String, Object> queryMap = null;
+ List<Map<String, Object>> operandList = new ArrayList<Map<String, Object>>();
+ for (Object o : koralSequence.getOperands()) {
+ operandList.add(buildQueryMap(o));
+ }
+ map.put("operands", operandList);
+ return map;
+ }
- 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) {
+ private Map<String, Object> createDistanceMap(Distance distance) {
+ Map<String, Object> distanceMap = new LinkedHashMap<String, Object>();
+ distanceMap.put("@type", "koral:distance");
+ distanceMap.put("key", distance.getKey());
+ distanceMap.put("min", distance.getMin());
+ distanceMap.put("max", distance.getMax());
+ return distanceMap;
- }else {
- addError(StatusCodes.QUERY_TOO_COMPLEX, "FCS diagnostic 11:"
- + queryNode.getNodeType().name()
- + " is currently unsupported.");
- }
+ }
- return queryMap;
- }
+ private Map<String, Object> createTermMap(KoralTerm fcsQuery) {
+ Map<String, Object> map = new LinkedHashMap<String, Object>();
+ map.put("@type", "koral:term");
+ if (!fcsQuery.isCaseSensitive()) {
+ map.put("caseInsensitive", "true");
+ }
+ map.put("key", fcsQuery.getQueryTerm());
+ map.put("foundry", fcsQuery.getFoundry());
+ map.put("layer", fcsQuery.getLayer());
+ map.put("match", fcsQuery.getOperator());
- 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;
- }
+ Map<String, Object> tokenMap = new LinkedHashMap<String, Object>();
+ tokenMap.put("@type", "koral:token");
+ tokenMap.put("wrap", map);
+ return tokenMap;
+ }
}
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
index 729381e..9b7da8b 100644
--- a/src/test/java/de/ids_mannheim/korap/query/serialize/FCSQLQueryProcessorTest.java
+++ b/src/test/java/de/ids_mannheim/korap/query/serialize/FCSQLQueryProcessorTest.java
@@ -2,89 +2,147 @@
import static org.junit.Assert.assertEquals;
+import java.util.List;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
-public class FcsqlQueryProcessorTest {
- ObjectMapper mapper = new ObjectMapper();
+public class FCSQLQueryProcessorTest {
- 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("\"", ""));
- }
+ ObjectMapper mapper = new ObjectMapper();
- @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);
- }
+ private void runAndValidate(String query, String jsonLD)
+ throws JsonProcessingException {
+ FCSQLQueryProcessor processor = new FCSQLQueryProcessor(query, "2.0");
+ String serializedQuery = mapper.writeValueAsString(processor
+ .getRequestMap().get("query"));
+ assertEquals(jsonLD.replace(" ", ""), serializedQuery.replace("\"", ""));
+ }
- @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);
- }
+ private List<Object> getError(FCSQLQueryProcessor processor) {
+ List<Object> errors = (List<Object>) processor.requestMap.get("errors");
+ return (List<Object>) errors.get(0);
+ }
- @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);
+ @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);
+ }
- query = "[lemma = \"sein\"]";
- jsonLd = "{@type:koral:token, wrap:{@type:koral:term, key:sein, "
- + "foundry:tt, layer:l, 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);
+ }
- 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 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);
- @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 = "[lemma = \"sein\"]";
+ jsonLd = "{@type:koral:token, wrap:{@type:koral:term, key:sein, "
+ + "foundry:tt, 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);
- }
+ 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 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 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);
- // @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);
- // }
+ 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 testTermQueryException() throws JsonProcessingException {
+ String query = "[opennlp:lemma = \"sein\"]";
+ List<Object> error = getError(new FCSQLQueryProcessor(query, "2.0"));
+ assertEquals(306, error.get(0));
+ assertEquals(
+ "SRU diagnostic 48: Layer lemma with qualifier opennlp is unsupported.",
+ error.get(1));
+
+ query = "[malt:lemma = \"sein\"]";
+ error = getError(new FCSQLQueryProcessor(query, "2.0"));
+ assertEquals(306, error.get(0));
+ assertEquals("SRU diagnostic 48: Qualifier malt is unsupported.",
+ error.get(1));
+
+ query = "[cnx:morph = \"heit\"]";
+ error = getError(new FCSQLQueryProcessor(query, "2.0"));
+ assertEquals(306, error.get(0));
+ assertEquals("SRU diagnostic 48: Layer morph is unsupported.",
+ error.get(1));
+
+ }
+
+ @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);
+ }
+
+ @Test
+ public void testAndQuery() throws JsonProcessingException {
+ String query = "[text=\"Sonne\" & text=\"scheint\"]";
+ String jsonLd = "{@type:koral:group, operation:operation:sequence, inOrder:false,"
+ + "distances:["
+ + "{@type:koral:distance, key:s, min:0, max:0}],"
+ + "operands:["
+ + "{@type:koral:token, wrap:{@type:koral:term, key:Sonne, foundry: opennlp, layer:orth, match:match:eq}},"
+ + "{@type:koral:token,wrap:{@type:koral:term, key:scheint, foundry: opennlp, layer:orth,match:match:eq}"
+ + "}]}";
+ runAndValidate(query, jsonLd);
+
+ // sru parser doesnt work for the following queries:
+ // String query = "\"Sonne & scheint\"";
+ // String query = "\"Sonne&scheint\"";
+ }
+
+ @Test
+ public void testVersion() throws JsonProcessingException {
+ List<Object> error = getError(new FCSQLQueryProcessor("\"Sonne\"",
+ "1.0"));
+ assertEquals(309, error.get(0));
+ assertEquals("SRU diagnostic 5: Only supports SRU version 2.0.",
+ error.get(1));
+
+ error = getError(new FCSQLQueryProcessor("\"Sonne\"", null));
+ assertEquals(309, error.get(0));
+ assertEquals("SRU diagnostic 7: Version number is missing.",
+ error.get(1));
+ }
}