Implemented exclusion for the Cosmas 2 IN operation.
Change-Id: Ibb964482b584d8f08452116a834b7be03f51ace7
diff --git a/src/main/java/de/ids_mannheim/korap/query/object/CosmasPosition.java b/src/main/java/de/ids_mannheim/korap/query/object/CosmasPosition.java
new file mode 100644
index 0000000..1b81929
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/object/CosmasPosition.java
@@ -0,0 +1,6 @@
+package de.ids_mannheim.korap.query.object;
+
+public enum CosmasPosition {
+
+ N, L, R, F, FE, FI;
+}
diff --git a/src/main/java/de/ids_mannheim/korap/query/object/KoralOperation.java b/src/main/java/de/ids_mannheim/korap/query/object/KoralOperation.java
index 98dae3e..675b627 100644
--- a/src/main/java/de/ids_mannheim/korap/query/object/KoralOperation.java
+++ b/src/main/java/de/ids_mannheim/korap/query/object/KoralOperation.java
@@ -5,7 +5,7 @@
*
*/
public enum KoralOperation {
- SEQUENCE, POSITION, DISJUNCTION, REPETITION, CLASS, MERGE, RELATION, FOCUS;
+ SEQUENCE, POSITION, DISJUNCTION, REPETITION, CLASS, MERGE, RELATION, FOCUS, EXCLUSION;
@Override
public String toString() {
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 60c2a51..7b101a9 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
@@ -46,7 +46,7 @@
* objects
* into last created objects.
*/
- LinkedList<LinkedHashMap<String, Object>> objectStack = new LinkedList<LinkedHashMap<String, Object>>();
+ LinkedList<Map<String, Object>> objectStack = new LinkedList<Map<String, Object>>();
/**
* Keeps track of how many objects there are to pop after every
* recursion
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 5a1c0b0..2611ab9 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
@@ -4,7 +4,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
-import java.util.LinkedHashMap;
+import java.util.Map;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -60,21 +60,21 @@
* uncreated
* objects.
*/
- LinkedList<LinkedHashMap<String, Object>> operandStack = new LinkedList<LinkedHashMap<String, Object>>();
+ LinkedList<Map<String, Object>> operandStack = new LinkedList<Map<String, Object>>();
/**
* Keeps track of explicitly (by #-var definition) or implicitly
* (number
* as reference) introduced entities (for later reference by
* #-operator)
*/
- Map<String, LinkedHashMap<String, Object>> nodeVariables = new LinkedHashMap<String, LinkedHashMap<String, Object>>();
+ Map<String, Map<String, Object>> nodeVariables = new HashMap<String, Map<String, Object>>();
/**
* Keeps track of explicitly (by #-var definition) or implicitly
* (number
* as reference) introduced entities (for later reference by
- * #-operator)
+ * #-operator)s
*/
- Map<ParseTree, String> nodes2refs = new LinkedHashMap<ParseTree, String>();
+ Map<ParseTree, String> nodes2refs = new HashMap<ParseTree, String>();
/**
* Counter for variable definitions.
*/
@@ -84,7 +84,7 @@
* flags
* (might already have been taken away from token stack).
*/
- LinkedHashMap<String, Object> curToken = new LinkedHashMap<String, Object>();
+ Map<String, Object> curToken = new HashMap<String, Object>();
/**
* Keeps track of operands lists that are to be serialised in an
* inverted
@@ -125,11 +125,11 @@
* classes for
* entities.
*/
- private LinkedHashMap<String, Integer> refClassMapping = new LinkedHashMap<String, Integer>();
+ private Map<String, Integer> refClassMapping = new HashMap<String, Integer>();
/**
* Keeps a record of unary relations on spans/tokens.
*/
- private LinkedHashMap<String, ArrayList<ParseTree>> unaryRelations = new LinkedHashMap<String, ArrayList<ParseTree>>();
+ private Map<String, ArrayList<ParseTree>> unaryRelations = new HashMap<String, ArrayList<ParseTree>>();
/**
* Keeps track of the number of references to a node/token by
* means of #n.
@@ -137,13 +137,13 @@
* #2 . #3</tt>,
* the 2nd token ("y") is referenced twice, the others once.
*/
- private LinkedHashMap<String, Integer> nodeReferencesTotal = new LinkedHashMap<String, Integer>();
+ private Map<String, Integer> nodeReferencesTotal = new HashMap<String, Integer>();
/**
* Keeps track of the number of references to a node/token that
* have
* already been processed.
*/
- private LinkedHashMap<String, Integer> nodeReferencesProcessed = new LinkedHashMap<String, Integer>();
+ private Map<String, Integer> nodeReferencesProcessed = new HashMap<String, Integer>();
/**
* Keeps track of queued relations. Relations sometimes cannot be
* processed
@@ -164,7 +164,7 @@
* class ID its
* derived KoralQuery object will receive.
*/
- private LinkedHashMap<ParseTree, Integer> objectsToWrapInClass = new LinkedHashMap<ParseTree, Integer>();
+ private Map<ParseTree, Integer> objectsToWrapInClass = new HashMap<ParseTree, Integer>();
public AnnisQueryProcessor (String query) {
@@ -200,7 +200,7 @@
"The relation " + queued.getText()
+ " is not bound to any other relations.");
requestMap
- .put("query", new LinkedHashMap<String, Object>());
+ .put("query", new HashMap<String, Object>());
}
}
}
@@ -360,7 +360,7 @@
ref = variableCount.toString();
}
nodes2refs.put(variableExprNode, ref);
- LinkedHashMap<String, Object> object = processVariableExpr(variableExprNode);
+ Map<String, Object> object = processVariableExpr(variableExprNode);
nodeVariables.put(ref, object);
variableCount++;
// Check if this object definition is part of a "direct declaration
@@ -396,7 +396,7 @@
private void processExprTop (ParseTree node) {
List<ParseTree> andTopExprs = getChildrenWithCat(node, "andTopExpr");
if (andTopExprs.size() > 1) {
- LinkedHashMap<String, Object> topOr = KoralObjectGenerator
+ Map<String, Object> topOr = KoralObjectGenerator
.makeGroup(KoralOperation.DISJUNCTION);
requestMap.put("query", topOr);
objectStack.push(topOr);
@@ -405,17 +405,17 @@
@SuppressWarnings("unchecked")
- private LinkedHashMap<String, Object> processVariableExpr (ParseTree node) {
+ private Map<String, Object> processVariableExpr (ParseTree node) {
// simplex word or complex assignment (like qname = textSpec)?
String firstChildNodeCat = getNodeCat(node.getChild(0));
- LinkedHashMap<String, Object> object = null;
+ Map<String, Object> object = null;
if (firstChildNodeCat.equals("node")) {
object = KoralObjectGenerator.makeSpan();
}
else if (firstChildNodeCat.equals("tok")) {
object = KoralObjectGenerator.makeToken();
if (node.getChildCount() > 1) { // empty tokens do not wrap a term
- LinkedHashMap<String, Object> term = KoralObjectGenerator
+ Map<String, Object> term = KoralObjectGenerator
.makeTerm();
term.put("layer", "orth");
object.put("wrap", term);
@@ -427,12 +427,12 @@
// (e.g. cnx/cat=NP vs mate/pos=NN)
// TODO generalize the list below -> look up layers associated with
// tokens rather than spans somewhere
- HashMap<String, Object> qNameParse = parseQNameNode(node
+ Map<String, Object> qNameParse = parseQNameNode(node
.getChild(0));
if (Arrays.asList(new String[] { "p", "lemma", "m", "orth" })
.contains(qNameParse.get("layer"))) {
object = KoralObjectGenerator.makeToken();
- LinkedHashMap<String, Object> term = KoralObjectGenerator
+ Map<String, Object> term = KoralObjectGenerator
.makeTerm();
object.put("wrap", term);
term.putAll(qNameParse);
@@ -444,7 +444,7 @@
}
else if (firstChildNodeCat.equals("textSpec")) {
object = KoralObjectGenerator.makeToken();
- LinkedHashMap<String, Object> term = KoralObjectGenerator
+ Map<String, Object> term = KoralObjectGenerator
.makeTerm();
object.put("wrap", term);
term.put("layer", "orth");
@@ -479,7 +479,7 @@
object.put("attr", parseUnaryOperator(unaryTermsForRef.get(0)));
}
else {
- LinkedHashMap<String, Object> termGroup = KoralObjectGenerator
+ Map<String, Object> termGroup = KoralObjectGenerator
.makeTermGroup(KoralTermGroupRelation.AND);
ArrayList<Object> operands = (ArrayList<Object>) termGroup
.get("operands");
@@ -526,8 +526,8 @@
* representation
* of the operand
*/
- private LinkedHashMap<String, Object> retrieveOperand (ParseTree operandNode) {
- LinkedHashMap<String, Object> operand = null;
+ private Map<String, Object> retrieveOperand (ParseTree operandNode) {
+ Map<String, Object> operand = null;
if (!getNodeCat(operandNode.getChild(0)).equals("variableExpr")) {
String ref = operandNode.getChild(0).toStringTree(parser)
.substring(1);
@@ -605,7 +605,7 @@
ParseTree operandTree2 = node.getChild(i + 1);
String reltype = getNodeCat(node.getChild(i).getChild(0));
- LinkedHashMap<String, Object> group = null;
+ Map<String, Object> group = null;
ArrayList<Object> operands = null;
// make sure one of the operands has already been put into a
// relation (if this is not the 1st relation). If none of the
@@ -625,8 +625,8 @@
}
}
// Retrieve operands.
- LinkedHashMap<String, Object> operand1 = retrieveOperand(operandTree1);
- LinkedHashMap<String, Object> operand2 = retrieveOperand(operandTree2);
+ Map<String, Object> operand1 = retrieveOperand(operandTree1);
+ Map<String, Object> operand2 = retrieveOperand(operandTree2);
// 'Proper' n_ary_linguistic_operators receive a considerably
// different serialisation than 'commonparent' and 'commonancestor'
// For the latter cases, a dummy span is introduced and declared as
@@ -640,11 +640,11 @@
// make an (outer) group and an inner group containing the dummy
// node or previous relations
group = KoralObjectGenerator.makeGroup(KoralOperation.RELATION);
- LinkedHashMap<String, Object> innerGroup = KoralObjectGenerator
+ Map<String, Object> innerGroup = KoralObjectGenerator
.makeGroup(KoralOperation.RELATION);
- LinkedHashMap<String, Object> relation = KoralObjectGenerator
+ Map<String, Object> relation = KoralObjectGenerator
.makeRelation();
- LinkedHashMap<String, Object> term = KoralObjectGenerator
+ Map<String, Object> term = KoralObjectGenerator
.makeTerm();
term.put("layer", "c");
relation.put("wrap", term);
@@ -696,7 +696,7 @@
// attributes defined in KoralQ. and can be handled more easily
}
else {
- LinkedHashMap<String, Object> operatorGroup = parseOperatorNode(node
+ Map<String, Object> operatorGroup = parseOperatorNode(node
.getChild(i).getChild(0));
String groupType;
try {
@@ -709,7 +709,7 @@
// || groupType.equals("treeRelation")
) {
group = KoralObjectGenerator.makeGroup(KoralOperation.RELATION);
- LinkedHashMap<String, Object> relation = new LinkedHashMap<String, Object>();
+ Map<String, Object> relation = new HashMap<String, Object>();
putAllButGroupType(relation, operatorGroup);
group.put("relation", relation);
}
@@ -718,7 +718,7 @@
putAllButGroupType(group, operatorGroup);
}
else if (groupType.equals("position")) {
- group = new LinkedHashMap<String, Object>();
+ group = new HashMap<String, Object>();
putAllButGroupType(group, operatorGroup);
}
@@ -735,7 +735,7 @@
: KoralFrame.ENDS_WITH;
ArrayList<KoralFrame> frames = new ArrayList<KoralFrame>();
frames.add(frame);
- LinkedHashMap<String, Object> positionGroup = KoralObjectGenerator
+ Map<String, Object> positionGroup = KoralObjectGenerator
.makePosition(frames);
operand2 = KoralObjectGenerator.wrapInClass(operand2,
++classCounter + 128);
@@ -831,11 +831,11 @@
* @return A map containing the attr key, to be inserted into
* koral:span
*/
- private LinkedHashMap<String, Object> parseUnaryOperator (ParseTree node) {
- LinkedHashMap<String, Object> term = KoralObjectGenerator.makeTerm();
+ private Map<String, Object> parseUnaryOperator (ParseTree node) {
+ Map<String, Object> term = KoralObjectGenerator.makeTerm();
String op = node.getChild(1).toStringTree(parser).substring(1);
if (op.equals("arity") || op.equals("tokenarity")) {
- LinkedHashMap<String, Object> boundary = boundaryFromRangeSpec(
+ Map<String, Object> boundary = boundaryFromRangeSpec(
node.getChild(3), false);
term.put(op, boundary);
}
@@ -847,9 +847,9 @@
@SuppressWarnings("unchecked")
- private LinkedHashMap<String, Object> parseOperatorNode (
+ private Map<String, Object> parseOperatorNode (
ParseTree operatorNode) {
- LinkedHashMap<String, Object> relation = null;
+ Map<String, Object> relation = null;
String operator = getNodeCat(operatorNode);
// DOMINANCE
if (operator.equals("dominance")) {
@@ -861,13 +861,13 @@
ParseTree star = getFirstChildWithCat(operatorNode, "*");
ParseTree rangeSpec = getFirstChildWithCat(operatorNode,
"rangeSpec");
- LinkedHashMap<String, Object> term = KoralObjectGenerator
+ Map<String, Object> term = KoralObjectGenerator
.makeTerm();
term.put("layer", "c");
if (qName != null)
term = parseQNameNode(qName);
if (edgeSpecNode != null) {
- LinkedHashMap<String, Object> edgeSpec = parseEdgeSpec(edgeSpecNode);
+ Map<String, Object> edgeSpec = parseEdgeSpec(edgeSpecNode);
String edgeSpecType = (String) edgeSpec.get("@type");
if (edgeSpecType.equals("koral:termGroup")) {
((ArrayList<Object>) edgeSpec.get("operands")).add(term);
@@ -878,7 +878,7 @@
ArrayList<Object> termGroupOperands = (ArrayList<Object>) term
.get("operands");
termGroupOperands.add(edgeSpec);
- LinkedHashMap<String, Object> constTerm = KoralObjectGenerator
+ Map<String, Object> constTerm = KoralObjectGenerator
.makeTerm();
constTerm.put("layer", "c");
termGroupOperands.add(constTerm);
@@ -899,7 +899,7 @@
ParseTree star = getFirstChildWithCat(operatorNode, "*");
ParseTree rangeSpec = getFirstChildWithCat(operatorNode,
"rangeSpec");
- LinkedHashMap<String, Object> term = KoralObjectGenerator
+ Map<String, Object> term = KoralObjectGenerator
.makeTerm();
if (qName != null)
term.putAll(parseQNameNode(qName));
@@ -913,7 +913,7 @@
relation.put("wrap", term);
}
else if (operator.equals("precedence")) {
- relation = new LinkedHashMap<String, Object>();
+ relation = new HashMap<String, Object>();
relation.put("groupType", "sequence");
ParseTree rangeSpec = getFirstChildWithCat(operatorNode,
"rangeSpec");
@@ -962,7 +962,7 @@
relation.put("groupType", "position");
}
else if (operator.equals("near")) {
- relation = new LinkedHashMap<String, Object>();
+ relation = new HashMap<String, Object>();
relation.put("groupType", "sequence");
ParseTree rangeSpec = getFirstChildWithCat(operatorNode,
"rangeSpec");
@@ -992,12 +992,12 @@
@SuppressWarnings("unchecked")
- private LinkedHashMap<String, Object> parseEdgeSpec (ParseTree edgeSpec) {
+ private Map<String, Object> parseEdgeSpec (ParseTree edgeSpec) {
List<ParseTree> annos = getChildrenWithCat(edgeSpec, "edgeAnno");
if (annos.size() == 1)
return parseEdgeAnno(annos.get(0));
else {
- LinkedHashMap<String, Object> termGroup = KoralObjectGenerator
+ Map<String, Object> termGroup = KoralObjectGenerator
.makeTermGroup(KoralTermGroupRelation.AND);
ArrayList<Object> operands = (ArrayList<Object>) termGroup
.get("operands");
@@ -1009,8 +1009,8 @@
}
- private LinkedHashMap<String, Object> parseEdgeAnno (ParseTree edgeAnnoSpec) {
- LinkedHashMap<String, Object> edgeAnno = KoralObjectGenerator
+ private Map<String, Object> parseEdgeAnno (ParseTree edgeAnnoSpec) {
+ Map<String, Object> edgeAnno = KoralObjectGenerator
.makeTerm();
ParseTree textSpecNode = getFirstChildWithCat(edgeAnnoSpec, "textSpec");
ParseTree layerNode = getFirstChildWithCat(edgeAnnoSpec, "layer");
@@ -1028,13 +1028,13 @@
}
- private LinkedHashMap<String, Object> boundaryFromRangeSpec (
+ private Map<String, Object> boundaryFromRangeSpec (
ParseTree rangeSpec) {
return boundaryFromRangeSpec(rangeSpec, true);
}
- private LinkedHashMap<String, Object> boundaryFromRangeSpec (
+ private Map<String, Object> boundaryFromRangeSpec (
ParseTree rangeSpec, boolean expandToMax) {
Integer min = Integer.parseInt(rangeSpec.getChild(0).toStringTree(
parser));
@@ -1047,7 +1047,7 @@
}
- private LinkedHashMap<String, Object> parseDistance (ParseTree rangeSpec) {
+ private Map<String, Object> parseDistance (ParseTree rangeSpec) {
String minString = rangeSpec.getChild(0).toStringTree(parser);
String maxString = null; // not always given, prevent NPE
if (minString.equals("0")) {
@@ -1066,8 +1066,8 @@
}
- private LinkedHashMap<String, Object> parseTextSpec (ParseTree node) {
- LinkedHashMap<String, Object> term = new LinkedHashMap<String, Object>();
+ private Map<String, Object> parseTextSpec (ParseTree node) {
+ Map<String, Object> term = new HashMap<String, Object>();
if (hasChild(node, "regex")) {
term.put("type", "type:regex");
term.put("key", node.getChild(0).getChild(0).toStringTree(parser)
@@ -1096,8 +1096,8 @@
}
- private LinkedHashMap<String, Object> parseQNameNode (ParseTree node) {
- LinkedHashMap<String, Object> fields = new LinkedHashMap<String, Object>();
+ private Map<String, Object> parseQNameNode (ParseTree node) {
+ Map<String, Object> fields = new HashMap<String, Object>();
ParseTree layerNode = getFirstChildWithCat(node, "layer");
ParseTree foundryNode = getFirstChildWithCat(node, "foundry");
if (foundryNode != null)
@@ -1112,13 +1112,13 @@
}
- private void putIntoSuperObject (LinkedHashMap<String, Object> object) {
+ private void putIntoSuperObject (Map<String, Object> object) {
putIntoSuperObject(object, 0);
}
@SuppressWarnings({ "unchecked" })
- private void putIntoSuperObject (LinkedHashMap<String, Object> object,
+ private void putIntoSuperObject (Map<String, Object> object,
int objStackPosition) {
if (objectStack.size() > objStackPosition) {
ArrayList<Object> topObjectOperands = (ArrayList<Object>) objectStack
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 c3b31e2..705963c 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
@@ -2,6 +2,7 @@
import de.ids_mannheim.korap.query.object.ClassRefCheck;
import de.ids_mannheim.korap.query.object.ClassRefOp;
+import de.ids_mannheim.korap.query.object.CosmasPosition;
import de.ids_mannheim.korap.query.object.KoralFrame;
import de.ids_mannheim.korap.query.object.KoralMatchOperator;
import de.ids_mannheim.korap.query.object.KoralOperation;
@@ -469,72 +470,120 @@
}
+ private boolean isExclusion (Tree node) {
+ Tree exclnode = getFirstChildWithCat(node, "EXCL");
+ if (exclnode != null
+ && exclnode.getChild(0).toStringTree().equals("YES")) {
+ return true;
+ }
+ return false;
+ }
+
+
+ private Map<String, Object> addClassRefCheck (
+ ArrayList<ClassRefCheck> check, Map<String, Object> group) {
+ Integer[] classIn = new Integer[] { classCounter + 128 - 2,
+ classCounter + 128 - 1 };
+ // wrap position in a classRefCheck
+ Map<String, Object> topGroup = KoralObjectGenerator
+ .makeClassRefCheck(check, classIn, classCounter + 128);
+ ((ArrayList<Object>) topGroup.get("operands")).add(group);
+ return topGroup;
+ }
+
+
+ private Map<String, Object> addClassFocus (boolean isMatchAll,
+ Map<String, Object> posGroup) {
+ Map<String, Object> focusGroup = null;
+ if (isMatchAll) {
+ focusGroup = KoralObjectGenerator.makeClassRefOp(ClassRefOp.DELETE,
+ new Integer[] { 128 + classCounter++ }, 128 + classCounter);
+ ((ArrayList<Object>) focusGroup.get("operands")).add(posGroup);
+ }
+ else { // match only first argument
+ focusGroup = KoralObjectGenerator.wrapInReference(posGroup,
+ classCounter + 128 - 1);
+ classCounter++;
+ }
+ return focusGroup;
+ }
+
+
@SuppressWarnings("unchecked")
private void processOPIN_OPOV (Tree node) {
- // Step I: create group
String nodeCat = getNodeCat(node);
- wrapOperandInClass(node, 2, 128 + classCounter++);
- wrapOperandInClass(node, 1, 128 + classCounter++);
+
// LinkedHashMap<String, Object> posgroup =
// makePosition(null);
- LinkedHashMap<String, Object> posGroup = KoralObjectGenerator
- .makeGroup(KoralOperation.POSITION);
- LinkedHashMap<String, Object> positionOptions;
- // posgroup
+ boolean isExclusion = isExclusion(node);
+
+ KoralOperation operation;
+ if (isExclusion) {
+ operation = KoralOperation.EXCLUSION;
+ }
+ else {
+ operation = KoralOperation.POSITION;
+ wrapOperandInClass(node, 2, 128 + classCounter++);
+ wrapOperandInClass(node, 1, 128 + classCounter++);
+ }
+
+ Map<String, Object> posGroup = KoralObjectGenerator
+ .makeGroup(operation);
+
+ Map<String, Object> positionOptions;
if (nodeCat.equals("OPIN")) {
- positionOptions = parseOPINOptions(node);
+ positionOptions = parseOPINOptions(node, isExclusion);
}
else {
positionOptions = parseOPOVOptions(node);
}
+
posGroup.put("frames", positionOptions.get("frames"));
- posGroup.put("frame", positionOptions.get("frame"));
- if (positionOptions.containsKey("exclude")) {
- posGroup.put("exclude", positionOptions.get("exclude"));
- }
+ // EM: is frame needed?
+ // posGroup.put("frame", positionOptions.get("frame"));
objectStack.push(posGroup);
- // mark this an inverted operands object
- invertedOperandsLists
- .push((ArrayList<Object>) posGroup.get("operands"));
stackedObjects++;
- // Step II: wrap in classRefCheck and/or focus and decide where to put
- ArrayList<ClassRefCheck> check = (ArrayList<ClassRefCheck>) positionOptions
+
+ ArrayList<ClassRefCheck> checkList = (ArrayList<ClassRefCheck>) positionOptions
.get("classRefCheck");
- Integer[] classIn = new Integer[] { classCounter + 128 - 2,
- classCounter + 128 - 1 };
- LinkedHashMap<String, Object> topGroup;
- if (!check.isEmpty()) {
- // wrap position in a classRefCheck
- topGroup = KoralObjectGenerator.makeClassRefCheck(check, classIn,
- classCounter + 128);
- ((ArrayList<Object>) topGroup.get("operands")).add(posGroup);
- }
- else {
- topGroup = posGroup;
- }
- LinkedHashMap<String, Object> focusGroup = null;
- if ((boolean) positionOptions.get("matchall") == true) {
- focusGroup = KoralObjectGenerator.makeClassRefOp(ClassRefOp.DELETE,
- new Integer[] { 128 + classCounter++ }, 128 + classCounter);
- ((ArrayList<Object>) focusGroup.get("operands")).add(topGroup);
- }
- else { // match only first argument
- focusGroup = KoralObjectGenerator.wrapInReference(topGroup,
- classCounter + 128 - 1);
- classCounter++;
- }
- // wrap in 'merge' operation if grouping option is set
- if (positionOptions.containsKey("grouping")) {
- if (positionOptions.get("grouping").equals(true)) {
- LinkedHashMap<String, Object> mergeOperation = KoralObjectGenerator
- .makeGroup(KoralOperation.MERGE);
- ArrayList<Object> mergeOperands = (ArrayList<Object>) mergeOperation
- .get("operands");
- mergeOperands.add(focusGroup);
- focusGroup = mergeOperation;
+
+ // EM: why bother inverting the operands and creating classes and focus?
+ // can't we agree on the first operand to be the results, like in operation:exclusion?
+ if (!isExclusion) {
+ // mark this an inverted operands object
+ invertedOperandsLists
+ .push((ArrayList<Object>) posGroup.get("operands"));
+
+ // Step II: wrap in classRefCheck and/or focus and decide where to put
+ if (!checkList.isEmpty()) {
+ posGroup = addClassRefCheck(checkList, posGroup);
}
+ posGroup = addClassFocus((boolean) positionOptions.get("matchall"),
+ posGroup);
+
}
- putIntoSuperObject(focusGroup, 1);
+ else if (!checkList.isEmpty()) {
+ wrapOperandInClass(node, 1, 128 + classCounter++);
+ wrapOperandInClass(node, 2, 128 + classCounter++);
+ posGroup = addClassRefCheck(
+ (ArrayList<ClassRefCheck>) positionOptions
+ .get("classRefCheck"),
+ posGroup);
+ posGroup = addClassFocus((boolean) positionOptions.get("matchall"),
+ posGroup);
+ }
+
+ // wrap in 'merge' operation if grouping option is set
+ if (positionOptions.containsKey("grouping")
+ && (boolean) positionOptions.get("grouping")) {
+ LinkedHashMap<String, Object> mergeOperation = KoralObjectGenerator
+ .makeGroup(KoralOperation.MERGE);
+ ArrayList<Object> mergeOperands = (ArrayList<Object>) mergeOperation
+ .get("operands");
+ mergeOperands.add(posGroup);
+ posGroup = mergeOperation;
+ }
+ putIntoSuperObject(posGroup, 1);
}
@@ -1099,60 +1148,34 @@
}
- private LinkedHashMap<String, Object> parseOPINOptions (Tree node) {
+ private LinkedHashMap<String, Object> parseOPINOptions (Tree node,
+ boolean isExclusion) {
Tree posnode = getFirstChildWithCat(node, "POS");
Tree rangenode = getFirstChildWithCat(node, "RANGE");
- Tree exclnode = getFirstChildWithCat(node, "EXCL");
Tree groupnode = getFirstChildWithCat(node, "GROUP");
- boolean negatePosition = false;
+
LinkedHashMap<String, Object> posOptions = new LinkedHashMap<String, Object>();
ArrayList<KoralFrame> positions = new ArrayList<KoralFrame>();
ArrayList<ClassRefCheck> classRefCheck = new ArrayList<ClassRefCheck>();
posOptions.put("matchall", false);
+
String posOption = null;
if (posnode != null) {
- posOption = posnode.getChild(0).toStringTree();
- switch (posOption) {
- case "L":
- positions.add(KoralFrame.STARTS_WITH);
- positions.add(KoralFrame.MATCHES);
- // classRefCheck.add("classRefCheck:includes");
- break;
- case "R":
- positions.add(KoralFrame.ENDS_WITH);
- positions.add(KoralFrame.MATCHES);
- // classRefCheck.add("classRefCheck:includes");
- break;
- case "F":
- positions.add(KoralFrame.MATCHES);
- // classRefCheck.add("classRefCheck:includes");
- break;
- case "FE":
- positions.add(KoralFrame.MATCHES);
- classRefCheck.add(ClassRefCheck.EQUALS);
- break;
- case "FI":
- positions.add(KoralFrame.MATCHES);
- classRefCheck.add(ClassRefCheck.UNEQUALS);
- // classRefCheck.add("classRefCheck:includes");
- break;
- case "N":
- positions.add(KoralFrame.IS_AROUND);
- // classRefCheck.add("classRefCheck:includes");
- break;
+ posOption = posnode.getChild(0).toStringTree().toUpperCase();
+ if (isExclusion) {
+ checkINWithExclusionOptions(posOption, positions,
+ classRefCheck);
+ }
+ else {
+ checkINOptions(posOption, positions, classRefCheck);
}
}
else {
classRefCheck.add(ClassRefCheck.INCLUDES);
}
+
posOptions.put("frames", Converter.enumListToStringList(positions));
posOptions.put("classRefCheck", classRefCheck);
- if (exclnode != null) {
- if (exclnode.getChild(0).toStringTree().equals("YES")) {
- negatePosition = !negatePosition;
- }
- }
-
if (rangenode != null) {
String range = rangenode.getChild(0).toStringTree().toLowerCase();
if (range.equals("all")) {
@@ -1163,15 +1186,10 @@
}
}
- if (negatePosition) {
- posOptions.put("exclude", true);
- }
-
- boolean grouping = false;
- if (groupnode != null) {
- if (groupnode.getChild(0).toStringTree().equalsIgnoreCase("max")) {
- grouping = true;
- }
+ Boolean grouping = false;
+ if (groupnode != null && groupnode.getChild(0).toStringTree()
+ .equalsIgnoreCase("max")) {
+ grouping = true;
}
posOptions.put("grouping", grouping);
@@ -1179,6 +1197,70 @@
}
+ private void checkINOptions (String posOption,
+ ArrayList<KoralFrame> positions,
+ ArrayList<ClassRefCheck> classRefCheck) {
+ switch (posOption) {
+ case "L":
+ positions.add(KoralFrame.STARTS_WITH);
+ positions.add(KoralFrame.MATCHES);
+ // classRefCheck.add("classRefCheck:includes");
+ break;
+ case "R":
+ positions.add(KoralFrame.ENDS_WITH);
+ positions.add(KoralFrame.MATCHES);
+ // classRefCheck.add("classRefCheck:includes");
+ break;
+ case "F":
+ positions.add(KoralFrame.MATCHES);
+ // classRefCheck.add("classRefCheck:includes");
+ break;
+ case "FE":
+ positions.add(KoralFrame.MATCHES);
+ classRefCheck.add(ClassRefCheck.EQUALS);
+ break;
+ case "FI":
+ positions.add(KoralFrame.MATCHES);
+ classRefCheck.add(ClassRefCheck.UNEQUALS);
+ // classRefCheck.add("classRefCheck:includes");
+ break;
+ case "N":
+ positions.add(KoralFrame.IS_AROUND);
+ // classRefCheck.add("classRefCheck:includes");
+ break;
+ }
+ }
+
+
+ private void checkINWithExclusionOptions (String posOption,
+ ArrayList<KoralFrame> positions,
+ ArrayList<ClassRefCheck> classRefCheck) {
+ if (CosmasPosition.N.name().equals(posOption)) {
+ positions.add(KoralFrame.IS_WITHIN);
+ return;
+ }
+ else if (CosmasPosition.L.name().equals(posOption)) {
+ positions.add(KoralFrame.ALIGNS_LEFT);
+ }
+ else if (CosmasPosition.R.name().equals(posOption)) {
+ positions.add(KoralFrame.ALIGNS_RIGHT);
+ }
+ else if (CosmasPosition.FE.name().equals(posOption)) {
+ classRefCheck.add(ClassRefCheck.UNEQUALS);
+ }
+ else if (CosmasPosition.FI.name().equals(posOption)) {
+ classRefCheck.add(ClassRefCheck.EQUALS);
+ }
+ else if (CosmasPosition.F.name().equals(posOption)) {}
+ else {
+ // throw an error or add an exception;
+ return;
+ }
+
+ positions.add(KoralFrame.MATCHES);
+ }
+
+
private LinkedHashMap<String, Object> parseOPOVOptions (Tree node) {
boolean negatePosition = false;
Tree posnode = getFirstChildWithCat(node, "POS");
@@ -1275,7 +1357,7 @@
@SuppressWarnings("unchecked")
- private void putIntoSuperObject (LinkedHashMap<String, Object> object,
+ private void putIntoSuperObject (Map<String, Object> object,
int objStackPosition) {
if (objectStack.size() > objStackPosition) {
ArrayList<Object> topObjectOperands = (ArrayList<Object>) objectStack
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/util/KoralObjectGenerator.java b/src/main/java/de/ids_mannheim/korap/query/serialize/util/KoralObjectGenerator.java
index 8f2b5c6..8fbb7fc 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/util/KoralObjectGenerator.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/util/KoralObjectGenerator.java
@@ -4,6 +4,7 @@
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import de.ids_mannheim.korap.query.object.ClassRefCheck;
import de.ids_mannheim.korap.query.object.ClassRefOp;
@@ -291,8 +292,8 @@
}
- public static LinkedHashMap<String, Object> wrapInReference (
- LinkedHashMap<String, Object> group, Integer classId) {
+ public static Map<String, Object> wrapInReference (
+ Map<String, Object> group, Integer classId) {
LinkedHashMap<String, Object> refGroup = makeReference(classId);
ArrayList<Object> operands = new ArrayList<Object>();
operands.add(group);
@@ -314,9 +315,9 @@
@SuppressWarnings("unchecked")
- public static LinkedHashMap<String, Object> wrapInClass (
- LinkedHashMap<String, Object> group, Integer classId) {
- LinkedHashMap<String, Object> classGroup = makeSpanClass(classId);
+ public static Map<String, Object> wrapInClass (
+ Map<String, Object> group, Integer classId) {
+ Map<String, Object> classGroup = makeSpanClass(classId);
((ArrayList<Object>) classGroup.get("operands")).add(group);
return classGroup;
}
diff --git a/src/test/java/de/ids_mannheim/korap/test/cosmas2/Cosmas2QueryProcessorTest.java b/src/test/java/de/ids_mannheim/korap/test/cosmas2/Cosmas2QueryProcessorTest.java
index 6d6d59c..b703ca3 100644
--- a/src/test/java/de/ids_mannheim/korap/test/cosmas2/Cosmas2QueryProcessorTest.java
+++ b/src/test/java/de/ids_mannheim/korap/test/cosmas2/Cosmas2QueryProcessorTest.java
@@ -1,4 +1,4 @@
-package de.ids_mannheim.korap.query.test;
+package de.ids_mannheim.korap.test.cosmas2;
import static org.junit.Assert.*;
@@ -694,180 +694,6 @@
@Test
- public void testOPIN () throws JsonProcessingException, IOException {
- query = "wegen #IN <s>";
- qs.setQuery(query, "cosmas2");
- res = mapper.readTree(qs.toJSON());
- assertEquals("koral:reference", res.at("/query/@type").asText());
- assertEquals("operation:focus", res.at("/query/operation").asText());
- assertEquals(130, res.at("/query/classRef/0").asInt());
- assertEquals("koral:group", res.at("/query/operands/0/@type").asText());
- assertEquals("operation:class", res.at("/query/operands/0/operation")
- .asText());
- assertEquals("classRefCheck:includes",
- res.at("/query/operands/0/classRefCheck/0").asText());
- assertEquals("koral:group", res
- .at("/query/operands/0/operands/0/@type").asText());
- assertEquals("operation:position",
- res.at("/query/operands/0/operands/0/operation").asText());
- assertEquals(true, res.at("/query/operands/0/operands/0/frames/0")
- .isMissingNode());
- assertEquals(129, res.at("/query/operands/0/classIn/0").asInt());
- assertEquals(130, res.at("/query/operands/0/classIn/1").asInt());
- assertEquals(131, res.at("/query/operands/0/classOut").asInt());
- assertEquals("koral:group", res
- .at("/query/operands/0/operands/0/@type").asText());
- assertEquals("operation:class",
- res.at("/query/operands/0/operands/0/operands/0/operation")
- .asText());
- assertEquals(129,
- res.at("/query/operands/0/operands/0/operands/0/classOut")
- .asInt());
- assertEquals(
- "koral:span",
- res.at("/query/operands/0/operands/0/operands/0/operands/0/@type")
- .asText());
- assertEquals(
- "s",
- res.at("/query/operands/0/operands/0/operands/0/operands/0/wrap/key")
- .asText());
- assertEquals("koral:group",
- res.at("/query/operands/0/operands/0/operands/1/@type")
- .asText());
- assertEquals("operation:class",
- res.at("/query/operands/0/operands/0/operands/1/operation")
- .asText());
- assertEquals(130,
- res.at("/query/operands/0/operands/0/operands/1/classOut")
- .asInt());
- assertEquals(
- "koral:token",
- res.at("/query/operands/0/operands/0/operands/1/operands/0/@type")
- .asText());
- assertEquals(
- "wegen",
- res.at("/query/operands/0/operands/0/operands/1/operands/0/wrap/key")
- .asText());
-
- query = "wegen #IN(L) <s>";
- qs.setQuery(query, "cosmas2");
- res = mapper.readTree(qs.toJSON());
- assertEquals("koral:reference", res.at("/query/@type").asText());
- assertEquals("operation:focus", res.at("/query/operation").asText());
- assertEquals(130, res.at("/query/classRef/0").asInt());
- assertEquals("koral:group", res.at("/query/operands/0/@type").asText());
- assertEquals("operation:position", res
- .at("/query/operands/0/operation").asText());
- assertEquals("frames:startsWith", res.at("/query/operands/0/frames/0")
- .asText());
- assertEquals("frames:matches", res.at("/query/operands/0/frames/1")
- .asText());
- assertEquals(true, res.at("/query/operands/0/frames/2").isMissingNode());
- assertEquals("koral:group", res.at("/query/operands/0/@type").asText());
- assertEquals("operation:class",
- res.at("/query/operands/0/operands/0/operation").asText());
- assertEquals(129, res.at("/query/operands/0/operands/0/classOut")
- .asInt());
- assertEquals("koral:span",
- res.at("/query/operands/0/operands/0/operands/0/@type")
- .asText());
- assertEquals("s",
- res.at("/query/operands/0/operands/0/operands/0/wrap/key")
- .asText());
- assertEquals("koral:group", res
- .at("/query/operands/0/operands/1/@type").asText());
- assertEquals("operation:class",
- res.at("/query/operands/0/operands/1/operation").asText());
- assertEquals(130, res.at("/query/operands/0/operands/1/classOut")
- .asInt());
- assertEquals("koral:token",
- res.at("/query/operands/0/operands/1/operands/0/@type")
- .asText());
- assertEquals("wegen",
- res.at("/query/operands/0/operands/1/operands/0/wrap/key")
- .asText());
-
- query = "wegen #IN(F) <s>";
- qs.setQuery(query, "cosmas2");
- res = mapper.readTree(qs.toJSON());
- assertEquals(true, res.at("/query/operands/0/classRefCheck")
- .isMissingNode());
- assertEquals("frames:matches", res.at("/query/operands/0/frames/0")
- .asText());
- assertEquals(true, res.at("/query/operands/0/frames/1").isMissingNode());
-
- query = "wegen #IN(FI) <s>";
- qs.setQuery(query, "cosmas2");
- res = mapper.readTree(qs.toJSON());
- assertEquals("classRefCheck:unequals",
- res.at("/query/operands/0/classRefCheck/0").asText());
- assertEquals("frames:matches",
- res.at("/query/operands/0/operands/0/frames/0").asText());
- assertEquals(true, res.at("/query/operands/0/operands/0/frames/1")
- .isMissingNode());
-
- query = "wegen #IN(FE) <s>";
- qs.setQuery(query, "cosmas2");
- res = mapper.readTree(qs.toJSON());
- assertEquals("classRefCheck:equals",
- res.at("/query/operands/0/classRefCheck/0").asText());
- assertEquals("frames:matches",
- res.at("/query/operands/0/operands/0/frames/0").asText());
- assertEquals(true, res.at("/query/operands/0/operands/0/frames/1")
- .isMissingNode());
-
- query = "wegen #IN(%, L) <s>";
- qs.setQuery(query, "cosmas2");
- res = mapper.readTree(qs.toJSON());
- assertEquals("frames:startsWith", res.at("/query/operands/0/frames/0")
- .asText());
- assertEquals("frames:matches", res.at("/query/operands/0/frames/1")
- .asText());
- // assertEquals(true, res.at("/query/operands/0/operands/0/exclude").isMissingNode());
-
- query = "wegen #IN(FE,%,MIN) <s>";
- qs.setQuery(query, "cosmas2");
- res = mapper.readTree(qs.toJSON());
- assertEquals("classRefCheck:equals",
- res.at("/query/operands/0/classRefCheck/0").asText());
- assertEquals("frames:matches",
- res.at("/query/operands/0/operands/0/frames/0").asText());
- // assertEquals(true, res.at("/query/operands/0/operands/0/exclude").isMissingNode());
-
- query = "wegen #IN(FE,ALL,%,MIN) <s>";
- qs.setQuery(query, "cosmas2");
- res = mapper.readTree(qs.toJSON());
- assertEquals("operation:class", res.at("/query/operation").asText());
- assertEquals("classRefOp:delete", res.at("/query/classRefOp").asText());
- assertEquals(131, res.at("/query/classIn/0").asInt());
- assertEquals("classRefCheck:equals",
- res.at("/query/operands/0/classRefCheck/0").asText());
- assertEquals("frames:matches",
- res.at("/query/operands/0/operands/0/frames/0").asText());
- assertEquals(true, res.at("/query/operands/0/operands/0/exclude")
- .asBoolean());
-
- query = "wegen #IN(FE,ALL,%,MAX) <s>";
- qs.setQuery(query, "cosmas2");
- res = mapper.readTree(qs.toJSON());
- assertEquals("operation:merge", res.at("/query/operation").asText());
- assertEquals("operation:class", res.at("/query/operands/0/operation")
- .asText());
- assertEquals("classRefOp:delete", res
- .at("/query/operands/0/classRefOp").asText());
- assertEquals(131, res.at("/query/operands/0/classIn/0").asInt());
- assertEquals("classRefCheck:equals",
- res.at("/query/operands/0/operands/0/classRefCheck/0").asText());
- assertEquals("frames:matches",
- res.at("/query/operands/0/operands/0/operands/0/frames/0")
- .asText());
- assertEquals(true,
- res.at("/query/operands/0/operands/0/operands/0/exclude")
- .asBoolean());
- }
-
-
- @Test
public void testOPOV () throws JsonProcessingException, IOException {
query = "wegen #OV <s>";
qs.setQuery(query, "cosmas2");
diff --git a/src/test/java/de/ids_mannheim/korap/test/cosmas2/OPINTest.java b/src/test/java/de/ids_mannheim/korap/test/cosmas2/OPINTest.java
new file mode 100644
index 0000000..d5f165e
--- /dev/null
+++ b/src/test/java/de/ids_mannheim/korap/test/cosmas2/OPINTest.java
@@ -0,0 +1,180 @@
+package de.ids_mannheim.korap.test.cosmas2;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import de.ids_mannheim.korap.query.serialize.QuerySerializer;
+
+public class OPINTest {
+ private String query;
+
+ private QuerySerializer qs = new QuerySerializer();
+ private ObjectMapper mapper = new ObjectMapper();
+ private JsonNode res;
+
+
+ @Test
+ public void testOPIN () throws JsonProcessingException, IOException {
+ query = "wegen #IN <s>";
+ qs.setQuery(query, "cosmas2");
+ res = mapper.readTree(qs.toJSON());
+ assertEquals("koral:reference", res.at("/query/@type").asText());
+ assertEquals("operation:focus", res.at("/query/operation").asText());
+ assertEquals(130, res.at("/query/classRef/0").asInt());
+ assertEquals("koral:group", res.at("/query/operands/0/@type").asText());
+ assertEquals("operation:class",
+ res.at("/query/operands/0/operation").asText());
+ assertEquals("classRefCheck:includes",
+ res.at("/query/operands/0/classRefCheck/0").asText());
+ assertEquals("koral:group",
+ res.at("/query/operands/0/operands/0/@type").asText());
+ assertEquals("operation:position",
+ res.at("/query/operands/0/operands/0/operation").asText());
+ assertEquals(true, res.at("/query/operands/0/operands/0/frames/0")
+ .isMissingNode());
+ assertEquals(129, res.at("/query/operands/0/classIn/0").asInt());
+ assertEquals(130, res.at("/query/operands/0/classIn/1").asInt());
+ assertEquals(131, res.at("/query/operands/0/classOut").asInt());
+ assertEquals("koral:group",
+ res.at("/query/operands/0/operands/0/@type").asText());
+ assertEquals("operation:class",
+ res.at("/query/operands/0/operands/0/operands/0/operation")
+ .asText());
+ assertEquals(129,
+ res.at("/query/operands/0/operands/0/operands/0/classOut")
+ .asInt());
+ assertEquals("koral:span",
+ res.at("/query/operands/0/operands/0/operands/0/operands/0/@type")
+ .asText());
+ assertEquals("s",
+ res.at("/query/operands/0/operands/0/operands/0/operands/0/wrap/key")
+ .asText());
+ assertEquals("koral:group", res
+ .at("/query/operands/0/operands/0/operands/1/@type").asText());
+ assertEquals("operation:class",
+ res.at("/query/operands/0/operands/0/operands/1/operation")
+ .asText());
+ assertEquals(130,
+ res.at("/query/operands/0/operands/0/operands/1/classOut")
+ .asInt());
+ assertEquals("koral:token",
+ res.at("/query/operands/0/operands/0/operands/1/operands/0/@type")
+ .asText());
+ assertEquals("wegen",
+ res.at("/query/operands/0/operands/0/operands/1/operands/0/wrap/key")
+ .asText());
+ }
+
+
+ @Test
+ public void testOPINWithOptionN ()
+ throws JsonProcessingException, IOException {
+ query = "wegen #IN(N) <s>";
+ qs.setQuery(query, "cosmas2");
+ res = mapper.readTree(qs.toJSON());
+ assertEquals("koral:reference", res.at("/query/@type").asText());
+ assertEquals("operation:focus", res.at("/query/operation").asText());
+ assertEquals(130, res.at("/query/classRef/0").asInt());
+ assertEquals("koral:group", res.at("/query/operands/0/@type").asText());
+ assertEquals("operation:position",
+ res.at("/query/operands/0/operation").asText());
+ assertEquals("frames:isAround",
+ res.at("/query/operands/0/frames/0").asText());
+ }
+
+
+ @Test
+ public void testOPINWithOptionL ()
+ throws JsonProcessingException, IOException {
+ query = "wegen #IN(L) <s>";
+ qs.setQuery(query, "cosmas2");
+ res = mapper.readTree(qs.toJSON());
+ assertEquals("koral:reference", res.at("/query/@type").asText());
+ assertEquals("operation:focus", res.at("/query/operation").asText());
+ assertEquals(130, res.at("/query/classRef/0").asInt());
+ assertEquals("koral:group", res.at("/query/operands/0/@type").asText());
+ assertEquals("operation:position",
+ res.at("/query/operands/0/operation").asText());
+ assertEquals("frames:startsWith",
+ res.at("/query/operands/0/frames/0").asText());
+ assertEquals("frames:matches",
+ res.at("/query/operands/0/frames/1").asText());
+ assertEquals(true,
+ res.at("/query/operands/0/frames/2").isMissingNode());
+ assertEquals("koral:group", res.at("/query/operands/0/@type").asText());
+ assertEquals("operation:class",
+ res.at("/query/operands/0/operands/0/operation").asText());
+ assertEquals(129,
+ res.at("/query/operands/0/operands/0/classOut").asInt());
+ assertEquals("koral:span", res
+ .at("/query/operands/0/operands/0/operands/0/@type").asText());
+ assertEquals("s",
+ res.at("/query/operands/0/operands/0/operands/0/wrap/key")
+ .asText());
+ assertEquals("koral:group",
+ res.at("/query/operands/0/operands/1/@type").asText());
+ assertEquals("operation:class",
+ res.at("/query/operands/0/operands/1/operation").asText());
+ assertEquals(130,
+ res.at("/query/operands/0/operands/1/classOut").asInt());
+ assertEquals("koral:token", res
+ .at("/query/operands/0/operands/1/operands/0/@type").asText());
+ assertEquals("wegen",
+ res.at("/query/operands/0/operands/1/operands/0/wrap/key")
+ .asText());
+ }
+
+ @Test
+ public void testOPINwithOptionF ()
+ throws JsonProcessingException, IOException {
+ query = "wegen #IN(F) <s>";
+ qs.setQuery(query, "cosmas2");
+ res = mapper.readTree(qs.toJSON());
+ assertEquals(true,
+ res.at("/query/operands/0/classRefCheck").isMissingNode());
+ assertEquals("frames:matches",
+ res.at("/query/operands/0/frames/0").asText());
+ assertEquals(true,
+ res.at("/query/operands/0/frames/1").isMissingNode());
+ }
+
+
+ @Test
+ public void testOPINwithOptionFI ()
+ throws JsonProcessingException, IOException {
+ query = "wegen #IN(FI) <s>";
+ qs.setQuery(query, "cosmas2");
+ res = mapper.readTree(qs.toJSON());
+ assertEquals("classRefCheck:unequals",
+ res.at("/query/operands/0/classRefCheck/0").asText());
+ assertEquals("frames:matches",
+ res.at("/query/operands/0/operands/0/frames/0").asText());
+ assertEquals(true, res.at("/query/operands/0/operands/0/frames/1")
+ .isMissingNode());
+
+ }
+
+
+ @Test
+ public void testOPINwithOptionFE ()
+ throws JsonProcessingException, IOException {
+ query = "wegen #IN(FE) <s>";
+ qs.setQuery(query, "cosmas2");
+ res = mapper.readTree(qs.toJSON());
+ assertEquals("classRefCheck:equals",
+ res.at("/query/operands/0/classRefCheck/0").asText());
+ assertEquals("frames:matches",
+ res.at("/query/operands/0/operands/0/frames/0").asText());
+ assertEquals(true, res.at("/query/operands/0/operands/0/frames/1")
+ .isMissingNode());
+ }
+
+
+}
diff --git a/src/test/java/de/ids_mannheim/korap/test/cosmas2/OPINWithExclusionTest.java b/src/test/java/de/ids_mannheim/korap/test/cosmas2/OPINWithExclusionTest.java
new file mode 100644
index 0000000..25eecf1
--- /dev/null
+++ b/src/test/java/de/ids_mannheim/korap/test/cosmas2/OPINWithExclusionTest.java
@@ -0,0 +1,185 @@
+package de.ids_mannheim.korap.test.cosmas2;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import de.ids_mannheim.korap.query.serialize.QuerySerializer;
+
+public class OPINWithExclusionTest {
+ private String query;
+
+ private QuerySerializer qs = new QuerySerializer();
+ private ObjectMapper mapper = new ObjectMapper();
+ private JsonNode res;
+
+
+ @Test
+ public void testOPINWithExclusionN ()
+ throws JsonProcessingException, IOException {
+ query = "wegen #IN(%,N) <s>";
+ qs.setQuery(query, "cosmas2");
+ res = mapper.readTree(qs.toJSON());
+
+ assertEquals("koral:group", res.at("/query/@type").asText());
+ assertEquals("operation:exclusion",
+ res.at("/query/operation").asText());
+ assertEquals(1, res.at("/query/frames").size());
+ assertEquals("frames:isWithin", res.at("/query/frames/0").asText());
+ assertEquals("koral:token", res.at("/query/operands/0/@type").asText());
+ assertEquals("koral:span", res.at("/query/operands/1/@type").asText());
+ }
+
+
+ @Test
+ public void testOPINwithExclusionL ()
+ throws JsonProcessingException, IOException {
+ query = "wegen #IN(%, L) <s>";
+ qs.setQuery(query, "cosmas2");
+ res = mapper.readTree(qs.toJSON());
+
+ assertEquals("koral:group", res.at("/query/@type").asText());
+ assertEquals("operation:exclusion",
+ res.at("/query/operation").asText());
+ assertEquals(2, res.at("/query/frames").size());
+ assertEquals("frames:alignsLeft", res.at("/query/frames/0").asText());
+ assertEquals("frames:matches", res.at("/query/frames/1").asText());
+ assertEquals("koral:token", res.at("/query/operands/0/@type").asText());
+ assertEquals("koral:span", res.at("/query/operands/1/@type").asText());
+ }
+
+
+ @Test
+ public void testOPINwithExclusionR ()
+ throws JsonProcessingException, IOException {
+ query = "wegen #IN(%, R) <s>";
+ qs.setQuery(query, "cosmas2");
+ res = mapper.readTree(qs.toJSON());
+
+ assertEquals("operation:exclusion",
+ res.at("/query/operation").asText());
+ assertEquals(2, res.at("/query/frames").size());
+ assertEquals("frames:alignsRight", res.at("/query/frames/0").asText());
+ assertEquals("frames:matches", res.at("/query/frames/1").asText());
+ }
+
+
+ @Test
+ public void testOPINwithExclusionF ()
+ throws JsonProcessingException, IOException {
+ query = "wegen #IN(%, F) <s>";
+ qs.setQuery(query, "cosmas2");
+ res = mapper.readTree(qs.toJSON());
+
+ assertEquals("operation:exclusion",
+ res.at("/query/operation").asText());
+ assertEquals(1, res.at("/query/frames").size());
+ assertEquals("frames:matches", res.at("/query/frames/0").asText());
+ }
+
+
+ @Test
+ public void testOPINwithExclusionFE ()
+ throws JsonProcessingException, IOException {
+ query = "wegen #IN(%, FE) <s>";
+ qs.setQuery(query, "cosmas2");
+ res = mapper.readTree(qs.toJSON());
+
+ assertEquals("koral:reference", res.at("/query/@type").asText());
+ assertEquals("operation:focus", res.at("/query/operation").asText());
+ assertEquals("130", res.at("/query/classRef/0").asText());
+
+ assertEquals("operation:class", res.at("/query/operands/0/operation").asText());
+ assertEquals("classRefCheck:unequals",
+ res.at("/query/operands/0/classRefCheck/0").asText());
+
+ JsonNode classRefCheckOperand = res.at("/query/operands/0/operands/0");
+ assertEquals("operation:exclusion",
+ classRefCheckOperand.at("/operation").asText());
+ assertEquals(1, classRefCheckOperand.at("/frames").size());
+ assertEquals("frames:matches",
+ classRefCheckOperand.at("/frames/0").asText());
+ }
+
+
+ @Test
+ public void testOPINwithExclusionFI ()
+ throws JsonProcessingException, IOException {
+ query = "wegen #IN(%, FI) <s>";
+ qs.setQuery(query, "cosmas2");
+ res = mapper.readTree(qs.toJSON());
+
+ assertEquals("koral:reference", res.at("/query/@type").asText());
+ assertEquals("operation:focus", res.at("/query/operation").asText());
+ assertEquals("130", res.at("/query/classRef/0").asText());
+
+ assertEquals("operation:class", res.at("/query/operands/0/operation").asText());
+ assertEquals("classRefCheck:equals",
+ res.at("/query/operands/0/classRefCheck/0").asText());
+
+ JsonNode classRefCheckOperand = res.at("/query/operands/0/operands/0");
+ assertEquals("operation:exclusion",
+ classRefCheckOperand.at("/operation").asText());
+ assertEquals(1, classRefCheckOperand.at("/frames").size());
+ assertEquals("frames:matches",
+ classRefCheckOperand.at("/frames/0").asText());
+ }
+
+
+ @Test
+ public void testOPINwithMultipleExclusion1 ()
+ throws JsonProcessingException, IOException {
+ query = "wegen #IN(FE,%,MIN) <s>";
+ qs.setQuery(query, "cosmas2");
+ res = mapper.readTree(qs.toJSON());
+ assertEquals("classRefCheck:unequals",
+ res.at("/query/operands/0/classRefCheck/0").asText());
+ assertEquals("frames:matches",
+ res.at("/query/operands/0/operands/0/frames/0").asText());
+ // assertEquals(true, res.at("/query/operands/0/operands/0/exclude").isMissingNode());
+ }
+
+
+ @Test
+ public void testOPINwithMultipleExclusion2 ()
+ throws JsonProcessingException, IOException {
+ query = "wegen #IN(FE,ALL,%,MIN) <s>";
+ qs.setQuery(query, "cosmas2");
+ res = mapper.readTree(qs.toJSON());
+ assertEquals("operation:class", res.at("/query/operation").asText());
+ assertEquals("classRefOp:delete", res.at("/query/classRefOp").asText());
+ assertEquals(131, res.at("/query/classIn/0").asInt());
+ assertEquals("classRefCheck:unequals",
+ res.at("/query/operands/0/classRefCheck/0").asText());
+ assertEquals("frames:matches",
+ res.at("/query/operands/0/operands/0/frames/0").asText());
+ }
+
+
+ @Test
+ public void testOPINwithMultipleExclusion3 ()
+ throws JsonProcessingException, IOException {
+ query = "wegen #IN(FE,ALL,%,MAX) <s>";
+ qs.setQuery(query, "cosmas2");
+ res = mapper.readTree(qs.toJSON());
+ assertEquals("operation:merge", res.at("/query/operation").asText());
+ assertEquals("operation:class",
+ res.at("/query/operands/0/operation").asText());
+ assertEquals("classRefOp:delete",
+ res.at("/query/operands/0/classRefOp").asText());
+ assertEquals(131, res.at("/query/operands/0/classIn/0").asInt());
+ assertEquals("classRefCheck:unequals", res
+ .at("/query/operands/0/operands/0/classRefCheck/0").asText());
+ assertEquals("frames:matches",
+ res.at("/query/operands/0/operands/0/operands/0/frames/0")
+ .asText());
+ }
+
+
+}