package org.apache.lucene.queryparser.flexible.aqp.processors;
import java.util.List;
import org.apache.lucene.queryparser.flexible.aqp.nodes.AqpANTLRNode;
import org.apache.lucene.queryparser.flexible.aqp.processors.AqpQProcessor;
import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
/**
* Joins the nodes below DEFOP QN so that 'weak lensing' becomes
* one string "weak lensing"
*
* DEFOP
* |
* / | \
* MODIFIER MOD.. CLAUSE
* / | \
* TMODIFIER TMODIFIER MODIFIER
* / | \
* FIELD FIELD .....
* / |
* QNORMAL QNORMAL
* / |
* weak lensing
*
* becomes:
* DEFOP
* |
* / \
* MODIFIER CLAUSE
* / \
* TMODIFIER MODIFIER
* / \
* FIELD .....
* /
* QNORMAL
* /
* weak lensing
*
*
* Care is taken not to join when the fields are different and
* when there is operator/clause/modifier inbetween
*
* @author rca
*
*/
public class AqpDEFOPChildrenCatenator extends AqpQProcessor {
public boolean nodeIsWanted(AqpANTLRNode node) {
if (node.getTokenLabel().equals("DEFOP")) {
return true;
}
return false;
}
public QueryNode createQNode(AqpANTLRNode node) throws QueryNodeException {
// only one child, do nothing
if (node.getChildren().size() == 1) {
return node;
}
List<QueryNode> children = node.getChildren();
Integer previous = null;
for (int i=0;i<children.size();i++) {
if (isBareNode(children.get(i))) {
if (previous == null) {
previous = i;
}
else if (previous+1 == i) {
joinChildren(children.get(previous), children.get(i));
children.remove(i);
i--;
continue;
}
else {
previous = i;
continue;
}
}
}
return node;
}
private boolean isBareNode(QueryNode node) {
StringBuffer sb = new StringBuffer();
harvestLabels(node, sb, 5);
if (sb.toString().equals("/MODIFIER/TMODIFIER/FIELD/QNORMAL")) {
return true;
}
return false;
}
private void harvestLabels(QueryNode node, StringBuffer data, int maxDepth) {
if (maxDepth > 0 && node instanceof AqpANTLRNode) {
if (node.isLeaf()) {
return; // avoid the terminal node
}
data.append("/");
data.append(((AqpANTLRNode) node).getTokenLabel());
for (QueryNode child: node.getChildren()) {
harvestLabels(child, data, maxDepth-1);
}
}
}
private QueryNode joinChildren(QueryNode first, QueryNode second) {
AqpANTLRNode firstValueNode = (AqpANTLRNode) getTerminalNode(first);
AqpANTLRNode secondValueNode = (AqpANTLRNode) getTerminalNode(second);
firstValueNode.setTokenInput(firstValueNode.getTokenInput() + " " + secondValueNode.getTokenInput());
firstValueNode.getTree().setTokenStopIndex(secondValueNode.getTokenEnd());
return first;
}
}