package querqy.solr;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import org.apache.lucene.analysis.util.ResourceLoader;
import org.apache.lucene.analysis.util.ResourceLoaderAware;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.search.QParser;
import org.apache.solr.search.QParserPlugin;
import org.apache.solr.search.SolrCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import querqy.lucene.rewrite.cache.CacheKey;
import querqy.lucene.rewrite.cache.TermQueryCache;
import querqy.lucene.rewrite.cache.TermQueryCacheValue;
import querqy.parser.QuerqyParser;
import querqy.rewrite.RewriteChain;
import querqy.rewrite.RewriterFactory;
/**
* Abstract superclass for QuerqyDismaxQParserPlugins.
*/
public abstract class AbstractQuerqyDismaxQParserPlugin extends QParserPlugin implements ResourceLoaderAware {
public static final String CONF_CACHE_NAME = "termQueryCache.name";
public static final String CONF_CACHE_UPDATE = "termQueryCache.update";
protected Logger logger = LoggerFactory.getLogger(getClass());
protected NamedList<?> initArgs = null;
protected RewriteChain rewriteChain = null;
protected SolrQuerqyParserFactory querqyParserFactory = null;
protected String termQueryCacheName = null;
protected boolean ignoreTermQueryCacheUpdates = true;
public abstract QParser createParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req, TermQueryCache termQueryCache);
@Override
public void init(@SuppressWarnings("rawtypes") NamedList args) {
this.initArgs = args;
}
@Override
public void inform(ResourceLoader loader) throws IOException {
NamedList<?> parserConfig = (NamedList<?>) initArgs.get("parser");
if (parserConfig == null) {
throw new IOException("Missing querqy parser configuration");
}
String className = (String) parserConfig.get("factory");
if (className == null) {
throw new IOException("Missing attribute 'factory' in querqy parser configuration");
}
SolrQuerqyParserFactory factory = loader.newInstance(className, SolrQuerqyParserFactory.class);
factory.init(parserConfig, loader);
rewriteChain = loadRewriteChain(loader);
termQueryCacheName = (String) initArgs.get(CONF_CACHE_NAME);
Boolean updateCache = initArgs.getBooleanArg(CONF_CACHE_UPDATE);
if (termQueryCacheName == null && updateCache != null) {
throw new IOException("Configuration property " + CONF_CACHE_NAME + " required if " + CONF_CACHE_UPDATE + " is set");
}
ignoreTermQueryCacheUpdates = (updateCache != null) && !updateCache;
this.querqyParserFactory = factory;
}
/**
* Loads the whole {@link RewriteChain}s from the args and returns a list of
* them.
*/
private RewriteChain loadRewriteChain(ResourceLoader loader) throws IOException {
NamedList<?> chainConfig = (NamedList<?>) initArgs.get("rewriteChain");
List<RewriterFactory> factories = new LinkedList<>();
if (chainConfig != null) {
@SuppressWarnings("unchecked")
List<NamedList<?>> rewriterConfigs = (List<NamedList<?>>) chainConfig.getAll("rewriter");
if (rewriterConfigs != null) {
for (NamedList<?> config : rewriterConfigs) {
RewriterFactoryAdapter factory = loader.newInstance((String) config.get("class"),
RewriterFactoryAdapter.class);
factories.add(factory.createRewriterFactory(config, loader));
}
}
}
return new RewriteChain(factories);
}
protected QuerqyParser createQuerqyParser(String qstr, SolrParams localParams, SolrParams params,
SolrQueryRequest req) {
return querqyParserFactory.createParser(qstr, localParams, params, req);
}
@Override
public final QParser createParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) {
if (termQueryCacheName == null) {
return createParser(qstr, localParams, params, req, null);
} else {
@SuppressWarnings("unchecked")
SolrCache<CacheKey, TermQueryCacheValue> solrCache = req.getSearcher().getCache(termQueryCacheName);
if (solrCache == null) {
logger.warn("Missing Solr cache {}", termQueryCacheName);
return createParser(qstr, localParams, params, req, null);
} else {
return createParser(qstr, localParams, params, req, new SolrTermQueryCacheAdapter(ignoreTermQueryCacheUpdates, solrCache));
}
}
}
public RewriteChain getRewriteChain() {
return rewriteChain;
}
}