package org.apache.lucene.queryparser.flexible.aqp.processors;
import java.util.List;
import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
import org.apache.lucene.queryparser.flexible.core.config.QueryConfigHandler;
import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages;
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessor;
import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessorImpl;
import org.apache.lucene.queryparser.flexible.aqp.nodes.AqpANTLRNode;
import org.apache.lucene.queryparser.flexible.aqp.nodes.AqpFuzzyModifierNode;
import org.apache.lucene.queryparser.flexible.aqp.parser.AqpStandardQueryConfigHandler;
/**
* Sets the node into the BoostQueryNode, this processor requires that
* {@link AqpTMODIFIERProcessor} ran before. Because we depend on the proper
* tree shape.
*
* <p>
*
* If BOOST 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>
* FUZZY
* / \
* ~0.1 rest
* </pre>
*
* We create a new node {@link AqpFuzzyModifierNode} (rest, 0.1) and
* return that node.
*
* <p>
*
* Presence of the BOOST node child means user specified at least "^" We'll use
* the default from the configuration.
*
* @see AqpTMODIFIERProcessor
* @see AqpFUZZYProcessor
*/
public class AqpFUZZYProcessor extends QueryNodeProcessorImpl implements
QueryNodeProcessor {
@Override
protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
if (node instanceof AqpANTLRNode
&& ((AqpANTLRNode) node).getTokenLabel().equals("FUZZY")) {
if (node.getChildren().size() == 1) {
return node.getChildren().get(0);
}
Float fuzzy = getFuzzyValue(node);
if (fuzzy == null) {
return node.getChildren().get(node.getChildren().size() - 1);
}
return new AqpFuzzyModifierNode(node.getChildren().get(
node.getChildren().size() - 1), fuzzy);
}
return node;
}
@Override
protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
return node;
}
@Override
protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
throws QueryNodeException {
return children;
}
private Float getFuzzyValue(QueryNode fuzzyNode) throws QueryNodeException {
if (fuzzyNode.getChildren() != null) {
AqpANTLRNode child = ((AqpANTLRNode) fuzzyNode.getChildren().get(0));
String input = child.getTokenInput();
float fuzzy;
if (input.equals("~")) {
QueryConfigHandler queryConfig = getQueryConfigHandler();
if (queryConfig == null
|| !queryConfig
.has(AqpStandardQueryConfigHandler.ConfigurationKeys.IMPLICIT_FUZZY)) {
throw new QueryNodeException(
new MessageImpl(
QueryParserMessages.LUCENE_QUERY_CONVERSION_ERROR,
"Configuration error: "
+ AqpStandardQueryConfigHandler.ConfigurationKeys.IMPLICIT_FUZZY
.toString() + " is missing"));
}
fuzzy = queryConfig
.get(AqpStandardQueryConfigHandler.ConfigurationKeys.IMPLICIT_FUZZY);
} else {
fuzzy = Float.valueOf(input.replace("~", ""));
}
return fuzzy;
}
return null;
}
}