package org.apache.lucene.queryparser.flexible.aqp.processors; import org.apache.lucene.queryparser.flexible.core.QueryNodeException; import org.apache.lucene.queryparser.flexible.core.config.QueryConfigHandler; import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode; import org.apache.lucene.queryparser.flexible.standard.nodes.TermRangeQueryNode; import org.apache.lucene.queryparser.flexible.standard.parser.EscapeQuerySyntaxImpl; import org.apache.lucene.queryparser.flexible.aqp.nodes.AqpANTLRNode; /** * Converts QRANGEIN node into {@link TermRangeQueryNode}. The field * value is the @{link DefaultFieldAttribute} specified in the configuration. * * Because QRANGE nodes have this shape: * * <pre> * QRANGE * / \ * QNORMAL QPHRASE * / \ * some "phrase" * </pre> * * It is important to queue {@AqpQRANGEEProcessor} and * {@AqpQRANGEINProcessor} <b>before</b> processors that * transform QNORMAL, QPHRASE and other Q nodes * <p> * If the user specified a field, it will be set by the @{link * AqpFIELDProcessor} Therefore this processor should queue before @{link * AqpFIELDProcessor}. * * * @see QueryConfigHandler * @see AqpQRANGEEXProcessor * */ public class AqpQRANGEINProcessor extends AqpQProcessor { protected boolean lowerInclusive = true; protected boolean upperInclusive = true; public boolean nodeIsWanted(AqpANTLRNode node) { if (node.getTokenLabel().equals("QRANGEIN")) { return true; } return false; } public QueryNode createQNode(AqpANTLRNode node) throws QueryNodeException { String field = getDefaultFieldName(); AqpANTLRNode lowerNode = (AqpANTLRNode) node.getChildren().get(0); AqpANTLRNode upperNode = (AqpANTLRNode) node.getChildren().get(1); NodeData lower = getTokenInput(lowerNode); NodeData upper = getTokenInput(upperNode); FieldQueryNode lowerBound = new FieldQueryNode(field, EscapeQuerySyntaxImpl.discardEscapeChar(lower.value), lower.start, lower.end); FieldQueryNode upperBound = new FieldQueryNode(field, EscapeQuerySyntaxImpl.discardEscapeChar(upper.value), upper.start, upper.end); return new TermRangeQueryNode(lowerBound, upperBound, lowerInclusive, upperInclusive); } public NodeData getTokenInput(AqpANTLRNode node) { String label = node.getTokenLabel(); AqpANTLRNode subNode = (AqpANTLRNode) node.getChildren().get(0); if (label.equals("QANYTHING")) { return new NodeData("*", subNode.getTokenStart(), subNode.getTokenEnd()); } else if (label.contains("PHRASE")) { return new NodeData(subNode.getTokenInput().substring(1, subNode.getTokenInput().length() - 1), subNode.getTokenStart() + 1, subNode.getTokenEnd() - 1); } else { return new NodeData(subNode.getTokenInput(), subNode.getTokenStart(), subNode.getTokenEnd()); } } class NodeData { public String value; public int start; public int end; NodeData(String value, int start, int end) { this.value = value; this.start = start; this.end = end; } } }