package org.apache.lucene.queryparser.flexible.aqp.processors;
import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages;
import org.apache.lucene.queryparser.flexible.core.nodes.ModifierQueryNode;
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
import org.apache.lucene.queryparser.flexible.aqp.nodes.AqpANTLRNode;
import org.apache.lucene.queryparser.flexible.aqp.nodes.AqpBooleanQueryNode;
/**
* Creates a {@link ModifierQueryNode} from the MODIFIER node last child
*
* If MODIFIER node contains only one child, we return that child and do
* nothing.
*
* <p>
*
* If BOOST node contains two children, we take the first and check its input,
* eg.
*
* <pre>
* MODIFIER
* / \
* + rest
* </pre>
*
* We create a new node ModifierQueryNode(rest, Modifier) and return that node.
*
* <p>
*
* This processor should run before {@link AqpOPERATORProcessor} to ensure that
* local modifiers have precedence over the boolean operations. For example:
*
* <pre>
* title:(+a -b c)
* </pre>
*
* Should produce (when OR is a default operator):
*
* <pre>
* +title:a -title:b title:c
* </pre>
*
* and when AND is the default operator:
*
* <pre>
* +title:a -title:b +title:c
* </pre>
*
* @see AqpBooleanQueryNode
*/
public class AqpMODIFIERProcessor extends AqpQProcessor {
public boolean nodeIsWanted(AqpANTLRNode node) {
if (node.getTokenLabel().equals("MODIFIER")) {
return true;
}
return false;
}
public AqpANTLRNode getModifierNode(QueryNode node) {
return ((AqpANTLRNode) node.getChildren().get(0));
}
public QueryNode getValueNode(QueryNode node) {
return node.getChildren().get(node.getChildren().size() - 1);
}
public QueryNode createQNode(AqpANTLRNode node) throws QueryNodeException {
if (node.getChildren().size() == 1) {
return node.getChildren().get(0);
}
AqpANTLRNode modifierNode = getModifierNode(node);
String modifier = modifierNode.getTokenName();
QueryNode childNode = getValueNode(node);
if (modifier.equals("PLUS")) {
return new ModifierQueryNode(childNode,
ModifierQueryNode.Modifier.MOD_REQ);
} else if (modifier.equals("MINUS")) {
return new ModifierQueryNode(childNode,
ModifierQueryNode.Modifier.MOD_NOT);
} else {
throw new QueryNodeException(new MessageImpl(
QueryParserMessages.LUCENE_QUERY_CONVERSION_ERROR,
"Unknown modifier: " + modifier + "\n" + node.toString()));
}
}
}