/* * Hibernate, Relational Persistence for Idiomatic Java * * Copyright (c) 2010, Red Hat, Inc. and/or its affiliates or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are * distributed under license by Red Hat, Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ package org.hibernate.search.test.util; import java.io.File; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Properties; import java.util.Set; import org.apache.lucene.analysis.StopAnalyzer; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.event.service.spi.EventListenerRegistry; import org.hibernate.event.spi.EventType; import org.hibernate.event.spi.LoadEventListener; import org.hibernate.internal.SessionFactoryImpl; import org.hibernate.search.FullTextSession; import org.hibernate.search.Search; import org.hibernate.search.SearchFactory; import org.hibernate.search.cfg.SearchMapping; import org.hibernate.search.test.TestConstants; import org.hibernate.search.util.impl.FileHelper; import org.hibernate.search.util.logging.impl.Log; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistryBuilder; import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.testing.cache.CachingRegionFactory; /** * Use the builder pattern to provide a SessionFactory. * This is meant to use only ram-based index and databases, for those test * which need to use several differently configured SessionFactories. * * @author Sanne Grinovero * @author Hardy Ferentschik */ public class FullTextSessionBuilder { private static final Log log = org.hibernate.search.util.logging.impl.LoggerFactory.make(); public static final File indexRootDirectory; private final Properties cfg = new Properties(); private final Set<Class<?>> annotatedClasses = new HashSet<Class<?>>(); private SessionFactory sessionFactory; private boolean usingFileSystem = false; private final List<LoadEventListener> additionalLoadEventListeners = new ArrayList<LoadEventListener>(); static { String buildDir = System.getProperty( "build.dir" ); if ( buildDir == null ) { buildDir = "."; } File current = new File( buildDir ); indexRootDirectory = new File( current, "indextemp" ); log.debugf( "Using %s as index directory.", indexRootDirectory.getAbsolutePath() ); } public FullTextSessionBuilder() { cfg.setProperty( "hibernate.search.lucene_version", TestConstants.getTargetLuceneVersion().name() ); cfg.setProperty( Environment.HBM2DDL_AUTO, "create-drop" ); //cache: cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "true" ); cfg.setProperty( Environment.CACHE_REGION_FACTORY, CachingRegionFactory.class.getCanonicalName() ); cfg.setProperty( Environment.USE_QUERY_CACHE, "true" ); //search specific: cfg.setProperty( org.hibernate.search.Environment.ANALYZER_CLASS, StopAnalyzer.class.getName() ); useRAMDirectoryProvider( true ); } /** * @param use if true, use indexes in RAM otherwise use FSDirectoryProvider * @return the same builder (this). */ public FullTextSessionBuilder useRAMDirectoryProvider(boolean use) { if ( use ) { cfg.setProperty( "hibernate.search.default.directory_provider", "ram" ); usingFileSystem = false; } else { cfg.setProperty( "hibernate.search.default.directory_provider", "filesystem" ); cfg.setProperty( "hibernate.search.default.indexBase", indexRootDirectory.getAbsolutePath() ); usingFileSystem = true; } return this; } /** * Override before building any parameter, or add new ones. * @param key Property name. * @param value Property value. * @return the same builder (this). */ public FullTextSessionBuilder setProperty(String key, String value) { cfg.setProperty( key, value ); return this; } /** * Adds classes to the SessionFactory being built. * @param annotatedClass The annotated class to add to the configuration. * @return the same builder (this) */ public FullTextSessionBuilder addAnnotatedClass(Class annotatedClass) { annotatedClasses.add( annotatedClass ); return this; } /** * @return a new FullTextSession based upon the built configuration. */ public FullTextSession openFullTextSession() { if ( sessionFactory == null ) { build(); } Session session = sessionFactory.openSession(); return Search.getFullTextSession( session ); } /** * Closes the SessionFactory. * Make sure you close all sessions first */ public void close() { if ( sessionFactory == null ) { throw new java.lang.IllegalStateException( "sessionFactory not yet built" ); } try { sessionFactory.close(); } finally { if ( usingFileSystem ) { cleanupFilesystem(); } } sessionFactory = null; } /** * Builds the sessionFactory as configured so far. */ public FullTextSessionBuilder build() { Configuration hibConfiguration = new Configuration(); for ( Class<?> annotatedClass : annotatedClasses ) { hibConfiguration.addAnnotatedClass( annotatedClass ); } hibConfiguration.getProperties().putAll( cfg ); ServiceRegistryBuilder registryBuilder = new ServiceRegistryBuilder(); registryBuilder.applySettings( hibConfiguration.getProperties() ); final ServiceRegistry serviceRegistry = registryBuilder.buildServiceRegistry(); SessionFactoryImpl sessionFactoryImpl = (SessionFactoryImpl) hibConfiguration.buildSessionFactory( serviceRegistry ); ServiceRegistryImplementor serviceRegistryImplementor = sessionFactoryImpl.getServiceRegistry(); EventListenerRegistry registry = serviceRegistryImplementor.getService( EventListenerRegistry.class ); for ( LoadEventListener listener : additionalLoadEventListeners ) { registry.getEventListenerGroup( EventType.LOAD ).appendListener( listener ); } sessionFactory = sessionFactoryImpl; return this; } /** * @return the SearchFactory */ public SearchFactory getSearchFactory() { FullTextSession fullTextSession = openFullTextSession(); try { return fullTextSession.getSearchFactory(); } finally { fullTextSession.close(); } } /** * Defines a programmatic configuration to be used by Search * @return the enabled SearchMapping. change it to define the mapping programmatically. */ public SearchMapping fluentMapping() { SearchMapping mapping = (SearchMapping) cfg.get( org.hibernate.search.Environment.MODEL_MAPPING ); if ( mapping == null ) { mapping = new SearchMapping(); cfg.put( org.hibernate.search.Environment.MODEL_MAPPING, mapping ); } return mapping; } public static void cleanupFilesystem() { FileHelper.delete( indexRootDirectory ); } public FullTextSessionBuilder addLoadEventListener(LoadEventListener additionalLoadEventListener) { additionalLoadEventListeners.add( additionalLoadEventListener ); return this; } }