package org.infinispan.query.dsl.embedded.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.infinispan.objectfilter.impl.syntax.parser.IckleParsingResult;
import org.infinispan.query.CacheQuery;
import org.infinispan.query.dsl.QueryFactory;
import org.infinispan.query.dsl.impl.BaseQuery;
/**
* A query implementation based on Lucene.
*
* @author anistor@redhat.com
* @since 6.0
*/
final class EmbeddedLuceneQuery<TypeMetadata> extends BaseQuery {
private final QueryEngine<TypeMetadata> queryEngine;
private final ResultProcessor resultProcessor;
private final IckleParsingResult<TypeMetadata> parsingResult;
/**
* An Infinispan Cache query that wraps an actual Lucene query object. This is built lazily when the query is
* executed first.
*/
private CacheQuery<Object> cacheQuery;
/**
* The cached results, lazily evaluated.
*/
private List<Object> results;
EmbeddedLuceneQuery(QueryEngine<TypeMetadata> queryEngine, QueryFactory queryFactory,
Map<String, Object> namedParameters, IckleParsingResult<TypeMetadata> parsingResult,
String[] projection, ResultProcessor resultProcessor,
long startOffset, int maxResults) {
super(queryFactory, parsingResult.getQueryString(), namedParameters, projection, startOffset, maxResults);
if (resultProcessor instanceof RowProcessor && (projection == null || projection.length == 0)) {
throw new IllegalArgumentException("A RowProcessor can only be specified with projections");
}
this.queryEngine = queryEngine;
this.resultProcessor = resultProcessor;
this.parsingResult = parsingResult;
}
@Override
public void resetQuery() {
results = null;
cacheQuery = null;
}
private CacheQuery<Object> createCacheQuery() {
// query is created first time only
if (cacheQuery == null) {
validateNamedParameters();
cacheQuery = queryEngine.buildLuceneQuery(parsingResult, namedParameters, startOffset, maxResults);
}
return cacheQuery;
}
@Override
@SuppressWarnings("unchecked")
public <T> List<T> list() {
if (results == null) {
results = listInternal();
}
return (List<T>) results;
}
private List<Object> listInternal() {
List<Object> list = createCacheQuery().list();
if (resultProcessor != null) {
results = new ArrayList<>(list.size());
list.forEach(r -> results.add(resultProcessor.process(r)));
} else {
results = list;
}
return results;
}
@Override
public int getResultSize() {
return createCacheQuery().getResultSize();
}
@Override
public String toString() {
return "EmbeddedLuceneQuery{" +
"queryString=" + queryString +
", namedParameters=" + namedParameters +
'}';
}
}