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.FieldQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.FuzzyQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.QuotedFieldQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.SlopQueryNode; import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessor; import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessorImpl; import org.apache.lucene.queryparser.flexible.standard.nodes.WildcardQueryNode; import org.apache.lucene.queryparser.flexible.aqp.config.AqpFeedback; import org.apache.lucene.queryparser.flexible.aqp.nodes.AqpFuzzyModifierNode; import org.apache.lucene.queryparser.flexible.aqp.nodes.SlowFuzzyQueryNode; import org.apache.lucene.queryparser.flexible.aqp.parser.AqpStandardQueryConfigHandler; /** * Rewrites the query node which is below the {@link AqpFuzzyModifierNode} * * The actions are: <p> * * * {@link FieldQueryNode} <p> * - query is turned into {@link FuzzyQueryNode} or {@link SlowFuzzyQueryNode} <p> * depending the configuration of {@link AqpStandardQueryConfigHandler}.ConfigurationKeys.ALLOW_SLOW_FUZZY * - invalid syntax is raised if not 0.0 > fuzzy < 1.0 <p> * * {@link WildcardQueryNode}, {@link QuotedFieldQueryNode} <p> * - becomes {@link SlopQueryNode} <p> * * * {@link QuotedFieldQueryNode} <p> * - wrapped with {@link SlopQueryNode} * * */ public class AqpFuzzyModifierProcessor extends QueryNodeProcessorImpl implements QueryNodeProcessor { @Override protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException { if (node instanceof AqpFuzzyModifierNode) { QueryNode child = ((AqpFuzzyModifierNode) node).getChild(); Float fuzzy = ((AqpFuzzyModifierNode) node).getFuzzyValue(); QueryConfigHandler config = getQueryConfigHandler(); if (child instanceof QuotedFieldQueryNode || child instanceof WildcardQueryNode) { if (fuzzy.intValue() < fuzzy) { if (config .has(AqpStandardQueryConfigHandler.ConfigurationKeys.FEEDBACK)) { AqpFeedback feedback = config .get(AqpStandardQueryConfigHandler.ConfigurationKeys.FEEDBACK); feedback.sendEvent(feedback.createEvent(AqpFeedback.TYPE.WARN, this.getClass(), node, "For phrases and wildcard queries the float attribute " + fuzzy + " is automatically converted to: " + fuzzy.intValue())); } } return new SlopQueryNode(child, fuzzy.intValue()); } else if (child instanceof FieldQueryNode) { FieldQueryNode fn = (FieldQueryNode) child; if (config .has(AqpStandardQueryConfigHandler.ConfigurationKeys.ALLOW_SLOW_FUZZY) != false && config .get(AqpStandardQueryConfigHandler.ConfigurationKeys.ALLOW_SLOW_FUZZY) == true) { if (fuzzy > 0.0f && fuzzy <= 1.0f) { return new SlowFuzzyQueryNode(fn.getFieldAsString(), fn.getTextAsString(), fuzzy, fn.getBegin(), fn.getEnd()); } } return new FuzzyQueryNode(fn.getFieldAsString(), fn.getTextAsString(), fuzzy, fn.getBegin(), fn.getEnd()); } else { throw new QueryNodeException(new MessageImpl( QueryParserMessages.INVALID_SYNTAX, node.toString() + "\nUse of ~ is not allowed here")); } } return node; } @Override protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException { return node; } @Override protected List<QueryNode> setChildrenOrder(List<QueryNode> children) throws QueryNodeException { return children; } }