package org.apache.lucene.queryparser.flexible.aqp.processors;
import java.util.List;
import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode;
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.config.AqpAdsabsQueryConfigHandler;
import org.apache.lucene.queryparser.flexible.aqp.nodes.AqpAdsabsSynonymQueryNode;
import org.apache.lucene.queryparser.flexible.aqp.nodes.AqpNonAnalyzedQueryNode;
import org.apache.solr.request.SolrQueryRequest;
/**
* If the node is {@link AqpAdsabsSynonymQueryNode} we'll check
* whether to analyze it. If yes, it will be passed to the normal
* analyzer for that given field. If not, then it will be processed
* by analyzers of our choice
*
* @author rchyla
*
*/
public class AqpAdsabsSynonymNodeProcessor extends QueryNodeProcessorImpl implements
QueryNodeProcessor {
@Override
protected QueryNode preProcessNode(QueryNode node)
throws QueryNodeException {
return node;
}
@Override
protected QueryNode postProcessNode(QueryNode node)
throws QueryNodeException {
if (node instanceof AqpAdsabsSynonymQueryNode) {
AqpAdsabsSynonymQueryNode synNode = (AqpAdsabsSynonymQueryNode) node;
if (synNode.isActivated()) {
return expandSynonyms(synNode);
}
else {
return applyNonAnalyzableToAllChildren(synNode.getChild());
}
}
return node;
}
protected QueryNode applyNonAnalyzableToAllChildren(QueryNode node) {
if (node instanceof AqpNonAnalyzedQueryNode) {
return node;
}
else if (node instanceof FieldQueryNode) {
if (node.getTag("aqp.exact") != null) {
// this node had a modifier (= or #)
// which only modifies the analysis, but doesn't turn it off
String field = ((FieldQueryNode) node).getFieldAsString() + "_nosyn";
if (hasAnalyzer(field)) {
((FieldQueryNode) node).setField(field); // change the field to use a different analyzer...
return node;
}
}
// catch all, avoid analysis
return new AqpNonAnalyzedQueryNode((FieldQueryNode) node);
}
List<QueryNode> children = node.getChildren();
if (children!=null) {
for (int i=0; i<children.size();i++) {
children.set(i, applyNonAnalyzableToAllChildren(children.get(i)));
}
node.set(children);
}
return node;
}
protected QueryNode expandSynonyms(AqpAdsabsSynonymQueryNode synNode) {
// I believe it is the job of the analyzers to expand the node, but it may depend...
return synNode.getChild();
}
// TODO: consider merging with AqpAdsabsCarefulAnalyzerProcessor
// where this code was copied from
private boolean hasAnalyzer(String fieldName) {
SolrQueryRequest req = this.getQueryConfigHandler()
.get(AqpAdsabsQueryConfigHandler.ConfigurationKeys.SOLR_REQUEST)
.getRequest();
if (req != null && req.getSchema().hasExplicitField(fieldName)) {
return true;
}
return false;
}
@Override
protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
throws QueryNodeException {
return children;
}
}