- removing all exceptions thrown, instead pass on errors in serialization
- bugfix: wrong class numbers in references
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 e6c4b4b..ca09dc7 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
@@ -12,8 +12,6 @@
public abstract class AbstractQueryProcessor {
- public abstract void process(String query);
-
Logger log;
/**
* The query
@@ -60,6 +58,8 @@
requestMap.put("meta", new LinkedHashMap<String, Object>());
}
+ public abstract void process(String query);
+
public void addWarning(int code, String msg) {
List<Object> warning = Arrays.asList(new Object[]{code, msg});
warnings.add(warning);
@@ -92,4 +92,4 @@
public Map<String, Object> getRequestMap() {
return requestMap;
}
-}
+}
\ No newline at end of file
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 a823f9d..52c5c78 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
@@ -77,18 +77,19 @@
* spans to refer back to previously established classes for entities.
*/
private LinkedHashMap<String, Integer> refClassMapping = new LinkedHashMap<String, Integer>();
+ /**
+ * Keeps track of the number of references to a node/token by means of #n. E.g. in the query
+ * <tt>tok="x" & tok="y" & tok="z" & #1 . #2 & #2 . #3</tt>, the 2nd token ("y") is referenced twice, the others once.
+ */
private LinkedHashMap<String, Integer> nodeReferencesTotal = new LinkedHashMap<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>();
- /**
- *
- * @param tree The syntax tree as returned by ANTLR
- * @param parser The ANTLR parser instance that generated the parse tree
- */
public AnnisQueryProcessor(String query) {
CqlfObjectGenerator.setQueryProcessor(this);
process(query);
- System.out.println(">>> "+requestMap.get("query")+" <<<");
}
@Override
@@ -210,7 +211,7 @@
}
}
}
- System.err.println(nodeVariables);
+ if (verbose) System.err.println(nodeVariables);
}
private void processUnary_linguistic_term(ParseTree node) {
@@ -311,7 +312,7 @@
operand = CqlfObjectGenerator.wrapInClass(operand, classCounter++);
} else if (nodeReferencesProcessed.get(ref)>0 && nodeReferencesTotal.get(ref)>1) {
try {
- operand = CqlfObjectGenerator.wrapInReference(operandStack.pop(), refClassMapping.get(ref));
+ operand = CqlfObjectGenerator.wrapInReference(operandStack.pop(), refClassMapping.get(ref), true);
} catch (NoSuchElementException e) {
operand = CqlfObjectGenerator.makeReference(refClassMapping.get(ref));
}
@@ -365,7 +366,7 @@
innerOperands.add(CqlfObjectGenerator.wrapInClass(CqlfObjectGenerator.makeSpan(), classCounter));
// add the first operand and wrap the whole group in a focusing reference
innerOperands.add(operand1);
- innerGroup = CqlfObjectGenerator.wrapInReference(innerGroup, classCounter);
+ innerGroup = CqlfObjectGenerator.wrapInReference(innerGroup, classCounter, true);
outerOperands.add(innerGroup);
} else {
outerOperands.add(operandStack.pop());
@@ -378,7 +379,7 @@
// Wrap in another reference object in case other relations are following
if (i < node.getChildCount()-2) {
- group = CqlfObjectGenerator.wrapInReference(group, classCounter);
+ group = CqlfObjectGenerator.wrapInReference(group, classCounter, true);
}
// All other n-ary linguistic relations have special 'relation' attributes defined in CQLF and can be
// handled more easily...
@@ -419,7 +420,7 @@
// Wrap in reference object in case other relations are following
if (i < node.getChildCount()-2) {
- group = CqlfObjectGenerator.wrapInReference(group, classCounter);
+ group = CqlfObjectGenerator.wrapInReference(group, classCounter, true);
}
// Inject operands.
@@ -714,20 +715,17 @@
Antlr4DescriptiveErrorListener errorListener = new Antlr4DescriptiveErrorListener(query);
// Like p. 111
try {
-
// Tokenize input data
ANTLRInputStream input = new ANTLRInputStream(query);
lexer.setInputStream(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
parser = new AqlParser(tokens);
-
// Don't throw out erroneous stuff
parser.setErrorHandler(new BailErrorStrategy());
lexer.removeErrorListeners();
lexer.addErrorListener(errorListener);
parser.removeErrorListeners();
parser.addErrorListener(errorListener);
-
// Get starting rule from parser
Method startRule = AqlParser.class.getMethod("start");
tree = (ParserRuleContext) startRule.invoke(parser, (Object[])null);
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr3AbstractQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr3AbstractQueryProcessor.java
index 4faa5e8..822d022 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr3AbstractQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr3AbstractQueryProcessor.java
@@ -8,19 +8,22 @@
import org.antlr.runtime.Parser;
import org.antlr.runtime.tree.Tree;
-public abstract class Antlr3AbstractQueryProcessor extends AbstractQueryProcessor {
-
- protected Parser parser;
+public abstract class Antlr3AbstractQueryProcessor extends
+ AbstractQueryProcessor {
+
+ protected Parser parser;
/**
- * Returns the category (or 'label') of the root of a (sub-) ParseTree (ANTLR 3).
+ * Returns the category (or 'label') of the root of a (sub-)
+ * ParseTree (ANTLR 3).
*
* @param node
* @return
*/
protected static String getNodeCat(Tree node) {
String nodeCat = node.toStringTree();
- Pattern p = Pattern.compile("\\((.*?)\\s"); // from opening parenthesis to 1st whitespace
+ // from opening parenthesis to 1st whitespace
+ Pattern p = Pattern.compile("\\((.*?)\\s");
Matcher m = p.matcher(node.toStringTree());
if (m.find()) {
nodeCat = m.group(1);
@@ -31,9 +34,12 @@
/**
* Tests whether a certain node has a child by a certain name
*
- * @param node The parent node.
- * @param childCat The category of the potential child.
- * @return true iff one or more children belong to the specified category
+ * @param node
+ * The parent node.
+ * @param childCat
+ * The category of the potential child.
+ * @return true iff one or more children belong to the specified
+ * category
*/
protected static boolean hasChild(Tree node, String childCat) {
for (int i = 0; i < node.getChildCount(); i++) {
@@ -43,7 +49,7 @@
}
return false;
}
-
+
protected static boolean hasDescendantWithCat(Tree node, String childCat) {
for (int i = 0; i < node.getChildCount(); i++) {
Tree child = node.getChild(i);
@@ -74,21 +80,21 @@
}
return children;
}
-
+
protected static Tree getFirstChildWithCat(Tree node, String nodeCat) {
return getNthChildWithCat(node, nodeCat, 1);
}
-
+
protected static Tree getNthChildWithCat(Tree node, String nodeCat, int n) {
- int counter = 0;
- for (int i = 0; i < node.getChildCount(); i++) {
- if (getNodeCat(node.getChild(i)).equals(nodeCat)) {
- counter++;
- if (counter == n) {
- return node.getChild(i);
- }
- }
- }
+ int counter = 0;
+ for (int i = 0; i < node.getChildCount(); i++) {
+ if (getNodeCat(node.getChild(i)).equals(nodeCat)) {
+ counter++;
+ if (counter == n) {
+ return node.getChild(i);
+ }
+ }
+ }
return null;
}
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessor.java
index 0cd2768..b76ad29 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessor.java
@@ -117,7 +117,7 @@
if (checkDateValidity(valueNode)) {
addWarning("The collection query contains a value that looks like a date ('"+valueNode.getText()+"')"
+ " and an operator that is only defined for strings ('"+match+"'). The value is interpreted as "
- + "a string, use a date operator to ensure the value is treated as a date");
+ + "a string. Use a date operator to ensure the value is treated as a date");
}
putIntoSuperObject(term);
}
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 2ab4ddb..53929e2 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
@@ -29,1109 +29,1287 @@
*/
public class Cosmas2QueryProcessor extends Antlr3AbstractQueryProcessor {
- private static Logger log = LoggerFactory.getLogger(Cosmas2QueryProcessor.class);
+ private static Logger log = LoggerFactory
+ .getLogger(Cosmas2QueryProcessor.class);
- LinkedList<LinkedHashMap[]> toWrapStack = new LinkedList<LinkedHashMap[]>();
- /**
- * Field for repetition query (Kleene + or * operations, or min/max queries: {2,4}
- */
- String repetition = "";
- /**
- * Global control structure for fieldGroups, keeps track of open fieldGroups.
- */
- LinkedList<ArrayList<Object>> openFieldGroups = new LinkedList<ArrayList<Object>>();
- /**
- * Keeps track of how many toWrap objects there are to pop after every recursion of {@link #processNode(ParseTree)}
- */
- LinkedList<Integer> toWrapsToPop = new LinkedList<Integer>();
- /**
- * Flag that indicates whether token fields or meta fields are currently being processed
- */
- boolean inMeta = false;
- /**
- * If true, a sequence (OPPROX node) is governed by an OPALL node (ALL()-operator), which requires to match
- * all tokens of the sequence.
- */
- boolean inOPALL = false;
- boolean inOPNHIT = false;
- /**
+ LinkedList<LinkedHashMap[]> toWrapStack = new LinkedList<LinkedHashMap[]>();
+ /**
+ * Field for repetition query (Kleene + or * operations, or
+ * min/max queries: {2,4}
+ */
+ String repetition = "";
+ /**
+ * Global control structure for fieldGroups, keeps track of open
+ * fieldGroups.
+ */
+ LinkedList<ArrayList<Object>> openFieldGroups = new LinkedList<ArrayList<Object>>();
+ /**
+ * Keeps track of how many toWrap objects there are to pop after
+ * every recursion of {@link #processNode(ParseTree)}
+ */
+ LinkedList<Integer> toWrapsToPop = new LinkedList<Integer>();
+ /**
+ * Flag that indicates whether token fields or meta fields are
+ * currently being processed
+ */
+ boolean inMeta = false;
+ /**
+ * If true, a sequence (OPPROX node) is governed by an OPALL node
+ * (ALL()-operator), which requires to match all tokens of the
+ * sequence.
+ */
+ boolean inOPALL = false;
+ boolean inOPNHIT = false;
+ /**
*
*/
- int classCounter = 1;
- boolean negate = false;
+ int classCounter = 1;
+ boolean negate = false;
- /**
- * Allows for the definition of objects to be wrapped around the arguments of an operation.
- * Each record in the table holds the parent node of the argument, the number of the argument
- * and an object in whose operands list the argument shall be wrapped.
- */
- Table<Tree,Integer,LinkedHashMap<String,Object>> operandWrap = HashBasedTable.create();
+ /**
+ * Allows for the definition of objects to be wrapped around the
+ * arguments of an operation. Each record in the table holds the
+ * parent node of the argument, the number of the argument and an
+ * object in whose operands list the argument shall be wrapped.
+ */
+ Table<Tree, Integer, LinkedHashMap<String, Object>> operandWrap = HashBasedTable
+ .create();
- /**
- * Keeps track of all visited nodes in a tree
- */
- List<Tree> visited = new ArrayList<Tree>();
+ /**
+ * Keeps track of all visited nodes in a tree
+ */
+ List<Tree> visited = new ArrayList<Tree>();
- Integer stackedToWrap = 0;
- /**
- * A list of node categories that can be sequenced (i.e. which can be in a sequence with any number of other nodes in this list)
- */
- private final List<String> sequentiableNodeTypes = Arrays.asList(new String[]{"OPWF", "OPLEM", "OPMORPH", "OPBEG", "OPEND", "OPIN", "OPBED", "OPELEM", "OPOR", "OPAND"});
- /**
- * Keeps track of sequenced nodes, i.e. nodes that implicitly govern a sequence, as in (C2PQ (OPWF der) (OPWF Mann)).
- * This is necessary in order to know when to take the sequence off the object stack, as the sequence is introduced by the
- * first child but cannot be closed after this first child in order not to lose its siblings
- */
- private LinkedList<Tree> sequencedNodes = new LinkedList<Tree>();
+ Integer stackedToWrap = 0;
+ /**
+ * A list of node categories that can be sequenced (i.e. which can
+ * be in a sequence with any number of other nodes in this list)
+ */
+ private final List<String> sequentiableNodeTypes = Arrays
+ .asList(new String[] { "OPWF", "OPLEM", "OPMORPH", "OPBEG",
+ "OPEND", "OPIN", "OPBED", "OPELEM", "OPOR", "OPAND" });
+ /**
+ * Keeps track of sequenced nodes, i.e. nodes that implicitly
+ * govern a sequence, as in (C2PQ (OPWF der) (OPWF Mann)). This is
+ * necessary in order to know when to take the sequence off the
+ * object stack, as the sequence is introduced by the first child
+ * but cannot be closed after this first child in order not to
+ * lose its siblings
+ */
+ private LinkedList<Tree> sequencedNodes = new LinkedList<Tree>();
- private boolean nodeHasSequentiableSiblings;
+ private boolean nodeHasSequentiableSiblings;
- /**
- * Keeps track of operands lists that are to be serialised in an inverted
- * order (e.g. the IN() operator) compared to their AST representation.
- */
- private LinkedList<ArrayList<Object>> invertedOperandsLists = new LinkedList<ArrayList<Object>>();
- /**
- * @param tree The syntax tree as returned by ANTLR
- * @param parser The ANTLR parser instance that generated the parse tree
- * @throws QueryException
- */
- public Cosmas2QueryProcessor(String query) {
- CqlfObjectGenerator.setQueryProcessor(this);
- this.query = query;
- process(query);
- log.info(">>> " + requestMap.get("query") + " <<<");
- }
+ /**
+ * Keeps track of operands lists that are to be serialised in an
+ * inverted order (e.g. the IN() operator) compared to their AST
+ * representation.
+ */
+ private LinkedList<ArrayList<Object>> invertedOperandsLists = new LinkedList<ArrayList<Object>>();
- @Override
- public void process(String query) {
- Tree tree = null;
- tree = parseCosmasQuery(query);
- log.info("Processing CosmasII query: "+query);
- if (tree != null) {
- log.debug("ANTLR parse tree: "+tree.toStringTree());
- processNode(tree);
- }
- }
+ /**
+ * @param tree
+ * The syntax tree as returned by ANTLR
+ * @param parser
+ * The ANTLR parser instance that generated the parse
+ * tree
+ * @throws QueryException
+ */
+ public Cosmas2QueryProcessor (String query) {
+ CqlfObjectGenerator.setQueryProcessor(this);
+ this.query = query;
+ process(query);
+ log.info(">>> " + requestMap.get("query") + " <<<");
+ }
- private void processNode(Tree node) {
- // Top-down processing
- if (visited.contains(node)) return;
- else visited.add(node);
+ @Override
+ public void process(String query) {
+ Tree tree = null;
+ tree = parseCosmasQuery(query);
+ log.info("Processing CosmasII query: " + query);
+ if (tree != null) {
+ log.debug("ANTLR parse tree: " + tree.toStringTree());
+ processNode(tree);
+ }
+ }
+ private void processNode(Tree node) {
+ // Top-down processing
+ if (visited.contains(node))
+ return;
+ else
+ visited.add(node);
- String nodeCat = getNodeCat(node);
- openNodeCats.push(nodeCat);
+ String nodeCat = getNodeCat(node);
+ openNodeCats.push(nodeCat);
- stackedObjects = 0;
- stackedToWrap = 0;
+ stackedObjects = 0;
+ stackedToWrap = 0;
- if (verbose) {
- System.err.println(" " + objectStack);
- System.out.println(openNodeCats);
- }
+ if (verbose) {
+ System.err.println(" " + objectStack);
+ System.out.println(openNodeCats);
+ }
+ /* ***************************************
+ * Processing individual node categories *
+ * ***************************************
+ */
- /* ***************************************
- * Processing individual node categories *
- *****************************************/
-
-
- // Check for potential implicit sequences as in (C2PQ (OPWF der) (OPWF Mann)). The sequence is introduced
- // by the first child if it (and its siblings) is sequentiable.
- if (sequentiableNodeTypes.contains(nodeCat)) {
- // for each node, check if parent has more than one child (-> could be implicit sequence)
- Tree parent = node.getParent();
- if (parent.getChildCount() > 1) {
- // if node is first child of parent...
- if (node == parent.getChild(0)) {
- nodeHasSequentiableSiblings = false;
- for (int i = 1; i < parent.getChildCount(); i++) {
- if (sequentiableNodeTypes.contains(getNodeCat(parent.getChild(i)))) {
- nodeHasSequentiableSiblings = true;
- continue;
- }
- }
- if (nodeHasSequentiableSiblings) {
- // Step I: create sequence
- LinkedHashMap<String, Object> sequence = new LinkedHashMap<String, Object>();
- sequence.put("@type", "korap:group");
- sequence.put("operation", "operation:sequence");
- sequence.put("operands", new ArrayList<Object>());
- // push sequence on object stack but don't increment stackedObjects counter since
- // we've got to wait until the parent node is processed - therefore, add the parent
- // to the sequencedNodes list and remove the sequence from the stack when the parent
- // has been processed
- objectStack.push(sequence);
- sequencedNodes.push(parent);
- // Step II: decide where to put sequence
- putIntoSuperObject(sequence, 1);
- }
- }
- }
- }
-
- if (nodeCat.equals("OPWF") || nodeCat.equals("OPLEM")) {
- processOPWF_OPLEM(node);
- }
-
- if (nodeCat.equals("OPMORPH")) {
- processOPMORPH(node);
- }
-
- if (nodeCat.equals("OPELEM")) {
- processOPELEM(node);
- }
-
- if (nodeCat.equals("OPLABEL")) {
- processOPLABEL(node);
- }
-
- if (nodeCat.equals("OPAND") || nodeCat.equals("OPNOT")) {
- processOPAND_OPNOT(node);
- }
-
- if (nodeCat.equals("OPOR")) {
- processOPOR(node);
- }
-
- if (nodeCat.equals("OPPROX")) {
- processOPPROX(node);
- }
-
- // inlcusion or overlap
- if (nodeCat.equals("OPIN") || nodeCat.equals("OPOV")) {
- processOPIN_OPOV(node);
- }
-
- // Wrap the argument of an #IN operator in a previously defined container
- if (nodeCat.equals("ARG1") || nodeCat.equals("ARG2")) {
- processARG1_ARG2(node);
- }
-
- if (nodeCat.equals("OPALL")) {
- inOPALL = true;
- }
-
- if (nodeCat.equals("OPNHIT")) {
- processOPNHIT(node);
- }
-
- if (nodeCat.equals("OPEND") || nodeCat.equals("OPBEG")) {
- processOPEND_OPBEG(node);
- }
-
- if (nodeCat.equals("OPBED")) {
- processOPBED(node);
- }
- objectsToPop.push(stackedObjects);
- toWrapsToPop.push(stackedToWrap);
-
- /*
- ****************************************************************
- ****************************************************************
- * recursion until 'request' node (root of tree) is processed *
- ****************************************************************
- ****************************************************************
- */
- for (int i = 0; i < node.getChildCount(); i++) {
- Tree child = node.getChild(i);
- processNode(child);
- }
-
- /*
- **************************************************************
- * Stuff that happens after processing the children of a node *
- **************************************************************
- */
-
- // remove sequence from object stack if node is implicitly sequenced
- if (sequencedNodes.size() > 0) {
- if (node == sequencedNodes.getFirst()) {
- objectStack.pop();
- sequencedNodes.pop();
- }
- }
-
- for (int i = 0; i < objectsToPop.get(0); i++) {
- objectStack.pop();
- }
- objectsToPop.pop();
-
-
- // if (!toWrapStack.isEmpty()) System.err.println(toWrapStack.get(0)[0]);
- for (int i = 0; i < toWrapsToPop.get(0); i++) {
- putIntoSuperObject(wrap(toWrapStack.pop()));
- }
- toWrapsToPop.pop();
-
- if (nodeCat.equals("ARG2") && openNodeCats.get(1).equals("OPNOT")) {
- negate = false;
- }
-
- if (nodeCat.equals("OPALL")) {
- inOPALL = false;
- }
-
- openNodeCats.pop();
- }
-
- private void processOPEND_OPBEG(Tree node) {
- // Step I: create group
- String nodeCat = getNodeCat(node);
- LinkedHashMap<String, Object> beggroup = new LinkedHashMap<String, Object>();
- beggroup.put("@type", "korap:reference");
- beggroup.put("operation", "operation:focus");
- ArrayList<Integer> spanRef = new ArrayList<Integer>();
- if (nodeCat.equals("OPBEG")) {
- spanRef.add(0);
- spanRef.add(1);
- } else if (nodeCat.equals("OPEND")) {
- spanRef.add(-1);
- spanRef.add(1);
- }
- beggroup.put("spanRef", spanRef);
- beggroup.put("operands", new ArrayList<Object>());
- objectStack.push(beggroup);
- stackedObjects++;
-
- // Step II: decide where to put
- putIntoSuperObject(beggroup, 1);
- }
-
- private void processOPBED(Tree node) {
- // Node structure is (OPBED X+ (OPTS (TPBEG tpos*) (TPEND tpos*)))
- // X is some segment, TPBEG or TPEND must be present (inclusive OR)
- // tpos is a three-char string of the form "[+-]?[spt][ae]". s/p/t indicates span, a/e beginning/end, - means negation
- // See C-II QL documentation for more detail:
- // http://www.ids-mannheim.de/cosmas2/win-app/hilfe/suchanfrage/eingabe-grafisch/syntax/textpositionen.html
-
- // Step I: create group
- int optsChild = node.getChildCount() - 1;
- Tree begConditions = getFirstChildWithCat(node.getChild(optsChild), "TPBEG");
- Tree endConditions = getFirstChildWithCat(node.getChild(optsChild), "TPEND");
-
- LinkedHashMap<String, Object> submatchgroup = CqlfObjectGenerator.makeReference(128+classCounter);
- ArrayList<Object> submatchOperands = new ArrayList<Object>();
- submatchgroup.put("operands", submatchOperands);
- putIntoSuperObject(submatchgroup);
-
- // Step II: collect all conditions, create groups for them in processPositionCondition()
- ArrayList<Object> distributedOperands = new ArrayList<Object>();
- ArrayList<LinkedHashMap<String, Object>> conditionGroups = new ArrayList<LinkedHashMap<String, Object>>();
- if (begConditions != null) {
- for (Tree condition : getChildren(begConditions)) {
- conditionGroups.add(processPositionCondition(condition, distributedOperands, "beg"));
- }
- }
- if (endConditions != null) {
- for (Tree condition : getChildren(endConditions)) {
- conditionGroups.add(processPositionCondition(condition, distributedOperands, "end"));
- }
- }
- // Step III: insert conditions. need to stack matches-groups because position groups may only have two operands
- ArrayList<Object> currentLowestOperands = submatchOperands; // indicates where to insert next condition group
- int conditionCount = 0;
- for (LinkedHashMap<String,Object> conditionGroup : conditionGroups) {
- conditionCount++;
- if (conditionGroups.size()==1) {
- submatchOperands.add(conditionGroup);
- } else if (conditionCount < conditionGroups.size()) {
- LinkedHashMap<String,Object> matchesGroup = CqlfObjectGenerator.makePosition(new String[]{"frames:matches"}, new String[0]);
- @SuppressWarnings("unchecked")
- ArrayList<Object> matchesOperands = (ArrayList<Object>) matchesGroup.get("operands");
- matchesOperands.add(conditionGroup);
- // matches groups that are embedded at the second or lower level receive an additional
- // focus to grep out only the query term to which the constraint applies
- if (conditionCount > 1) {
- LinkedHashMap<String,Object> focus = CqlfObjectGenerator.makeReference(128+classCounter-conditionGroups.size()+conditionCount-1);
- ArrayList<Object> focusOperands = new ArrayList<Object>();
- focus.put("operands", focusOperands);
- focusOperands.add(matchesGroup);
- currentLowestOperands.add(focus);
- } else {
- currentLowestOperands.add(matchesGroup);
- }
- currentLowestOperands = matchesOperands;
- } else {
- currentLowestOperands.add(conditionGroup);
- }
- }
- }
-
- private void processOPNHIT(Tree node) {
- Integer[] classRef = new Integer[]{128+classCounter+1, 128+classCounter+2};
- // classRef.add(classCounter + 1); // yes, do this twice (two classes)!
- LinkedHashMap<String, Object> group = CqlfObjectGenerator.makeReference(128+classCounter);
- LinkedHashMap<String, Object> classRefCheck = CqlfObjectGenerator.makeClassRefOp("classRefOp:inversion", classRef, classCounter+128);
- ArrayList<Object> operands = new ArrayList<Object>();
- operands.add(classRefCheck);
- group.put("operands", operands);
- classCounter++;
- wrapOperandInClass(node.getChild(0),1,classCounter++); // direct child is OPPROX
- wrapOperandInClass(node.getChild(0),2,classCounter++);
- objectStack.push(classRefCheck);
- stackedObjects++;
- putIntoSuperObject(group, 1);
- }
-
- private void processARG1_ARG2(Tree node) {
- String nodeCat = getNodeCat(node);
- Tree parent = node.getParent();
- if (operandWrap.containsRow(parent)) {
- // Step I: create group
- int argNr = nodeCat.equals("ARG1") ? 1 : 2;
- LinkedHashMap<String,Object> container = operandWrap.row(parent).get(argNr);
- // Step II: ingest
- if (container!=null) {
- objectStack.push(container);
- stackedObjects++;
- putIntoSuperObject(container,1);
- }
- }
- }
-
-
- @SuppressWarnings("unchecked")
- private void processOPIN_OPOV(Tree node) {
- // Step I: create group
- String nodeCat = getNodeCat(node);
- wrapOperandInClass(node,2,classCounter++);
- wrapOperandInClass(node,1,classCounter++);
- // LinkedHashMap<String, Object> posgroup = makePosition(null);
- LinkedHashMap<String, Object> posgroup = CqlfObjectGenerator.makeGroup("position");
- LinkedHashMap<String, Object> positionOptions;
- // posgroup
- if (nodeCat.equals("OPIN")) {
- positionOptions = parseOPINOptions(node);
- } 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"));
- }
- if (positionOptions.containsKey("grouping")) {
- posgroup.put("grouping", positionOptions.get("grouping"));
- }
- objectStack.push(posgroup);
- // mark this an inverted operands object
- invertedOperandsLists.push((ArrayList<Object>) posgroup.get("operands"));
- stackedObjects++;
- // Step II: wrap in reference and decide where to put
- ArrayList<String> check = (ArrayList<String>) positionOptions.get("classRefCheck");
- Integer[] classIn = new Integer[]{128+classCounter-2,128+classCounter-1};
- LinkedHashMap<String, Object> classRefCheck = CqlfObjectGenerator.makeClassRefCheck(check, classIn, 128+classCounter);
- ((ArrayList<Object>) classRefCheck.get("operands")).add(posgroup);
- LinkedHashMap<String, Object> focusGroup = null;
- if ((boolean) positionOptions.get("matchall") == true) {
- focusGroup = CqlfObjectGenerator.makeResetReference();
- ((ArrayList<Object>) focusGroup.get("operands")).add(classRefCheck);
- } else { // match only first argument
- focusGroup = CqlfObjectGenerator.wrapInReference(classRefCheck, 128+classCounter-1);
- }
- putIntoSuperObject(focusGroup, 1);
- }
-
- @SuppressWarnings("unchecked")
- private void processOPPROX(Tree node) {
- // collect info
- Tree prox_opts = node.getChild(0);
- Tree typ = prox_opts.getChild(0);
- Tree dist_list = prox_opts.getChild(1);
- // Step I: create group
- LinkedHashMap<String, Object> group = CqlfObjectGenerator.makeGroup("sequence");
-
- ArrayList<Object> constraints = new ArrayList<Object>();
- boolean exclusion = typ.getChild(0).toStringTree().equals("EXCL");
-
- boolean inOrder = false;
- boolean invertedOperands = false;
-
- group.put("inOrder", inOrder);
- group.put("distances", constraints);
-
- boolean putIntoOverlapDisjunction = false;
-
- int min = 0, max = 0;
- // possibly several distance constraints
- for (int i = 0; i < dist_list.getChildCount(); i++) {
- String direction = dist_list.getChild(i).getChild(0).getChild(0).toStringTree().toLowerCase();
- String minStr = dist_list.getChild(i).getChild(1).getChild(0).toStringTree();
- String maxStr = dist_list.getChild(i).getChild(1).getChild(1).toStringTree();
- String meas = dist_list.getChild(i).getChild(2).getChild(0).toStringTree();
- if (minStr.equals("VAL0")) {
- minStr = "0";
- }
- min = Integer.parseInt(minStr);
- max = Integer.parseInt(maxStr);
- // If zero word-distance, wrap this sequence in a disjunction along with an overlap position
- // between the two operands
- /*
- XXX: This is currently deactivated. Uncomment to activate treatment of zero-word distances as overlap-alternatives
- (see google doc on special distances serialization)
-
- if (meas.equals("w") && min == 0) {
- min = 1;
- putIntoOverlapDisjunction = true;
+ // Check for potential implicit sequences as in (C2PQ (OPWF
+ // der) (OPWF Mann)). The sequence is introduced
+ // by the first child if it (and its siblings) is
+ // sequentiable.
+ if (sequentiableNodeTypes.contains(nodeCat)) {
+ // for each node, check if parent has more than one child
+ // (-> could be implicit sequence)
+ Tree parent = node.getParent();
+ if (parent.getChildCount() > 1) {
+ // if node is first child of parent...
+ if (node == parent.getChild(0)) {
+ nodeHasSequentiableSiblings = false;
+ for (int i = 1; i < parent.getChildCount(); i++) {
+ if (sequentiableNodeTypes.contains(getNodeCat(parent
+ .getChild(i)))) {
+ nodeHasSequentiableSiblings = true;
+ continue;
+ }
+ }
+ if (nodeHasSequentiableSiblings) {
+ // Step I: create sequence
+ LinkedHashMap<String, Object> sequence = new LinkedHashMap<String, Object>();
+ sequence.put("@type", "korap:group");
+ sequence.put("operation", "operation:sequence");
+ sequence.put("operands", new ArrayList<Object>());
+ // push sequence on object stack but don't
+ // increment stackedObjects counter since
+ // we've got to wait until the parent node is
+ // processed - therefore, add the parent
+ // to the sequencedNodes list and remove the
+ // sequence from the stack when the parent
+ // has been processed
+ objectStack.push(sequence);
+ sequencedNodes.push(parent);
+ // Step II: decide where to put sequence
+ putIntoSuperObject(sequence, 1);
+ }
+ }
}
- */
- if (!meas.equals("w") && min == 0 ) {
- processSpanDistance(meas,min,max);
- }
- LinkedHashMap<String, Object> distance = CqlfObjectGenerator.makeDistance(meas,min,max);
- if (exclusion) {
- distance.put("exclude", true);
- }
- // if (! openNodeCats.get(1).equals("OPNHIT")) {
- constraints.add(distance);
- // }
- if (i==0) {
- if (direction.equals("plus")) {
- inOrder = true;
- } else if (direction.equals("minus")) {
- inOrder = true;
- invertedOperands = true;
- } else if (direction.equals("both")) {
- inOrder = false;
- }
- }
- }
- group.put("inOrder", inOrder);
- LinkedHashMap<String, Object> embeddedSequence = group;
+ }
- if (! (openNodeCats.get(1).equals("OPBEG") || openNodeCats.get(1).equals("OPEND") || inOPALL || openNodeCats.get(1).equals("OPNHIT"))) {
- wrapOperandInClass(node,1,classCounter);
- wrapOperandInClass(node,2,classCounter);
- group = CqlfObjectGenerator.wrapInReference(group, 128+classCounter++);
- } else if (openNodeCats.get(1).equals("OPNHIT")) {
- LinkedHashMap<String,Object> repetition = CqlfObjectGenerator.makeRepetition(min, max);
- ((ArrayList<Object>) repetition.get("operands")).add(CqlfObjectGenerator.makeToken());
- // TODO go on with this: put the repetition into a class and put it in between the operands
- // -> what if there's several distance constraints. with different keys, like /w4,s0?
- }
+ if (nodeCat.equals("OPWF") || nodeCat.equals("OPLEM")) {
+ processOPWF_OPLEM(node);
+ }
- LinkedHashMap<String,Object> sequence = null;
- if (putIntoOverlapDisjunction) {
- sequence = embeddedSequence;
- group = CqlfObjectGenerator.makeGroup("or");
- ArrayList<Object> disjOperands = (ArrayList<Object>) group.get("operands");
- String[] sharedClasses = new String[]{"intersects"};
- LinkedHashMap<String,Object> overlapsGroup = CqlfObjectGenerator.makePosition(new String[0], sharedClasses);
+ if (nodeCat.equals("OPMORPH")) {
+ processOPMORPH(node);
+ }
- ArrayList<Object> overlapsOperands = (ArrayList<Object>) overlapsGroup.get("operands");
- // this ensures identity of the operands lists and thereby a distribution of the operands for both created objects
- sequence.put("operands", overlapsOperands);
- if (invertedOperands) {
- invertedOperandsLists.push(overlapsOperands);
- }
- disjOperands.add(overlapsGroup);
- disjOperands.add(CqlfObjectGenerator.wrapInReference(sequence, 0));
- // Step II: decide where to put
- putIntoSuperObject(group, 0);
- objectStack.push(sequence);
- }
- else {
- if (invertedOperands) {
- ArrayList<Object> operands = (ArrayList<Object>) embeddedSequence.get("operands");
- invertedOperandsLists.push(operands);
- }
- // Step II: decide where to put
- putIntoSuperObject(group, 0);
- objectStack.push(embeddedSequence);
- }
- stackedObjects++;
- visited.add(node.getChild(0));
- }
+ if (nodeCat.equals("OPELEM")) {
+ processOPELEM(node);
+ }
- private void processOPOR(Tree node) {
- // Step I: create group
- LinkedHashMap<String, Object> disjunction = new LinkedHashMap<String, Object>();
- disjunction.put("@type", "korap:group");
- disjunction.put("operation", "operation:or");
- disjunction.put("operands", new ArrayList<Object>());
- objectStack.push(disjunction);
- stackedObjects++;
- // Step II: decide where to put
- putIntoSuperObject(disjunction, 1);
- }
+ if (nodeCat.equals("OPLABEL")) {
+ processOPLABEL(node);
+ }
- private void processOPAND_OPNOT(Tree node) {
- // Step I: create group
- String nodeCat = getNodeCat(node);
- LinkedHashMap<String, Object> distgroup = new LinkedHashMap<String, Object>();
- distgroup.put("@type", "korap:group");
- distgroup.put("operation", "operation:sequence");
- ArrayList<Object> distances = new ArrayList<Object>();
- LinkedHashMap<String, Object> zerodistance = new LinkedHashMap<String, Object>();
- zerodistance.put("@type", "cosmas:distance");
- zerodistance.put("key", "t");
- zerodistance.put("min", 0);
- zerodistance.put("max", 0);
- if (nodeCat.equals("OPNOT")) zerodistance.put("exclude", true);
- distances.add(zerodistance);
- distgroup.put("distances", distances);
- distgroup.put("operands", new ArrayList<Object>());
- objectStack.push(distgroup);
- stackedObjects++;
- // Step II: decide where to put
- putIntoSuperObject(distgroup, 1);
- }
+ if (nodeCat.equals("OPAND") || nodeCat.equals("OPNOT")) {
+ processOPAND_OPNOT(node);
+ }
- private void processOPLABEL(Tree node) {
- // Step I: create element
- LinkedHashMap<String, Object> elem = new LinkedHashMap<String, Object>();
- elem.put("@type", "korap:span");
- elem.put("key", node.getChild(0).toStringTree().replaceAll("<|>", ""));
- //Step II: decide where to put
- putIntoSuperObject(elem);
- }
+ if (nodeCat.equals("OPOR")) {
+ processOPOR(node);
+ }
- @SuppressWarnings("unchecked")
- private void processOPELEM(Tree node) {
- // Step I: create element
- LinkedHashMap<String, Object> span = CqlfObjectGenerator.makeSpan();
- if (node.getChild(0).toStringTree().equals("EMPTY")) {
+ if (nodeCat.equals("OPPROX")) {
+ processOPPROX(node);
+ }
- } else {
- int elname = 0;
- Tree elnameNode = getFirstChildWithCat(node, "ELNAME");
- if (elnameNode != null) {
- span.put("key", elnameNode.getChild(0).toStringTree().toLowerCase());
- elname = 1;
- }
- if (node.getChildCount() > elname) {
- /*
- * Attributes can carry several values, like #ELEM(W ANA != 'N V'),
- * denoting a word whose POS is neither N nor V.
- * When seeing this, create a sub-termGroup and put it into the top-level
- * term group, but only if there are other attributes in that group. If
- * not, put the several values as distinct attr-val-pairs into the
- * top-level group (in order to avoid a top-level group that only
- * contains a sub-group).
- */
- LinkedHashMap<String, Object> termGroup = CqlfObjectGenerator.makeTermGroup("and");
- ArrayList<Object> termGroupOperands = (ArrayList<Object>) termGroup.get("operands");
- for (int i = elname; i < node.getChildCount(); i++) {
- Tree attrNode = node.getChild(i);
- if (attrNode.getChildCount() == 2) {
- LinkedHashMap<String, Object> term = CqlfObjectGenerator.makeTerm();
- termGroupOperands.add(term);
- String layer = attrNode.getChild(0).toStringTree();
- String[] splitted = layer.split("/");
- if (splitted.length > 1) {
- term.put("foundry", splitted[0]);
- layer = splitted[1];
- }
- term.put("layer", translateMorph(layer));
- term.put("key", attrNode.getChild(1).toStringTree());
- String match = getNodeCat(attrNode).equals("EQ") ? "eq" : "ne";
- term.put("match", "match:" + match);
- } else {
- LinkedHashMap<String, Object> subTermGroup = CqlfObjectGenerator.makeTermGroup("and");
- ArrayList<Object> subTermGroupOperands = (ArrayList<Object>) subTermGroup.get("operands");
- int j;
- for (j = 1; j < attrNode.getChildCount(); j++) {
- LinkedHashMap<String, Object> term = CqlfObjectGenerator.makeTerm();
- String layer = attrNode.getChild(0).toStringTree();
- String[] splitted = layer.split("/");
- if (splitted.length > 1) {
- term.put("foundry", splitted[0]);
- layer = splitted[1];
- }
- term.put("layer", translateMorph(layer));
- term.put("key", attrNode.getChild(j).toStringTree());
- String match = getNodeCat(attrNode).equals("EQ") ? "eq" : "ne";
- term.put("match", "match:" + match);
- if (node.getChildCount() == elname + 1) {
- termGroupOperands.add(term);
- } else {
- subTermGroupOperands.add(term);
- }
- }
- if (node.getChildCount() > elname + 1) {
- termGroupOperands.add(subTermGroup);
- }
- }
- if (getNodeCat(attrNode).equals("NOTEQ")) negate = true;
- }
- // possibly only one term was present throughout all nodes: extract it from the group
- if (termGroupOperands.size()==1) {
- termGroup = (LinkedHashMap<String, Object>) termGroupOperands.get(0);
- }
- span.put("attr", termGroup);
- }
- }
- //Step II: decide where to put
- putIntoSuperObject(span);
- }
+ // inlcusion or overlap
+ if (nodeCat.equals("OPIN") || nodeCat.equals("OPOV")) {
+ processOPIN_OPOV(node);
+ }
- private void processOPMORPH(Tree node) {
- //Step I: get info
- String[] morphterms = node.getChild(0).toStringTree().replace(" ", "").split("&");
- LinkedHashMap<String, Object> token = CqlfObjectGenerator.makeToken();
- ArrayList<Object> terms = new ArrayList<Object>();
- LinkedHashMap<String, Object> fieldMap = null;
- for (String morphterm : morphterms) {
- // regex group #2 is foundry, #4 layer, #5 operator #6 key, #8 value
- Pattern p = Pattern.compile("((\\w+)/)?((\\w*)(!?=))?(\\w+)(:(\\w+))?");
- Matcher m = p.matcher(morphterm);
- if (! m.matches()) {
- addError(StatusCodes.UNKNOWN_QUERY_ERROR, "Something went wrong parsing the argument in MORPH().");
- requestMap.put("query", new LinkedHashMap<String, Object>());
- return;
- }
-
- fieldMap = new LinkedHashMap<String, Object>();
- fieldMap.put("@type", "korap:term");
-
- if (m.group(2) != null) fieldMap.put("foundry", m.group(2));
- if (m.group(4) != null) fieldMap.put("layer", m.group(4));
- if (m.group(5) != null) {
- if ("!=".equals(m.group(5))) negate = !negate;
- }
- if (m.group(6) != null) fieldMap.put("key", m.group(6));
- if (m.group(8) != null) fieldMap.put("value", m.group(8));
+ // Wrap the argument of an #IN operator in a previously
+ // defined container
+ if (nodeCat.equals("ARG1") || nodeCat.equals("ARG2")) {
+ processARG1_ARG2(node);
+ }
- // negate field (see above)
- if (negate) {
- fieldMap.put("match", "match:ne");
- } else {
- fieldMap.put("match", "match:eq");
- }
- terms.add(fieldMap);
- }
- if (morphterms.length == 1) {
- token.put("wrap", fieldMap);
- } else {
- LinkedHashMap<String, Object> termGroup = CqlfObjectGenerator.makeTermGroup("and");
- termGroup.put("operands", terms);
- token.put("wrap", termGroup);
- }
- //Step II: decide where to put
- putIntoSuperObject(token, 0);
- visited.add(node.getChild(0));
- }
+ if (nodeCat.equals("OPALL")) {
+ inOPALL = true;
+ }
- /**
- * Nodes introducing tokens. Process all in the same manner, except for the fieldMap entry
- * @param node
- */
- private void processOPWF_OPLEM(Tree node) {
- String nodeCat = getNodeCat(node);
- //Step I: get info
- LinkedHashMap<String, Object> token = new LinkedHashMap<String, Object>();
- token.put("@type", "korap:token");
- objectStack.push(token);
- stackedObjects++;
- LinkedHashMap<String, Object> fieldMap = new LinkedHashMap<String, Object>();
- token.put("wrap", fieldMap);
+ if (nodeCat.equals("OPNHIT")) {
+ processOPNHIT(node);
+ }
- fieldMap.put("@type", "korap:term");
- // make category-specific fieldMap entry
- String attr = nodeCat.equals("OPWF") ? "orth" : "lemma";
- String value = node.getChild(0).toStringTree().replaceAll("\"", "");
- // check for wildcard string
- Pattern p = Pattern.compile("[+*?]");
- Matcher m = p.matcher(value);
- if (m.find()) fieldMap.put("type", "type:wildcard");
+ if (nodeCat.equals("OPEND") || nodeCat.equals("OPBEG")) {
+ processOPEND_OPBEG(node);
+ }
- if (value.startsWith("$")) {
- value = value.substring(1);
- fieldMap.put("caseInsensitive", true);
- }
+ if (nodeCat.equals("OPBED")) {
+ processOPBED(node);
+ }
+ objectsToPop.push(stackedObjects);
+ toWrapsToPop.push(stackedToWrap);
- fieldMap.put("key", value);
- fieldMap.put("layer", attr);
+ /*
+ * ***************************************************************
+ * ***************************************************************
+ * recursion until 'request' node (root of tree) is processed
+ * *
+ * ***********************************************************
+ * ****
+ * ********************************************************
+ * *******
+ */
+ for (int i = 0; i < node.getChildCount(); i++) {
+ Tree child = node.getChild(i);
+ processNode(child);
+ }
- // negate field (see above)
- if (negate) {
- fieldMap.put("match", "match:ne");
- } else {
- fieldMap.put("match", "match:eq");
- }
- //Step II: decide where to put
- if (!hasChild(node, "TPOS")) {
- putIntoSuperObject(token, 1);
- visited.add(node.getChild(0));
- } else {
- // TODO
- }
- }
+ /*
+ * *************************************************************
+ * Stuff that happens after processing the children of a node
+ * *
+ * ***********************************************************
+ * **
+ */
- private void processSpanDistance(String meas, int min, int max) {
- // Do stuff here in case we'll decide one day to treat span distances in a special way.
- // (see GDoc Special Distances Serialization)
- }
+ // remove sequence from object stack if node is implicitly
+ // sequenced
+ if (sequencedNodes.size() > 0) {
+ if (node == sequencedNodes.getFirst()) {
+ objectStack.pop();
+ sequencedNodes.pop();
+ }
+ }
- /**
- * Registers an entry in the {@link #operandWrap} table in order to allow an operator's arguments
- * (or only one of them) to be wrapped in a class group.
- * @param node The operator node (parent node of the ARG1/ARG2 node)
- * @param arg The argument number (1 or 2)
- * @param cls The class id.
- */
- private void wrapOperandInClass(Tree node, int arg, int cls) {
- LinkedHashMap<String,Object> clsGroup = CqlfObjectGenerator.makeSpanClass(cls);
- wrapOperand(node,arg,clsGroup);
- }
+ for (int i = 0; i < objectsToPop.get(0); i++) {
+ objectStack.pop();
+ }
+ objectsToPop.pop();
- /**
- * Registers an entry in the {@link #operandWrap} table in order to allow an operator's arguments
- * (or only one of them) to be wrapped in an arbitrary object, e.g. a reference group.
- * @param node The operator node (parent node of the ARG1/ARG2 node)
- * @param arg The argument number (1 or 2)
- * @param container The object in whose operand list the argument shall be wrapped.
- */
- private void wrapOperand(Tree node, int arg, LinkedHashMap<String, Object> container) {
- operandWrap.put(node, arg, container);
- }
+ // if (!toWrapStack.isEmpty())
+ // System.err.println(toWrapStack.get(0)[0]);
+ for (int i = 0; i < toWrapsToPop.get(0); i++) {
+ putIntoSuperObject(wrap(toWrapStack.pop()));
+ }
+ toWrapsToPop.pop();
- private Object translateMorph(String layer) {
- // might be extended...
- if (layer.equals("ANA"))
- return ResourceMapper.descriptor2policy("ANA");
- else
- return layer;
+ if (nodeCat.equals("ARG2") && openNodeCats.get(1).equals("OPNOT")) {
+ negate = false;
+ }
- }
+ if (nodeCat.equals("OPALL")) {
+ inOPALL = false;
+ }
- @SuppressWarnings("unchecked")
- /**
- * Processes individual position conditions as provided in the OPTS node under the OPBEG node.
- * #BEG allows to specify position constrains that apply to the beginning or the end of the subquery X.
- * E.g., in #BEG(X, tpos/tpos), the 'tpos' constraints before the slash indicate conditions that apply
- * to the beginning of X, those after the slash are conditions that apply to the end of X.
- * See the official C-II documentation for more details. <br/><br/>
- * What's important here is what follows: <br/>
- * Assume the query #BED(der Mann, sa/pa). This means that <b>the beginning<b/> of "der Mann" stands at
- * the beginning of a sentence and that <b>the end</b> (because this constraint comes after the slash) stands at the
- * beginning of a paragraph. The "end" means the last item, here "Mann", so this token comes at the beginning
- * of a paragraph. To capture this, we choose spanRefs: The last item of X matches the first item of the span (here: P).
- * @param cond
- * @param distributedOperands
- * @param mode
- * @return
- */
- private LinkedHashMap<String, Object> processPositionCondition(Tree cond, ArrayList<Object> distributedOperands, String mode) {
- boolean negated = false;
- String elem; // the 'span' (s/p/t)
- String position = "frames:matches"; // default
- Integer[] elemSpanRef = null; // spanRef to be used for the element ('span')
- Integer[] hitSpanRef = null; // spanRef to be used for the subquery X
+ openNodeCats.pop();
+ }
- String nodeString = cond.toStringTree();
- if (nodeString.startsWith("-")) {
- negated = true;
- nodeString = nodeString.substring(1);
- } else if (nodeString.startsWith("+")) {
- nodeString = nodeString.substring(1);
- }
+ private void processOPEND_OPBEG(Tree node) {
+ // Step I: create group
+ String nodeCat = getNodeCat(node);
+ LinkedHashMap<String, Object> beggroup = new LinkedHashMap<String, Object>();
+ beggroup.put("@type", "korap:reference");
+ beggroup.put("operation", "operation:focus");
+ ArrayList<Integer> spanRef = new ArrayList<Integer>();
+ if (nodeCat.equals("OPBEG")) {
+ spanRef.add(0);
+ spanRef.add(1);
+ }
+ else if (nodeCat.equals("OPEND")) {
+ spanRef.add(-1);
+ spanRef.add(1);
+ }
+ beggroup.put("spanRef", spanRef);
+ beggroup.put("operands", new ArrayList<Object>());
+ objectStack.push(beggroup);
+ stackedObjects++;
- elem = nodeString.substring(0, 1);
- nodeString = nodeString.substring(1);
+ // Step II: decide where to put
+ putIntoSuperObject(beggroup, 1);
+ }
- // in cases where the end of X shall match the beginning of the span, or vice versa,
- // we need to define spanRefs
- if (mode.equals("beg")) {
- if (nodeString.equals("a")) {
- position = "frames:startswith";
- } else if (nodeString.equals("e")) {
- hitSpanRef = new Integer[]{0,1};
- elemSpanRef = new Integer[]{-1,1};
- }
- } else if (mode.equals("end")) {
- if (nodeString.equals("e")) {
- position = "frames:endswith";
- } else if (nodeString.equals("a")) {
- hitSpanRef = new Integer[]{0,1};
- elemSpanRef = new Integer[]{-1,1};
- }
- }
- // Create the position group and add the span and the subquery as operands, possibly wrapped in spanRefs
- LinkedHashMap<String, Object> positionGroup = CqlfObjectGenerator.makePosition(new String[]{position}, new String[0]);
- if (negated) positionGroup.put("exclude", true);
- ArrayList<Object> posOperands = new ArrayList<Object>();
- LinkedHashMap<String, Object> classGroup = CqlfObjectGenerator.makeSpanClass(classCounter++);
- classGroup.put("operands", distributedOperands);
- positionGroup.put("operands", posOperands);
- LinkedHashMap<String, Object> span = new LinkedHashMap<String, Object>();
- span.put("@type", "korap:span");
- span.put("key", elem);
- objectStack.push(classGroup);
- if (hitSpanRef != null) {
- LinkedHashMap<String, Object> spanRefAroundHit = CqlfObjectGenerator.makeSpanReference(hitSpanRef, "focus");
- ((ArrayList<Object>) spanRefAroundHit.get("operands")).add(classGroup);
- classGroup = spanRefAroundHit; //re-assign after wrapping classGroup in spanRef
- }
- if (elemSpanRef != null) {
- LinkedHashMap<String, Object> spanRefAroundSpan = CqlfObjectGenerator.makeSpanReference(elemSpanRef, "focus");
- ((ArrayList<Object>) spanRefAroundSpan.get("operands")).add(span);
- span = spanRefAroundSpan; //re-assign after wrapping span in spanRef
- }
- posOperands.add(span);
- posOperands.add(classGroup);
- return positionGroup;
- }
+ private void processOPBED(Tree node) {
+ // Node structure is (OPBED X+ (OPTS (TPBEG tpos*) (TPEND
+ // tpos*)))
+ // X is some segment, TPBEG or TPEND must be present
+ // (inclusive OR)
+ // tpos is a three-char string of the form "[+-]?[spt][ae]".
+ // s/p/t indicates span, a/e beginning/end, - means negation
+ // See C-II QL documentation for more detail:
+ // http://www.ids-mannheim.de/cosmas2/win-app/hilfe/suchanfrage/eingabe-grafisch/syntax/textpositionen.html
- private LinkedHashMap<String, Object> parseOPINOptions(Tree node) {
- 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<String> positions = new ArrayList<String>();
- ArrayList<String> classRefCheck = new ArrayList<String>();
- posOptions.put("matchall", false);
- String frame = "";
- String posOption = null;
- if (posnode != null) {
- posOption = posnode.getChild(0).toStringTree();
- switch (posOption) {
- case "L":
- positions.add("frames:startswith");
- classRefCheck.add("classRefCheck:includes");
- frame = "startswith";
- break;
- case "R":
- positions.add("frames:endswith");
- classRefCheck.add("classRefCheck:includes");
- frame = "endswith";
- break;
- case "F":
- positions.add("frames:matches");
- classRefCheck.add("classRefCheck:includes");
- frame = "matches";
- break;
- case "FE":
- positions.add("frames:matches");
- classRefCheck.add("classRefCheck:equals");
- frame = "matches";
- break;
- case "FI":
- positions.add("frames:matches");
- classRefCheck.add("classRefCheck:unequals");
- classRefCheck.add("classRefCheck:includes");
- frame = "matches-noident";
- break;
- case "N":
- positions.add("frames:contains");
- classRefCheck.add("classRefCheck:includes");
- frame = "contains";
- break;
- }
- } else {
- classRefCheck.add("classRefCheck:includes");
- frame = "contains";
- }
- posOptions.put("frames", positions);
- posOptions.put("classRefCheck", classRefCheck);
- posOptions.put("frame", "frame:"+frame);
- addMessage(StatusCodes.DEPRECATED_QUERY_ELEMENT, "Deprecated 2014-09-22: 'frame' only to be supported until 3 months from deprecation date. " +
- "Position frames are now expressed through 'frames' and 'sharedClasses'");
+ // Step I: create group
+ int optsChild = node.getChildCount() - 1;
+ Tree begConditions = getFirstChildWithCat(node.getChild(optsChild),
+ "TPBEG");
+ Tree endConditions = getFirstChildWithCat(node.getChild(optsChild),
+ "TPEND");
- if (exclnode != null) {
- if (exclnode.getChild(0).toStringTree().equals("YES")) {
- negatePosition = !negatePosition;
- }
- }
+ LinkedHashMap<String, Object> submatchgroup =
+ CqlfObjectGenerator.makeReference(128 + classCounter);
+ ArrayList<Object> submatchOperands = new ArrayList<Object>();
+ submatchgroup.put("operands", submatchOperands);
+ putIntoSuperObject(submatchgroup);
- if (rangenode != null) {
- String range = rangenode.getChild(0).toStringTree().toLowerCase();
- if (range.equals("all")) {
- posOptions.put("matchall", true);
- // LinkedHashMap<String,Object> ref = makeResetReference(); // reset all defined classes
- // wrapOperand(node,2,ref);
- }
- }
+ // Step II: collect all conditions, create groups for them in
+ // processPositionCondition()
+ ArrayList<Object> distributedOperands = new ArrayList<Object>();
+ ArrayList<LinkedHashMap<String, Object>> conditionGroups =
+ new ArrayList<LinkedHashMap<String, Object>>();
+ if (begConditions != null) {
+ for (Tree condition : getChildren(begConditions)) {
+ conditionGroups.add(processPositionCondition(condition,
+ distributedOperands, "beg"));
+ }
+ }
+ if (endConditions != null) {
+ for (Tree condition : getChildren(endConditions)) {
+ conditionGroups.add(processPositionCondition(condition,
+ distributedOperands, "end"));
+ }
+ }
+ // Step III: insert conditions. need to stack matches-groups
+ // because position groups may only have two operands
+ // indicates where to insert next condition group
+ ArrayList<Object> currentLowestOperands = submatchOperands;
+ int conditionCount = 0;
+ for (LinkedHashMap<String, Object> conditionGroup : conditionGroups) {
+ conditionCount++;
+ if (conditionGroups.size() == 1) {
+ submatchOperands.add(conditionGroup);
+ }
+ else if (conditionCount < conditionGroups.size()) {
+ LinkedHashMap<String, Object> matchesGroup = CqlfObjectGenerator
+ .makePosition(new String[] { "frames:matches" },
+ new String[0]);
+ @SuppressWarnings("unchecked")
+ ArrayList<Object> matchesOperands =
+ (ArrayList<Object>) matchesGroup.get("operands");
+ matchesOperands.add(conditionGroup);
+ // matches groups that are embedded at the second or
+ // lower level receive an additional
+ // focus to grep out only the query term to which the
+ // constraint applies
+ if (conditionCount > 1) {
+ LinkedHashMap<String, Object> focus =
+ CqlfObjectGenerator.makeReference(128 + classCounter - 2);
+ ArrayList<Object> focusOperands = new ArrayList<Object>();
+ focus.put("operands", focusOperands);
+ focusOperands.add(matchesGroup);
+ currentLowestOperands.add(focus);
+ }
+ else {
+ currentLowestOperands.add(matchesGroup);
+ }
+ currentLowestOperands = matchesOperands;
+ }
+ else {
+ currentLowestOperands.add(conditionGroup);
+ }
+ }
+ }
- if (negatePosition) {
- posOptions.put("exclude", "true");
- }
+ private void processOPNHIT(Tree node) {
+ Integer[] classRef = new Integer[] { 128 + classCounter + 1,
+ 128 + classCounter + 2 };
+ // classRef.add(classCounter + 1); // yes, do this twice (two
+ // classes)!
+ LinkedHashMap<String, Object> group =
+ CqlfObjectGenerator.makeReference(128 + classCounter);
+ LinkedHashMap<String, Object> classRefCheck =
+ CqlfObjectGenerator.makeClassRefOp("classRefOp:inversion", classRef,
+ classCounter + 128);
+ ArrayList<Object> operands = new ArrayList<Object>();
+ operands.add(classRefCheck);
+ group.put("operands", operands);
+ classCounter++;
+ // direct child is OPPROX
+ wrapOperandInClass(node.getChild(0), 1, classCounter++);
+ wrapOperandInClass(node.getChild(0), 2, classCounter++);
+ objectStack.push(classRefCheck);
+ stackedObjects++;
+ putIntoSuperObject(group, 1);
+ }
- if (groupnode != null) {
- String grouping = groupnode.getChild(0).toStringTree().equals("max") ? "true" : "false";
- posOptions.put("grouping", grouping);
- }
- return posOptions;
- }
+ private void processARG1_ARG2(Tree node) {
+ String nodeCat = getNodeCat(node);
+ Tree parent = node.getParent();
+ if (operandWrap.containsRow(parent)) {
+ // Step I: create group
+ int argNr = nodeCat.equals("ARG1") ? 1 : 2;
+ LinkedHashMap<String, Object> container = operandWrap.row(parent)
+ .get(argNr);
+ // Step II: ingest
+ if (container != null) {
+ objectStack.push(container);
+ stackedObjects++;
+ putIntoSuperObject(container, 1);
+ }
+ }
+ }
+ @SuppressWarnings("unchecked")
+ private void processOPIN_OPOV(Tree node) {
+ // Step I: create group
+ String nodeCat = getNodeCat(node);
+ wrapOperandInClass(node, 2, classCounter++);
+ wrapOperandInClass(node, 1, classCounter++);
+ // LinkedHashMap<String, Object> posgroup =
+ // makePosition(null);
+ LinkedHashMap<String, Object> posgroup = CqlfObjectGenerator
+ .makeGroup("position");
+ LinkedHashMap<String, Object> positionOptions;
+ // posgroup
+ if (nodeCat.equals("OPIN")) {
+ positionOptions = parseOPINOptions(node);
+ }
+ 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"));
+ }
+ if (positionOptions.containsKey("grouping")) {
+ posgroup.put("grouping", positionOptions.get("grouping"));
+ }
+ objectStack.push(posgroup);
+ // mark this an inverted operands object
+ invertedOperandsLists.push((ArrayList<Object>) posgroup.get("operands"));
+ stackedObjects++;
+ // Step II: wrap in reference and decide where to put
+ ArrayList<String> check =
+ (ArrayList<String>) positionOptions.get("classRefCheck");
+ Integer[] classIn =
+ new Integer[] { 128 + classCounter - 2, 128 + classCounter - 1 };
+ LinkedHashMap<String, Object> classRefCheck =
+ CqlfObjectGenerator.makeClassRefCheck(check, classIn, 128 + classCounter);
+ ((ArrayList<Object>) classRefCheck.get("operands")).add(posgroup);
+ LinkedHashMap<String, Object> focusGroup = null;
+ if ((boolean) positionOptions.get("matchall") == true) {
+ focusGroup = CqlfObjectGenerator.makeResetReference();
+ ((ArrayList<Object>) focusGroup.get("operands")).add(classRefCheck);
+ }
+ else { // match only first argument
+ focusGroup = CqlfObjectGenerator.wrapInReference(classRefCheck,
+ 128 + classCounter - 1);
+ }
+ putIntoSuperObject(focusGroup, 1);
+ }
+ @SuppressWarnings("unchecked")
+ private void processOPPROX(Tree node) {
+ // collect info
+ Tree prox_opts = node.getChild(0);
+ Tree typ = prox_opts.getChild(0);
+ Tree dist_list = prox_opts.getChild(1);
+ // Step I: create group
+ LinkedHashMap<String, Object> group = CqlfObjectGenerator
+ .makeGroup("sequence");
- private LinkedHashMap<String, Object> parseOPOVOptions(Tree node) {
- boolean negatePosition = false;
- Tree posnode = getFirstChildWithCat(node, "POS");
- Tree rangenode = getFirstChildWithCat(node, "RANGE");
- Tree exclnode = getFirstChildWithCat(node, "EXCL");
- Tree groupnode = getFirstChildWithCat(node, "GROUP");
- LinkedHashMap<String, Object> posOptions = new LinkedHashMap<String, Object>();
- ArrayList<String> positions = new ArrayList<String>();
- ArrayList<String> classRefCheck = new ArrayList<String>();
- posOptions.put("matchall", false);
- String frame = "";
- String posOption = null;
- if (posnode != null) {
- posOption = posnode.getChild(0).toStringTree();
- switch (posOption) {
- case "L":
- positions.add("frames:startswith");
- positions.add("frames:overlapsLeft");
- classRefCheck.add("classRefCheck:intersects");
- frame = "overlapsLeft";
- break;
- case "R":
- positions.add("frames:endswith");
- positions.add("frames:overlapsRight");
- classRefCheck.add("classRefCheck:intersects");
- frame = "overlapsRight";
- break;
- case "F":
- positions.add("frames:matches");
- classRefCheck.add("classRefCheck:intersects");
- frame = "matches";
- break;
- case "FE":
- positions.add("frames:matches");
- classRefCheck.add("classRefCheck:equals");
- frame = "matches";
- break;
- case "FI":
- positions.add("frames:matches");
- classRefCheck.add("classRefCheck:unequals");
- frame = "matches-noident";
- break;
- case "X":
- positions.add("frames:contains");
- classRefCheck.add("classRefCheck:intersects");
- frame = "overlaps";
- break;
- }
- } else {
- classRefCheck.add("classRefCheck:intersects");
- frame = "overlaps";
- }
+ ArrayList<Object> constraints = new ArrayList<Object>();
+ boolean exclusion = typ.getChild(0).toStringTree().equals("EXCL");
- posOptions.put("frames", positions);
- posOptions.put("classRefCheck", classRefCheck);
- posOptions.put("frame", "frame:"+frame);
- addMessage(StatusCodes.DEPRECATED_QUERY_ELEMENT, "Deprecated 2014-09-22: 'frame' only to be supported until 3 months from deprecation date. " +
- "Position frames are now expressed through 'frames' and 'sharedClasses'");
+ boolean inOrder = false;
+ boolean invertedOperands = false;
- if (exclnode != null) {
- if (exclnode.getChild(0).toStringTree().equals("YES")) {
- negatePosition = !negatePosition;
- }
- }
+ group.put("inOrder", inOrder);
+ group.put("distances", constraints);
- if (rangenode != null) {
- String range = rangenode.getChild(0).toStringTree().toLowerCase();
- if (range.equals("all")) {
- posOptions.put("matchall", true);
- // LinkedHashMap<String,Object> ref = makeResetReference(); // reset all defined classes
- // wrapOperand(node,2,ref);
- }
- }
+ boolean putIntoOverlapDisjunction = false;
- if (negatePosition) {
- posOptions.put("exclude", "true");
- }
+ int min = 0, max = 0;
+ // possibly several distance constraints
+ for (int i = 0; i < dist_list.getChildCount(); i++) {
+ String direction = dist_list.getChild(i).getChild(0).getChild(0)
+ .toStringTree().toLowerCase();
+ String minStr = dist_list.getChild(i).getChild(1).getChild(0)
+ .toStringTree();
+ String maxStr = dist_list.getChild(i).getChild(1).getChild(1)
+ .toStringTree();
+ String meas = dist_list.getChild(i).getChild(2).getChild(0)
+ .toStringTree();
+ if (minStr.equals("VAL0")) {
+ minStr = "0";
+ }
+ min = Integer.parseInt(minStr);
+ max = Integer.parseInt(maxStr);
+ // If zero word-distance, wrap this sequence in a
+ // disjunction along with an overlap position
+ // between the two operands
+ /*
+ * XXX: This is currently deactivated. Uncomment to
+ * activate treatment of zero-word distances as
+ * overlap-alternatives (see google doc on special
+ * distances serialization)
+ *
+ * if (meas.equals("w") && min == 0) { min = 1;
+ * putIntoOverlapDisjunction = true; }
+ */
+ if (!meas.equals("w") && min == 0) {
+ processSpanDistance(meas, min, max);
+ }
+ LinkedHashMap<String, Object> distance = CqlfObjectGenerator
+ .makeDistance(meas, min, max);
+ if (exclusion) {
+ distance.put("exclude", true);
+ }
+ // if (! openNodeCats.get(1).equals("OPNHIT")) {
+ constraints.add(distance);
+ // }
+ if (i == 0) {
+ if (direction.equals("plus")) {
+ inOrder = true;
+ }
+ else if (direction.equals("minus")) {
+ inOrder = true;
+ invertedOperands = true;
+ }
+ else if (direction.equals("both")) {
+ inOrder = false;
+ }
+ }
+ }
+ group.put("inOrder", inOrder);
+ LinkedHashMap<String, Object> embeddedSequence = group;
- if (groupnode != null) {
- String grouping = groupnode.getChild(0).toStringTree().equals("max") ? "true" : "false";
- posOptions.put("grouping", grouping);
- }
- return posOptions;
- }
+ if (!(openNodeCats.get(1).equals("OPBEG")
+ || openNodeCats.get(1).equals("OPEND")
+ || inOPALL
+ || openNodeCats.get(1).equals("OPNHIT"))) {
+ wrapOperandInClass(node, 1, classCounter);
+ wrapOperandInClass(node, 2, classCounter);
+ group = CqlfObjectGenerator.wrapInReference(group,
+ 128 + classCounter++);
+ }
+ else if (openNodeCats.get(1).equals("OPNHIT")) {
+ LinkedHashMap<String, Object> repetition = CqlfObjectGenerator
+ .makeRepetition(min, max);
+ ((ArrayList<Object>) repetition.get("operands"))
+ .add(CqlfObjectGenerator.makeToken());
+ // TODO go on with this: put the repetition into a class
+ // and put it in between the operands
+ // -> what if there's several distance constraints. with
+ // different keys, like /w4,s0?
+ }
- @SuppressWarnings({ "unchecked" })
- private LinkedHashMap<String,Object> wrap(LinkedHashMap[] wrapCascade) {
- int i;
- for (i=0; i<wrapCascade.length-1; i++) {
- ArrayList<Object> containerOperands = (ArrayList<Object>) wrapCascade[i+1].get("operands");
- containerOperands.add(0,wrapCascade[i]);
- }
- return wrapCascade[i];
- }
+ LinkedHashMap<String, Object> sequence = null;
+ if (putIntoOverlapDisjunction) {
+ sequence = embeddedSequence;
+ group = CqlfObjectGenerator.makeGroup("or");
+ ArrayList<Object> disjOperands =
+ (ArrayList<Object>) group.get("operands");
+ String[] sharedClasses = new String[] { "intersects" };
+ LinkedHashMap<String, Object> overlapsGroup = CqlfObjectGenerator
+ .makePosition(new String[0], sharedClasses);
- LinkedList<ArrayList<Object>> nestedDistOperands = new LinkedList<ArrayList<Object>>();
+ ArrayList<Object> overlapsOperands =
+ (ArrayList<Object>) overlapsGroup.get("operands");
+ // this ensures identity of the operands lists and thereby
+ // a distribution of the operands for both created objects
+ sequence.put("operands", overlapsOperands);
+ if (invertedOperands) {
+ invertedOperandsLists.push(overlapsOperands);
+ }
+ disjOperands.add(overlapsGroup);
+ disjOperands.add(CqlfObjectGenerator.wrapInReference(sequence, 0));
+ // Step II: decide where to put
+ putIntoSuperObject(group, 0);
+ objectStack.push(sequence);
+ }
+ else {
+ if (invertedOperands) {
+ ArrayList<Object> operands =
+ (ArrayList<Object>) embeddedSequence.get("operands");
+ invertedOperandsLists.push(operands);
+ }
+ // Step II: decide where to put
+ putIntoSuperObject(group, 0);
+ objectStack.push(embeddedSequence);
+ }
+ stackedObjects++;
+ visited.add(node.getChild(0));
+ }
- @SuppressWarnings("unchecked")
- private void putIntoSuperObject(LinkedHashMap<String, Object> object, int objStackPosition) {
- if (objectStack.size() > objStackPosition) {
- ArrayList<Object> topObjectOperands = (ArrayList<Object>) objectStack.get(objStackPosition).get("operands");
- if (!invertedOperandsLists.contains(topObjectOperands)) {
- topObjectOperands.add(object);
- } else {
- topObjectOperands.add(0, object);
- }
+ private void processOPOR(Tree node) {
+ // Step I: create group
+ LinkedHashMap<String, Object> disjunction = new LinkedHashMap<String, Object>();
+ disjunction.put("@type", "korap:group");
+ disjunction.put("operation", "operation:or");
+ disjunction.put("operands", new ArrayList<Object>());
+ objectStack.push(disjunction);
+ stackedObjects++;
+ // Step II: decide where to put
+ putIntoSuperObject(disjunction, 1);
+ }
- } else {
- requestMap.put("query", object);
- }
- }
+ private void processOPAND_OPNOT(Tree node) {
+ // Step I: create group
+ String nodeCat = getNodeCat(node);
+ LinkedHashMap<String, Object> distgroup = new LinkedHashMap<String, Object>();
+ distgroup.put("@type", "korap:group");
+ distgroup.put("operation", "operation:sequence");
+ ArrayList<Object> distances = new ArrayList<Object>();
+ LinkedHashMap<String, Object> zerodistance = new LinkedHashMap<String, Object>();
+ zerodistance.put("@type", "cosmas:distance");
+ zerodistance.put("key", "t");
+ zerodistance.put("min", 0);
+ zerodistance.put("max", 0);
+ if (nodeCat.equals("OPNOT"))
+ zerodistance.put("exclude", true);
+ distances.add(zerodistance);
+ distgroup.put("distances", distances);
+ distgroup.put("operands", new ArrayList<Object>());
+ objectStack.push(distgroup);
+ stackedObjects++;
+ // Step II: decide where to put
+ putIntoSuperObject(distgroup, 1);
+ }
- private void putIntoSuperObject(LinkedHashMap<String, Object> object) {
- putIntoSuperObject(object, 0);
- }
+ private void processOPLABEL(Tree node) {
+ // Step I: create element
+ LinkedHashMap<String, Object> elem = new LinkedHashMap<String, Object>();
+ elem.put("@type", "korap:span");
+ elem.put("key", node.getChild(0).toStringTree().replaceAll("<|>", ""));
+ // Step II: decide where to put
+ putIntoSuperObject(elem);
+ }
- /**
- * Normalises position operators to equivalents using #BED
- */
- private String rewritePositionQuery(String q) {
- Pattern p = Pattern.compile("(\\w+):((\\+|-)?(sa|se|pa|pe|ta|te),?)+");
- Matcher m = p.matcher(q);
+ @SuppressWarnings("unchecked")
+ private void processOPELEM(Tree node) {
+ // Step I: create element
+ LinkedHashMap<String, Object> span = CqlfObjectGenerator.makeSpan();
+ if (node.getChild(0).toStringTree().equals("EMPTY")) {
- String rewrittenQuery = q;
- while (m.find()) {
- String match = m.group();
- String conditionsString = match.split(":")[1];
- Pattern conditionPattern = Pattern.compile("(\\+|-)?(sa|se|pa|pe|ta|te)");
- Matcher conditionMatcher = conditionPattern.matcher(conditionsString);
- String replacement = "#BED(" + m.group(1) + " , ";
- while (conditionMatcher.find()) {
- replacement = replacement + conditionMatcher.group() + ",";
- }
- replacement = replacement.substring(0, replacement.length() - 1) + ")"; //remove trailing comma and close parenthesis
- rewrittenQuery = rewrittenQuery.replace(match, replacement);
- }
- return rewrittenQuery;
- }
+ }
+ else {
+ int elname = 0;
+ Tree elnameNode = getFirstChildWithCat(node, "ELNAME");
+ if (elnameNode != null) {
+ span.put("key", elnameNode.getChild(0).toStringTree()
+ .toLowerCase());
+ elname = 1;
+ }
+ if (node.getChildCount() > elname) {
+ /*
+ * Attributes can carry several values, like #ELEM(W
+ * ANA != 'N V'), denoting a word whose POS is neither
+ * N nor V. When seeing this, create a sub-termGroup
+ * and put it into the top-level term group, but only
+ * if there are other attributes in that group. If
+ * not, put the several values as distinct
+ * attr-val-pairs into the top-level group (in order
+ * to avoid a top-level group that only contains a
+ * sub-group).
+ */
+ LinkedHashMap<String, Object> termGroup =
+ CqlfObjectGenerator.makeTermGroup("and");
+ ArrayList<Object> termGroupOperands =
+ (ArrayList<Object>) termGroup.get("operands");
+ for (int i = elname; i < node.getChildCount(); i++) {
+ Tree attrNode = node.getChild(i);
+ if (attrNode.getChildCount() == 2) {
+ LinkedHashMap<String, Object> term =
+ CqlfObjectGenerator.makeTerm();
+ termGroupOperands.add(term);
+ String layer = attrNode.getChild(0).toStringTree();
+ String[] splitted = layer.split("/");
+ if (splitted.length > 1) {
+ term.put("foundry", splitted[0]);
+ layer = splitted[1];
+ }
+ term.put("layer", translateMorph(layer));
+ term.put("key", attrNode.getChild(1).toStringTree());
+ String match = getNodeCat(attrNode).equals("EQ") ? "eq":"ne";
+ term.put("match", "match:" + match);
+ }
+ else {
+ LinkedHashMap<String, Object> subTermGroup = CqlfObjectGenerator
+ .makeTermGroup("and");
+ ArrayList<Object> subTermGroupOperands =
+ (ArrayList<Object>) subTermGroup.get("operands");
+ int j;
+ for (j = 1; j < attrNode.getChildCount(); j++) {
+ LinkedHashMap<String, Object> term =
+ CqlfObjectGenerator.makeTerm();
+ String layer = attrNode.getChild(0).toStringTree();
+ String[] splitted = layer.split("/");
+ if (splitted.length > 1) {
+ term.put("foundry", splitted[0]);
+ layer = splitted[1];
+ }
+ term.put("layer", translateMorph(layer));
+ term.put("key", attrNode.getChild(j).toStringTree());
+ String match =
+ getNodeCat(attrNode).equals("EQ") ? "eq" : "ne";
+ term.put("match", "match:" + match);
+ if (node.getChildCount() == elname + 1) {
+ termGroupOperands.add(term);
+ }
+ else {
+ subTermGroupOperands.add(term);
+ }
+ }
+ if (node.getChildCount() > elname + 1) {
+ termGroupOperands.add(subTermGroup);
+ }
+ }
+ if (getNodeCat(attrNode).equals("NOTEQ"))
+ negate = true;
+ }
+ // possibly only one term was present throughout all
+ // nodes: extract it from the group
+ if (termGroupOperands.size() == 1) {
+ termGroup = (LinkedHashMap<String, Object>)
+ termGroupOperands.get(0);
+ }
+ span.put("attr", termGroup);
+ }
+ }
+ // Step II: decide where to put
+ putIntoSuperObject(span);
+ }
- private Tree parseCosmasQuery(String query) {
- query = rewritePositionQuery(query);
- Tree tree = null;
- Antlr3DescriptiveErrorListener errorListener = new Antlr3DescriptiveErrorListener(query);
- try {
- ANTLRStringStream ss = new ANTLRStringStream(query);
- c2psLexer lex = new c2psLexer(ss);
- org.antlr.runtime.CommonTokenStream tokens = new org.antlr.runtime.CommonTokenStream(lex); //v3
- parser = new c2psParser(tokens);
-
- lex.setErrorReporter(errorListener); // Use the custom error reporter
- ((c2psParser) parser).setErrorReporter(errorListener); // Use the custom error reporter
- c2psParser.c2ps_query_return c2Return = ((c2psParser) parser).c2ps_query(); // statt t().
- // AST Tree anzeigen:
- tree = (Tree) c2Return.getTree();
+ private void processOPMORPH(Tree node) {
+ // Step I: get info
+ String[] morphterms =
+ node.getChild(0).toStringTree().replace(" ", "").split("&");
+ LinkedHashMap<String, Object> token = CqlfObjectGenerator.makeToken();
+ ArrayList<Object> terms = new ArrayList<Object>();
+ LinkedHashMap<String, Object> fieldMap = null;
+ for (String morphterm : morphterms) {
+ // regex group #2 is foundry, #4 layer, #5 operator #6
+ // key, #8 value
+ Pattern p = Pattern
+ .compile("((\\w+)/)?((\\w*)(!?=))?(\\w+)(:(\\w+))?");
+ Matcher m = p.matcher(morphterm);
+ if (!m.matches()) {
+ addError(StatusCodes.UNKNOWN_QUERY_ERROR,
+ "Something went wrong parsing the argument in MORPH().");
+ requestMap.put("query", new LinkedHashMap<String, Object>());
+ return;
+ }
- } catch (RecognitionException e) {
- log.error("Could not parse query. Please make sure it is well-formed.");
- addError(StatusCodes.MALFORMED_QUERY, "Could not parse query. Please make sure it is well-formed.");
- }
- String treestring = tree.toStringTree();
-
- boolean erroneous = false;
- if (parser.failed() || parser.getNumberOfSyntaxErrors() > 0) {
- erroneous = true;
- tree = null;
- }
+ fieldMap = new LinkedHashMap<String, Object>();
+ fieldMap.put("@type", "korap:term");
- if (erroneous || treestring.contains("<mismatched token") ||
- treestring.contains("<error") || treestring.contains("<unexpected")) {
- log.error(errorListener.generateFullErrorMsg().toString());
- addError(errorListener.generateFullErrorMsg());
- }
- return tree;
- }
+ if (m.group(2) != null)
+ fieldMap.put("foundry", m.group(2));
+ if (m.group(4) != null)
+ fieldMap.put("layer", m.group(4));
+ if (m.group(5) != null) {
+ if ("!=".equals(m.group(5)))
+ negate = !negate;
+ }
+ if (m.group(6) != null)
+ fieldMap.put("key", m.group(6));
+ if (m.group(8) != null)
+ fieldMap.put("value", m.group(8));
+
+ // negate field (see above)
+ if (negate) {
+ fieldMap.put("match", "match:ne");
+ }
+ else {
+ fieldMap.put("match", "match:eq");
+ }
+ terms.add(fieldMap);
+ }
+ if (morphterms.length == 1) {
+ token.put("wrap", fieldMap);
+ }
+ else {
+ LinkedHashMap<String, Object> termGroup =
+ CqlfObjectGenerator.makeTermGroup("and");
+ termGroup.put("operands", terms);
+ token.put("wrap", termGroup);
+ }
+ // Step II: decide where to put
+ putIntoSuperObject(token, 0);
+ visited.add(node.getChild(0));
+ }
+
+ /**
+ * Nodes introducing tokens. Process all in the same manner,
+ * except for the fieldMap entry
+ *
+ * @param node
+ */
+ private void processOPWF_OPLEM(Tree node) {
+ String nodeCat = getNodeCat(node);
+ // Step I: get info
+ LinkedHashMap<String, Object> token =
+ new LinkedHashMap<String, Object>();
+ token.put("@type", "korap:token");
+ objectStack.push(token);
+ stackedObjects++;
+ LinkedHashMap<String, Object> fieldMap =
+ new LinkedHashMap<String, Object>();
+ token.put("wrap", fieldMap);
+
+ fieldMap.put("@type", "korap:term");
+ // make category-specific fieldMap entry
+ String attr = nodeCat.equals("OPWF") ? "orth" : "lemma";
+ String value = node.getChild(0).toStringTree().replaceAll("\"", "");
+ // check for wildcard string
+ Pattern p = Pattern.compile("[+*?]");
+ Matcher m = p.matcher(value);
+ if (m.find())
+ fieldMap.put("type", "type:wildcard");
+
+ if (value.startsWith("$")) {
+ value = value.substring(1);
+ fieldMap.put("caseInsensitive", true);
+ }
+
+ fieldMap.put("key", value);
+ fieldMap.put("layer", attr);
+
+ // negate field (see above)
+ if (negate) {
+ fieldMap.put("match", "match:ne");
+ }
+ else {
+ fieldMap.put("match", "match:eq");
+ }
+ // Step II: decide where to put
+ if (!hasChild(node, "TPOS")) {
+ putIntoSuperObject(token, 1);
+ visited.add(node.getChild(0));
+ }
+ else {
+ // TODO
+ }
+ }
+
+ private void processSpanDistance(String meas, int min, int max) {
+ // Do stuff here in case we'll decide one day to treat span distances
+ // in a special way (see GDoc Special Distances Serialization).
+ }
+
+ /**
+ * Registers an entry in the {@link #operandWrap} table in order
+ * to allow an operator's arguments (or only one of them) to be
+ * wrapped in a class group.
+ *
+ * @param node
+ * The operator node (parent node of the ARG1/ARG2
+ * node)
+ * @param arg
+ * The argument number (1 or 2)
+ * @param cls
+ * The class id.
+ */
+ private void wrapOperandInClass(Tree node, int arg, int cls) {
+ LinkedHashMap<String, Object> clsGroup =
+ CqlfObjectGenerator.makeSpanClass(cls);
+ wrapOperand(node, arg, clsGroup);
+ }
+
+ /**
+ * Registers an entry in the {@link #operandWrap} table in order
+ * to allow an operator's arguments (or only one of them) to be
+ * wrapped in an arbitrary object, e.g. a reference group.
+ *
+ * @param node
+ * The operator node (parent node of the ARG1/ARG2
+ * node)
+ * @param arg
+ * The argument number (1 or 2)
+ * @param container
+ * The object in whose operand list the argument shall
+ * be wrapped.
+ */
+ private void wrapOperand(Tree node, int arg,
+ LinkedHashMap<String, Object> container) {
+ operandWrap.put(node, arg, container);
+ }
+
+ private Object translateMorph(String layer) {
+ // might be extended...
+ if (layer.equals("ANA"))
+ return ResourceMapper.descriptor2policy("ANA");
+ else
+ return layer;
+
+ }
+
+ @SuppressWarnings("unchecked")
+ /**
+ * Processes individual position conditions as provided in the OPTS node under the OPBEG node.
+ * #BEG allows to specify position constrains that apply to the beginning or the end of the subquery X.
+ * E.g., in #BEG(X, tpos/tpos), the 'tpos' constraints before the slash indicate conditions that apply
+ * to the beginning of X, those after the slash are conditions that apply to the end of X.
+ * See the official C-II documentation for more details. <br/><br/>
+ * What's important here is what follows: <br/>
+ * Assume the query #BED(der Mann, sa/pa). This means that <b>the beginning<b/> of "der Mann" stands at
+ * the beginning of a sentence and that <b>the end</b> (because this constraint comes after the slash) stands at the
+ * beginning of a paragraph. The "end" means the last item, here "Mann", so this token comes at the beginning
+ * of a paragraph. To capture this, we choose spanRefs: The last item of X matches the first item of the span (here: P).
+ * @param cond
+ * @param distributedOperands
+ * @param mode
+ * @return
+ */
+ private LinkedHashMap<String, Object> processPositionCondition(Tree cond,
+ ArrayList<Object> distributedOperands, String mode) {
+ boolean negated = false;
+ String elem; // the 'span' (s/p/t)
+ String position = "frames:matches"; // default
+ // spanRef to be used for the element ('span')
+ Integer[] elemSpanRef = null;
+ // spanRef to be used for the subquery X
+ Integer[] hitSpanRef = null;
+
+ String nodeString = cond.toStringTree();
+ if (nodeString.startsWith("-")) {
+ negated = true;
+ nodeString = nodeString.substring(1);
+ }
+ else if (nodeString.startsWith("+")) {
+ nodeString = nodeString.substring(1);
+ }
+ elem = nodeString.substring(0, 1);
+ nodeString = nodeString.substring(1);
+ // in cases where the end of X shall match the beginning of
+ // the span, or vice versa,
+ // we need to define spanRefs
+ if (mode.equals("beg")) {
+ if (nodeString.equals("a")) {
+ position = "frames:startswith";
+ }
+ else if (nodeString.equals("e")) {
+ hitSpanRef = new Integer[] { 0, 1 };
+ elemSpanRef = new Integer[] { -1, 1 };
+ }
+ }
+ else if (mode.equals("end")) {
+ if (nodeString.equals("e")) {
+ position = "frames:endswith";
+ }
+ else if (nodeString.equals("a")) {
+ hitSpanRef = new Integer[] { 0, 1 };
+ elemSpanRef = new Integer[] { -1, 1 };
+ }
+ }
+ // Create the position group and add the span and the subquery
+ // as operands, possibly wrapped in spanRefs
+ LinkedHashMap<String, Object> positionGroup = CqlfObjectGenerator
+ .makePosition(new String[] { position }, new String[0]);
+ if (negated)
+ positionGroup.put("exclude", true);
+ ArrayList<Object> posOperands = new ArrayList<Object>();
+ LinkedHashMap<String, Object> classGroup =
+ CqlfObjectGenerator.makeSpanClass(classCounter++);
+ classGroup.put("operands", distributedOperands);
+ positionGroup.put("operands", posOperands);
+ LinkedHashMap<String, Object> span = new LinkedHashMap<String, Object>();
+ span.put("@type", "korap:span");
+ span.put("key", elem);
+ objectStack.push(classGroup);
+ if (hitSpanRef != null) {
+ LinkedHashMap<String, Object> spanRefAroundHit =
+ CqlfObjectGenerator.makeSpanReference(hitSpanRef, "focus");
+ ((ArrayList<Object>) spanRefAroundHit.get("operands"))
+ .add(classGroup);
+ // re-assign after wrapping classGroup in spanRef
+ classGroup = spanRefAroundHit;
+ }
+ if (elemSpanRef != null) {
+ LinkedHashMap<String, Object> spanRefAroundSpan =
+ CqlfObjectGenerator.makeSpanReference(elemSpanRef, "focus");
+ ((ArrayList<Object>) spanRefAroundSpan.get("operands")).add(span);
+ // re-assign after wrapping span in spanRef
+ span = spanRefAroundSpan;
+ }
+ posOperands.add(span);
+ posOperands.add(classGroup);
+ return positionGroup;
+ }
+
+ private LinkedHashMap<String, Object> parseOPINOptions(Tree node) {
+ 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<String> positions = new ArrayList<String>();
+ ArrayList<String> classRefCheck = new ArrayList<String>();
+ posOptions.put("matchall", false);
+ String frame = "";
+ String posOption = null;
+ if (posnode != null) {
+ posOption = posnode.getChild(0).toStringTree();
+ switch (posOption) {
+ case "L":
+ positions.add("frames:startswith");
+ classRefCheck.add("classRefCheck:includes");
+ frame = "startswith";
+ break;
+ case "R":
+ positions.add("frames:endswith");
+ classRefCheck.add("classRefCheck:includes");
+ frame = "endswith";
+ break;
+ case "F":
+ positions.add("frames:matches");
+ classRefCheck.add("classRefCheck:includes");
+ frame = "matches";
+ break;
+ case "FE":
+ positions.add("frames:matches");
+ classRefCheck.add("classRefCheck:equals");
+ frame = "matches";
+ break;
+ case "FI":
+ positions.add("frames:matches");
+ classRefCheck.add("classRefCheck:unequals");
+ classRefCheck.add("classRefCheck:includes");
+ frame = "matches-noident";
+ break;
+ case "N":
+ positions.add("frames:contains");
+ classRefCheck.add("classRefCheck:includes");
+ frame = "contains";
+ break;
+ }
+ }
+ else {
+ classRefCheck.add("classRefCheck:includes");
+ frame = "contains";
+ }
+ posOptions.put("frames", positions);
+ posOptions.put("classRefCheck", classRefCheck);
+ posOptions.put("frame", "frame:" + frame);
+ addMessage(
+ StatusCodes.DEPRECATED_QUERY_ELEMENT,
+ "Deprecated 2014-09-22: 'frame' only to be supported until 3 months from deprecation date. "
+ + "Position frames are now expressed through 'frames' and 'sharedClasses'");
+
+ 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")) {
+ posOptions.put("matchall", true);
+ // LinkedHashMap<String,Object> ref =
+ // makeResetReference(); // reset all defined classes
+ // wrapOperand(node,2,ref);
+ }
+ }
+
+ if (negatePosition) {
+ posOptions.put("exclude", "true");
+ }
+
+ if (groupnode != null) {
+ String grouping = groupnode.getChild(0).toStringTree()
+ .equals("max") ? "true" : "false";
+ posOptions.put("grouping", grouping);
+ }
+ return posOptions;
+ }
+
+ private LinkedHashMap<String, Object> parseOPOVOptions(Tree node) {
+ boolean negatePosition = false;
+ Tree posnode = getFirstChildWithCat(node, "POS");
+ Tree rangenode = getFirstChildWithCat(node, "RANGE");
+ Tree exclnode = getFirstChildWithCat(node, "EXCL");
+ Tree groupnode = getFirstChildWithCat(node, "GROUP");
+ LinkedHashMap<String, Object> posOptions = new LinkedHashMap<String, Object>();
+ ArrayList<String> positions = new ArrayList<String>();
+ ArrayList<String> classRefCheck = new ArrayList<String>();
+ posOptions.put("matchall", false);
+ String frame = "";
+ String posOption = null;
+ if (posnode != null) {
+ posOption = posnode.getChild(0).toStringTree();
+ switch (posOption) {
+ case "L":
+ positions.add("frames:startswith");
+ positions.add("frames:overlapsLeft");
+ classRefCheck.add("classRefCheck:intersects");
+ frame = "overlapsLeft";
+ break;
+ case "R":
+ positions.add("frames:endswith");
+ positions.add("frames:overlapsRight");
+ classRefCheck.add("classRefCheck:intersects");
+ frame = "overlapsRight";
+ break;
+ case "F":
+ positions.add("frames:matches");
+ classRefCheck.add("classRefCheck:intersects");
+ frame = "matches";
+ break;
+ case "FE":
+ positions.add("frames:matches");
+ classRefCheck.add("classRefCheck:equals");
+ frame = "matches";
+ break;
+ case "FI":
+ positions.add("frames:matches");
+ classRefCheck.add("classRefCheck:unequals");
+ frame = "matches-noident";
+ break;
+ case "X":
+ positions.add("frames:contains");
+ classRefCheck.add("classRefCheck:intersects");
+ frame = "overlaps";
+ break;
+ }
+ }
+ else {
+ classRefCheck.add("classRefCheck:intersects");
+ frame = "overlaps";
+ }
+
+ posOptions.put("frames", positions);
+ posOptions.put("classRefCheck", classRefCheck);
+ posOptions.put("frame", "frame:" + frame);
+ addMessage(
+ StatusCodes.DEPRECATED_QUERY_ELEMENT,
+ "Deprecated 2014-09-22: 'frame' only to be supported until 3 months from deprecation date. "
+ + "Position frames are now expressed through 'frames' and 'sharedClasses'");
+
+ 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")) {
+ posOptions.put("matchall", true);
+ // LinkedHashMap<String,Object> ref =
+ // makeResetReference(); // reset all defined classes
+ // wrapOperand(node,2,ref);
+ }
+ }
+
+ if (negatePosition) {
+ posOptions.put("exclude", "true");
+ }
+
+ if (groupnode != null) {
+ String grouping = groupnode.getChild(0).toStringTree()
+ .equals("max") ? "true" : "false";
+ posOptions.put("grouping", grouping);
+ }
+ return posOptions;
+ }
+
+ @SuppressWarnings({ "unchecked" })
+ private LinkedHashMap<String, Object> wrap(LinkedHashMap[] wrapCascade) {
+ int i;
+ for (i = 0; i < wrapCascade.length - 1; i++) {
+ ArrayList<Object> containerOperands = (ArrayList<Object>) wrapCascade[i + 1]
+ .get("operands");
+ containerOperands.add(0, wrapCascade[i]);
+ }
+ return wrapCascade[i];
+ }
+
+ @SuppressWarnings("unchecked")
+ private void putIntoSuperObject(LinkedHashMap<String, Object> object,
+ int objStackPosition) {
+ if (objectStack.size() > objStackPosition) {
+ ArrayList<Object> topObjectOperands = (ArrayList<Object>) objectStack
+ .get(objStackPosition).get("operands");
+ if (!invertedOperandsLists.contains(topObjectOperands)) {
+ topObjectOperands.add(object);
+ }
+ else {
+ topObjectOperands.add(0, object);
+ }
+ }
+ else {
+ requestMap.put("query", object);
+ }
+ }
+
+ private void putIntoSuperObject(LinkedHashMap<String, Object> object) {
+ putIntoSuperObject(object, 0);
+ }
+
+ /**
+ * Normalises position operators to equivalents using #BED
+ */
+ private String rewritePositionQuery(String q) {
+ Pattern p = Pattern.compile("(\\w+):((\\+|-)?(sa|se|pa|pe|ta|te),?)+");
+ Matcher m = p.matcher(q);
+
+ String rewrittenQuery = q;
+ while (m.find()) {
+ String match = m.group();
+ String conditionsString = match.split(":")[1];
+ Pattern conditionPattern = Pattern
+ .compile("(\\+|-)?(sa|se|pa|pe|ta|te)");
+ Matcher conditionMatcher = conditionPattern
+ .matcher(conditionsString);
+ String replacement = "#BED(" + m.group(1) + " , ";
+ while (conditionMatcher.find()) {
+ replacement = replacement + conditionMatcher.group() + ",";
+ }
+ // remove trailing comma and close parenthesis
+ replacement =
+ replacement.substring(0, replacement.length() - 1)+ ")";
+ rewrittenQuery = rewrittenQuery.replace(match, replacement);
+ }
+ return rewrittenQuery;
+ }
+
+ private Tree parseCosmasQuery(String query) {
+ query = rewritePositionQuery(query);
+ Tree tree = null;
+ Antlr3DescriptiveErrorListener errorListener =
+ new Antlr3DescriptiveErrorListener(query);
+ try {
+ ANTLRStringStream ss = new ANTLRStringStream(query);
+ c2psLexer lex = new c2psLexer(ss);
+ org.antlr.runtime.CommonTokenStream tokens =
+ new org.antlr.runtime.CommonTokenStream(lex); // v3
+ parser = new c2psParser(tokens);
+ // Use custom error reporters
+ lex.setErrorReporter(errorListener);
+ ((c2psParser) parser).setErrorReporter(errorListener);
+ c2psParser.c2ps_query_return c2Return = ((c2psParser) parser)
+ .c2ps_query(); // statt t().
+ // AST Tree anzeigen:
+ tree = (Tree) c2Return.getTree();
+
+ }
+ catch (RecognitionException e) {
+ log.error("Could not parse query. Please make sure it is well-formed.");
+ addError(StatusCodes.MALFORMED_QUERY,
+ "Could not parse query. Please make sure it is well-formed.");
+ }
+ String treestring = tree.toStringTree();
+
+ boolean erroneous = false;
+ if (parser.failed() || parser.getNumberOfSyntaxErrors() > 0) {
+ erroneous = true;
+ tree = null;
+ }
+
+ if (erroneous || treestring.contains("<mismatched token")
+ || treestring.contains("<error")
+ || treestring.contains("<unexpected")) {
+ log.error(errorListener.generateFullErrorMsg().toString());
+ addError(errorListener.generateFullErrorMsg());
+ }
+ return tree;
+ }
}
\ No newline at end of file
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 7e76964..9064a0e 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
@@ -12,7 +12,7 @@
/**
* @author margaretha
- * @date 09.05.14
+ * @date 09.05.14
*/
public class CqlQueryProcessor extends AbstractQueryProcessor {
@@ -22,7 +22,10 @@
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";
@@ -31,16 +34,17 @@
private LinkedHashMap<String, Object> requestMap;
private String version;
private boolean isCaseSensitive; // default true
-
- public CqlQueryProcessor(String query) {
+
+ public CqlQueryProcessor (String query) {
this(query, VERSION_1_2, true);
}
- public CqlQueryProcessor(String query, String version) {
- this(query, version, true);
+ public CqlQueryProcessor (String query, String version) {
+ this(query, version, true);
}
- public CqlQueryProcessor(String query, String version, boolean isCaseSensitive) {
+ public CqlQueryProcessor (String query, String version,
+ boolean isCaseSensitive) {
this.version = version;
this.isCaseSensitive = isCaseSensitive;
this.requestMap = new LinkedHashMap<>();
@@ -48,41 +52,41 @@
process(query);
}
-
@Override
public Map<String, Object> getRequestMap() {
return this.requestMap;
}
@Override
- public void process(String query) {
- if ((query == null) || query.isEmpty())
- addError(StatusCodes.MALFORMED_QUERY, "SRU diagnostic 27: An empty query is unsupported.");
-
+ public void process(String query) {
+ if ((query == null) || query.isEmpty())
+ addError(StatusCodes.MALFORMED_QUERY,
+ "SRU diagnostic 27: An empty query is unsupported.");
+
CQLNode cqlNode = parseQuerytoCQLNode(query);
- Map<String,Object> queryMap = parseCQLNode(cqlNode);
+ Map<String, Object> queryMap = parseCQLNode(cqlNode);
requestMap.put("query", queryMap);
- //requestMap.put("query", sentenceWrapper(queryMap));
+ // requestMap.put("query", sentenceWrapper(queryMap));
}
- private Map<String,Object> sentenceWrapper(Map<String,Object> m){
- Map<String, Object> map = new LinkedHashMap<String,Object>();
+ private Map<String, Object> sentenceWrapper(Map<String, Object> m) {
+ Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("@type", "korap:group");
map.put("operation", OPERATION_POSITION);
map.put("frame", "frame:contains");
-
- Map<String, Object> sentence = new LinkedHashMap<String,Object>();
+
+ Map<String, Object> sentence = new LinkedHashMap<String, Object>();
sentence.put("@type", "korap:span");
sentence.put("key", "s");
-
+
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
list.add(sentence);
list.add(m);
- map.put("operands", list);
-
- return map;
+ map.put("operands", list);
+
+ return map;
}
-
+
private CQLNode parseQuerytoCQLNode(String query) {
try {
int compat = -1;
@@ -95,140 +99,153 @@
}
return new CQLParser(compat).parse(query);
- } catch (CQLParseException | IOException e) {
+ }
+ catch (CQLParseException | IOException e) {
addError(StatusCodes.MALFORMED_QUERY, "Error parsing CQL");
return null;
}
}
- private Map<String,Object> parseCQLNode(CQLNode node) {
-
+ private Map<String, Object> parseCQLNode(CQLNode node) {
+
if (node instanceof CQLTermNode) {
return parseTermNode((CQLTermNode) node);
- } else if (node instanceof CQLAndNode) {
+ }
+ else if (node instanceof CQLAndNode) {
return parseAndNode((CQLAndNode) node);
- } else if (node instanceof CQLOrNode) {
+ }
+ else if (node instanceof CQLOrNode) {
return parseOrNode((CQLOrNode) node);
- } else {
- addError(StatusCodes.UNKNOWN_QUERY_ELEMENT, "SRU diagnostic 48: Only basic search including term-only " +
- "and boolean (AND,OR) operator queries are currently supported.");
- return new LinkedHashMap<String,Object>();
+ }
+ else {
+ addError(
+ StatusCodes.UNKNOWN_QUERY_ELEMENT,
+ "SRU diagnostic 48: Only basic search including term-only "
+ + "and boolean (AND,OR) operator queries are currently supported.");
+ return new LinkedHashMap<String, Object>();
}
}
- private Map<String,Object> parseTermNode(CQLTermNode node) {
+ private Map<String, Object> parseTermNode(CQLTermNode node) {
checkTermNode(node);
final String term = node.getTerm();
if ((term == null) || term.isEmpty()) {
- addError(StatusCodes.NO_QUERY, "SRU diagnostic 27: An empty term is unsupported.");
- return new LinkedHashMap<String,Object>();
- } else if (term.contains(" ")) {
+ addError(StatusCodes.NO_QUERY,
+ "SRU diagnostic 27: An empty term is unsupported.");
+ return new LinkedHashMap<String, Object>();
+ }
+ else if (term.contains(" ")) {
return writeSequence(term);
- } else {
+ }
+ else {
return writeTerm(term);
}
}
- private Map<String,Object> parseAndNode(CQLAndNode node) {
+ private Map<String, Object> parseAndNode(CQLAndNode node) {
checkBooleanModifier(node);
-
- Map<String, Object> map = new LinkedHashMap<String,Object>();
+
+ Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("@type", "korap:group");
map.put("operation", OPERATION_SEQUENCE);
map.put("inOrder", false);
-
+
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
- Map<String, Object> distanceMap = new LinkedHashMap<String,Object>();
+ Map<String, Object> distanceMap = new LinkedHashMap<String, Object>();
distanceMap.put("@type", "korap:distance");
distanceMap.put("key", "s");
distanceMap.put("min", "0");
distanceMap.put("max", "0");
list.add(distanceMap);
map.put("distances", list);
-
- List<Map<String, Object>> operandList = new ArrayList<Map<String, Object>>();
+
+ List<Map<String, Object>> operandList = new ArrayList<Map<String, Object>>();
operandList.add(parseCQLNode(node.getLeftOperand()));
operandList.add(parseCQLNode(node.getRightOperand()));
map.put("operands", operandList);
-
+
return map;
}
- private Map<String,Object> parseOrNode(CQLOrNode node) {
- checkBooleanModifier(node);
-
- Map<String, Object> map = new LinkedHashMap<String,Object>();
- map.put("@type", "korap:group");
+ private Map<String, Object> parseOrNode(CQLOrNode node) {
+ checkBooleanModifier(node);
+
+ Map<String, Object> map = new LinkedHashMap<String, Object>();
+ map.put("@type", "korap:group");
map.put("operation", OPERATION_OR);
-
+
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
list.add(parseCQLNode(node.getLeftOperand()));
list.add(parseCQLNode(node.getRightOperand()));
map.put("operands", list);
-
- return map;
+
+ return map;
}
private Map<String, Object> writeSequence(String str) {
- Map<String, Object> sequenceMap = new LinkedHashMap<String,Object>();
+ Map<String, Object> sequenceMap = new LinkedHashMap<String, Object>();
sequenceMap.put("@type", "korap:group");
sequenceMap.put("operation", OPERATION_SEQUENCE);
-
+
List<Map<String, Object>> termList = new ArrayList<Map<String, Object>>();
String[] terms = str.split(" ");
- for (String term : terms){
- termList.add(writeTerm(term));
+ for (String term : terms) {
+ termList.add(writeTerm(term));
}
sequenceMap.put("operands", termList);
-
+
return sequenceMap;
}
- private Map<String, Object> writeTerm(String term) {
- Map<String, Object> map = new LinkedHashMap<String,Object>();
- map.put("@type", "korap:term");
- if (!isCaseSensitive) {
- map.put("caseInsensitive","true");
- }
- map.put("key", term);
- map.put("layer", "orth");
- map.put("match", "match:eq");
-
- Map<String, Object> tokenMap = new LinkedHashMap<String,Object>();
- tokenMap.put("@type", "korap:token");
- tokenMap.put("wrap", map);
- return tokenMap;
+ private Map<String, Object> writeTerm(String term) {
+ Map<String, Object> map = new LinkedHashMap<String, Object>();
+ map.put("@type", "korap:term");
+ if (!isCaseSensitive) {
+ map.put("caseInsensitive", "true");
+ }
+ map.put("key", term);
+ map.put("layer", "orth");
+ map.put("match", "match:eq");
+
+ Map<String, Object> tokenMap = new LinkedHashMap<String, Object>();
+ tokenMap.put("@type", "korap:token");
+ tokenMap.put("wrap", map);
+ return tokenMap;
}
private void checkBooleanModifier(CQLBooleanNode node) {
List<Modifier> modifiers = node.getModifiers();
if ((modifiers != null) && !modifiers.isEmpty()) {
Modifier modifier = modifiers.get(0);
- addError(105, "SRU diagnostic 20: Relation modifier " +
- modifier.toCQL() + " is not supported.");
+ addError(105,
+ "SRU diagnostic 20: Relation modifier " + modifier.toCQL()
+ + " is not supported.");
}
}
private void checkTermNode(CQLTermNode node) {
// only allow "cql.serverChoice" and "words" index
- if (!(INDEX_CQL_SERVERCHOICE.equals(node.getIndex()) ||
- INDEX_WORDS.equals(node.getIndex()))) {
- addError(105, "SRU diagnostic 16: Index " + node.getIndex() + " is not supported.");
+ if (!(INDEX_CQL_SERVERCHOICE.equals(node.getIndex()) || INDEX_WORDS
+ .equals(node.getIndex()))) {
+ addError(105, "SRU diagnostic 16: Index " + node.getIndex()
+ + " is not supported.");
}
// only allow "=" relation without any modifiers
CQLRelation relation = node.getRelation();
String baseRel = relation.getBase();
- if (!(TERM_RELATION_CQL_1_1.equals(baseRel) ||
- TERM_RELATION_CQL_1_2.equals(baseRel) ||
- SUPPORTED_RELATION_EXACT.equals(baseRel))) {
- addError(105, "SRU diagnostic 19: Relation " +
- relation.getBase() + " is not supported.");
+ if (!(TERM_RELATION_CQL_1_1.equals(baseRel)
+ || TERM_RELATION_CQL_1_2.equals(baseRel) || SUPPORTED_RELATION_EXACT
+ .equals(baseRel))) {
+ addError(105, "SRU diagnostic 19: Relation " + relation.getBase()
+ + " is not supported.");
}
List<Modifier> modifiers = relation.getModifiers();
if ((modifiers != null) && !modifiers.isEmpty()) {
Modifier modifier = modifiers.get(0);
- addError(105, "SRU diagnostic 20: Relation modifier " +
- modifier.getValue() + " is not supported.");
+ addError(
+ 105,
+ "SRU diagnostic 20: Relation modifier "
+ + modifier.getValue() + " is not supported.");
}
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/DummyQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/DummyQueryProcessor.java
index 6c49737..5ce7a0c 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/DummyQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/DummyQueryProcessor.java
@@ -1,16 +1,18 @@
package de.ids_mannheim.korap.query.serialize;
/**
- * This class serves as a dummy class for reporting errors when the query or query language as specified
- * in the {@link #QuerySerializer} are empty or erroneous. Without instatiating a class, errors/warnings cannot
- * be reported.
+ * This class serves as a dummy class for reporting errors when the
+ * query or query language as specified in the
+ * {@link #QuerySerializer} are empty or erroneous. Without
+ * instatiating a class, errors/warnings cannot be reported.
+ *
* @author bingel
*
*/
public final class DummyQueryProcessor extends AbstractQueryProcessor {
- @Override
- public void process(String query) {
- // This is just a dummy class. Do nothing!
- }
+ @Override
+ public void process(String query) {
+ // This is just a dummy class. Do nothing!
+ }
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/IdWriter.java b/src/main/java/de/ids_mannheim/korap/query/serialize/IdWriter.java
index 77dfafc..70d6a31 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/IdWriter.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/IdWriter.java
@@ -9,15 +9,15 @@
/**
* @author hanl
* @date 04/06/2014
- * <p/>
- * create idn for korap:token
+ * <p/>
+ * create idn for korap:token
*/
public class IdWriter {
private JsonNode node;
private int counter;
- public IdWriter(String json) {
+ public IdWriter (String json) {
node = JsonUtils.readTree(json);
counter = 0;
}
@@ -32,7 +32,8 @@
Iterator<JsonNode> operands = node.path("operands").elements();
while (operands.hasNext())
process(operands.next());
- } else if (node.path("@type").asText().equals("korap:token"))
+ }
+ else if (node.path("@type").asText().equals("korap:token"))
addId(node);
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/MetaQueryBuilder.java b/src/main/java/de/ids_mannheim/korap/query/serialize/MetaQueryBuilder.java
index d30fd6d..85b7a0e 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/MetaQueryBuilder.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/MetaQueryBuilder.java
@@ -16,7 +16,7 @@
private Map meta;
private SpanContext spanContext;
- public MetaQueryBuilder() {
+ public MetaQueryBuilder () {
this.meta = new LinkedHashMap();
}
@@ -31,7 +31,7 @@
* @return
*/
public MetaQueryBuilder setSpanContext(Integer left, String leftType,
- Integer right, String rightType) {
+ Integer right, String rightType) {
this.spanContext = new SpanContext(left, leftType, right, rightType);
return this;
}
@@ -41,8 +41,9 @@
}
/**
- * context if of type paragraph or sentence where left and right size delimiters are irrelevant; or 2-token, 2-char
- * p/paragraph, s/sentence or token, char
+ * context if of type paragraph or sentence where left and right
+ * size delimiters are irrelevant; or 2-token, 2-char p/paragraph,
+ * s/sentence or token, char
*
* @param context
* @return
@@ -51,17 +52,17 @@
if (context.startsWith("s") | context.startsWith("p"))
this.spanContext = new SpanContext(context);
else {
- String[] ct = context.replaceAll("\\s+","").split(",");
+ String[] ct = context.replaceAll("\\s+", "").split(",");
String[] lc = ct[0].split("-");
String[] rc = ct[1].split("-");
- this.spanContext = new SpanContext(Integer.valueOf(lc[0]), lc[1], Integer.valueOf(rc[0]), rc[1]);
+ this.spanContext = new SpanContext(Integer.valueOf(lc[0]), lc[1],
+ Integer.valueOf(rc[0]), rc[1]);
}
return this;
}
public MetaQueryBuilder fillMeta(Integer pageIndex, Integer pageInteger,
- Integer pageLength,
- String ctx, Boolean cutoff) {
+ Integer pageLength, String ctx, Boolean cutoff) {
if (pageIndex != null)
this.addEntry("startIndex", pageIndex);
if (pageIndex == null && pageInteger != null)
@@ -75,7 +76,6 @@
return this;
}
-
public MetaQueryBuilder addEntry(String name, Object value) {
meta.put(name, value);
return this;
@@ -95,7 +95,6 @@
private int right_size;
private String context = null;
-
/**
* context segment if context is either of type char or token.
* size can differ for left and right span
@@ -106,14 +105,14 @@
* @param rt
* @return
*/
- public SpanContext(int ls, String lt, int rs, String rt) {
+ public SpanContext (int ls, String lt, int rs, String rt) {
this.left_type = lt;
this.left_size = ls;
this.right_type = rt;
this.right_size = rs;
}
- public SpanContext(String context) {
+ public SpanContext (String context) {
this.context = context;
}
@@ -130,7 +129,8 @@
r.add(this.right_size);
map.put("right", r);
meta.put("context", map);
- } else
+ }
+ else
meta.put("context", this.context);
return meta;
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessor.java
index 0da9e5c..3ccd297 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessor.java
@@ -21,763 +21,887 @@
*/
public class PoliqarpPlusQueryProcessor extends Antlr4AbstractQueryProcessor {
- private static Logger log = LoggerFactory.getLogger(PoliqarpPlusQueryProcessor.class);
- private int classCounter = 128;
+ private static Logger log = LoggerFactory
+ .getLogger(PoliqarpPlusQueryProcessor.class);
+ private int classCounter = 128;
- /**
- * Most centrally, this class maintains a set of nested maps and lists which represent the JSON tree, which is built by the JSON serialiser
- * on basis of the {@link #requestMap} at the root of the tree.
- * <br/>
- * The class further maintains a set of stacks which effectively keep track of which objects to embed in which containing objects.
- *
- * @param query The syntax tree as returned by ANTLR
- * @throws QueryException
- */
- public PoliqarpPlusQueryProcessor(String query) {
- CqlfObjectGenerator.setQueryProcessor(this);
- process(query);
- log.info(">>> " + requestMap.get("query") + " <<<");
- }
+ /**
+ * Most centrally, this class maintains a set of nested maps and
+ * lists which represent the JSON tree, which is built by the JSON
+ * serialiser on basis of the {@link #requestMap} at the root of
+ * the tree. <br/>
+ * The class further maintains a set of stacks which effectively
+ * keep track of which objects to embed in which containing
+ * objects.
+ *
+ * @param query
+ * The syntax tree as returned by ANTLR
+ * @throws QueryException
+ */
+ public PoliqarpPlusQueryProcessor (String query) {
+ CqlfObjectGenerator.setQueryProcessor(this);
+ process(query);
+ log.info(">>> " + requestMap.get("query") + " <<<");
+ }
- @Override
- public void process(String query) {
- ParseTree tree;
- tree = parsePoliqarpQuery(query);
- super.parser = this.parser;
- log.info("Processing PoliqarpPlus query: "+query);
- if (tree != null) {
- log.debug("ANTLR parse tree: "+tree.toStringTree(parser));
- processNode(tree);
- } else {
- addError(StatusCodes.MALFORMED_QUERY, "Could not parse query >>> "+query+" <<<.");
- }
- }
+ @Override
+ public void process(String query) {
+ ParseTree tree;
+ tree = parsePoliqarpQuery(query);
+ super.parser = this.parser;
+ log.info("Processing PoliqarpPlus query: " + query);
+ if (tree != null) {
+ log.debug("ANTLR parse tree: " + tree.toStringTree(parser));
+ processNode(tree);
+ }
+ else {
+ addError(StatusCodes.MALFORMED_QUERY, "Could not parse query >>> "
+ + query + " <<<.");
+ }
+ }
- /**
- * Recursively calls itself with the children of the currently active node, traversing the tree nodes in a top-down, depth-first fashion.
- * A list is maintained that contains all visited nodes
- * which have been directly addressed by their (grand-/grand-grand-/...) parent nodes, such that some processing time is saved, as these node will
- * not be processed. This method is effectively a list of if-statements that are responsible for treating the different node types correctly and filling the
- * respective maps/lists.
- *
- * @param node The currently processed node. The process(String query) method calls this method with the root.
- * @throws QueryException
- */
- private void processNode(ParseTree node) {
- // Top-down processing
- if (visited.contains(node)) return;
- else visited.add(node);
+ /**
+ * Recursively calls itself with the children of the currently
+ * active node, traversing the tree nodes in a top-down,
+ * depth-first fashion. A list is maintained that contains all
+ * visited nodes which have been directly addressed by their
+ * (grand-/grand-grand-/...) parent nodes, such that some
+ * processing time is saved, as these node will not be processed.
+ * This method is effectively a list of if-statements that are
+ * responsible for treating the different node types correctly and
+ * filling the respective maps/lists.
+ *
+ * @param node
+ * The currently processed node. The process(String
+ * query) method calls this method with the root.
+ * @throws QueryException
+ */
+ private void processNode(ParseTree node) {
+ // Top-down processing
+ if (visited.contains(node))
+ return;
+ else
+ visited.add(node);
- currentNode = node;
+ currentNode = node;
- String nodeCat = getNodeCat(node);
- openNodeCats.push(nodeCat);
+ String nodeCat = getNodeCat(node);
+ openNodeCats.push(nodeCat);
- stackedObjects = 0;
+ stackedObjects = 0;
- if (verbose) {
- System.err.println(" " + objectStack);
- System.out.println(openNodeCats);
- }
+ if (verbose) {
+ System.err.println(" " + objectStack);
+ System.out.println(openNodeCats);
+ }
- /*
- ****************************************************************
- ****************************************************************
- * Processing individual node categories *
- ****************************************************************
- ****************************************************************
- */
-
- if (nodeCat.equals("segment")) {
- processSegment(node);
- }
-
- if (nodeCat.equals("sequence")) {
- processSequence(node);
- }
+ /*
+ * ***************************************************************
+ * ***************************************************************
+ * *********** Processing individual node categories *************
+ * ***************************************************************
+ * ***************************************************************
+ */
- if (nodeCat.equals("emptyTokenSequence")) {
- processEmptyTokenSequence(node);
- }
+ if (nodeCat.equals("segment")) {
+ processSegment(node);
+ }
- if (nodeCat.equals("emptyTokenSequenceClass")) {
- processEmptyTokenSequenceClass(node);
- }
+ if (nodeCat.equals("sequence")) {
+ processSequence(node);
+ }
- if (nodeCat.equals("token")) {
- processToken(node);
- }
+ if (nodeCat.equals("emptyTokenSequence")) {
+ processEmptyTokenSequence(node);
+ }
- if (nodeCat.equals("alignment")) {
- processAlignment(node);
- }
+ if (nodeCat.equals("emptyTokenSequenceClass")) {
+ processEmptyTokenSequenceClass(node);
+ }
- if (nodeCat.equals("span")) {
- processSpan(node);
- }
+ if (nodeCat.equals("token")) {
+ processToken(node);
+ }
- if (nodeCat.equals("disjunction")) {
- processDisjunction(node);
- }
+ if (nodeCat.equals("alignment")) {
+ processAlignment(node);
+ }
- if (nodeCat.equals("position")) {
- processPosition(node);
- }
+ if (nodeCat.equals("span")) {
+ processSpan(node);
+ }
- if (nodeCat.equals("relation")) {
- processRelation(node);
- }
+ if (nodeCat.equals("disjunction")) {
+ processDisjunction(node);
+ }
- if (nodeCat.equals("spanclass")) {
- processSpanclass(node);
- }
+ if (nodeCat.equals("position")) {
+ processPosition(node);
+ }
- if (nodeCat.equals("matching")) {
- processMatching(node);
- }
+ if (nodeCat.equals("relation")) {
+ processRelation(node);
+ }
- if (nodeCat.equals("submatch")) {
- processSubmatch(node);
- }
+ if (nodeCat.equals("spanclass")) {
+ processSpanclass(node);
+ }
- if (nodeCat.equals("meta")) {
- processMeta(node);
- }
+ if (nodeCat.equals("matching")) {
+ processMatching(node);
+ }
- if (nodeCat.equals("within") && !getNodeCat(node.getParent()).equals("position")) {
- processWithin(node);
- }
+ if (nodeCat.equals("submatch")) {
+ processSubmatch(node);
+ }
- objectsToPop.push(stackedObjects);
+ if (nodeCat.equals("meta")) {
+ processMeta(node);
+ }
- /*
- ****************************************************************
- ****************************************************************
- * recursion until 'request' node (root of tree) is processed *
- ****************************************************************
- ****************************************************************
- */
- for (int i = 0; i < node.getChildCount(); i++) {
- ParseTree child = node.getChild(i);
- processNode(child);
- }
+ if (nodeCat.equals("within")
+ && !getNodeCat(node.getParent()).equals("position")) {
+ processWithin(node);
+ }
- // Stuff that happens when leaving a node (taking items off the stacks)
- for (int i = 0; i < objectsToPop.get(0); i++) {
- objectStack.pop();
- }
- objectsToPop.pop();
- openNodeCats.pop();
- }
+ objectsToPop.push(stackedObjects);
- private void processSegment(ParseTree node) {
- // Cover possible quantification (i.e. repetition) of segment
- ParseTree quantification = getFirstChildWithCat(node, "repetition");
- if (quantification != null) {
- LinkedHashMap<String,Object> quantGroup = CqlfObjectGenerator.makeGroup("repetition");
- Integer[] minmax = parseRepetition(quantification);
- quantGroup.put("boundary", CqlfObjectGenerator.makeBoundary(minmax[0], minmax[1]));
- if (minmax[0] != null) quantGroup.put("min", minmax[0]);
- if (minmax[1] != null) quantGroup.put("max", minmax[1]);
- addMessage(StatusCodes.DEPRECATED_QUERY_ELEMENT, "Deprecated 2014-07-24: 'min' and 'max' to be " +
- "supported until 3 months from deprecation date.");
- putIntoSuperObject(quantGroup);
- objectStack.push(quantGroup);
- stackedObjects++;
- }
- }
+ /*
+ * ***************************************************************
+ * ***************************************************************
+ * recursion until 'request' node (root of tree) is processed
+ * *
+ * ***********************************************************
+ * ****
+ * ********************************************************
+ * *******
+ */
+ for (int i = 0; i < node.getChildCount(); i++) {
+ ParseTree child = node.getChild(i);
+ processNode(child);
+ }
- private void processSequence(ParseTree node) {
- LinkedHashMap<String,Object> sequence = CqlfObjectGenerator.makeGroup("sequence");
- ParseTree distanceNode = getFirstChildWithCat(node, "distance");
+ // Stuff that happens when leaving a node (taking items off
+ // the stacks)
+ for (int i = 0; i < objectsToPop.get(0); i++) {
+ objectStack.pop();
+ }
+ objectsToPop.pop();
+ openNodeCats.pop();
+ }
- if (distanceNode!=null) {
- Integer[] minmax = parseDistance(distanceNode);
- LinkedHashMap<String,Object> distance = CqlfObjectGenerator.makeDistance("w", minmax[0], minmax[1]);
- sequence.put("inOrder", true);
- ArrayList<Object> distances = new ArrayList<Object>();
- distances.add(distance);
- sequence.put("distances", distances);
- visited.add(distanceNode.getChild(0)); // don't re-visit the emptyTokenSequence node
- }
- putIntoSuperObject(sequence);
- objectStack.push(sequence);
- stackedObjects++;
- }
+ private void processSegment(ParseTree node) {
+ // Cover possible quantification (i.e. repetition) of segment
+ ParseTree quantification = getFirstChildWithCat(node, "repetition");
+ if (quantification != null) {
+ LinkedHashMap<String, Object> quantGroup =
+ CqlfObjectGenerator.makeGroup("repetition");
+ Integer[] minmax = parseRepetition(quantification);
+ quantGroup.put("boundary",
+ CqlfObjectGenerator.makeBoundary(minmax[0], minmax[1]));
+ putIntoSuperObject(quantGroup);
+ objectStack.push(quantGroup);
+ stackedObjects++;
+ }
+ }
- @SuppressWarnings("unchecked")
- /**
- * empty tokens at beginning/end of sequence
- * @param node
- */
- private void processEmptyTokenSequence(ParseTree node) {
- Integer[] minmax = parseEmptySegments(node);
- // object will be either a repetition group or a single empty token
- LinkedHashMap<String,Object> object;
- LinkedHashMap<String,Object> emptyToken = CqlfObjectGenerator.makeToken();
- if (minmax[0] != 1 || minmax[1] == null || minmax[1] != 1) {
- object = CqlfObjectGenerator.makeRepetition(minmax[0], minmax[1]);
- ((ArrayList<Object>) object.get("operands")).add(emptyToken);
- } else {
- object = emptyToken;
- }
- putIntoSuperObject(object);
- objectStack.push(object);
- stackedObjects++;
- }
+ private void processSequence(ParseTree node) {
+ LinkedHashMap<String, Object> sequence =
+ CqlfObjectGenerator.makeGroup("sequence");
+ ParseTree distanceNode = getFirstChildWithCat(node, "distance");
- private void processEmptyTokenSequenceClass(ParseTree node) {
- int classId = 1;
- if (hasChild(node, "spanclass_id")) {
- classId = Integer.parseInt(node.getChild(1).getChild(0).toStringTree(parser));
- }
- LinkedHashMap<String,Object> classGroup = CqlfObjectGenerator.makeSpanClass(classId, false);
- putIntoSuperObject(classGroup);
- objectStack.push(classGroup);
- stackedObjects++;
- }
+ if (distanceNode != null) {
+ Integer[] minmax = parseDistance(distanceNode);
+ LinkedHashMap<String, Object> distance =
+ CqlfObjectGenerator.makeDistance("w", minmax[0], minmax[1]);
+ sequence.put("inOrder", true);
+ ArrayList<Object> distances = new ArrayList<Object>();
+ distances.add(distance);
+ sequence.put("distances", distances);
+ // don't re-visit the emptyTokenSequence node
+ visited.add(distanceNode.getChild(0));
+ }
+ putIntoSuperObject(sequence);
+ objectStack.push(sequence);
+ stackedObjects++;
+ }
- private void processToken(ParseTree node) {
- LinkedHashMap<String,Object> token = CqlfObjectGenerator.makeToken();
- // handle negation
- List<ParseTree> negations = getChildrenWithCat(node, "!");
- boolean negated = false;
- boolean isRegex = false;
- if (negations.size() % 2 == 1) negated = true;
- if (getNodeCat(node.getChild(0)).equals("key")) {
- // no 'term' child, but direct key specification: process here
- LinkedHashMap<String,Object> term = CqlfObjectGenerator.makeTerm();
+ @SuppressWarnings("unchecked")
+ /**
+ * empty tokens at beginning/end of sequence
+ * @param node
+ */
+ private void processEmptyTokenSequence(ParseTree node) {
+ Integer[] minmax = parseEmptySegments(node);
+ // object will be either a repetition group or a single empty
+ // token
+ LinkedHashMap<String, Object> object;
+ LinkedHashMap<String, Object> emptyToken =
+ CqlfObjectGenerator.makeToken();
+ if (minmax[0] != 1 || minmax[1] == null || minmax[1] != 1) {
+ object = CqlfObjectGenerator.makeRepetition(minmax[0], minmax[1]);
+ ((ArrayList<Object>) object.get("operands")).add(emptyToken);
+ }
+ else {
+ object = emptyToken;
+ }
+ putIntoSuperObject(object);
+ objectStack.push(object);
+ stackedObjects++;
+ }
- String key = node.getChild(0).getText();
- if (getNodeCat(node.getChild(0).getChild(0)).equals("regex")) {
- isRegex = true;
- term.put("type", "type:regex");
- key = key.substring(1,key.length()-1);
- }
- term.put("layer", "orth");
- term.put("key", key);
- String matches = negated ? "ne" : "eq";
- term.put("match", "match:"+matches);
- ParseTree flagNode = getFirstChildWithCat(node, "flag");
- if (flagNode != null) {
- // substring removes leading slash '/'
- String flag = getNodeCat(flagNode.getChild(0)).substring(1);
- if (flag.contains("i")) term.put("caseInsensitive", true);
- else if (flag.contains("I")) term.put("caseInsensitive", false);
- if (flag.contains("x")) {
- term.put("type", "type:regex");
- if (!isRegex) {
- key = QueryUtils.escapeRegexSpecialChars(key);
- }
- term.put("key", ".*?"+key+".*?"); // overwrite key
- }
- }
- token.put("wrap", term);
- } else {
- // child is 'term' or 'termGroup' -> process in extra method
- LinkedHashMap<String,Object> termOrTermGroup =
- parseTermOrTermGroup(node.getChild(1), negated);
- token.put("wrap", termOrTermGroup);
- }
- putIntoSuperObject(token);
- visited.add(node.getChild(0));
- visited.add(node.getChild(2));
- }
-
+ private void processEmptyTokenSequenceClass(ParseTree node) {
+ int classId = 1;
+ if (hasChild(node, "spanclass_id")) {
+ classId = Integer.parseInt(node.getChild(1).getChild(0)
+ .toStringTree(parser));
+ }
+ LinkedHashMap<String, Object> classGroup =
+ CqlfObjectGenerator.makeSpanClass(classId, false);
+ putIntoSuperObject(classGroup);
+ objectStack.push(classGroup);
+ stackedObjects++;
+ }
- @SuppressWarnings("unchecked")
- private void processAlignment(ParseTree node) {
- LinkedHashMap<String,Object> alignClass = CqlfObjectGenerator.makeSpanClass(++classCounter,false);
- LinkedHashMap<String,Object> metaMap = (LinkedHashMap<String, Object>) requestMap.get("meta");
- if (metaMap.containsKey("alignment")) {
- ArrayList<Integer> alignedClasses = new ArrayList<Integer>();
- try {
- alignedClasses = (ArrayList<Integer>) metaMap.get("alignment");
- } catch (ClassCastException cce) {
- alignedClasses.add((Integer) metaMap.get("alignment"));
- }
- alignedClasses.add(classCounter);
- metaMap.put("alignment", alignedClasses);
- } else {
- metaMap.put("alignment", classCounter);
- }
+ private void processToken(ParseTree node) {
+ LinkedHashMap<String, Object> token = CqlfObjectGenerator.makeToken();
+ // handle negation
+ List<ParseTree> negations = getChildrenWithCat(node, "!");
+ boolean negated = false;
+ boolean isRegex = false;
+ if (negations.size() % 2 == 1)
+ negated = true;
+ if (getNodeCat(node.getChild(0)).equals("key")) {
+ // no 'term' child, but direct key specification: process here
+ LinkedHashMap<String, Object> term = CqlfObjectGenerator.makeTerm();
+ String key = node.getChild(0).getText();
+ if (getNodeCat(node.getChild(0).getChild(0)).equals("regex")) {
+ isRegex = true;
+ term.put("type", "type:regex");
+ key = key.substring(1, key.length() - 1);
+ }
+ term.put("layer", "orth");
+ term.put("key", key);
+ String matches = negated ? "ne" : "eq";
+ term.put("match", "match:" + matches);
+ ParseTree flagNode = getFirstChildWithCat(node, "flag");
+ if (flagNode != null) {
+ // substring removes leading slash '/'
+ String flag = getNodeCat(flagNode.getChild(0)).substring(1);
+ if (flag.contains("i"))
+ term.put("caseInsensitive", true);
+ else if (flag.contains("I"))
+ term.put("caseInsensitive", false);
+ if (flag.contains("x")) {
+ term.put("type", "type:regex");
+ if (!isRegex) {
+ key = QueryUtils.escapeRegexSpecialChars(key);
+ }
+ // overwrite key
+ term.put("key", ".*?" + key + ".*?");
+ }
+ }
+ token.put("wrap", term);
+ }
+ else {
+ // child is 'term' or 'termGroup' -> process in extra method
+ LinkedHashMap<String, Object> termOrTermGroup =
+ parseTermOrTermGroup(node.getChild(1), negated);
+ token.put("wrap", termOrTermGroup);
+ }
+ putIntoSuperObject(token);
+ visited.add(node.getChild(0));
+ visited.add(node.getChild(2));
+ }
- putIntoSuperObject(alignClass);
- objectStack.push(alignClass);
- stackedObjects++;
- }
+ @SuppressWarnings("unchecked")
+ private void processAlignment(ParseTree node) {
+ LinkedHashMap<String, Object> alignClass =
+ CqlfObjectGenerator.makeSpanClass(++classCounter, false);
+ LinkedHashMap<String, Object> metaMap =
+ (LinkedHashMap<String, Object>) requestMap.get("meta");
+ if (metaMap.containsKey("alignment")) {
+ ArrayList<Integer> alignedClasses = new ArrayList<Integer>();
+ try {
+ alignedClasses = (ArrayList<Integer>) metaMap.get("alignment");
+ }
+ catch (ClassCastException cce) {
+ alignedClasses.add((Integer) metaMap.get("alignment"));
+ }
+ alignedClasses.add(classCounter);
+ metaMap.put("alignment", alignedClasses);
+ }
+ else {
+ metaMap.put("alignment", classCounter);
+ }
- private void processSpan(ParseTree node) {
- List<ParseTree> negations = getChildrenWithCat(node, "!");
- boolean negated = false;
- if (negations.size() % 2 == 1) negated = true;
- LinkedHashMap<String,Object> span = CqlfObjectGenerator.makeSpan();
- ParseTree keyNode = getFirstChildWithCat(node, "key");
- ParseTree layerNode = getFirstChildWithCat(node, "layer");
- ParseTree foundryNode = getFirstChildWithCat(node, "foundry");
- ParseTree termOpNode = getFirstChildWithCat(node, "termOp");
- ParseTree termNode = getFirstChildWithCat(node, "term");
- ParseTree termGroupNode = getFirstChildWithCat(node, "termGroup");
- if (foundryNode != null) span.put("foundry", foundryNode.getText());
- if (layerNode != null) {
- String layer = layerNode.getText();
- if (layer.equals("base")) layer="lemma";
- span.put("layer", layer);
- }
- span.put("key", keyNode.getText());
- if (termOpNode != null) {
- String termOp = termOpNode.getText();
- if (termOp.equals("==")) span.put("match", "match:eq");
- else if (termOp.equals("!=")) span.put("match", "match:ne");
- }
- if (termNode != null) {
- LinkedHashMap<String,Object> termOrTermGroup =
- parseTermOrTermGroup(termNode, negated, "span");
- span.put("attr", termOrTermGroup);
- }
- if (termGroupNode != null) {
- LinkedHashMap<String,Object> termOrTermGroup =
- parseTermOrTermGroup(termGroupNode, negated, "span");
- span.put("attr", termOrTermGroup);
- }
- putIntoSuperObject(span);
- objectStack.push(span);
- stackedObjects++;
- }
+ putIntoSuperObject(alignClass);
+ objectStack.push(alignClass);
+ stackedObjects++;
+ }
- private void processDisjunction(ParseTree node) {
- LinkedHashMap<String,Object> disjunction = CqlfObjectGenerator.makeGroup("or");
- putIntoSuperObject(disjunction);
- objectStack.push(disjunction);
- stackedObjects++;
- }
+ private void processSpan(ParseTree node) {
+ List<ParseTree> negations = getChildrenWithCat(node, "!");
+ boolean negated = false;
+ if (negations.size() % 2 == 1)
+ negated = true;
+ LinkedHashMap<String, Object> span = CqlfObjectGenerator.makeSpan();
+ ParseTree keyNode = getFirstChildWithCat(node, "key");
+ ParseTree layerNode = getFirstChildWithCat(node, "layer");
+ ParseTree foundryNode = getFirstChildWithCat(node, "foundry");
+ ParseTree termOpNode = getFirstChildWithCat(node, "termOp");
+ ParseTree termNode = getFirstChildWithCat(node, "term");
+ ParseTree termGroupNode = getFirstChildWithCat(node, "termGroup");
+ if (foundryNode != null)
+ span.put("foundry", foundryNode.getText());
+ if (layerNode != null) {
+ String layer = layerNode.getText();
+ if (layer.equals("base"))
+ layer = "lemma";
+ span.put("layer", layer);
+ }
+ span.put("key", keyNode.getText());
+ if (termOpNode != null) {
+ String termOp = termOpNode.getText();
+ if (termOp.equals("=="))
+ span.put("match", "match:eq");
+ else if (termOp.equals("!="))
+ span.put("match", "match:ne");
+ }
+ if (termNode != null) {
+ LinkedHashMap<String, Object> termOrTermGroup =
+ parseTermOrTermGroup(termNode, negated, "span");
+ span.put("attr", termOrTermGroup);
+ }
+ if (termGroupNode != null) {
+ LinkedHashMap<String, Object> termOrTermGroup =
+ parseTermOrTermGroup(termGroupNode, negated, "span");
+ span.put("attr", termOrTermGroup);
+ }
+ putIntoSuperObject(span);
+ objectStack.push(span);
+ stackedObjects++;
+ }
- private void processPosition(ParseTree node) {
- LinkedHashMap<String,Object> position = parseFrame(node.getChild(0));
- putIntoSuperObject(position);
- objectStack.push(position);
- stackedObjects++;
- }
+ private void processDisjunction(ParseTree node) {
+ LinkedHashMap<String, Object> disjunction =
+ CqlfObjectGenerator.makeGroup("or");
+ putIntoSuperObject(disjunction);
+ objectStack.push(disjunction);
+ stackedObjects++;
+ }
- private void processRelation(ParseTree node) {
- LinkedHashMap<String, Object> relationGroup = CqlfObjectGenerator.makeGroup("relation");
- LinkedHashMap<String, Object> relation = CqlfObjectGenerator.makeRelation();
- relationGroup.put("relation", relation);
- if (node.getChild(0).getText().equals("dominates")) {
- relation.put("layer", "c");
- }
- ParseTree relSpec = getFirstChildWithCat(node, "relSpec");
- ParseTree repetition = getFirstChildWithCat(node, "repetition");
- if (relSpec != null) {
- ParseTree foundry = getFirstChildWithCat(relSpec, "foundry");
- ParseTree layer = getFirstChildWithCat(relSpec, "layer");
- ParseTree key = getFirstChildWithCat(relSpec, "key");
- if (foundry != null) relation.put("foundry", foundry.getText());
- if (layer != null) relation.put("layer", layer.getText());
- if (key != null) relation.put("key", key.getText());
- }
- if (repetition != null) {
- Integer[] minmax = parseRepetition(repetition);
- relation.put("boundary", CqlfObjectGenerator.makeBoundary(minmax[0], minmax[1]));
- }
- putIntoSuperObject(relationGroup);
- objectStack.push(relationGroup);
- stackedObjects++;
- }
+ private void processPosition(ParseTree node) {
+ LinkedHashMap<String, Object> position = parseFrame(node.getChild(0));
+ putIntoSuperObject(position);
+ objectStack.push(position);
+ stackedObjects++;
+ }
- private void processSpanclass(ParseTree node) {
- // Step I: get info
- int classId = 1;
- if (getNodeCat(node.getChild(1)).equals("spanclass_id")) {
- String ref = node.getChild(1).getChild(0).toStringTree(parser);
- try {
- classId = Integer.parseInt(ref);
- } catch (NumberFormatException e) {
- String msg = "The specified class reference in the " +
- "focus/split-Operator is not a number: " + ref;
- log.error(msg);
- addError(StatusCodes.UNDEFINED_CLASS_REFERENCE, msg);
- }
- // only allow class id up to 127
- if (classId > 127) {
- addWarning("Only class IDs up to 127 are allowed. Your class "+classId+" has been set back to 127. "
- + "Check for possible conflict with other classes.");
- classId = 127;
- }
- }
- LinkedHashMap<String, Object> classGroup = CqlfObjectGenerator.makeSpanClass(classId, false);
- putIntoSuperObject(classGroup);
- objectStack.push(classGroup);
- stackedObjects++;
-
- }
+ private void processRelation(ParseTree node) {
+ LinkedHashMap<String, Object> relationGroup =
+ CqlfObjectGenerator.makeGroup("relation");
+ LinkedHashMap<String, Object> relation =
+ CqlfObjectGenerator.makeRelation();
+ relationGroup.put("relation", relation);
+ if (node.getChild(0).getText().equals("dominates")) {
+ relation.put("layer", "c");
+ }
+ ParseTree relSpec = getFirstChildWithCat(node, "relSpec");
+ ParseTree repetition = getFirstChildWithCat(node, "repetition");
+ if (relSpec != null) {
+ ParseTree foundry = getFirstChildWithCat(relSpec, "foundry");
+ ParseTree layer = getFirstChildWithCat(relSpec, "layer");
+ ParseTree key = getFirstChildWithCat(relSpec, "key");
+ if (foundry != null)
+ relation.put("foundry", foundry.getText());
+ if (layer != null)
+ relation.put("layer", layer.getText());
+ if (key != null)
+ relation.put("key", key.getText());
+ }
+ if (repetition != null) {
+ Integer[] minmax = parseRepetition(repetition);
+ relation.put("boundary",
+ CqlfObjectGenerator.makeBoundary(minmax[0], minmax[1]));
+ }
+ putIntoSuperObject(relationGroup);
+ objectStack.push(relationGroup);
+ stackedObjects++;
+ }
- private void processMatching(ParseTree node) {
- // Step I: get info
- ArrayList<Integer> classRefs = new ArrayList<Integer>();
- String classRefOp = null;
- if (getNodeCat(node.getChild(2)).equals("spanclass_id")) {
- ParseTree spanNode = node.getChild(2);
- for (int i = 0; i < spanNode.getChildCount() - 1; i++) {
- String ref = spanNode.getChild(i).getText();
- if (ref.equals("|") || ref.equals("&")) {
- classRefOp = ref.equals("|") ? "intersection" : "union";
- } else {
- try {
- int classRef = Integer.parseInt(ref);
- // only allow class id up to 127
- if (classRef > 127) {
- addWarning("Only class references up to 127 are allowed. Your reference to class "+classRef+" has been set back to 127. "
- + "Check for possible conflict with other classes.");
- classRef = 127;
- }
- classRefs.add(classRef);
- } catch (NumberFormatException e) {
- String err = "The specified class reference in the " +
- "shrink/split-Operator is not a number.";
- addError(StatusCodes.UNDEFINED_CLASS_REFERENCE, err);
- }
- }
- }
- } else {
- classRefs.add(1);
- }
- LinkedHashMap<String, Object> referenceGroup = CqlfObjectGenerator.makeReference(classRefs);
+ private void processSpanclass(ParseTree node) {
+ // Step I: get info
+ int classId = 1;
+ if (getNodeCat(node.getChild(1)).equals("spanclass_id")) {
+ String ref = node.getChild(1).getChild(0).toStringTree(parser);
+ try {
+ classId = Integer.parseInt(ref);
+ }
+ catch (NumberFormatException e) {
+ String msg = "The specified class reference in the "
+ + "focus/split-Operator is not a number: " + ref;
+ log.error(msg);
+ addError(StatusCodes.UNDEFINED_CLASS_REFERENCE, msg);
+ }
+ // only allow class id up to 127
+ if (classId > 127) {
+ addWarning("Only class IDs up to 127 are allowed. Your class "
+ + classId + " has been set back to 127. "
+ + "Check for possible conflict with other classes.");
+ classId = 127;
+ }
+ }
+ LinkedHashMap<String, Object> classGroup =
+ CqlfObjectGenerator.makeSpanClass(classId, false);
+ putIntoSuperObject(classGroup);
+ objectStack.push(classGroup);
+ stackedObjects++;
- String type = node.getChild(0).toStringTree(parser);
- // Default is focus(), if deviating catch here
- if (type.equals("split")) referenceGroup.put("operation", "operation:split");
- if (type.equals("submatch") || type.equals("shrink")) {
- String warning = "Deprecated 2014-07-24: "+type + "() as a match reducer " +
- "to a specific class is deprecated in favor of focus() and will " +
- "only be supported for 3 months after deprecation date.";
- addMessage(StatusCodes.DEPRECATED_QUERY_ELEMENT, warning);
- }
- if (classRefOp != null) {
- referenceGroup.put("classRefOp", "classRefOp:" + classRefOp);
- }
- ArrayList<Object> referenceOperands = new ArrayList<Object>();
- referenceGroup.put("operands", referenceOperands);
- // Step II: decide where to put the group
- putIntoSuperObject(referenceGroup);
- objectStack.push(referenceGroup);
- stackedObjects++;
- visited.add(node.getChild(0));
- }
+ }
- private void processSubmatch(ParseTree node) {
- LinkedHashMap<String,Object> submatch = CqlfObjectGenerator.makeReference(null);
- submatch.put("operands", new ArrayList<Object>());
- ParseTree startpos = getFirstChildWithCat(node,"startpos");
- ParseTree length = getFirstChildWithCat(node,"length");
- ArrayList<Integer> spanRef = new ArrayList<Integer>();
- spanRef.add(Integer.parseInt(startpos.getText()));
- if (length != null) {
- spanRef.add(Integer.parseInt(length.getText()));
- }
- submatch.put("spanRef", spanRef);
- putIntoSuperObject(submatch);
- objectStack.push(submatch);
- stackedObjects++;
- visited.add(node.getChild(0));
- }
+ private void processMatching(ParseTree node) {
+ // Step I: get info
+ ArrayList<Integer> classRefs = new ArrayList<Integer>();
+ String classRefOp = null;
+ if (getNodeCat(node.getChild(2)).equals("spanclass_id")) {
+ ParseTree spanNode = node.getChild(2);
+ for (int i = 0; i < spanNode.getChildCount() - 1; i++) {
+ String ref = spanNode.getChild(i).getText();
+ if (ref.equals("|") || ref.equals("&")) {
+ classRefOp = ref.equals("|") ? "intersection" : "union";
+ }
+ else {
+ try {
+ int classRef = Integer.parseInt(ref);
+ // only allow class id up to 127
+ if (classRef > 127) {
+ addWarning("Only class references up to 127 are "
+ + "allowed. Your reference to class "
+ + classRef + " has been set back to 127. "
+ + "Check for possible conflict with "
+ + "other classes.");
+ classRef = 127;
+ }
+ classRefs.add(classRef);
+ }
+ catch (NumberFormatException e) {
+ String err = "The specified class reference in the "
+ + "shrink/split-Operator is not a number.";
+ addError(StatusCodes.UNDEFINED_CLASS_REFERENCE, err);
+ }
+ }
+ }
+ }
+ else {
+ classRefs.add(1);
+ }
+ LinkedHashMap<String, Object> referenceGroup =
+ CqlfObjectGenerator.makeReference(classRefs);
- /**
- * Creates meta field in requestMap, later filled by terms
- * @param node
- */
- private void processMeta(ParseTree node) {
- LinkedHashMap<String, Object> metaFilter = new LinkedHashMap<String, Object>();
- requestMap.put("meta", metaFilter);
- metaFilter.put("@type", "korap:meta");
- }
+ String type = node.getChild(0).toStringTree(parser);
+ // Default is focus(), if deviating catch here
+ if (type.equals("split"))
+ referenceGroup.put("operation", "operation:split");
+ if (type.equals("submatch") || type.equals("shrink")) {
+ String warning = "Deprecated 2014-07-24: "
+ + type
+ + "() as a match reducer "
+ + "to a specific class is deprecated in favor of focus() and will "
+ + "only be supported for 3 months after deprecation date.";
+ addMessage(StatusCodes.DEPRECATED_QUERY_ELEMENT, warning);
+ }
+ if (classRefOp != null) {
+ referenceGroup.put("classRefOp", "classRefOp:" + classRefOp);
+ }
+ ArrayList<Object> referenceOperands = new ArrayList<Object>();
+ referenceGroup.put("operands", referenceOperands);
+ // Step II: decide where to put the group
+ putIntoSuperObject(referenceGroup);
+ objectStack.push(referenceGroup);
+ stackedObjects++;
+ visited.add(node.getChild(0));
+ }
- /**
- * NB: requires that parent is not 'position'!
- * @param node
- */
- private void processWithin(ParseTree node) {
- ParseTree domainNode = node.getChild(2);
- String domain = getNodeCat(domainNode);
- LinkedHashMap<String, Object> curObject =
- (LinkedHashMap<String, Object>) objectStack.getFirst();
- curObject.put("within", domain);
- visited.add(node.getChild(0));
- visited.add(node.getChild(1));
- visited.add(domainNode);
- }
+ private void processSubmatch(ParseTree node) {
+ LinkedHashMap<String, Object> submatch =
+ CqlfObjectGenerator.makeReference(null);
+ submatch.put("operands", new ArrayList<Object>());
+ ParseTree startpos = getFirstChildWithCat(node, "startpos");
+ ParseTree length = getFirstChildWithCat(node, "length");
+ ArrayList<Integer> spanRef = new ArrayList<Integer>();
+ spanRef.add(Integer.parseInt(startpos.getText()));
+ if (length != null) {
+ spanRef.add(Integer.parseInt(length.getText()));
+ }
+ submatch.put("spanRef", spanRef);
+ putIntoSuperObject(submatch);
+ objectStack.push(submatch);
+ stackedObjects++;
+ visited.add(node.getChild(0));
+ }
- /**
- * Parses a repetition node
- * @param node
- * @return A two-element array, of which the first element is an int representing
- * the minimal number of repetitions of the quantified element, and the second
- * element representing the maximal number of repetitions
- */
- private Integer[] parseRepetition(ParseTree node) {
- Integer min = 0, max = 0;
- boolean maxInfinite = false;
- // (repetition) node can be of two types: 'kleene' or 'range'
- ParseTree repetitionTypeNode = node.getChild(0);
- String repetitionType = getNodeCat(repetitionTypeNode);
- if (repetitionType.equals("kleene")) {
- // kleene operators (+ and *) as well as optionality (?)
- String kleeneOp = repetitionTypeNode.getText();
- if (kleeneOp.equals("*")) {
- maxInfinite = true;
- } else if (kleeneOp.equals("+")) {
- min = 1;
- maxInfinite = true;
- } if (kleeneOp.equals("?")) {
- max = 1;
- }
- } else {
- // Range node of form "{ min , max }" or "{ max }" or "{ , max }" or "{ min , }"
- ParseTree minNode = getFirstChildWithCat(repetitionTypeNode, "min");
- ParseTree maxNode = getFirstChildWithCat(repetitionTypeNode, "max");
- if (maxNode!=null) max = Integer.parseInt(maxNode.getText());
- else maxInfinite = true;
- // min is optional: if not specified, min = max
- if (minNode!=null) min = Integer.parseInt(minNode.getText());
- else if (hasChild(repetitionTypeNode, ",")) min = 0;
- else {
- min = max;
-// warnings.add("Your query contains a segment of the form {n}, where n is some number. This expression is ambiguous. "
-// + "It could mean a repetition (\"Repeat the previous element n times!\") or a word form that equals the number, "
-// + "enclosed by a \"class\" (which is denoted by braces like '{x}', see the documentation on classes)."
-// + "KorAP has by default interpreted the segment as a repetition statement. If you want to express the"
-// + "number as a word form inside a class, use the non-shorthand form {[orth=n]}.");
- }
- }
- if (maxInfinite) {
- max = null;
- }
- return new Integer[]{min,max};
- }
+ /**
+ * Creates meta field in requestMap, later filled by terms
+ *
+ * @param node
+ */
+ private void processMeta(ParseTree node) {
+ LinkedHashMap<String, Object> metaFilter = new LinkedHashMap<String, Object>();
+ requestMap.put("meta", metaFilter);
+ metaFilter.put("@type", "korap:meta");
+ }
- private LinkedHashMap<String,Object> parseFrame(ParseTree node) {
- String operator = node.toStringTree(parser).toLowerCase();
- String[] frames = new String[]{""};
- String[] classRefCheck = new String[]{"classRefCheck:includes"};
- switch (operator) {
- case "contains":
- frames = new String[]{"frames:contains"};
- break;
- case "matches":
- frames = new String[]{"frames:matches"};
- break;
- case "startswith":
- frames = new String[]{"frames:startswith"};
- break;
- case "endswith":
- frames = new String[]{"frames:endswith"};
- break;
- case "overlaps":
- frames = new String[]{"frames:overlapsLeft","frames:overlapsRight"};
- classRefCheck = new String[]{"classRefCheck:intersects"};
- break;
- }
- return CqlfObjectGenerator.makePosition(frames,classRefCheck);
- }
+ /**
+ * NB: requires that parent is not 'position'!
+ *
+ * @param node
+ */
+ private void processWithin(ParseTree node) {
+ ParseTree domainNode = node.getChild(2);
+ String domain = getNodeCat(domainNode);
+ LinkedHashMap<String, Object> curObject = (LinkedHashMap<String, Object>) objectStack
+ .getFirst();
+ curObject.put("within", domain);
+ visited.add(node.getChild(0));
+ visited.add(node.getChild(1));
+ visited.add(domainNode);
+ }
+ /**
+ * Parses a repetition node
+ *
+ * @param node
+ * @return A two-element array, of which the first element is an
+ * int representing the minimal number of repetitions of
+ * the quantified element, and the second element
+ * representing the maximal number of repetitions
+ */
+ private Integer[] parseRepetition(ParseTree node) {
+ Integer min = 0, max = 0;
+ boolean maxInfinite = false;
+ // (repetition) node can be of two types: 'kleene' or 'range'
+ ParseTree repetitionTypeNode = node.getChild(0);
+ String repetitionType = getNodeCat(repetitionTypeNode);
+ if (repetitionType.equals("kleene")) {
+ // kleene operators (+ and *) as well as optionality (?)
+ String kleeneOp = repetitionTypeNode.getText();
+ if (kleeneOp.equals("*")) {
+ maxInfinite = true;
+ }
+ else if (kleeneOp.equals("+")) {
+ min = 1;
+ maxInfinite = true;
+ }
+ if (kleeneOp.equals("?")) {
+ max = 1;
+ }
+ }
+ else {
+ // Range node of form "{ min , max }" or "{ max }" or
+ // "{ , max }" or "{ min , }"
+ ParseTree minNode = getFirstChildWithCat(repetitionTypeNode, "min");
+ ParseTree maxNode = getFirstChildWithCat(repetitionTypeNode, "max");
+ if (maxNode != null)
+ max = Integer.parseInt(maxNode.getText());
+ else
+ maxInfinite = true;
+ // min is optional: if not specified, min = max
+ if (minNode != null)
+ min = Integer.parseInt(minNode.getText());
+ else if (hasChild(repetitionTypeNode, ","))
+ min = 0;
+ else {
+ min = max;
+// addWarning("Your query contains a segment of the form {n}, where n is some number. This expression is ambiguous. "
+// + "It could mean a repetition (\"Repeat the previous element n times!\") or a word form that equals the number, "
+// + "enclosed by a \"class\" (which is denoted by braces like '{x}', see the documentation on classes)."
+// + "KorAP has by default interpreted the segment as a repetition statement. If you want to express the"
+// + "number as a word form inside a class, use the non-shorthand form {[orth=n]}.");
+ }
+ }
+ if (maxInfinite) {
+ max = null;
+ }
+ return new Integer[] { min, max };
+ }
- private LinkedHashMap<String, Object> parseTermOrTermGroup(
- ParseTree node, boolean negated) {
- return parseTermOrTermGroup(node, negated, "token");
- }
+ private LinkedHashMap<String, Object> parseFrame(ParseTree node) {
+ String operator = node.toStringTree(parser).toLowerCase();
+ String[] frames = new String[] { "" };
+ String[] classRefCheck = new String[] { "classRefCheck:includes" };
+ switch (operator) {
+ case "contains":
+ frames = new String[] { "frames:contains" };
+ break;
+ case "matches":
+ frames = new String[] { "frames:matches" };
+ break;
+ case "startswith":
+ frames = new String[] { "frames:startswith" };
+ break;
+ case "endswith":
+ frames = new String[] { "frames:endswith" };
+ break;
+ case "overlaps":
+ frames = new String[] { "frames:overlapsLeft",
+ "frames:overlapsRight" };
+ classRefCheck = new String[] { "classRefCheck:intersects" };
+ break;
+ }
+ return CqlfObjectGenerator.makePosition(frames, classRefCheck);
+ }
- /**
- * Parses a (term) or (termGroup) node
- * @param node
- * @param negatedGlobal Indicates whether the term/termGroup is globally negated, e.g. through a negation
- * operator preceding the related token like "![base=foo]". Global negation affects the term's "match" parameter.
- * @return A term or termGroup object, depending on input
- */
- @SuppressWarnings("unchecked")
- private LinkedHashMap<String, Object> parseTermOrTermGroup(ParseTree node, boolean negatedGlobal, String mode) {
- String nodeCat = getNodeCat(node);
- if (nodeCat.equals("term")) {
- String key = null;
- LinkedHashMap<String,Object> term = CqlfObjectGenerator.makeTerm();
- // handle negation
- boolean negated = negatedGlobal;
- boolean isRegex = false;
- List<ParseTree> negations = getChildrenWithCat(node, "!");
- if (negations.size() % 2 == 1) negated = !negated;
- // retrieve possible nodes
- ParseTree keyNode = getFirstChildWithCat(node, "key");
- ParseTree valueNode = getFirstChildWithCat(node, "value");
- ParseTree layerNode = getFirstChildWithCat(node, "layer");
- ParseTree foundryNode = getFirstChildWithCat(node, "foundry");
- ParseTree termOpNode = getFirstChildWithCat(node, "termOp");
- ParseTree flagNode = getFirstChildWithCat(node, "flag");
- // process foundry
- if (foundryNode != null) term.put("foundry", foundryNode.getText());
- // process layer: map "base" -> "lemma"
- if (layerNode != null) {
- String layer = layerNode.getText();
- if (layer.equals("base")) layer="lemma";
- if (mode.equals("span")) term.put("key", layer);
- else term.put("layer", layer);
- }
- // process key: 'normal' or regex?
- key = keyNode.getText();
- if (getNodeCat(keyNode.getChild(0)).equals("regex")) {
- isRegex = true;
- term.put("type", "type:regex");
- key = key.substring(1, key.length()-1); // remove leading and trailing quotes
- }
- if (mode.equals("span")) term.put("value", key);
- else term.put("key", key);
- // process value
- if (valueNode != null) term.put("value", valueNode.getText());
- // process operator ("match" property)
- if (termOpNode != null) {
- String termOp = termOpNode.getText();
- negated = termOp.contains("!") ? !negated : negated;
- if (!negated) term.put("match", "match:eq");
- else term.put("match", "match:ne");
- }
- // process possible flags
- if (flagNode != null) {
- String flag = getNodeCat(flagNode.getChild(0)).substring(1); //substring removes leading slash '/'
- if (flag.contains("i")) term.put("caseInsensitive", true);
- else if (flag.contains("I")) term.put("caseInsensitive", false);
- if (flag.contains("x")) {
- if (!isRegex) {
- key = QueryUtils.escapeRegexSpecialChars(key);
- }
- term.put("key", ".*?"+key+".*?"); // flag 'x' allows submatches: overwrite key with appended .*?
- term.put("type", "type:regex");
- }
- }
- return term;
- } else if (nodeCat.equals("termGroup")) {
- // For termGroups, establish a boolean relation between operands and recursively call this function with
- // the term or termGroup operands
- LinkedHashMap<String,Object> termGroup = null;
- ParseTree leftOp = null;
- ParseTree rightOp = null;
- // check for leading/trailing parantheses
- if (!getNodeCat(node.getChild(0)).equals("(")) leftOp = node.getChild(0);
- else leftOp = node.getChild(1);
- if (!getNodeCat(node.getChild(node.getChildCount()-1)).equals(")")) rightOp = node.getChild(node.getChildCount()-1);
- else rightOp = node.getChild(node.getChildCount()-2);
- // establish boolean relation
- ParseTree boolOp = getFirstChildWithCat(node, "boolOp");
- String operator = boolOp.getText().equals("&") ? "and" : "or";
- termGroup = CqlfObjectGenerator.makeTermGroup(operator);
- ArrayList<Object> operands = (ArrayList<Object>) termGroup.get("operands");
- // recursion with left/right operands
- operands.add(parseTermOrTermGroup(leftOp, negatedGlobal, mode));
- operands.add(parseTermOrTermGroup(rightOp, negatedGlobal, mode));
- return termGroup;
- }
- return null;
- }
+ private LinkedHashMap<String, Object> parseTermOrTermGroup(ParseTree node,
+ boolean negated) {
+ return parseTermOrTermGroup(node, negated, "token");
+ }
- /**
- * Puts an object into the operands list of its governing (or "super") object which had been placed on the
- * {@link #objectStack} before and is still on top of the stack. If this is the top object of the tree, it is put there
- * instead of into some (non-existent) operand stack.
- * @param object The object to be inserted
- */
- private void putIntoSuperObject(LinkedHashMap<String, Object> object) {
- putIntoSuperObject(object, 0);
- }
+ /**
+ * Parses a (term) or (termGroup) node
+ *
+ * @param node
+ * @param negatedGlobal
+ * Indicates whether the term/termGroup is globally
+ * negated, e.g. through a negation operator preceding
+ * the related token like "![base=foo]". Global
+ * negation affects the term's "match" parameter.
+ * @return A term or termGroup object, depending on input
+ */
+ @SuppressWarnings("unchecked")
+ private LinkedHashMap<String, Object> parseTermOrTermGroup(ParseTree node,
+ boolean negatedGlobal, String mode) {
+ String nodeCat = getNodeCat(node);
+ if (nodeCat.equals("term")) {
+ String key = null;
+ LinkedHashMap<String, Object> term =
+ CqlfObjectGenerator.makeTerm();
+ // handle negation
+ boolean negated = negatedGlobal;
+ boolean isRegex = false;
+ List<ParseTree> negations = getChildrenWithCat(node, "!");
+ if (negations.size() % 2 == 1)
+ negated = !negated;
+ // retrieve possible nodes
+ ParseTree keyNode = getFirstChildWithCat(node, "key");
+ ParseTree valueNode = getFirstChildWithCat(node, "value");
+ ParseTree layerNode = getFirstChildWithCat(node, "layer");
+ ParseTree foundryNode = getFirstChildWithCat(node, "foundry");
+ ParseTree termOpNode = getFirstChildWithCat(node, "termOp");
+ ParseTree flagNode = getFirstChildWithCat(node, "flag");
+ // process foundry
+ if (foundryNode != null)
+ term.put("foundry", foundryNode.getText());
+ // process layer: map "base" -> "lemma"
+ if (layerNode != null) {
+ String layer = layerNode.getText();
+ if (layer.equals("base"))
+ layer = "lemma";
+ if (mode.equals("span"))
+ term.put("key", layer);
+ else
+ term.put("layer", layer);
+ }
+ // process key: 'normal' or regex?
+ key = keyNode.getText();
+ if (getNodeCat(keyNode.getChild(0)).equals("regex")) {
+ isRegex = true;
+ term.put("type", "type:regex");
+ // remove leading and trailing quotes
+ key = key.substring(1, key.length() - 1);
+ }
+ if (mode.equals("span"))
+ term.put("value", key);
+ else
+ term.put("key", key);
+ // process value
+ if (valueNode != null)
+ term.put("value", valueNode.getText());
+ // process operator ("match" property)
+ if (termOpNode != null) {
+ String termOp = termOpNode.getText();
+ negated = termOp.contains("!") ? !negated : negated;
+ if (!negated)
+ term.put("match", "match:eq");
+ else
+ term.put("match", "match:ne");
+ }
+ // process possible flags
+ if (flagNode != null) {
+ // substring removes leading slash
+ String flag = getNodeCat(flagNode.getChild(0)).substring(1);
+ if (flag.contains("i"))
+ term.put("caseInsensitive", true);
+ else if (flag.contains("I"))
+ term.put("caseInsensitive", false);
+ if (flag.contains("x")) {
+ if (!isRegex) {
+ key = QueryUtils.escapeRegexSpecialChars(key);
+ }
+ // flag 'x' allows submatches:
+ // overwrite key with appended .*?
+ term.put("key", ".*?" + key + ".*?"); //
+ term.put("type", "type:regex");
+ }
+ }
+ return term;
+ }
+ else if (nodeCat.equals("termGroup")) {
+ // For termGroups, establish a boolean relation between
+ // operands and recursively call this function with
+ // the term or termGroup operands
+ LinkedHashMap<String, Object> termGroup = null;
+ ParseTree leftOp = null;
+ ParseTree rightOp = null;
+ // check for leading/trailing parantheses
+ if (!getNodeCat(node.getChild(0)).equals("("))
+ leftOp = node.getChild(0);
+ else
+ leftOp = node.getChild(1);
+ if (!getNodeCat(node.getChild(node.getChildCount() - 1))
+ .equals(")"))
+ rightOp = node.getChild(node.getChildCount() - 1);
+ else
+ rightOp = node.getChild(node.getChildCount() - 2);
+ // establish boolean relation
+ ParseTree boolOp = getFirstChildWithCat(node, "boolOp");
+ String operator = boolOp.getText().equals("&") ? "and" : "or";
+ termGroup = CqlfObjectGenerator.makeTermGroup(operator);
+ ArrayList<Object> operands = (ArrayList<Object>) termGroup
+ .get("operands");
+ // recursion with left/right operands
+ operands.add(parseTermOrTermGroup(leftOp, negatedGlobal, mode));
+ operands.add(parseTermOrTermGroup(rightOp, negatedGlobal, mode));
+ return termGroup;
+ }
+ return null;
+ }
- /**
- * Puts an object into the operands list of its governing (or "super") object which had been placed on the
- * {@link #objectStack} before. If this is the top object of the tree, it is put there
- * instead of into some (non-existent) operand stack.
- * @param object The object to be inserted
- * @param objStackPosition Indicated the position of the super object on the {@link #objectStack} (in case not the top
- * element of the stack is the super object.
- */
- @SuppressWarnings({ "unchecked" })
- private void putIntoSuperObject(LinkedHashMap<String, Object> object, int objStackPosition) {
- if (objectStack.size()>objStackPosition) {
- ArrayList<Object> topObjectOperands = (ArrayList<Object>) objectStack.get(objStackPosition).get("operands");
- topObjectOperands.add(object);
- } else {
- requestMap.put("query", object);
- }
- }
+ /**
+ * Puts an object into the operands list of its governing (or
+ * "super") object which had been placed on the
+ * {@link #objectStack} before and is still on top of the stack.
+ * If this is the top object of the tree, it is put there instead
+ * of into some (non-existent) operand stack.
+ *
+ * @param object
+ * The object to be inserted
+ */
+ private void putIntoSuperObject(LinkedHashMap<String, Object> object) {
+ putIntoSuperObject(object, 0);
+ }
- /**
- * Basically only increases the min and max counters as required by Poliqarp
- * @param distanceNode
- * @return
- */
- private Integer[] parseDistance(ParseTree distanceNode) {
- int emptyTokenSeqIndex = getNodeCat(distanceNode).equals("distance") ? 0 : 2;
- Integer[] minmax = parseEmptySegments(distanceNode.getChild(emptyTokenSeqIndex));
- Integer min = minmax[0];
- Integer max = minmax[1];
- min++;
- if (max != null) max++;
- // min = cropToMaxValue(min);
- // max = cropToMaxValue(max);
- return new Integer[]{min, max};
- }
+ /**
+ * Puts an object into the operands list of its governing (or
+ * "super") object which had been placed on the
+ * {@link #objectStack} before. If this is the top object of the
+ * tree, it is put there instead of into some (non-existent)
+ * operand stack.
+ *
+ * @param object
+ * The object to be inserted
+ * @param objStackPosition
+ * Indicated the position of the super object on the
+ * {@link #objectStack} (in case not the top element of
+ * the stack is the super object.
+ */
+ @SuppressWarnings({ "unchecked" })
+ private void putIntoSuperObject(LinkedHashMap<String, Object> object,
+ int objStackPosition) {
+ if (objectStack.size() > objStackPosition) {
+ ArrayList<Object> topObjectOperands = (ArrayList<Object>) objectStack
+ .get(objStackPosition).get("operands");
+ topObjectOperands.add(object);
+ }
+ else {
+ requestMap.put("query", object);
+ }
+ }
- private Integer[] parseEmptySegments(ParseTree emptySegments) {
- Integer min = 0;
- Integer max = 0;
- ParseTree child;
- for (int i = 0; i < emptySegments.getChildCount(); i++) {
- child = emptySegments.getChild(i);
- ParseTree nextSibling = emptySegments.getChild(i + 1);
- if (child.toStringTree(parser).equals("(emptyToken [ ])")) {
- if (nextSibling != null && getNodeCat(nextSibling).equals("repetition")) {
- Integer[] minmax = parseRepetition(nextSibling);
- min += minmax[0];
- if (minmax[1] != null) {
- max += minmax[1];
- } else {
- max = null;
- }
- } else {
- min++;
- max++;
- }
- }
- }
- // min = cropToMaxValue(min);
- // max = cropToMaxValue(max);
- return new Integer[]{min, max};
- }
+ /**
+ * Basically only increases the min and max counters as required
+ * by Poliqarp
+ *
+ * @param distanceNode
+ * @return
+ */
+ private Integer[] parseDistance(ParseTree distanceNode) {
+ int emptyTokenSeqIndex = getNodeCat(distanceNode).equals("distance") ? 0
+ : 2;
+ Integer[] minmax = parseEmptySegments(distanceNode
+ .getChild(emptyTokenSeqIndex));
+ Integer min = minmax[0];
+ Integer max = minmax[1];
+ min++;
+ if (max != null)
+ max++;
+ // min = cropToMaxValue(min);
+ // max = cropToMaxValue(max);
+ return new Integer[] { min, max };
+ }
+ private Integer[] parseEmptySegments(ParseTree emptySegments) {
+ Integer min = 0;
+ Integer max = 0;
+ ParseTree child;
+ for (int i = 0; i < emptySegments.getChildCount(); i++) {
+ child = emptySegments.getChild(i);
+ ParseTree nextSibling = emptySegments.getChild(i + 1);
+ if (child.toStringTree(parser).equals("(emptyToken [ ])")) {
+ if (nextSibling != null
+ && getNodeCat(nextSibling).equals("repetition")) {
+ Integer[] minmax = parseRepetition(nextSibling);
+ min += minmax[0];
+ if (minmax[1] != null) {
+ max += minmax[1];
+ }
+ else {
+ max = null;
+ }
+ }
+ else {
+ min++;
+ max++;
+ }
+ }
+ }
+ // min = cropToMaxValue(min);
+ // max = cropToMaxValue(max);
+ return new Integer[] { min, max };
+ }
- private ParserRuleContext parsePoliqarpQuery(String query) {
- Lexer lexer = new PoliqarpPlusLexer((CharStream) null);
- ParserRuleContext tree = null;
- Antlr4DescriptiveErrorListener errorListener = new Antlr4DescriptiveErrorListener(query);
- // Like p. 111
- try {
- // Tokenize input data
- ANTLRInputStream input = new ANTLRInputStream(query);
- lexer.setInputStream(input);
- CommonTokenStream tokens = new CommonTokenStream(lexer);
- parser = new PoliqarpPlusParser(tokens);
+ private ParserRuleContext parsePoliqarpQuery(String query) {
+ Lexer lexer = new PoliqarpPlusLexer((CharStream) null);
+ ParserRuleContext tree = null;
+ Antlr4DescriptiveErrorListener errorListener =
+ new Antlr4DescriptiveErrorListener(query);
+ // Like p. 111
+ try {
+ // Tokenize input data
+ ANTLRInputStream input = new ANTLRInputStream(query);
+ lexer.setInputStream(input);
+ CommonTokenStream tokens = new CommonTokenStream(lexer);
+ parser = new PoliqarpPlusParser(tokens);
- // Don't throw out erroneous stuff
- parser.setErrorHandler(new BailErrorStrategy());
- lexer.removeErrorListeners();
+ // Don't throw out erroneous stuff
+ parser.setErrorHandler(new BailErrorStrategy());
+ lexer.removeErrorListeners();
lexer.addErrorListener(errorListener);
parser.removeErrorListeners();
parser.addErrorListener(errorListener);
- // Get starting rule from parser
- Method startRule = PoliqarpPlusParser.class.getMethod("request");
- tree = (ParserRuleContext) startRule.invoke(parser, (Object[]) null);
- }
- // Some things went wrong ...
- catch (Exception e) {
- log.error("Could not parse query. Please make sure it is well-formed.");
- log.error(errorListener.generateFullErrorMsg().toString());
- addError(errorListener.generateFullErrorMsg());
- }
- return tree;
- }
+ // Get starting rule from parser
+ Method startRule = PoliqarpPlusParser.class.getMethod("request");
+ tree =
+ (ParserRuleContext) startRule.invoke(parser, (Object[]) null);
+ }
+ // Some things went wrong ...
+ catch (Exception e) {
+ log.error("Could not parse query. "
+ + "Please make sure it is well-formed.");
+ log.error(errorListener.generateFullErrorMsg().toString());
+ addError(errorListener.generateFullErrorMsg());
+ }
+ return tree;
+ }
}
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 9760854..e056c30 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
@@ -19,22 +19,22 @@
* @author bingel, hanl
*/
public class QuerySerializer {
-
- public enum QueryLanguage {
- POLIQARPPLUS, ANNIS, COSMAS2, CQL, CQP
- }
-
- static HashMap<String, Class<? extends AbstractQueryProcessor>> qlProcessorAssignment;
- static {
- qlProcessorAssignment = new HashMap<String, Class<? extends AbstractQueryProcessor>>();
- qlProcessorAssignment.put("poliqarpplus", PoliqarpPlusQueryProcessor.class);
- qlProcessorAssignment.put("cosmas2", Cosmas2QueryProcessor.class);
- qlProcessorAssignment.put("annis", AnnisQueryProcessor.class);
- qlProcessorAssignment.put("cql", CqlQueryProcessor.class);
- }
-
-
+ public enum QueryLanguage {
+ POLIQARPPLUS, ANNIS, COSMAS2, CQL, CQP
+ }
+
+ static HashMap<String, Class<? extends AbstractQueryProcessor>> qlProcessorAssignment;
+
+ static {
+ qlProcessorAssignment =
+ new HashMap<String, Class<? extends AbstractQueryProcessor>>();
+ qlProcessorAssignment.put("poliqarpplus", PoliqarpPlusQueryProcessor.class);
+ qlProcessorAssignment.put("cosmas2", Cosmas2QueryProcessor.class);
+ qlProcessorAssignment.put("annis", AnnisQueryProcessor.class);
+ qlProcessorAssignment.put("cql", CqlQueryProcessor.class);
+ }
+
private Logger qllogger = KorAPLogger.initiate("ql");
public static String queryLanguageVersion;
@@ -54,44 +54,55 @@
public static void main(String[] args) {
/*
* just for testing...
- */
+ */
QuerySerializer jg = new QuerySerializer();
int i = 0;
String[] queries;
if (args.length == 0) {
- queries = new String[]{
- };
- } else
- queries = new String[]{args[0]};
-
+ queries = new String[] {};
+ }
+ else
+ queries = new String[] { args[0] };
+
for (String q : queries) {
i++;
try {
System.out.println(q);
String ql = "cosmas2";
jg.setCollection("pubDate=2014");
- jg.run(q, ql, System.getProperty("user.home") + "/" + ql + "_" + i + ".jsonld");
+ jg.run(q, ql, System.getProperty("user.home") + "/" + ql + "_"
+ + i + ".jsonld");
System.out.println();
- } catch (NullPointerException npe) {
+ }
+ catch (NullPointerException npe) {
npe.printStackTrace();
System.out.println("null\n");
- } catch (JsonGenerationException e) {
+ }
+ catch (JsonGenerationException e) {
e.printStackTrace();
- } catch (JsonMappingException e) {
+ }
+ catch (JsonMappingException e) {
e.printStackTrace();
- } 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.
+ * 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 outFile The file to which the serialization is written
- * @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'.
+ * @param outFile
+ * The file to which the serialization is written
+ * @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
* @throws QueryException
*/
@@ -99,41 +110,56 @@
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("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) {
- ast = new DummyQueryProcessor();
- if (query == null || query.isEmpty()) {
- ast.addError(StatusCodes.NO_QUERY, "You did not specify a query!");
- } else if (ql == null || ql.isEmpty()){
- ast.addError(StatusCodes.NO_QUERY, "You did not specify any query language!");
- } else if (ql.equalsIgnoreCase("poliqarp")) {
+ ast = new DummyQueryProcessor();
+ if (query == null || query.isEmpty()) {
+ ast.addError(StatusCodes.NO_QUERY, "You did not specify a query!");
+ }
+ else if (ql == null || ql.isEmpty()) {
+ ast.addError(StatusCodes.NO_QUERY,
+ "You did not specify any query language!");
+ }
+ else if (ql.equalsIgnoreCase("poliqarp")) {
ast = new PoliqarpPlusQueryProcessor(query);
- } else if (ql.equalsIgnoreCase("cosmas2")) {
+ }
+ 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")) {
+ }
+ else if (ql.equalsIgnoreCase("cql")) {
if (version == null)
ast = new CqlQueryProcessor(query);
else
ast = new CqlQueryProcessor(query, version);
- } else if (ql.equalsIgnoreCase("annis")) {
+ }
+ 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_QL, ql
+ + " is not a supported query language!");
}
return this;
}
@@ -174,19 +200,16 @@
requestMap.put("warnings", warnings);
}
if (this.messages != null) {
- messages.addAll(this.messages);
+ messages.addAll(this.messages);
requestMap.put("messages", messages);
}
-
return requestMap;
}
return new HashMap<>();
}
-
- 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);
@@ -234,7 +257,8 @@
return this;
}
- public QuerySerializer setDeprCollection(CollectionQueryBuilder collections) {
+ public QuerySerializer setDeprCollection
+ (CollectionQueryBuilder collections) {
this.collection = collections.raw();
return this;
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/QueryUtils.java b/src/main/java/de/ids_mannheim/korap/query/serialize/QueryUtils.java
index 537e578..c6d1ebb 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/QueryUtils.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/QueryUtils.java
@@ -17,388 +17,252 @@
* @date 10/12/2013
*/
public class QueryUtils {
- //
- // /**
- // * Returns the category (or 'label') of the root of a ParseTree (ANTLR 4).
- // *
- // * @param node
- // * @return
- // */
- // public static String getNodeCat(ParseTree node) {
- // String nodeCat = node.toStringTree(parser);
- // Pattern p = Pattern.compile("\\((.*?)\\s"); // from opening parenthesis to 1st whitespace
- // Matcher m = p.matcher(node.toStringTree(parser));
- // if (m.find()) {
- // nodeCat = m.group(1);
- // }
- // return nodeCat;
- // }
- //
- // /**
- // * Returns the category (or 'label') of the root of a ParseTree (ANTLR 3).
- // *
- // * @param node
- // * @return
- // */
- // public static String getNodeCat(Tree node) {
- // String nodeCat = node.toStringTree();
- // Pattern p = Pattern.compile("\\((.*?)\\s"); // from opening parenthesis to 1st whitespace
- // Matcher m = p.matcher(node.toStringTree());
- // if (m.find()) {
- // nodeCat = m.group(1);
- // }
- // return nodeCat;
- // }
- //
- //
- // /**
- // * Tests whether a certain node has a child by a certain name
- // *
- // * @param node The parent node.
- // * @param childCat The category of the potential child.
- // * @return true iff one or more children belong to the specified category
- // */
- // public static boolean hasChild(Tree node, String childCat) {
- // for (int i = 0; i < node.getChildCount(); i++) {
- // if (getNodeCat(node.getChild(i)).equals(childCat)) {
- // return true;
- // }
- // }
- // return false;
- // }
- //
- // /**
- // * Tests whether a certain node has a child by a certain name
- // *
- // * @param node The parent node.
- // * @param childCat The category of the potential child.
- // * @return true iff one or more children belong to the specified category
- // */
- // public static boolean hasChild(ParseTree node, String childCat) {
- // for (int i = 0; i < node.getChildCount(); i++) {
- // if (getNodeCat(node.getChild(i)).equals(childCat)) {
- // return true;
- // }
- // }
- // return false;
- // }
- //
- // public static boolean hasDescendant(ParseTree node, String childCat) {
- // for (int i = 0; i < node.getChildCount(); i++) {
- // ParseTree child = node.getChild(i);
- // if (getNodeCat(child).equals(childCat)) {
- // return true;
- // }
- // if (hasDescendant(child, childCat)) {
- // return true;
- // }
- // }
- // return false;
- // }
- //
- // public static List<Tree> getChildrenWithCat(Tree node, String nodeCat) {
- // ArrayList<Tree> children = new ArrayList<Tree>();
- // for (int i = 0; i < node.getChildCount(); i++) {
- // if (getNodeCat(node.getChild(i)).equals(nodeCat)) {
- // children.add(node.getChild(i));
- // }
- // }
- // return children;
- // }
- //
- // public static List<ParseTree> getChildrenWithCat(ParseTree node, String nodeCat) {
- // ArrayList<ParseTree> children = new ArrayList<ParseTree>();
- // for (int i = 0; i < node.getChildCount(); i++) {
- // if (getNodeCat(node.getChild(i)).equals(nodeCat)) {
- // children.add(node.getChild(i));
- // }
- // }
- // return children;
- // }
- //
- // public static List<ParseTree> getChildren(ParseTree node) {
- // ArrayList<ParseTree> children = new ArrayList<ParseTree>();
- // for (int i = 0; i < node.getChildCount(); i++) {
- // children.add(node.getChild(i));
- // }
- // return children;
- // }
- //
- // public static Tree getFirstChildWithCat(Tree node, String nodeCat) {
- // for (int i = 0; i < node.getChildCount(); i++) {
- // if (getNodeCat(node.getChild(i)).equals(nodeCat)) {
- // return node.getChild(i);
- // }
- // }
- // return null;
- // }
- //
- // public static ParseTree getFirstChildWithCat(ParseTree node, String nodeCat) {
- // for (int i = 0; i < node.getChildCount(); i++) {
- // if (getNodeCat(node.getChild(i)).equals(nodeCat)) {
- // return node.getChild(i);
- // }
- // }
- // return null;
- // }
- //
- // /**
- // * Checks whether a node only serves as a container for another node (e.g. in (cq_segment ( cg_seg_occ ...)), the cq_segment node does not contain
- // * any information and only contains the cq_seg_occ node.
- // * @param node The node to check
- // * @return true iff the node is a container only.
- // */
- // public static boolean isContainerOnly(ParseTree node) {
- // String[] validNodeNamesArray = "cq_segment sq_segment element empty_segments".split(" ");
- // List<String> validNodeNames = Arrays.asList(validNodeNamesArray);
- // List<ParseTree> children = getChildren(node);
- // for (ParseTree child : children) {
- // if (validNodeNames.contains(getNodeCat(child))) {
- // return false;
- // }
- // }
- // return true;
- // }
- public static SimpleEntry<String, Integer> checkUnbalancedPars(String q) {
- Map<Character, Character> brackets = new HashMap<Character, Character>();
- brackets.put('[', ']');
- brackets.put('{', '}');
- brackets.put('(', ')');
- Set<Character> allChars = new HashSet<Character>();
- allChars.addAll(brackets.keySet());
- allChars.addAll(brackets.values());
- int lastOpenBracket = 0;
-
- final Stack<Character> stack = new Stack<Character>();
- for (int i = 0; i < q.length(); i++) {
- if (!allChars.contains(q.charAt(i))) continue;
- if (brackets.containsKey(q.charAt(i))) {
- stack.push(q.charAt(i));
- lastOpenBracket = i;
- } else if (stack.empty() || (q.charAt(i) != brackets.get(stack.pop()))) {
- return new SimpleEntry<String, Integer>("Parantheses/brackets unbalanced.",i);
- }
- }
- if (!stack.empty()) return new SimpleEntry<String, Integer>("Parantheses/brackets unbalanced.", lastOpenBracket);
- return null;
- }
+ public static SimpleEntry<String, Integer> checkUnbalancedPars(String q) {
+ Map<Character, Character> brackets = new HashMap<Character, Character>();
+ brackets.put('[', ']');
+ brackets.put('{', '}');
+ brackets.put('(', ')');
+ Set<Character> allChars = new HashSet<Character>();
+ allChars.addAll(brackets.keySet());
+ allChars.addAll(brackets.values());
+ int lastOpenBracket = 0;
- public static List<String> parseMorph(String stringTree) {
+ final Stack<Character> stack = new Stack<Character>();
+ for (int i = 0; i < q.length(); i++) {
+ if (!allChars.contains(q.charAt(i)))
+ continue;
+ if (brackets.containsKey(q.charAt(i))) {
+ stack.push(q.charAt(i));
+ lastOpenBracket = i;
+ }
+ else if (stack.empty()
+ || (q.charAt(i) != brackets.get(stack.pop()))) {
+ return new SimpleEntry<String, Integer>(
+ "Parantheses/brackets unbalanced.", i);
+ }
+ }
+ if (!stack.empty())
+ return new SimpleEntry<String, Integer>(
+ "Parantheses/brackets unbalanced.", lastOpenBracket);
+ return null;
+ }
- ArrayList<String> morph = new ArrayList<String>();
- return morph;
- }
+ public static List<String> parseMorph(String stringTree) {
+ ArrayList<String> morph = new ArrayList<String>();
+ return morph;
+ }
- public static String buildCypherQuery(String cypher, String ctypel, String ctyper,
- int cl, int cr, int page, int limit) {
- //todo: implies that there is only one type allowed!
- String sctypel = "", sctyper = "";
- switch (ctypel) {
- case "C":
- sctypel = "chars";
- break;
- case "T":
- sctypel = "tokens";
- break;
- }
- switch (ctyper) {
- case "C":
- sctyper = "chars";
- break;
- case "T":
- sctyper = "tokens";
- break;
- }
+ public static String buildCypherQuery(String cypher, String ctypel,
+ String ctyper, int cl, int cr, int page, int limit) {
+ // todo: implies that there is only one type allowed!
+ String sctypel = "", sctyper = "";
+ switch (ctypel) {
+ case "C":
+ sctypel = "chars";
+ break;
+ case "T":
+ sctypel = "tokens";
+ break;
+ }
+ switch (ctyper) {
+ case "C":
+ sctyper = "chars";
+ break;
+ case "T":
+ sctyper = "tokens";
+ break;
+ }
- StringBuffer buffer = new StringBuffer();
- buffer.append("<query><cypher><![CDATA[");
- buffer.append(cypher);
- buffer.append("]]></cypher>");
- buffer.append("<wordAliasPrefix>wtok_</wordAliasPrefix>");
- buffer.append("<contextColumn>sent</contextColumn>");
- buffer.append("<contextIdColumn>sid</contextIdColumn>");
- buffer.append("<textColumn>txt</textColumn>");
- buffer.append("<startIndex>");
- buffer.append(page);
- buffer.append("</startIndex>");
- buffer.append("<itemsPerPage>");
- buffer.append(limit);
- buffer.append("</itemsPerPage>");
- buffer.append("<context>");
- buffer.append("<left>");
- buffer.append("<" + sctypel + ">");
- buffer.append(cl);
- buffer.append("</" + sctypel + ">");
- buffer.append("</left>");
- buffer.append("<right>");
- buffer.append("<" + sctyper + ">");
- buffer.append(cr);
- buffer.append("</" + sctyper + ">");
- buffer.append("</right>");
- buffer.append("</context>");
- buffer.append("</query>");
- return buffer.toString();
- }
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("<query><cypher><![CDATA[");
+ buffer.append(cypher);
+ buffer.append("]]></cypher>");
+ buffer.append("<wordAliasPrefix>wtok_</wordAliasPrefix>");
+ buffer.append("<contextColumn>sent</contextColumn>");
+ buffer.append("<contextIdColumn>sid</contextIdColumn>");
+ buffer.append("<textColumn>txt</textColumn>");
+ buffer.append("<startIndex>");
+ buffer.append(page);
+ buffer.append("</startIndex>");
+ buffer.append("<itemsPerPage>");
+ buffer.append(limit);
+ buffer.append("</itemsPerPage>");
+ buffer.append("<context>");
+ buffer.append("<left>");
+ buffer.append("<" + sctypel + ">");
+ buffer.append(cl);
+ buffer.append("</" + sctypel + ">");
+ buffer.append("</left>");
+ buffer.append("<right>");
+ buffer.append("<" + sctyper + ">");
+ buffer.append(cr);
+ buffer.append("</" + sctyper + ">");
+ buffer.append("</right>");
+ buffer.append("</context>");
+ buffer.append("</query>");
+ return buffer.toString();
+ }
- public static String buildDotQuery(long sid, String graphdb_id) {
- StringBuffer b = new StringBuffer();
- b.append("<query>");
- b.append("<sentenceId>");
- b.append(sid);
- b.append("</sentenceId>");
- b.append("<gdbId>");
- b.append(graphdb_id);
- b.append("</gdbId>");
- b.append("<hls>");
- b.append("<hl>");
- b.append(40857);
- b.append("</hl>");
- b.append("<hl>");
- b.append(40856);
- b.append("</hl>");
- b.append("</hls>");
- b.append("</query>");
+ public static String buildDotQuery(long sid, String graphdb_id) {
+ StringBuffer b = new StringBuffer();
+ b.append("<query>");
+ b.append("<sentenceId>");
+ b.append(sid);
+ b.append("</sentenceId>");
+ b.append("<gdbId>");
+ b.append(graphdb_id);
+ b.append("</gdbId>");
+ b.append("<hls>");
+ b.append("<hl>");
+ b.append(40857);
+ b.append("</hl>");
+ b.append("<hl>");
+ b.append(40856);
+ b.append("</hl>");
+ b.append("</hls>");
+ b.append("</query>");
- return b.toString();
- }
+ return b.toString();
+ }
- public String buildaggreQuery(String query) {
- StringBuffer b = new StringBuffer();
- b.append("<query><cypher><![CDATA[");
- b.append(query);
- b.append("]]></cypher>");
- b.append("<columns>");
- b.append("<column agg='true' sum='false'>");
- b.append("<cypherAlias>");
- b.append("aggBy");
- b.append("</cypherAlias>");
- b.append("<displayName>");
- b.append("Aggregate");
- b.append("</displayName>");
- b.append("</column>");
+ public String buildaggreQuery(String query) {
+ StringBuffer b = new StringBuffer();
+ b.append("<query><cypher><![CDATA[");
+ b.append(query);
+ b.append("]]></cypher>");
+ b.append("<columns>");
+ b.append("<column agg='true' sum='false'>");
+ b.append("<cypherAlias>");
+ b.append("aggBy");
+ b.append("</cypherAlias>");
+ b.append("<displayName>");
+ b.append("Aggregate");
+ b.append("</displayName>");
+ b.append("</column>");
- b.append("<column agg='fals' sum='true'>");
- b.append("<cypherAlias>");
- b.append("cnt");
- b.append("</cypherAlias>");
- b.append("<displayName>");
- b.append("Count");
- b.append("</displayName>");
- b.append("</column>");
- b.append("</columns>");
+ b.append("<column agg='fals' sum='true'>");
+ b.append("<cypherAlias>");
+ b.append("cnt");
+ b.append("</cypherAlias>");
+ b.append("<displayName>");
+ b.append("Count");
+ b.append("</displayName>");
+ b.append("</column>");
+ b.append("</columns>");
- b.append("</query>");
- return b.toString();
- }
+ b.append("</query>");
+ return b.toString();
+ }
- @Deprecated
- public static Map addParameters(Map request, int page, int num, String cli, String cri,
- int cls, int crs, boolean cutoff) {
- Map ctx = new LinkedHashMap();
- List left = new ArrayList();
- left.add(cli);
- left.add(cls);
- List right = new ArrayList();
- right.add(cri);
- right.add(crs);
- ctx.put("left", left);
- ctx.put("right", right);
+ @Deprecated
+ public static Map addParameters(Map request, int page, int num, String cli,
+ String cri, int cls, int crs, boolean cutoff) {
+ Map ctx = new LinkedHashMap();
+ List left = new ArrayList();
+ left.add(cli);
+ left.add(cls);
+ List right = new ArrayList();
+ right.add(cri);
+ right.add(crs);
+ ctx.put("left", left);
+ ctx.put("right", right);
- request.put("startPage", page);
- request.put("count", num);
- request.put("context", ctx);
- request.put("cutOff", cutoff);
+ request.put("startPage", page);
+ request.put("count", num);
+ request.put("context", ctx);
+ request.put("cutOff", cutoff);
- return request;
- }
+ return request;
+ }
- public static void prepareContext(LinkedHashMap<String, Object> requestMap) {
- LinkedHashMap<String, Object> context = new LinkedHashMap<String, Object>();
+ public static void prepareContext(LinkedHashMap<String, Object> requestMap) {
+ LinkedHashMap<String, Object> context = new LinkedHashMap<String, Object>();
- LinkedHashMap<String, Object> classMap = new LinkedHashMap<String, Object>();
- LinkedHashMap<String, Object> operands = new LinkedHashMap<String, Object>();
- LinkedHashMap<String, Object> operation = new LinkedHashMap<String, Object>();
- LinkedHashMap<String, Object> frame = new LinkedHashMap<String, Object>();
- LinkedHashMap<String, Object> classRef = new LinkedHashMap<String, Object>();
- LinkedHashMap<String, Object> spanRef = new LinkedHashMap<String, Object>();
- LinkedHashMap<String, Object> classRefOp = new LinkedHashMap<String, Object>();
- LinkedHashMap<String, Object> min = new LinkedHashMap<String, Object>();
- LinkedHashMap<String, Object> max = new LinkedHashMap<String, Object>();
- LinkedHashMap<String, Object> exclude = new LinkedHashMap<String, Object>();
- LinkedHashMap<String, Object> distances = new LinkedHashMap<String, Object>();
- LinkedHashMap<String, Object> inOrder = new LinkedHashMap<String, Object>();
+ LinkedHashMap<String, Object> classMap = new LinkedHashMap<String, Object>();
+ LinkedHashMap<String, Object> operands = new LinkedHashMap<String, Object>();
+ LinkedHashMap<String, Object> operation = new LinkedHashMap<String, Object>();
+ LinkedHashMap<String, Object> frame = new LinkedHashMap<String, Object>();
+ LinkedHashMap<String, Object> classRef = new LinkedHashMap<String, Object>();
+ LinkedHashMap<String, Object> spanRef = new LinkedHashMap<String, Object>();
+ LinkedHashMap<String, Object> classRefOp = new LinkedHashMap<String, Object>();
+ LinkedHashMap<String, Object> min = new LinkedHashMap<String, Object>();
+ LinkedHashMap<String, Object> max = new LinkedHashMap<String, Object>();
+ LinkedHashMap<String, Object> exclude = new LinkedHashMap<String, Object>();
+ LinkedHashMap<String, Object> distances = new LinkedHashMap<String, Object>();
+ LinkedHashMap<String, Object> inOrder = new LinkedHashMap<String, Object>();
- operation.put("@id", "group:operation/");
- operation.put("@type", "@id");
+ operation.put("@id", "group:operation/");
+ operation.put("@type", "@id");
- classMap.put("@id", "group:class");
- classMap.put("@type", "xsd:integer");
+ classMap.put("@id", "group:class");
+ classMap.put("@type", "xsd:integer");
- operands.put("@id", "group:operands");
- operands.put("@container", "@list");
+ operands.put("@id", "group:operands");
+ operands.put("@container", "@list");
- frame.put("@id", "group:frame/");
- frame.put("@type", "@id");
+ frame.put("@id", "group:frame/");
+ frame.put("@type", "@id");
- classRef.put("@id", "group:classRef");
- classRef.put("@type", "xsd:integer");
+ classRef.put("@id", "group:classRef");
+ classRef.put("@type", "xsd:integer");
- spanRef.put("@id", "group:spanRef");
- spanRef.put("@type", "xsd:integer");
+ spanRef.put("@id", "group:spanRef");
+ spanRef.put("@type", "xsd:integer");
- classRefOp.put("@id", "group:classRefOp");
- classRefOp.put("@type", "@id");
+ classRefOp.put("@id", "group:classRefOp");
+ classRefOp.put("@type", "@id");
- min.put("@id", "boundary:min");
- min.put("@type", "xsd:integer");
+ min.put("@id", "boundary:min");
+ min.put("@type", "xsd:integer");
- max.put("@id", "boundary:max");
- max.put("@type", "xsd:integer");
+ max.put("@id", "boundary:max");
+ max.put("@type", "xsd:integer");
- exclude.put("@id", "group:exclude");
- exclude.put("@type", "xsd:boolean");
+ exclude.put("@id", "group:exclude");
+ exclude.put("@type", "xsd:boolean");
- distances.put("@id", "group:distances");
- distances.put("@container", "@list");
+ distances.put("@id", "group:distances");
+ distances.put("@container", "@list");
- inOrder.put("@id", "group:inOrder");
- inOrder.put("@type", "xsd:boolean");
+ inOrder.put("@id", "group:inOrder");
+ inOrder.put("@type", "xsd:boolean");
- context.put("korap", "http://korap.ids-mannheim.de/ns/KorAP/json-ld/v0.1/");
- context.put("boundary", "korap:boundary/");
- context.put("group", "korap:group/");
- context.put("operation", operation);
- context.put("class", classMap);
- context.put("operands", operands);
- context.put("frame", frame);
- context.put("classRef", classRef);
- context.put("spanRef", spanRef);
- context.put("classRefOp", classRefOp);
- context.put("min", min);
- context.put("max", max);
- context.put("exclude", exclude);
- context.put("distances", distances);
- context.put("inOrder", inOrder);
+ context.put("korap",
+ "http://korap.ids-mannheim.de/ns/KorAP/json-ld/v0.1/");
+ context.put("boundary", "korap:boundary/");
+ context.put("group", "korap:group/");
+ context.put("operation", operation);
+ context.put("class", classMap);
+ context.put("operands", operands);
+ context.put("frame", frame);
+ context.put("classRef", classRef);
+ context.put("spanRef", spanRef);
+ context.put("classRefOp", classRefOp);
+ context.put("min", min);
+ context.put("max", max);
+ context.put("exclude", exclude);
+ context.put("distances", distances);
+ context.put("inOrder", inOrder);
- requestMap.put("@context", context);
- }
+ requestMap.put("@context", context);
+ }
- public static String escapeRegexSpecialChars(String key) {
- key.replace("\\", "\\\\");
- Pattern p = Pattern.compile("\\.|\\^|\\$|\\||\\?|\\*|\\+|\\(|\\)|\\[|\\]|\\{|\\}");
- Matcher m = p.matcher(key);
- while (m.find()) {
- System.out.println(m.group(0));
- String match = m.group();
- System.out.println(key);
- key = m.replaceAll("\\\\"+match);
- System.out.println(" > "+key);
- }
- return key;
- }
-
+ public static String escapeRegexSpecialChars(String key) {
+ key.replace("\\", "\\\\");
+ Pattern p = Pattern
+ .compile("\\.|\\^|\\$|\\||\\?|\\*|\\+|\\(|\\)|\\[|\\]|\\{|\\}");
+ Matcher m = p.matcher(key);
+ while (m.find()) {
+ System.out.println(m.group(0));
+ String match = m.group();
+ System.out.println(key);
+ key = m.replaceAll("\\\\" + match);
+ System.out.println(" > " + key);
+ }
+ return key;
+ }
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/util/Antlr3DescriptiveErrorListener.java b/src/main/java/de/ids_mannheim/korap/query/serialize/util/Antlr3DescriptiveErrorListener.java
index 7a2d3bb..cf81273 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/util/Antlr3DescriptiveErrorListener.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/util/Antlr3DescriptiveErrorListener.java
@@ -9,81 +9,86 @@
import de.ids_mannheim.korap.query.serialize.QueryUtils;
/**
- * Custom descriptive error listener for Antlr3 grammars. Requires interface IErrorReporter to be present in
- * grammar destination (generated source directory).
+ * Custom descriptive error listener for Antlr3 grammars. Requires
+ * interface IErrorReporter to be present in grammar destination
+ * (generated source directory).
+ *
* @author Joachim Bingel (bingel@ids-mannheim.de)
*
*/
public class Antlr3DescriptiveErrorListener implements IErrorReporter {
- private String query;
- private String offendingSymbol;
- private String expected;
- private int charPosition;
+ private String query;
+ private String offendingSymbol;
+ private String expected;
+ private int charPosition;
- public Antlr3DescriptiveErrorListener(String query) {
- this.query = query;
- };
+ public Antlr3DescriptiveErrorListener (String query) {
+ this.query = query;
+ };
- @Override
- public void reportError(String error) {
- String charPositionStr = null;
- String offendingSymbol = null;
- String expected = null;
- Pattern p = Pattern.compile("line \\d+:(\\d+).* '(.+?)' expecting (.+)");
- Matcher m = p.matcher(error);
- if (m.find()) {
- charPositionStr = m.group(1);
- offendingSymbol = m.group(2);
- expected = m.group(3);
- }
- if (charPositionStr != null)
- this.charPosition = Integer.parseInt(charPositionStr);
- if (offendingSymbol != null)
- this.offendingSymbol = offendingSymbol;
- if (expected != null)
- this.expected = expected;
- }
+ @Override
+ public void reportError(String error) {
+ String charPositionStr = null;
+ String offendingSymbol = null;
+ String expected = null;
+ Pattern p = Pattern
+ .compile("line \\d+:(\\d+).* '(.+?)' expecting (.+)");
+ Matcher m = p.matcher(error);
+ if (m.find()) {
+ charPositionStr = m.group(1);
+ offendingSymbol = m.group(2);
+ expected = m.group(3);
+ }
+ if (charPositionStr != null)
+ this.charPosition = Integer.parseInt(charPositionStr);
+ if (offendingSymbol != null)
+ this.offendingSymbol = offendingSymbol;
+ if (expected != null)
+ this.expected = expected;
+ }
- public ArrayList<Object> generateFullErrorMsg() {
- ArrayList<Object> errorSpecs = new ArrayList<Object>();
- String msg = getDetailedErrorMessage();
- errorSpecs.add(StatusCodes.MALFORMED_QUERY);
- errorSpecs.add(msg);
- errorSpecs.add(getCharPosition());
- return errorSpecs;
- }
+ public ArrayList<Object> generateFullErrorMsg() {
+ ArrayList<Object> errorSpecs = new ArrayList<Object>();
+ String msg = getDetailedErrorMessage();
+ errorSpecs.add(StatusCodes.MALFORMED_QUERY);
+ errorSpecs.add(msg);
+ errorSpecs.add(getCharPosition());
+ return errorSpecs;
+ }
- private String getDetailedErrorMessage() {
- // default message, in case no detailed info is available;
- String msg = "Malformed query. Could not parse.";
- char offendingSymbol = query.charAt(0);
- if (query.length() > charPosition) offendingSymbol = query.charAt(charPosition);
- msg = "Failing to parse at symbol: '"+offendingSymbol+"'";
- if (expected != null) {
- if (expected.equals("EOF") || expected.equals("<EOF>")) {
- msg += " Expected end of query.";
- } else {
- msg += " Expected '"+expected+"'";
- }
- }
- // check for unbalanced parantheses
- SimpleEntry<String, Integer> unbalanced = QueryUtils.checkUnbalancedPars(query);
- if (unbalanced != null) {
- msg = unbalanced.getKey();
- charPosition = unbalanced.getValue();
- }
- // check if more more arguments expected before closing operator
- if (String.valueOf(offendingSymbol).equals(")")) {
- msg = "Early closing parenthesis. Possibly lacking arguments for operator.";
- }
+ private String getDetailedErrorMessage() {
+ // default message, in case no detailed info is available;
+ String msg = "Malformed query. Could not parse.";
+ char offendingSymbol = query.charAt(0);
+ if (query.length() > charPosition)
+ offendingSymbol = query.charAt(charPosition);
+ msg = "Failing to parse at symbol: '" + offendingSymbol + "'";
+ if (expected != null) {
+ if (expected.equals("EOF") || expected.equals("<EOF>")) {
+ msg += " Expected end of query.";
+ }
+ else {
+ msg += " Expected '" + expected + "'";
+ }
+ }
+ // check for unbalanced parantheses
+ SimpleEntry<String, Integer> unbalanced = QueryUtils
+ .checkUnbalancedPars(query);
+ if (unbalanced != null) {
+ msg = unbalanced.getKey();
+ charPosition = unbalanced.getValue();
+ }
+ // check if more more arguments expected before closing
+ // operator
+ if (String.valueOf(offendingSymbol).equals(")")) {
+ msg = "Early closing parenthesis. Possibly lacking arguments for operator.";
+ }
+ return msg;
+ }
- return msg;
- }
-
- public int getCharPosition() {
- return charPosition;
- }
-
+ public int getCharPosition() {
+ return charPosition;
+ }
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/util/Antlr4DescriptiveErrorListener.java b/src/main/java/de/ids_mannheim/korap/query/serialize/util/Antlr4DescriptiveErrorListener.java
index fd38556..7fa82aa 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/util/Antlr4DescriptiveErrorListener.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/util/Antlr4DescriptiveErrorListener.java
@@ -10,66 +10,65 @@
import de.ids_mannheim.korap.query.serialize.QueryUtils;
public class Antlr4DescriptiveErrorListener extends BaseErrorListener {
-
+
String query;
String message;
- int line;
+ int line;
int charPosition;
-
- public Antlr4DescriptiveErrorListener(String query) {
- this.query = query;
+
+ public Antlr4DescriptiveErrorListener (String query) {
+ this.query = query;
};
@Override
- public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol,
- int line, int charPositionInLine,
- String msg, RecognitionException e)
- {
- this.message = msg;
- this.line = line;
- this.charPosition = charPositionInLine;
+ public void syntaxError(Recognizer<?, ?> recognizer,
+ Object offendingSymbol, int line, int charPositionInLine,
+ String msg, RecognitionException e) {
+ this.message = msg;
+ this.line = line;
+ this.charPosition = charPositionInLine;
}
-
+
public String getMessage() {
- return message;
- }
+ return message;
+ }
- public int getLine() {
- return line;
- }
+ public int getLine() {
+ return line;
+ }
- public int getCharPosition() {
- return charPosition;
- }
-
- public ArrayList<Object> generateFullErrorMsg() {
- ArrayList<Object> errorSpecs = new ArrayList<Object>();
- String msg = getDetailedErrorMessage();
- errorSpecs.add(StatusCodes.MALFORMED_QUERY);
- errorSpecs.add(msg);
- errorSpecs.add(getCharPosition());
- return errorSpecs;
- }
+ public int getCharPosition() {
+ return charPosition;
+ }
- private String getDetailedErrorMessage() {
- // default message, in case no detailed info is available;
- String msg = "Malformed query. Could not parse.";
- char offendingSymbol = query.charAt(0);
- if (query.length() > charPosition) offendingSymbol = query.charAt(charPosition);
- msg = "Failing to parse at symbol: '"+offendingSymbol+"'";
- // check for unbalanced parantheses
- SimpleEntry<String, Integer> unbalanced = QueryUtils.checkUnbalancedPars(query);
- if (unbalanced != null) {
- msg = unbalanced.getKey();
- charPosition = unbalanced.getValue();
- }
- // check if more more arguments expected before closing operator
- if (String.valueOf(offendingSymbol).equals(")")) {
- msg = "Early closing parenthesis. Possibly lacking arguments for operator.";
- }
- return msg;
- }
-
-
+ public ArrayList<Object> generateFullErrorMsg() {
+ ArrayList<Object> errorSpecs = new ArrayList<Object>();
+ String msg = getDetailedErrorMessage();
+ errorSpecs.add(StatusCodes.MALFORMED_QUERY);
+ errorSpecs.add(msg);
+ errorSpecs.add(getCharPosition());
+ return errorSpecs;
+ }
+
+ private String getDetailedErrorMessage() {
+ // default message, in case no detailed info is available;
+ String msg = "Malformed query. Could not parse.";
+ char offendingSymbol = query.charAt(0);
+ if (query.length() > charPosition)
+ offendingSymbol = query.charAt(charPosition);
+ msg = "Failing to parse at symbol: '" + offendingSymbol + "'";
+ // check for unbalanced parantheses
+ SimpleEntry<String, Integer> unbalanced = QueryUtils
+ .checkUnbalancedPars(query);
+ if (unbalanced != null) {
+ msg = unbalanced.getKey();
+ charPosition = unbalanced.getValue();
+ }
+ // check if more more arguments expected before closing operator
+ if (String.valueOf(offendingSymbol).equals(")")) {
+ msg = "Early closing parenthesis. Possibly lacking arguments for operator.";
+ }
+ return msg;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/util/CosmasCondition.java b/src/main/java/de/ids_mannheim/korap/query/serialize/util/CosmasCondition.java
index 454e9f6..4c79500 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/util/CosmasCondition.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/util/CosmasCondition.java
@@ -20,6 +20,7 @@
elem = nodeString.substring(0, 1);
nodeString = nodeString.substring(1);
- position = nodeString.equals("a") ? "frames:startswith" : "frames:endswith";
+ position = nodeString.equals("a") ?
+ "frames:startswith" : "frames:endswith";
}
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/util/CqlfObjectGenerator.java b/src/main/java/de/ids_mannheim/korap/query/serialize/util/CqlfObjectGenerator.java
index abc4511..50b71a6 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/util/CqlfObjectGenerator.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/util/CqlfObjectGenerator.java
@@ -8,265 +8,299 @@
public class CqlfObjectGenerator {
- protected static final Integer MAXIMUM_DISTANCE = 100;
- private static AbstractQueryProcessor qp;
-
- public static void setQueryProcessor(AbstractQueryProcessor qp) {
- CqlfObjectGenerator.qp = qp;
- }
-
- public static LinkedHashMap<String, Object> makeSpan() {
- LinkedHashMap<String, Object> span = new LinkedHashMap<String, Object>();
- span.put("@type", "korap:span");
- return span;
- }
-
- public static LinkedHashMap<String, Object> makeSpan(String key) {
- LinkedHashMap<String, Object> span = new LinkedHashMap<String, Object>();
- span.put("@type", "korap:span");
- span.put("key", key);
- return span;
- }
-
- public static LinkedHashMap<String, Object> makeTerm() {
- LinkedHashMap<String, Object> term = new LinkedHashMap<String, Object>();
- term.put("@type", "korap:term");
- return term;
- }
-
- public static LinkedHashMap<String, Object> makeTermGroup(String relation) {
- LinkedHashMap<String, Object> term = new LinkedHashMap<String, Object>();
- term.put("@type", "korap:termGroup");
- term.put("relation", "relation:"+relation);
- term.put("operands", new ArrayList<Object>());
- return term;
- }
-
- public static LinkedHashMap<String, Object> makeDoc() {
- LinkedHashMap<String, Object> term = new LinkedHashMap<String, Object>();
- term.put("@type", "korap:doc");
- return term;
- }
-
- public static LinkedHashMap<String, Object> makeDocGroup(String relation) {
- LinkedHashMap<String, Object> term = new LinkedHashMap<String, Object>();
- term.put("@type", "korap:docGroup");
- term.put("operation", "operation:"+relation);
- term.put("operands", new ArrayList<Object>());
- return term;
- }
-
- public static LinkedHashMap<String, Object> makeToken() {
- LinkedHashMap<String, Object> token = new LinkedHashMap<String, Object>();
- token.put("@type", "korap:token");
- return token;
- }
-
- public static LinkedHashMap<String, Object> makeGroup(String operation) {
- LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
- group.put("@type", "korap:group");
- group.put("operation", "operation:"+operation);
- group.put("operands", new ArrayList<Object>());
- return group;
- }
-
- public static LinkedHashMap<String, Object> makeRepetition(Integer min, Integer max) {
- LinkedHashMap<String, Object> group = makeGroup("repetition");
- group.put("boundary", makeBoundary(min, max));
- group.put("min", min);
- return group;
- }
-
- @Deprecated
- public static LinkedHashMap<String, Object> makePosition(String frame) {
- LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
- group.put("@type", "korap:group");
- group.put("operation", "operation:position");
- group.put("frame", "frame:"+frame);
- group.put("operands", new ArrayList<Object>());
- return group;
- }
-
- public static LinkedHashMap<String, Object> makePosition(String[] allowedFrames, String[] classRefCheck) {
- LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
- group.put("@type", "korap:group");
- group.put("operation", "operation:position");
- group.put("frames", Arrays.asList(allowedFrames));
- group.put("operands", new ArrayList<Object>());
- return group;
- }
-
- public static LinkedHashMap<String, Object> makeSpanClass(int classCount) {
- return makeSpanClass(classCount, true);
- }
-
- public static LinkedHashMap<String, Object> makeSpanClass(int classCount, boolean setBySystem) {
- LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
- group.put("@type", "korap:group");
- group.put("operation", "operation:class");
- if (setBySystem) {
- group.put("class", 128+classCount);
- group.put("classOut", 128+classCount);
- qp.addMessage("A class has been introduced into the backend representation of " +
- "your query for later reference to a part of the query. The class id is "+(128+classCount));
- } else {
- group.put("class", classCount);
- group.put("classOut", classCount);
- }
- qp.addMessage(StatusCodes.DEPRECATED_QUERY_ELEMENT, "Deprecated 2014-10-07: 'class' only to be supported until 3 months from deprecation date. " +
- "Classes are now defined using the 'classOut' attribute.");
- group.put("operands", new ArrayList<Object>());
- return group;
- }
-
- public static LinkedHashMap<String, Object> makeClassRefCheck(ArrayList<String> check, Integer[] classIn, int classOut) {
- LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
- group.put("@type", "korap:group");
- group.put("operation", "operation:class");
- group.put("classRefCheck", check);
- group.put("classIn", Arrays.asList(classIn));
- group.put("classOut", classOut);
- group.put("class", classOut);
- qp.addMessage(StatusCodes.DEPRECATED_QUERY_ELEMENT, "Deprecated 2014-10-07: 'class' only to be supported until 3 months from deprecation date. " +
- "Classes are now defined using the 'classOut' attribute.");
- group.put("operands", new ArrayList<Object>());
- return group;
- }
-
- public static LinkedHashMap<String, Object> makeClassRefOp(String operation, Integer[] classIn, int classOut) {
- LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
- group.put("@type", "korap:group");
- group.put("operation", "operation:class");
- group.put("classRefOp", operation);
- group.put("classIn", Arrays.asList(classIn));
- group.put("classOut", classOut);
- group.put("operands", new ArrayList<Object>());
- return group;
- }
-
- @Deprecated
- public static LinkedHashMap<String, Object> makeTreeRelation(String reltype) {
- LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
- group.put("@type", "korap:treeRelation");
- if (reltype != null) group.put("reltype", reltype);
- return group;
- }
-
- public static LinkedHashMap<String, Object> makeRelation() {
- LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
- group.put("@type", "korap:relation");
- return group;
- }
-
- public static LinkedHashMap<String, Object> makeBoundary(Integer min, Integer max) {
- LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
- group.put("@type", "korap:boundary");
- group.put("min", min);
- if (max != null) {
- group.put("max", max);
- }
- return group;
- }
+ protected static final Integer MAXIMUM_DISTANCE = 100;
+ private static AbstractQueryProcessor qp;
- public static LinkedHashMap<String, Object> makeDistance(String key, Integer min, Integer max) {
- LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
- if (key.equals("w")) {
- group.put("@type", "korap:distance");
- } else {
- group.put("@type", "cosmas:distance");
- }
- group.put("key", key);
- group.put("boundary", makeBoundary(min, max));
- group.put("min", min);
- if (max != null) {
- group.put("max", max);
- }
- qp.addMessage(StatusCodes.DEPRECATED_QUERY_ELEMENT, "Deprecated 2014-07-24: 'min' and 'max' to be supported until 3 months from deprecation date.");
- return group;
- }
-
- public static LinkedHashMap<String, Object> makeReference(ArrayList<Integer> classRefs, String operation) {
- LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
- group.put("@type", "korap:reference");
- group.put("operation", "operation:"+operation);
- if (classRefs!= null && !classRefs.isEmpty()) {
- group.put("classRef", classRefs);
- }
- return group;
- }
-
- public static LinkedHashMap<String, Object> makeReference(ArrayList<Integer> classRefs) {
- return makeReference(classRefs, "focus");
- }
-
- public static LinkedHashMap<String, Object> makeReference(int classRef, String operation, boolean setBySystem) {
- ArrayList<Integer> classRefs = new ArrayList<Integer>();
- if (setBySystem) classRef = classRef+128;
- classRefs.add(classRef);
- return makeReference(classRefs, operation);
- }
-
- public static LinkedHashMap<String, Object> makeReference(int classRef, boolean setBySystem) {
- ArrayList<Integer> classRefs = new ArrayList<Integer>();
- if (setBySystem) classRef = classRef+128;
- classRefs.add(classRef);
- return makeReference(classRefs, "focus");
- }
-
- public static LinkedHashMap<String, Object> makeReference(int classRef) {
- return makeReference(classRef, false);
- }
-
- public static LinkedHashMap<String, Object> makeResetReference() {
- LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
- group.put("@type", "korap:reference");
- group.put("operation", "operation:focus");
- group.put("reset", true);
- group.put("operands", new ArrayList<Object>());
- return group;
- }
-
- public static LinkedHashMap<String, Object> makeSpanReference(Integer[] spanRef, String operation) {
- LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
- group.put("@type", "korap:reference");
- group.put("operation", "operation:"+operation);
- group.put("spanRef", Arrays.asList(spanRef));
- group.put("operands", new ArrayList<Object>());
- return group;
- }
-
- public static void addOperandsToGroup(LinkedHashMap<String, Object> group) {
- ArrayList<Object> operands = new ArrayList<Object>();
- group.put("operands", operands);
- }
-
- public static LinkedHashMap<String, Object> wrapInReference(LinkedHashMap<String, Object> group, Integer classId) {
- LinkedHashMap<String, Object> refGroup = makeReference(classId);
- ArrayList<Object> operands = new ArrayList<Object>();
- operands.add(group);
- refGroup.put("operands", operands);
- return refGroup;
- }
+ public static void setQueryProcessor(AbstractQueryProcessor qp) {
+ CqlfObjectGenerator.qp = qp;
+ }
- @SuppressWarnings("unchecked")
- public static LinkedHashMap<String, Object> wrapInClass(LinkedHashMap<String, Object> group, Integer classId) {
- LinkedHashMap<String, Object> classGroup = makeSpanClass(classId, true);
- ((ArrayList<Object>) classGroup.get("operands")).add(group);
- return classGroup;
- }
-
- /**
- * Ensures that a distance or quantification value does not exceed the allowed maximum value.
- * @param number
- * @return The input number if it is below the allowed maximum value, else the maximum value.
- */
- public static int cropToMaxValue(int number) {
- if (number > MAXIMUM_DISTANCE) {
- number = MAXIMUM_DISTANCE;
- String warning = String.format("You specified a distance between two segments that is greater than " +
- "the allowed max value of %d. Your query will be re-interpreted using a distance of %d.", MAXIMUM_DISTANCE, MAXIMUM_DISTANCE);
- qp.addWarning(warning);
- }
- return number;
- }
+ public static LinkedHashMap<String, Object> makeSpan() {
+ LinkedHashMap<String, Object> span = new LinkedHashMap<String, Object>();
+ span.put("@type", "korap:span");
+ return span;
+ }
+
+ public static LinkedHashMap<String, Object> makeSpan(String key) {
+ LinkedHashMap<String, Object> span = new LinkedHashMap<String, Object>();
+ span.put("@type", "korap:span");
+ span.put("key", key);
+ return span;
+ }
+
+ public static LinkedHashMap<String, Object> makeTerm() {
+ LinkedHashMap<String, Object> term = new LinkedHashMap<String, Object>();
+ term.put("@type", "korap:term");
+ return term;
+ }
+
+ public static LinkedHashMap<String, Object> makeTermGroup(String relation) {
+ LinkedHashMap<String, Object> term = new LinkedHashMap<String, Object>();
+ term.put("@type", "korap:termGroup");
+ term.put("relation", "relation:" + relation);
+ term.put("operands", new ArrayList<Object>());
+ return term;
+ }
+
+ public static LinkedHashMap<String, Object> makeDoc() {
+ LinkedHashMap<String, Object> term = new LinkedHashMap<String, Object>();
+ term.put("@type", "korap:doc");
+ return term;
+ }
+
+ public static LinkedHashMap<String, Object> makeDocGroup(String relation) {
+ LinkedHashMap<String, Object> term = new LinkedHashMap<String, Object>();
+ term.put("@type", "korap:docGroup");
+ term.put("operation", "operation:" + relation);
+ term.put("operands", new ArrayList<Object>());
+ return term;
+ }
+
+ public static LinkedHashMap<String, Object> makeToken() {
+ LinkedHashMap<String, Object> token = new LinkedHashMap<String, Object>();
+ token.put("@type", "korap:token");
+ return token;
+ }
+
+ public static LinkedHashMap<String, Object> makeGroup(String operation) {
+ LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
+ group.put("@type", "korap:group");
+ group.put("operation", "operation:" + operation);
+ group.put("operands", new ArrayList<Object>());
+ return group;
+ }
+
+ public static LinkedHashMap<String, Object> makeRepetition(Integer min,
+ Integer max) {
+ LinkedHashMap<String, Object> group = makeGroup("repetition");
+ group.put("boundary", makeBoundary(min, max));
+ group.put("min", min);
+ return group;
+ }
+
+ @Deprecated
+ public static LinkedHashMap<String, Object> makePosition(String frame) {
+ LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
+ group.put("@type", "korap:group");
+ group.put("operation", "operation:position");
+ group.put("frame", "frame:" + frame);
+ group.put("operands", new ArrayList<Object>());
+ return group;
+ }
+
+ public static LinkedHashMap<String, Object> makePosition(
+ String[] allowedFrames, String[] classRefCheck) {
+ LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
+ group.put("@type", "korap:group");
+ group.put("operation", "operation:position");
+ group.put("frames", Arrays.asList(allowedFrames));
+ group.put("operands", new ArrayList<Object>());
+ return group;
+ }
+
+ public static LinkedHashMap<String, Object> makeSpanClass(int classCount) {
+ return makeSpanClass(classCount, true);
+ }
+
+ public static LinkedHashMap<String, Object> makeSpanClass(int classId,
+ boolean setBySystem) {
+ LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
+ group.put("@type", "korap:group");
+ group.put("operation", "operation:class");
+ if (setBySystem) {
+ classId += 128;
+ qp.addMessage("A class has been introduced into the backend representation of "
+ + "your query for later reference to a part of the query. The class id is "
+ + classId);
+ }
+ group.put("class", classId);
+ group.put("classOut", classId);
+ qp.addMessage(
+ StatusCodes.DEPRECATED_QUERY_ELEMENT,
+ "Deprecated 2014-10-07: 'class' only to be supported until 3 months from deprecation date. "
+ + "Classes are now defined using the 'classOut' attribute.");
+ group.put("operands", new ArrayList<Object>());
+ return group;
+ }
+
+ public static LinkedHashMap<String, Object> makeClassRefCheck(
+ ArrayList<String> check, Integer[] classIn, int classOut) {
+ LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
+ group.put("@type", "korap:group");
+ group.put("operation", "operation:class");
+ group.put("classRefCheck", check);
+ group.put("classIn", Arrays.asList(classIn));
+ group.put("classOut", classOut);
+ group.put("class", classOut);
+ qp.addMessage(
+ StatusCodes.DEPRECATED_QUERY_ELEMENT,
+ "Deprecated 2014-10-07: 'class' only to be supported until 3 months from deprecation date. "
+ + "Classes are now defined using the 'classOut' attribute.");
+ group.put("operands", new ArrayList<Object>());
+ return group;
+ }
+
+ public static LinkedHashMap<String, Object> makeClassRefOp(
+ String operation, Integer[] classIn, int classOut) {
+ LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
+ group.put("@type", "korap:group");
+ group.put("operation", "operation:class");
+ group.put("classRefOp", operation);
+ group.put("classIn", Arrays.asList(classIn));
+ group.put("classOut", classOut);
+ group.put("operands", new ArrayList<Object>());
+ return group;
+ }
+
+ @Deprecated
+ public static LinkedHashMap<String, Object> makeTreeRelation(String reltype) {
+ LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
+ group.put("@type", "korap:treeRelation");
+ if (reltype != null)
+ group.put("reltype", reltype);
+ return group;
+ }
+
+ public static LinkedHashMap<String, Object> makeRelation() {
+ LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
+ group.put("@type", "korap:relation");
+ return group;
+ }
+
+ public static LinkedHashMap<String, Object> makeBoundary(Integer min,
+ Integer max) {
+ LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
+ group.put("@type", "korap:boundary");
+ group.put("min", min);
+ if (max != null) {
+ group.put("max", max);
+ }
+ return group;
+ }
+
+ public static LinkedHashMap<String, Object> makeDistance(String key,
+ Integer min, Integer max) {
+ LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
+ if (key.equals("w")) {
+ group.put("@type", "korap:distance");
+ }
+ else {
+ group.put("@type", "cosmas:distance");
+ }
+ group.put("key", key);
+ group.put("boundary", makeBoundary(min, max));
+ group.put("min", min);
+ if (max != null) {
+ group.put("max", max);
+ }
+ qp.addMessage(
+ StatusCodes.DEPRECATED_QUERY_ELEMENT,
+ "Deprecated 2014-07-24: 'min' and 'max' to be supported until 3 months from deprecation date.");
+ return group;
+ }
+
+ public static LinkedHashMap<String, Object> makeReference(
+ ArrayList<Integer> classRefs, String operation) {
+ LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
+ group.put("@type", "korap:reference");
+ group.put("operation", "operation:" + operation);
+ if (classRefs != null && !classRefs.isEmpty()) {
+ group.put("classRef", classRefs);
+ }
+ return group;
+ }
+
+ public static LinkedHashMap<String, Object> makeReference(
+ ArrayList<Integer> classRefs) {
+ return makeReference(classRefs, "focus");
+ }
+
+ public static LinkedHashMap<String, Object> makeReference(int classRef,
+ String operation, boolean setBySystem) {
+ ArrayList<Integer> classRefs = new ArrayList<Integer>();
+ if (setBySystem)
+ classRef = classRef + 128;
+ classRefs.add(classRef);
+ return makeReference(classRefs, operation);
+ }
+
+ public static LinkedHashMap<String, Object> makeReference(int classRef,
+ boolean setBySystem) {
+ ArrayList<Integer> classRefs = new ArrayList<Integer>();
+ if (setBySystem)
+ classRef = classRef + 128;
+ classRefs.add(classRef);
+ return makeReference(classRefs, "focus");
+ }
+
+ public static LinkedHashMap<String, Object> makeReference(int classRef) {
+ return makeReference(classRef, false);
+ }
+
+ public static LinkedHashMap<String, Object> makeResetReference() {
+ LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
+ group.put("@type", "korap:reference");
+ group.put("operation", "operation:focus");
+ group.put("reset", true);
+ group.put("operands", new ArrayList<Object>());
+ return group;
+ }
+
+ public static LinkedHashMap<String, Object> makeSpanReference(
+ Integer[] spanRef, String operation) {
+ LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
+ group.put("@type", "korap:reference");
+ group.put("operation", "operation:" + operation);
+ group.put("spanRef", Arrays.asList(spanRef));
+ group.put("operands", new ArrayList<Object>());
+ return group;
+ }
+
+ public static void addOperandsToGroup(LinkedHashMap<String, Object> group) {
+ ArrayList<Object> operands = new ArrayList<Object>();
+ group.put("operands", operands);
+ }
+
+ public static LinkedHashMap<String, Object> wrapInReference(
+ LinkedHashMap<String, Object> group, Integer classId) {
+ return wrapInReference(group, classId, false);
+ }
+
+ public static LinkedHashMap<String, Object> wrapInReference(
+ LinkedHashMap<String, Object> group, Integer classId,
+ boolean setBySystem) {
+ LinkedHashMap<String, Object> refGroup = makeReference(classId, setBySystem);
+ ArrayList<Object> operands = new ArrayList<Object>();
+ operands.add(group);
+ refGroup.put("operands", operands);
+ return refGroup;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static LinkedHashMap<String, Object> wrapInClass(
+ LinkedHashMap<String, Object> group, Integer classId) {
+ LinkedHashMap<String, Object> classGroup = makeSpanClass(classId, true);
+ ((ArrayList<Object>) classGroup.get("operands")).add(group);
+ return classGroup;
+ }
+
+ /**
+ * Ensures that a distance or quantification value does not exceed
+ * the allowed maximum value.
+ *
+ * @param number
+ * @return The input number if it is below the allowed maximum
+ * value, else the maximum value.
+ */
+ public static int cropToMaxValue(int number) {
+ if (number > MAXIMUM_DISTANCE) {
+ number = MAXIMUM_DISTANCE;
+ String warning = String
+ .format("You specified a distance between two segments that is greater than "
+ + "the allowed max value of %d. Your query will be re-interpreted using a distance of %d.",
+ MAXIMUM_DISTANCE, MAXIMUM_DISTANCE);
+ qp.addWarning(warning);
+ }
+ return number;
+ }
}
\ No newline at end of file
diff --git a/src/test/java/AnnisQueryProcessorTest.java b/src/test/java/AnnisQueryProcessorTest.java
index aff5770..2788dad 100644
--- a/src/test/java/AnnisQueryProcessorTest.java
+++ b/src/test/java/AnnisQueryProcessorTest.java
@@ -10,7 +10,6 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import de.ids_mannheim.korap.query.serialize.QuerySerializer;
-import de.ids_mannheim.korap.query.serialize.util.QueryException;
/**
* Tests for JSON-LD serialization of ANNIS QL queries.
@@ -27,7 +26,7 @@
JsonNode res;
@Test
- public void testContext() throws QueryException, JsonProcessingException, IOException {
+ public void testContext() throws JsonProcessingException, IOException {
String contextUrl = "http://ids-mannheim.de/ns/KorAP/json-ld/v0.2/context.jsonld";
query = "foo";
qs.setQuery(query, "annis");
@@ -36,7 +35,7 @@
}
@Test
- public void testSingleTokens() throws QueryException, JsonProcessingException, IOException {
+ public void testSingleTokens() throws JsonProcessingException, IOException {
query = "\"Mann\"";
qs.setQuery(query, "annis");
res = mapper.readTree(qs.toJSON());
@@ -68,7 +67,7 @@
}
@Test
- public void testSpans() throws QueryException, JsonProcessingException, IOException {
+ public void testSpans() throws JsonProcessingException, IOException {
query = "node"; // special keyword for general span
qs.setQuery(query, "annis");
res = mapper.readTree(qs.toJSON());
@@ -90,7 +89,7 @@
}
@Test
- public void testRegex() throws QueryException, JsonProcessingException, IOException {
+ public void testRegex() throws JsonProcessingException, IOException {
query = "/Mann/";
qs.setQuery(query, "annis");
res = mapper.readTree(qs.toJSON());
@@ -109,7 +108,7 @@
}
@Test
- public void testFoundriesLayers() throws QueryException, JsonProcessingException, IOException {
+ public void testFoundriesLayers() throws JsonProcessingException, IOException {
query = "c=\"np\"";
qs.setQuery(query, "annis");
res = mapper.readTree(qs.toJSON());
@@ -136,7 +135,7 @@
}
@Test
- public void testDirectDeclarationRelations() throws QueryException, JsonProcessingException, IOException {
+ public void testDirectDeclarationRelations() throws JsonProcessingException, IOException {
query = "node > node";
qs.setQuery(query, "annis");
res = mapper.readTree(qs.toJSON());
@@ -184,7 +183,7 @@
}
@Test
- public void testDefPredicationInversion() throws QueryException, JsonProcessingException, IOException {
+ public void testDefPredicationInversion() throws JsonProcessingException, IOException {
query = "#1 > #2 & cnx/cat=\"vp\" & cnx/cat=\"np\"";
qs.setQuery(query, "annis");
res = mapper.readTree(qs.toJSON());
@@ -205,7 +204,7 @@
}
@Test
- public void testSimpleDominance() throws QueryException, JsonProcessingException, IOException {
+ public void testSimpleDominance() throws JsonProcessingException, IOException {
query = "node & node & #2 > #1";
qs.setQuery(query, "annis");
res = mapper.readTree(qs.toJSON());
@@ -287,7 +286,7 @@
}
@Test
- public void testIndirectDominance() throws QueryException, JsonProcessingException, IOException {
+ public void testIndirectDominance() throws JsonProcessingException, IOException {
query = "node & node & #1 >2,4 #2";
qs.setQuery(query, "annis");
res = mapper.readTree(qs.toJSON());
@@ -310,8 +309,26 @@
@Test
- public void testMultipleDominance() throws QueryException {
-
+ public void testMultipleDominance() throws JsonProcessingException, IOException {
+ query = "cat=\"CP\" & cat=\"VP\" & cat=\"NP\" & #1 > #2 > #3";
+ qs.setQuery(query, "annis");
+ res = mapper.readTree(qs.toJSON());
+ assertEquals("korap:group", res.at("/query/@type").asText());
+ assertEquals("operation:relation", res.at("/query/operation").asText());
+ assertEquals("korap:reference", res.at("/query/operands/0/@type").asText());
+ assertEquals("operation:focus", res.at("/query/operands/0/operation").asText());
+ assertEquals(128, res.at("/query/operands/0/classRef/0").asInt());
+ assertEquals("korap:group", res.at("/query/operands/0/operands/0/@type").asText());
+ assertEquals("operation:relation", res.at("/query/operands/0/operands/0/operation").asText());
+ assertEquals("korap:relation", res.at("/query/operands/0/operands/0/relation/@type").asText());
+ assertEquals("c", res.at("/query/operands/0/operands/0/relation/wrap/layer").asText());
+ assertEquals("korap:span", res.at("/query/operands/0/operands/0/operands/0/@type").asText());
+ assertEquals("c", res.at("/query/operands/0/operands/0/operands/0/layer").asText());
+ assertEquals("CP", res.at("/query/operands/0/operands/0/operands/0/key").asText());
+ assertEquals("korap: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(128, res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
+ assertEquals("VP", res.at("/query/operands/0/operands/0/operands/1/operands/0/key").asText());
}
// query = "cat=\"CP\" & cat=\"VP\" & cat=\"NP\" & #1 > #2 > #3";
// String dom1 =
@@ -358,7 +375,7 @@
// }
//
// @Test
-// public void testPointingRelations() throws QueryException {
+// public void testPointingRelations() throws Exception {
// query = "node & node & #2 ->coref[val=\"true\"] #1";
// String dom1 =
// "{@type=korap:group, operation=operation:relation, operands=[" +
@@ -383,7 +400,7 @@
// }
//
// @Test
-// public void testSequence() throws QueryException {
+// public void testSequence() throws Exception {
// query = "node & node & #1 . #2";
// String seq1 =
// "{@type=korap:group, operation=operation:sequence, " +
@@ -424,30 +441,38 @@
//
// }
//
-// @Test
-// public void testMultipleSequence() throws QueryException {
-// query = "tok=\"Sonne\" & tok=\"Mond\" & tok=\"Sterne\" & #1 .0,2 #2 .0,4 #3";
-// String seq4 =
-// "{@type=korap:group, operation=operation:sequence," +
-// "operands=[" +
-// "{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
-// "{@type=korap:group, operation=operation:sequence, operands=[" +
-// "{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Sonne, match=match:eq}}," +
-// "{@type=korap:group, operation=operation:class, class=128, classOut=128, operands=[" +
-// "{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Mond, match=match:eq}}" +
-// "]}" +
-// "], distances=[" +
-// "{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=0, max=2}, min=0, max=2}" +
-// "], inOrder=true}" +
-// "]}," +
-// "{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Sterne, match=match:eq}}" +
-// "],distances=[" +
-// "{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=0, max=4}, min=0, max=4}" +
-// "], inOrder=true" +
-// "}";
-// aqlt = new AqlTree(query);
-// map = aqlt.getRequestMap().get("query").toString();
-// assertEquals(seq4.replaceAll(" ", ""), map.replaceAll(" ", ""));
+ @Test
+ public void testMultipleSequence() throws Exception {
+ query = "tok=\"a\" & tok=\"b\" & tok=\"c\" & #1 . #2 & #2 . #3";
+ String seq4 =
+ "{@type=korap:group, operation=operation:sequence," +
+ "operands=[" +
+ "{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
+ "{@type=korap:group, operation=operation:sequence, operands=[" +
+ "{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Sonne, match=match:eq}}," +
+ "{@type=korap:group, operation=operation:class, class=128, classOut=128, operands=[" +
+ "{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Mond, match=match:eq}}" +
+ "]}" +
+ "], distances=[" +
+ "{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=0, max=2}, min=0, max=2}" +
+ "], inOrder=true}" +
+ "]}," +
+ "{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Sterne, match=match:eq}}" +
+ "],distances=[" +
+ "{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=0, max=4}, min=0, max=4}" +
+ "], inOrder=true" +
+ "}";
+ qs.setQuery(query, "annis");
+ res = mapper.readTree(qs.toJSON());
+ assertEquals("korap:group", res.at("/query/@type").asText());
+ assertEquals("operation:sequence", res.at("/query/operation").asText());
+ assertEquals("korap:reference", res.at("/query/operands/0/@type").asText());
+ assertEquals(128, res.at("/query/operands/0/classRef/0").asInt());
+ assertEquals(res.at("/query/operands/0/classRef/0").asInt(),
+ res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
+ }
+
+
//
// query = "node & node & node & #1 . #2 .1,3 #3";
// String seq5 =
@@ -499,7 +524,7 @@
// }
//
// @Test
-// public void testMultipleMixedOperators() throws QueryException {
+// public void testMultipleMixedOperators() throws Exception {
// query = "tok=\"Sonne\" & tok=\"Mond\" & tok=\"Sterne\" & #1 > #2 .0,4 #3";
// String seq4 =
// "{@type=korap:group, operation=operation:sequence, operands=[" +
@@ -568,7 +593,7 @@
// }
// /*
// @Test
-// public void testMultipleOperatorsWithSameOperands() throws QueryException {
+// public void testMultipleOperatorsWithSameOperands() throws Exception {
//
// query = "cat=\"NP\" > cat=\"VP\" & #1 _l_ #2";
// String eq2 =
@@ -590,7 +615,7 @@
// }
// */
// @Test
-// public void testPositions() throws QueryException {
+// public void testPositions() throws Exception {
// query = "node & node & #2 _=_ #1";
// String pos1 =
// "{@type=korap:group, operation=operation:position, frames=[frames:matches], operands=[" +
@@ -647,7 +672,7 @@
// }
//
// @Test
-// public void testMultiplePredications() throws QueryException {
+// public void testMultiplePredications() throws Exception {
// // a noun before a verb before a preposition
// query = "pos=\"N\" & pos=\"V\" & pos=\"P\" & #1 . #2 & #2 . #3";
// String mult1 =
@@ -733,7 +758,7 @@
// }
//
// @Test
-// public void testUnaryRelations() throws QueryException {
+// public void testUnaryRelations() throws Exception {
// query = "node & #1:tokenarity=2";
// String unary1 =
// "{@type=korap:span, attr={@type=korap:term, tokenarity={@type=korap:boundary,min=2,max=2}}}";
@@ -768,7 +793,7 @@
// }
//
// @Test
-// public void testCommonParent() throws QueryException {
+// public void testCommonParent() throws Exception {
// query = "cat=\"NP\" & cat=\"VP\" & #1 $ #2";
// String cp1 =
// "{@type=korap:group, operation=operation:relation, operands=[" +
@@ -861,7 +886,7 @@
/*
@Test
- public void testEqualNotequalValue() throws QueryException {
+ public void testEqualNotequalValue() throws Exception {
query = "cat=\"NP\" & cat=\"VP\" & #1 == #2";
String eq1 =
"{}"; // ???
diff --git a/src/test/java/CollectionQueryProcessorTest.java b/src/test/java/CollectionQueryProcessorTest.java
index 1d3046d..ebd5555 100644
--- a/src/test/java/CollectionQueryProcessorTest.java
+++ b/src/test/java/CollectionQueryProcessorTest.java
@@ -4,7 +4,6 @@
import java.util.ArrayList;
import de.ids_mannheim.korap.query.serialize.QuerySerializer;
-import de.ids_mannheim.korap.query.serialize.util.QueryException;
import org.junit.Test;
@@ -24,7 +23,7 @@
JsonNode res;
@Test
- public void testContext() throws QueryException, JsonProcessingException, IOException {
+ public void testContext() throws JsonProcessingException, IOException {
collection = "textClass=politik";
String contextString = "http://ids-mannheim.de/ns/KorAP/json-ld/v0.2/context.jsonld";
qs.setQuery(query,ql);
@@ -34,7 +33,7 @@
}
@Test
- public void testSimple() throws QueryException, JsonProcessingException, IOException {
+ public void testSimple() throws JsonProcessingException, IOException {
collection = "textClass=politik";
qs.setQuery(query,ql);
qs.setCollection(collection);
@@ -55,7 +54,7 @@
}
@Test
- public void testContains() throws QueryException, JsonProcessingException, IOException {
+ public void testContains() throws JsonProcessingException, IOException {
collection = "title~Mannheim";
qs.setQuery(query,ql);
qs.setCollection(collection);
@@ -76,7 +75,7 @@
}
@Test
- public void testTwoConjuncts() throws QueryException, JsonProcessingException, IOException {
+ public void testTwoConjuncts() throws JsonProcessingException, IOException {
collection = "textClass=Sport & pubDate in 2014";
qs.setQuery(query,ql);
qs.setCollection(collection);
@@ -112,7 +111,7 @@
}
@Test
- public void testThreeConjuncts() throws QueryException, JsonProcessingException, IOException {
+ public void testThreeConjuncts() throws JsonProcessingException, IOException {
collection = "textClass=Sport & pubDate in 2014 & corpusId=WPD";
qs.setQuery(query,ql);
qs.setCollection(collection);
@@ -136,7 +135,7 @@
assertEquals("match:eq", res.at("/collection/operands/1/operands/1/match").asText());
}
@Test
- public void testTwoDisjuncts() throws QueryException, JsonProcessingException, IOException {
+ public void testTwoDisjuncts() throws JsonProcessingException, IOException {
collection = "textClass=Sport | pubDate in 2014";
qs.setQuery(query,ql);
qs.setCollection(collection);
@@ -155,7 +154,7 @@
}
@Test
- public void testThreeDisjuncts() throws QueryException, JsonProcessingException, IOException {
+ public void testThreeDisjuncts() throws JsonProcessingException, IOException {
collection = "textClass=Sport | pubDate in 2014 | corpusId=WPD";
qs.setQuery(query,ql);
qs.setCollection(collection);
@@ -180,7 +179,7 @@
}
@Test
- public void testMixed() throws QueryException, JsonProcessingException, IOException {
+ public void testMixed() throws JsonProcessingException, IOException {
collection = "textClass=Sport | (pubDate in 2014 & corpusId=WPD)";
qs.setQuery(query,ql);
qs.setCollection(collection);
@@ -291,7 +290,7 @@
}
@Test
- public void testDateYear() throws QueryException, JsonProcessingException, IOException {
+ public void testDateYear() throws JsonProcessingException, IOException {
collection = "pubDate in 2000";
qs.setQuery(query,ql);
qs.setCollection(collection);
@@ -334,7 +333,7 @@
}
@Test
- public void testDateMonthDay() throws QueryException, JsonProcessingException, IOException {
+ public void testDateMonthDay() throws JsonProcessingException, IOException {
collection = "pubDate in 2000-02";
qs.setQuery(query,ql);
qs.setCollection(collection);
diff --git a/src/test/java/Cosmas2QueryProcessorTest.java b/src/test/java/Cosmas2QueryProcessorTest.java
index 2a545cf..6d5194f 100644
--- a/src/test/java/Cosmas2QueryProcessorTest.java
+++ b/src/test/java/Cosmas2QueryProcessorTest.java
@@ -6,7 +6,6 @@
import org.junit.Test;
import de.ids_mannheim.korap.query.serialize.QuerySerializer;
-import de.ids_mannheim.korap.query.serialize.util.QueryException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
@@ -28,7 +27,7 @@
JsonNode res;
@Test
- public void testContext() throws QueryException, JsonProcessingException, IOException {
+ public void testContext() throws JsonProcessingException, IOException {
String contextString = "http://ids-mannheim.de/ns/KorAP/json-ld/v0.2/context.jsonld";
query = "foo";
qs.setQuery(query, "cosmas2");
@@ -38,7 +37,7 @@
@Test
- public void testSingleToken() throws QueryException, JsonProcessingException, IOException {
+ public void testSingleToken() throws JsonProcessingException, IOException {
query = "der";
qs.setQuery(query, "cosmas2");
res = mapper.readTree(qs.toJSON());
@@ -61,7 +60,7 @@
@Test
- public void testWildcardToken() throws QueryException, JsonProcessingException, IOException {
+ public void testWildcardToken() throws JsonProcessingException, IOException {
query = "*der";
qs.setQuery(query, "cosmas2");
res = mapper.readTree(qs.toJSON());
@@ -78,7 +77,7 @@
}
//
@Test
- public void testCaseSensitivityFlag() throws QueryException, JsonProcessingException, IOException {
+ public void testCaseSensitivityFlag() throws JsonProcessingException, IOException {
query = "$deutscher";
qs.setQuery(query, "cosmas2");
res = mapper.readTree(qs.toJSON());
@@ -103,7 +102,7 @@
}
@Test
- public void testMORPH() throws QueryException, JsonProcessingException, IOException {
+ public void testMORPH() throws JsonProcessingException, IOException {
query = "MORPH(p=V)";
qs.setQuery(query, "cosmas2");
res = mapper.readTree(qs.toJSON());
@@ -159,7 +158,7 @@
}
@Test
- public void testSequence() throws QueryException, JsonProcessingException, IOException {
+ public void testSequence() throws JsonProcessingException, IOException {
query = "der Mann";
qs.setQuery(query, "cosmas2");
res = mapper.readTree(qs.toJSON());
@@ -224,7 +223,7 @@
}
@Test
- public void testOPOR() throws QueryException, JsonProcessingException, IOException {
+ public void testOPOR() throws JsonProcessingException, IOException {
query = "Sonne oder Mond";
qs.setQuery(query, "cosmas2");
res = mapper.readTree(qs.toJSON());
@@ -263,7 +262,7 @@
}
@Test
- public void testOPORAND() throws QueryException, JsonProcessingException, IOException {
+ public void testOPORAND() throws JsonProcessingException, IOException {
query = "(Sonne oder Mond) und scheint";
qs.setQuery(query, "cosmas2");
res = mapper.readTree(qs.toJSON());
@@ -321,7 +320,7 @@
}
@Test
- public void testOPNOT() throws QueryException, JsonProcessingException, IOException {
+ public void testOPNOT() throws JsonProcessingException, IOException {
query = "Sonne nicht Mond";
qs.setQuery(query, "cosmas2");
res = mapper.readTree(qs.toJSON());
@@ -382,7 +381,7 @@
}
@Test
- public void testOPPROX() throws QueryException, JsonProcessingException, IOException {
+ public void testOPPROX() throws JsonProcessingException, IOException {
query = "Sonne /+w1:4 Mond";
qs.setQuery(query, "cosmas2");
res = mapper.readTree(qs.toJSON());
@@ -461,7 +460,7 @@
}
@Test
- public void testOPPROXNested() throws QueryException, JsonProcessingException, IOException {
+ public void testOPPROXNested() throws JsonProcessingException, IOException {
query = "Sonne /+w1:4 Mond /+w1:7 Sterne";
qs.setQuery(query, "cosmas2");
res = mapper.readTree(qs.toJSON());
@@ -532,7 +531,7 @@
}
@Test
- public void testOPIN() throws QueryException, JsonProcessingException, IOException {
+ public void testOPIN() throws JsonProcessingException, IOException {
query = "wegen #IN <s>";
qs.setQuery(query, "cosmas2");
res = mapper.readTree(qs.toJSON());
@@ -613,7 +612,7 @@
}
@Test
- public void testOPOV() throws QueryException, JsonProcessingException, IOException {
+ public void testOPOV() throws JsonProcessingException, IOException {
query = "wegen #OV <s>";
qs.setQuery(query, "cosmas2");
res = mapper.readTree(qs.toJSON());
@@ -668,7 +667,7 @@
@Test
- public void testBEG_END() throws QueryException, JsonProcessingException, IOException {
+ public void testBEG_END() throws JsonProcessingException, IOException {
query = "#BEG(der /w3:5 Mann)";
qs.setQuery(query, "cosmas2");
res = mapper.readTree(qs.toJSON());
@@ -777,7 +776,7 @@
}
@Test
- public void testELEM() throws QueryException, JsonProcessingException, IOException {
+ public void testELEM() throws JsonProcessingException, IOException {
query = "#ELEM(S)";
qs.setQuery(query, "cosmas2");
res = mapper.readTree(qs.toJSON());
@@ -847,7 +846,7 @@
assertEquals("match:ne", res.at("/query/attr/operands/1/operands/1/match").asText());
}
@Test
- public void testOPALL() throws QueryException, JsonProcessingException, IOException {
+ public void testOPALL() throws JsonProcessingException, IOException {
query = "#ALL(gehen /w1:10 voran)";
qs.setQuery(query, "cosmas2");
res = mapper.readTree(qs.toJSON());
@@ -883,7 +882,7 @@
}
@Test
- public void testOPNHIT() throws QueryException, JsonProcessingException, IOException {
+ public void testOPNHIT() throws JsonProcessingException, IOException {
query = "#NHIT(gehen /w1:10 voran)";
qs.setQuery(query, "cosmas2");
res = mapper.readTree(qs.toJSON());
@@ -944,7 +943,7 @@
}
@Test
- public void testOPBED() throws QueryException, JsonProcessingException, IOException {
+ public void testOPBED() throws JsonProcessingException, IOException {
query = "#BED(der , sa)";
qs.setQuery(query, "cosmas2");
res = mapper.readTree(qs.toJSON());
@@ -1026,7 +1025,7 @@
}
@Test
- public void testColonSeparatedConditions() throws QueryException, JsonProcessingException, IOException {
+ public void testColonSeparatedConditions() throws JsonProcessingException, IOException {
query = "der:sa";
qs.setQuery(query, "cosmas2");
res = mapper.readTree(qs.toJSON());
diff --git a/src/test/java/CqlQueryProcessorTest.java b/src/test/java/CqlQueryProcessorTest.java
index 7fd62ae..91917f1 100644
--- a/src/test/java/CqlQueryProcessorTest.java
+++ b/src/test/java/CqlQueryProcessorTest.java
@@ -10,7 +10,6 @@
import de.ids_mannheim.korap.query.serialize.CqlQueryProcessor;
import de.ids_mannheim.korap.query.serialize.Cosmas2QueryProcessor;
-import de.ids_mannheim.korap.query.serialize.util.QueryException;
public class CqlQueryProcessorTest {
@@ -24,7 +23,7 @@
query = "(Kuh) prox (Germ) ";
try {
CqlQueryProcessor cqlTree = new CqlQueryProcessor(query, version);
- } catch (QueryException e) {
+ } catch (Exception e) {
int errorCode = Integer.parseInt(e.getMessage().split(":")[0].replace("SRU diagnostic ", ""));
assertEquals(48,errorCode);
}
@@ -32,7 +31,7 @@
query = "(Kuh) or/rel.combine=sum (Germ) ";
try {
CqlQueryProcessor cqlTree = new CqlQueryProcessor(query, version);
- }catch (QueryException e) {
+ }catch (Exception e) {
int errorCode = Integer.parseInt(e.getMessage().split(":")[0].replace("SRU diagnostic ", ""));
assertEquals(20,errorCode);
}
@@ -40,7 +39,7 @@
query = "dc.title any Germ ";
try {
CqlQueryProcessor cqlTree = new CqlQueryProcessor(query, version);
- } catch (QueryException e) {
+ } catch (Exception e) {
int errorCode = Integer.parseInt(e.getMessage().split(":")[0].replace("SRU diagnostic ", ""));
assertEquals(16,errorCode);
}
@@ -48,7 +47,7 @@
query = "cql.serverChoice any Germ ";
try {
CqlQueryProcessor cqlTree = new CqlQueryProcessor(query, version);
- } catch (QueryException e) {
+ } catch (Exception e) {
int errorCode = Integer.parseInt(e.getMessage().split(":")[0].replace("SRU diagnostic ", ""));
assertEquals(19,errorCode);
}
@@ -56,14 +55,14 @@
query = "";
try {
CqlQueryProcessor cqlTree = new CqlQueryProcessor(query, version);
- } catch (QueryException e) {
+ } catch (Exception e) {
int errorCode = Integer.parseInt(e.getMessage().split(":")[0].replace("SRU diagnostic ", ""));
assertEquals(27,errorCode);
}
}
@Test
- public void testAndQuery() throws CQLParseException, IOException, QueryException{
+ public void testAndQuery() throws CQLParseException, IOException, Exception{
query="(Sonne) and (scheint)";
String jsonLd =
"{@type : korap:group, operation : operation:sequence, inOrder : false," +
@@ -84,7 +83,7 @@
}
@Test
- public void testBooleanQuery() throws CQLParseException, IOException, QueryException{
+ public void testBooleanQuery() throws CQLParseException, IOException, Exception{
query="((Sonne) or (Mond)) and (scheint)";
String jsonLd =
"{@type:korap:group, operation:operation:sequence, inOrder : false, distances:[" +
@@ -119,7 +118,7 @@
}
@Test
- public void testOrQuery() throws CQLParseException, IOException, QueryException{
+ public void testOrQuery() throws CQLParseException, IOException, Exception{
query = "(Sonne) or (Mond)";
String jsonLd =
"{@type:korap:group, operation:operation:or, operands:[" +
@@ -163,7 +162,7 @@
}
@Test
- public void testTermQuery() throws CQLParseException, IOException, QueryException{
+ public void testTermQuery() throws CQLParseException, IOException, Exception{
query = "Sonne";
String jsonLd = "{@type:korap:token, wrap:{@type:korap:term, key:Sonne, layer:orth, match:match:eq}}";
CqlQueryProcessor cqlTree = new CqlQueryProcessor(query, version);
@@ -172,7 +171,7 @@
}
@Test
- public void testPhraseQuery() throws CQLParseException, IOException, QueryException{
+ public void testPhraseQuery() throws CQLParseException, IOException, Exception{
query="\"der Mann\"";
String jsonLd =
"{@type:korap:group, operation:operation:sequence, operands:[" +
diff --git a/src/test/java/PoliqarpPlusQueryProcessorTest.java b/src/test/java/PoliqarpPlusQueryProcessorTest.java
index d5b5890..309bdc6 100644
--- a/src/test/java/PoliqarpPlusQueryProcessorTest.java
+++ b/src/test/java/PoliqarpPlusQueryProcessorTest.java
@@ -12,7 +12,6 @@
import de.ids_mannheim.korap.query.serialize.QuerySerializer;
-import de.ids_mannheim.korap.query.serialize.util.QueryException;
/**
* Tests for JSON-LD serialization of PoliqarpPlus queries.
@@ -29,7 +28,7 @@
JsonNode res;
@Test
- public void testContext() throws QueryException, JsonProcessingException, IOException {
+ public void testContext() throws JsonProcessingException, IOException {
query = "foo";
String contextString = "http://ids-mannheim.de/ns/KorAP/json-ld/v0.2/context.jsonld";
qs.setQuery(query, "poliqarpplus");
@@ -38,7 +37,7 @@
}
@Test
- public void testSingleTokens() throws QueryException, JsonProcessingException, IOException {
+ public void testSingleTokens() throws JsonProcessingException, IOException {
query = "[base=Mann]";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -82,7 +81,7 @@
}
@Test
- public void testValue() throws QueryException, JsonProcessingException, IOException {
+ public void testValue() throws JsonProcessingException, IOException {
query = "[mate/m=temp:pres]";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -96,7 +95,7 @@
}
@Test
- public void testRegex() throws QueryException, JsonProcessingException, IOException {
+ public void testRegex() throws JsonProcessingException, IOException {
query = "[orth=\"M(a|ä)nn(er)?\"]";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -140,7 +139,7 @@
}
@Test
- public void testCaseSensitivityFlag() throws QueryException, JsonProcessingException, IOException {
+ public void testCaseSensitivityFlag() throws JsonProcessingException, IOException {
query = "[orth=deutscher/i]";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -207,7 +206,7 @@
}
@Test
- public void testSpans() throws QueryException, JsonProcessingException, IOException {
+ public void testSpans() throws JsonProcessingException, IOException {
query = "<s>";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -283,7 +282,7 @@
}
@Test
- public void testDistances() throws QueryException, JsonProcessingException, IOException {
+ public void testDistances() throws JsonProcessingException, IOException {
query = "[base=der][][base=Mann]";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -439,7 +438,7 @@
}
@Test
- public void testDistancesWithClass() throws QueryException, JsonProcessingException, IOException {
+ public void testDistancesWithClass() throws JsonProcessingException, IOException {
query = "[base=der]{[]}[base=Mann]";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -482,7 +481,7 @@
}
@Test
- public void testLeadingTrailingEmptyTokens() throws QueryException, JsonProcessingException, IOException {
+ public void testLeadingTrailingEmptyTokens() throws JsonProcessingException, IOException {
query = "[][base=Mann]";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -512,7 +511,7 @@
}
@Test
- public void testRepetition() throws QueryException, JsonProcessingException, IOException {
+ public void testRepetition() throws JsonProcessingException, IOException {
query = "der{3}";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -554,7 +553,7 @@
};
@Test
- public void testGroupRepetition() throws QueryException, JsonProcessingException, IOException {
+ public void testGroupRepetition() throws JsonProcessingException, IOException {
query = "contains(<s>, (der){3})";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -591,7 +590,7 @@
};
@Test
- public void testPositions() throws QueryException, JsonProcessingException, IOException {
+ public void testPositions() throws JsonProcessingException, IOException {
query = "contains(<s>, der)";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -674,7 +673,7 @@
};
@Test
- public void testCoordinatedFields() throws QueryException, JsonProcessingException, IOException {
+ public void testCoordinatedFields() throws JsonProcessingException, IOException {
query = "[base=Mann&(cas=N|cas=A)]";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -705,7 +704,7 @@
}
@Test
- public void testTokenSequence() throws QueryException, JsonProcessingException, IOException {
+ public void testTokenSequence() throws JsonProcessingException, IOException {
query = "[base=Mann][orth=Frau]";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -730,7 +729,7 @@
}
@Test
- public void testDisjSegments() throws QueryException, JsonProcessingException, IOException {
+ public void testDisjSegments() throws JsonProcessingException, IOException {
query = "[base=der]|[base=das]";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -822,7 +821,7 @@
}
@Test
- public void testTokenSpanSequence() throws QueryException, JsonProcessingException, IOException {
+ public void testTokenSpanSequence() throws JsonProcessingException, IOException {
query = "[base=Mann]<vp>";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -857,7 +856,7 @@
}
@Test
- public void testClasses() throws QueryException, JsonProcessingException, IOException {
+ public void testClasses() throws JsonProcessingException, IOException {
query = "{[base=Mann]}";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -912,7 +911,7 @@
}
@Test
- public void testFocusSplit() throws QueryException, JsonProcessingException, IOException {
+ public void testFocusSplit() throws JsonProcessingException, IOException {
query = "focus([orth=Der]{[orth=Mann]})";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -997,7 +996,7 @@
}
@Test
- public void testSubmatch() throws QueryException, JsonProcessingException, IOException {
+ public void testSubmatch() throws JsonProcessingException, IOException {
query = "submatch(1,:<s>)";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -1027,7 +1026,7 @@
assertEquals("Haus", res.at("/query/operands/0/operands/1/wrap/key").asText());
}
@Test
- public void testRelations() throws QueryException, JsonProcessingException, IOException {
+ public void testRelations() throws JsonProcessingException, IOException {
query = "relatesTo(<s>,<np>)";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -1104,7 +1103,7 @@
}
@Test
- public void testAlign() throws QueryException, JsonProcessingException, IOException {
+ public void testAlign() throws JsonProcessingException, IOException {
query = "[orth=der]^[orth=Mann]";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());
@@ -1157,7 +1156,7 @@
}
@Test
- public void testSimpleQueries() throws QueryException, JsonProcessingException, IOException {
+ public void testSimpleQueries() throws JsonProcessingException, IOException {
query = "Baum";
qs.setQuery(query, "poliqarpplus");
res = mapper.readTree(qs.toJSON());