package org.apache.lucene.queryparser.flexible.aqp.processors; import java.util.List; import org.apache.lucene.queryparser.flexible.aqp.parser.AqpStandardQueryConfigHandler; 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.FieldableNode; 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.standard.processors.AnalyzerQueryNodeProcessor; import org.apache.lucene.queryparser.flexible.standard.processors.MatchAllDocsQueryNodeProcessor; import org.apache.lucene.queryparser.flexible.standard.processors.MultiFieldQueryNodeProcessor; /** * This processor changes field value 'null' into ''. * * The processor solves the following problem (probably affecting SOLR only): * * {@link MultiFieldQueryNodeProcessor} looks at {@link FieldableNode} and * eventually creates several instances of them (eg. "query" becomes field:query * fieldb:query). But this works only when the initial field==null. If it was * '', nothing happens. If the current configuration contains * {@link MultiFieldQueryNodeProcessor} but it is empty, also the field will be * null (because DefaultField is by default null) * * {@link AnalyzerQueryNodeProcessor}, on the other hand, expects that field is * a string value - to be precise, it asks the current analyzer to check the * field. And if the field was null, then with SOLR this throws * {@link NullPointerException} * * Please put {@link AqpNullDefaultFieldProcessor} also before * {@link MatchAllDocsQueryNodeProcessor} otherwise you will get * {@link NullPointerException} if the default field is null * * @see FieldableNode * @see MultiFieldQueryNodeProcessor * @see AnalyzerQueryNodeProcessor * */ public class AqpNullDefaultFieldProcessor extends QueryNodeProcessorImpl implements QueryNodeProcessor { @Override protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException { if (node instanceof FieldQueryNode && ((FieldQueryNode) node).getField() == null) { String field = getDefaultFieldName(); if (field != null) { ((FieldQueryNode) node).setField(field); } else { ((FieldQueryNode) node).setField(""); } } 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 String getDefaultFieldName() throws QueryNodeException { QueryConfigHandler queryConfig = getQueryConfigHandler(); if (queryConfig != null) { if (queryConfig .has(AqpStandardQueryConfigHandler.ConfigurationKeys.DEFAULT_FIELD)) { return queryConfig .get(AqpStandardQueryConfigHandler.ConfigurationKeys.DEFAULT_FIELD); } } return null; } }