/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.search.test.id.providedId;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.similarities.ClassicSimilarity;
import org.apache.lucene.search.similarities.Similarity;
import org.hibernate.search.backend.spi.Work;
import org.hibernate.search.backend.spi.WorkType;
import org.hibernate.search.engine.integration.impl.ExtendedSearchIntegrator;
import org.hibernate.search.engine.spi.EntityIndexBinding;
import org.hibernate.search.query.engine.QueryTimeoutException;
import org.hibernate.search.query.engine.impl.DocumentExtractorImpl;
import org.hibernate.search.query.engine.impl.LazyQueryState;
import org.hibernate.search.query.engine.impl.QueryFilters;
import org.hibernate.search.query.engine.impl.QueryHits;
import org.hibernate.search.query.engine.impl.TimeoutManagerImpl;
import org.hibernate.search.query.engine.spi.DocumentExtractor;
import org.hibernate.search.testsupport.TestConstants;
import org.hibernate.search.testsupport.junit.SearchFactoryHolder;
import org.hibernate.search.testsupport.junit.SkipOnElasticsearch;
import org.hibernate.search.testsupport.setup.TransactionContextForTest;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
* @author Navin Surtani
* @author Sanne Grinovero
*/
@Category(SkipOnElasticsearch.class) // This test is specific to Lucene
public class ProvidedIdTest {
@Rule
public SearchFactoryHolder configuration = new SearchFactoryHolder( ProvidedIdPerson.class, ProvidedIdPersonSub.class );
@Test
public void testProvidedId() throws Exception {
ExtendedSearchIntegrator extendedIntegrator = configuration.getSearchFactory();
ProvidedIdPerson person1 = new ProvidedIdPerson();
person1.setName( "Big Goat" );
person1.setBlurb( "Eats grass" );
ProvidedIdPerson person2 = new ProvidedIdPerson();
person2.setName( "Mini Goat" );
person2.setBlurb( "Eats cheese" );
ProvidedIdPersonSub person3 = new ProvidedIdPersonSub();
person3.setName( "Regular goat" );
person3.setBlurb( "Is anorexic" );
TransactionContextForTest tc = new TransactionContextForTest();
Work work = new Work( person1, 1, WorkType.INDEX );
extendedIntegrator.getWorker().performWork( work, tc );
work = new Work( person2, 2, WorkType.INDEX );
extendedIntegrator.getWorker().performWork( work, tc );
Work work2 = new Work( person3, 3, WorkType.INDEX );
extendedIntegrator.getWorker().performWork( work2, tc );
tc.end();
QueryParser parser = new QueryParser( "name", TestConstants.standardAnalyzer );
Query luceneQuery = parser.parse( "Goat" );
//we cannot use FTQuery because @ProvidedId does not provide the getter id and Hibernate Search Query extension
//needs it. So we use plain Lucene
IndexReader indexReader = extendedIntegrator.getIndexReaderAccessor().open( ProvidedIdPerson.class );
IndexSearcher searcher = new IndexSearcher( indexReader );
TopDocs hits = searcher.search( luceneQuery, 1000 );
assertEquals( 3, hits.totalHits );
final Similarity defaultSimilarity = new ClassicSimilarity();
//follows an example of what Infinispan Query actually needs to resolve a search request:
LazyQueryState lowLevelSearcher = new LazyQueryState(
luceneQuery,
QueryFilters.EMPTY_FILTERSET,
indexReader,
defaultSimilarity,
extendedIntegrator,
extendedIntegrator.getIndexBindings().values(),
false,
false
);
QueryHits queryHits = new QueryHits(
lowLevelSearcher, QueryFilters.EMPTY_FILTERSET, null,
new TimeoutManagerImpl( luceneQuery, QueryTimeoutException.DEFAULT_TIMEOUT_EXCEPTION_FACTORY, extendedIntegrator.getTimingSource() ),
null,
null,
null,
null
);
Set<String> identifiers = new HashSet<String>();
identifiers.add( "providedId" );
Map<String, EntityIndexBinding> targetedEntityBindings = new HashMap<>();
targetedEntityBindings.put( ProvidedIdPerson.class.getName(), extendedIntegrator.getIndexBinding( ProvidedIdPerson.class ) );
targetedEntityBindings.put( ProvidedIdPersonSub.class.getName(), extendedIntegrator.getIndexBinding( ProvidedIdPersonSub.class ) );
DocumentExtractor extractor = new DocumentExtractorImpl(
queryHits, extendedIntegrator, new String[] { "name" },
identifiers, false,
lowLevelSearcher,
0, 0, //not used in this case
targetedEntityBindings
);
HashSet<String> titles = new HashSet<String>( 3 );
for ( int id = 0; id < hits.totalHits; id++ ) {
String projectedTitle = (String) extractor.extract( id ).getProjection()[0];
assertNotNull( projectedTitle );
titles.add( projectedTitle );
}
assertTrue( titles.contains( "Regular goat" ) );
assertTrue( titles.contains( "Mini Goat" ) );
assertTrue( titles.contains( "Big Goat" ) );
extendedIntegrator.getIndexReaderAccessor().close( indexReader );
}
}