[hibernate-commits] Hibernate SVN: r19834 - in search/trunk/hibernate-search/src: main/java/org/hibernate/search/backend/impl/lucene and 12 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Mon Jun 28 08:32:47 EDT 2010


Author: epbernard
Date: 2010-06-28 08:32:47 -0400 (Mon, 28 Jun 2010)
New Revision: 19834

Added:
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/ImmutableSearchFactory.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/MutableSearchFactory.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryBuilder.java
Removed:
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java
Modified:
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/batchlucene/DirectoryProviderWorkspace.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/lucene/PerDPResources.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/lucene/works/DeleteExtWorkDelegate.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/lucene/works/LuceneWorkVisitor.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/SearchFactoryImplementor.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/event/ContextHolder.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/event/FullTextIndexEventListener.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/spi/BuildContext.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/spi/WorkerBuildContext.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/store/FSMasterDirectoryProvider.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/SearchTestCase.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/ConfigurationReadTestCase.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/CustomBackendTest.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/errorhandling/LuceneErrorHandlingTest.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdTest.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/jgroups/common/JGroupsCommonTest.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/worker/duplication/WorkDuplicationTest.java
Log:
Merge branch 'immutablefactory'

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/batchlucene/DirectoryProviderWorkspace.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/batchlucene/DirectoryProviderWorkspace.java	2010-06-28 12:31:04 UTC (rev 19833)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/batchlucene/DirectoryProviderWorkspace.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -68,7 +68,7 @@
 		}
 		this.monitor = monitor;
 		workspace = new Workspace( context, dp );
-		visitor = new LuceneWorkVisitor( workspace );
+		visitor = new LuceneWorkVisitor( workspace, context );
 		executor = Executors.newFixedThreadPool( maxThreads, "indexwriter" );
 	}
 

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/lucene/PerDPResources.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/lucene/PerDPResources.java	2010-06-28 12:31:04 UTC (rev 19833)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/lucene/PerDPResources.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -54,7 +54,7 @@
 	
 	PerDPResources(WorkerBuildContext context, DirectoryProvider<?> dp) {
 		workspace = new Workspace( context, dp );
-		visitor = new LuceneWorkVisitor( workspace );
+		visitor = new LuceneWorkVisitor( workspace, context );
 		executor = Executors.newFixedThreadPool( 1, "Directory writer" );
 		exclusiveIndexUsage = context.isExclusiveIndexUsageEnabled( dp );
 		errorHandler = context.getErrorHandler();

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/lucene/works/DeleteExtWorkDelegate.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/lucene/works/DeleteExtWorkDelegate.java	2010-06-28 12:31:04 UTC (rev 19833)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/lucene/works/DeleteExtWorkDelegate.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -33,6 +33,7 @@
 import org.hibernate.search.backend.LuceneWork;
 import org.hibernate.search.backend.Workspace;
 import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
+import org.hibernate.search.spi.WorkerBuildContext;
 import org.hibernate.search.util.LoggerFactory;
 import org.slf4j.Logger;
 
@@ -51,10 +52,10 @@
 	private final DocumentBuilderIndexedEntity<?> builder;
 	private final Logger log = LoggerFactory.make();
 
-	DeleteExtWorkDelegate(Workspace workspace) {
+	DeleteExtWorkDelegate(Workspace workspace, WorkerBuildContext context) {
 		super( workspace );
 		managedType = workspace.getEntitiesInDirectory().iterator().next();
-		builder = workspace.getDocumentBuilder( managedType );
+		builder = context.getDocumentBuilderIndexedEntity( managedType );
 	}
 
 	@Override

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/lucene/works/LuceneWorkVisitor.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/lucene/works/LuceneWorkVisitor.java	2010-06-28 12:31:04 UTC (rev 19833)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/lucene/works/LuceneWorkVisitor.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -30,6 +30,7 @@
 import org.hibernate.search.backend.PurgeAllLuceneWork;
 import org.hibernate.search.backend.WorkVisitor;
 import org.hibernate.search.backend.Workspace;
+import org.hibernate.search.spi.WorkerBuildContext;
 
 /**
  * @author Sanne Grinovero
@@ -41,9 +42,9 @@
 	private final OptimizeWorkDelegate optimizeDelegate;
 	private final PurgeAllWorkDelegate purgeAllDelegate;
 	
-	public LuceneWorkVisitor(Workspace workspace) {
+	public LuceneWorkVisitor(Workspace workspace, WorkerBuildContext context) {
 		if ( workspace.getEntitiesInDirectory().size() == 1 ) {
-			this.deleteDelegate = new DeleteExtWorkDelegate( workspace );
+			this.deleteDelegate = new DeleteExtWorkDelegate( workspace, context );
 		}
 		else {
 			this.deleteDelegate = new DeleteWorkDelegate( workspace );

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/SearchFactoryImplementor.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/SearchFactoryImplementor.java	2010-06-28 12:31:04 UTC (rev 19833)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/SearchFactoryImplementor.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -49,8 +49,6 @@
 public interface SearchFactoryImplementor extends SearchFactory {
 	BackendQueueProcessorFactory getBackendQueueProcessorFactory();
 
-	void setBackendQueueProcessorFactory(BackendQueueProcessorFactory backendQueueProcessorFactory);
-
 	Map<Class<?>, DocumentBuilderIndexedEntity<?>> getDocumentBuildersIndexedEntities();
 
 	<T> DocumentBuilderIndexedEntity<T> getDocumentBuilderIndexedEntity(Class<T> entityType);
@@ -59,8 +57,6 @@
 
 	Worker getWorker();
 
-	void addOptimizerStrategy(DirectoryProvider<?> provider, OptimizerStrategy optimizerStrategy);
-
 	OptimizerStrategy getOptimizerStrategy(DirectoryProvider<?> provider);
 
 	FilterCachingStrategy getFilterCachingStrategy();
@@ -69,22 +65,16 @@
 
 	LuceneIndexingParameters getIndexingParameters(DirectoryProvider<?> provider);
 
-	void addIndexingParameters(DirectoryProvider<?> provider, LuceneIndexingParameters indexingParams);
-
 	String getIndexingStrategy();
 
 	void close();
 
-	void addClassToDirectoryProvider(Class<?> clazz, DirectoryProvider<?> directoryProvider, boolean exclusiveIndexUsage);
-
 	Set<Class<?>> getClassesInDirectoryProvider(DirectoryProvider<?> directoryProvider);
 
 	Set<DirectoryProvider<?>> getDirectoryProviders();
 
 	ReentrantLock getDirectoryProviderLock(DirectoryProvider<?> dp);
 
-	void addDirectoryProvider(DirectoryProvider<?> provider, boolean exclusiveIndexUsage);
-	
 	int getFilterCacheBitResultsSize();
 
 	Set<Class<?>> getIndexedTypesPolymorphic(Class<?>[] classes);

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/event/ContextHolder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/event/ContextHolder.java	2010-06-28 12:31:04 UTC (rev 19833)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/event/ContextHolder.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -30,7 +30,7 @@
 import org.hibernate.cfg.Configuration;
 import org.hibernate.search.cfg.SearchConfigurationFromHibernateCore;
 import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.hibernate.search.impl.SearchFactoryImpl;
+import org.hibernate.search.impl.SearchFactoryBuilder;
 
 /**
  * Holds already built SearchFactory per Hibernate Configuration object
@@ -44,20 +44,22 @@
  * @author Emmanuel Bernard
  */
 public class ContextHolder {
-	private static final ThreadLocal<WeakHashMap<Configuration, SearchFactoryImpl>> contexts =
-			new ThreadLocal<WeakHashMap<Configuration, SearchFactoryImpl>>();
+	private static final ThreadLocal<WeakHashMap<Configuration, SearchFactoryImplementor>> contexts =
+			new ThreadLocal<WeakHashMap<Configuration, SearchFactoryImplementor>>();
 
 	//code doesn't have to be multithreaded because SF creation is not.
 	//this is not a public API, should really only be used during the SessionFactory building
-	public static SearchFactoryImpl getOrBuildSearchFactory(Configuration cfg) {
-		WeakHashMap<Configuration, SearchFactoryImpl> contextMap = contexts.get();
+	public static SearchFactoryImplementor getOrBuildSearchFactory(Configuration cfg) {
+		WeakHashMap<Configuration, SearchFactoryImplementor> contextMap = contexts.get();
 		if ( contextMap == null ) {
-			contextMap = new WeakHashMap<Configuration, SearchFactoryImpl>( 2 );
+			contextMap = new WeakHashMap<Configuration, SearchFactoryImplementor>( 2 );
 			contexts.set( contextMap );
 		}
-		SearchFactoryImpl searchFactory = contextMap.get( cfg );
+		SearchFactoryImplementor searchFactory = contextMap.get( cfg );
 		if ( searchFactory == null ) {
-			searchFactory = new SearchFactoryImpl( new SearchConfigurationFromHibernateCore( cfg ) );
+			searchFactory = new SearchFactoryBuilder()
+					.configuration( new SearchConfigurationFromHibernateCore( cfg ) )
+					.buildSearchFactory();
 			contextMap.put( cfg, searchFactory );
 		}
 		return searchFactory;
@@ -66,9 +68,9 @@
 	//code doesn't have to be multithreaded because SF creation is not.
 	//this is not a public API, should really only be used by the same 
 	public static void removeSearchFactoryFromCache(SearchFactoryImplementor factory) {
-		WeakHashMap<Configuration, SearchFactoryImpl> contextMap = contexts.get();
+		WeakHashMap<Configuration, SearchFactoryImplementor> contextMap = contexts.get();
 		if ( contextMap != null ) {
-			for ( Map.Entry<Configuration, SearchFactoryImpl> entry : contextMap.entrySet() ) {
+			for ( Map.Entry<Configuration, SearchFactoryImplementor> entry : contextMap.entrySet() ) {
 				if ( entry.getValue() == factory ) {
 					contextMap.remove( entry.getKey() );
 				}

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/event/FullTextIndexEventListener.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/event/FullTextIndexEventListener.java	2010-06-28 12:31:04 UTC (rev 19833)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/event/FullTextIndexEventListener.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -62,7 +62,7 @@
 import org.hibernate.search.backend.impl.EventSourceTransactionContext;
 import org.hibernate.search.cfg.SearchConfigurationFromHibernateCore;
 import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.hibernate.search.impl.SearchFactoryImpl;
+import org.hibernate.search.impl.SearchFactoryBuilder;
 import org.hibernate.search.util.LoggerFactory;
 import org.hibernate.search.util.ReflectionHelper;
 import org.hibernate.search.util.WeakIdentityHashMap;
@@ -124,7 +124,9 @@
 		}
 		else {
 			if ( searchFactoryImplementor == null ) {
-				searchFactoryImplementor = new SearchFactoryImpl( new SearchConfigurationFromHibernateCore( cfg ) );
+				searchFactoryImplementor = new SearchFactoryBuilder()
+						.configuration( new SearchConfigurationFromHibernateCore( cfg ) )
+						.buildSearchFactory();
 			}
 		}
 		String indexingStrategy = searchFactoryImplementor.getIndexingStrategy();

Added: search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/ImmutableSearchFactory.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/ImmutableSearchFactory.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/ImmutableSearchFactory.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -0,0 +1,300 @@
+/* $Id$
+ * 
+ * Hibernate, Relational Persistence for Idiomatic Java
+ * 
+ * Copyright (c) 2009, 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.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.search.Similarity;
+import org.slf4j.Logger;
+
+import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.search.Environment;
+import org.hibernate.search.SearchException;
+import org.hibernate.search.Version;
+import org.hibernate.search.backend.BackendQueueProcessorFactory;
+import org.hibernate.search.backend.LuceneIndexingParameters;
+import org.hibernate.search.backend.LuceneWork;
+import org.hibernate.search.backend.OptimizeLuceneWork;
+import org.hibernate.search.backend.Worker;
+import org.hibernate.search.backend.configuration.MaskedProperty;
+import org.hibernate.search.backend.impl.batchlucene.BatchBackend;
+import org.hibernate.search.backend.impl.batchlucene.LuceneBatchBackend;
+import org.hibernate.search.batchindexing.MassIndexerProgressMonitor;
+import org.hibernate.search.engine.DocumentBuilderContainedEntity;
+import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
+import org.hibernate.search.engine.FilterDef;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.hibernate.search.exception.ErrorHandler;
+import org.hibernate.search.filter.FilterCachingStrategy;
+import org.hibernate.search.query.dsl.v2.QueryContextBuilder;
+import org.hibernate.search.query.dsl.v2.impl.ConnectedQueryContextBuilder;
+import org.hibernate.search.reader.ReaderProvider;
+import org.hibernate.search.spi.WorkerBuildContext;
+import org.hibernate.search.store.DirectoryProvider;
+import org.hibernate.search.store.optimization.OptimizerStrategy;
+import org.hibernate.search.util.LoggerFactory;
+import org.hibernate.search.util.PluginLoader;
+import org.hibernate.util.StringHelper;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class ImmutableSearchFactory implements SearchFactoryImplementor, WorkerBuildContext {
+
+	static {
+		Version.touch();
+	}
+
+	private static final Logger log = LoggerFactory.make();
+
+	private final Map<Class<?>, DocumentBuilderIndexedEntity<?>> documentBuildersIndexedEntities;
+	private final Map<Class<?>, DocumentBuilderContainedEntity<?>> documentBuildersContainedEntities;
+	//keep track of the index modifiers per DirectoryProvider since multiple entity can use the same directory provider
+	private final Map<DirectoryProvider<?>, DirectoryProviderData> dirProviderData;
+	private final Worker worker;
+	private final ReaderProvider readerProvider;
+	private final BackendQueueProcessorFactory backendQueueProcessorFactory;
+	private final Map<String, FilterDef> filterDefinitions;
+	private final FilterCachingStrategy filterCachingStrategy;
+	private final Map<String, Analyzer> analyzers;
+	private final AtomicBoolean stopped = new AtomicBoolean( false );
+	private final int cacheBitResultsSize;
+	private final Properties configurationProperties;
+	private final ErrorHandler errorHandler;
+	private final PolymorphicIndexHierarchy indexHierarchy;
+
+	/**
+	 * Each directory provider (index) can have its own performance settings.
+	 */
+	private final Map<DirectoryProvider, LuceneIndexingParameters> dirProviderIndexingParams;
+	private final String indexingStrategy;
+
+	public ImmutableSearchFactory(SearchFactoryBuilder cfg) {
+		this.analyzers = cfg.analyzers;
+		this.backendQueueProcessorFactory = cfg.backendQueueProcessorFactory;
+		this.cacheBitResultsSize = cfg.cacheBitResultsSize;
+		this.configurationProperties = cfg.configurationProperties;
+		this.dirProviderData = cfg.dirProviderData;
+		this.dirProviderIndexingParams = cfg.dirProviderIndexingParams;
+		this.documentBuildersIndexedEntities = cfg.documentBuildersIndexedEntities;
+		this.documentBuildersContainedEntities = cfg.documentBuildersContainedEntities;
+		this.errorHandler = cfg.errorHandler;
+		this.filterCachingStrategy = cfg.filterCachingStrategy;
+		this.filterDefinitions = cfg.filterDefinitions;
+		this.indexHierarchy = cfg.indexHierarchy;
+		this.indexingStrategy = cfg.indexingStrategy;
+		this.readerProvider = cfg.readerProvider;
+		this.worker = cfg.worker;
+	}
+
+
+	public BackendQueueProcessorFactory getBackendQueueProcessorFactory() {
+		return backendQueueProcessorFactory;
+	}
+
+	public String getIndexingStrategy() {
+		return indexingStrategy;
+	}
+
+	public void close() {
+		if ( stopped.compareAndSet( false, true ) ) {  //make sure we only sop once
+			try {
+				worker.close();
+			}
+			catch ( Exception e ) {
+				log.error( "Worker raises an exception on close()", e );
+			}
+
+			try {
+				readerProvider.destroy();
+			}
+			catch ( Exception e ) {
+				log.error( "ReaderProvider raises an exception on destroy()", e );
+			}
+
+			//TODO move directory provider cleaning to DirectoryProviderFactory
+			for ( DirectoryProvider dp : getDirectoryProviders() ) {
+				try {
+					dp.stop();
+				}
+				catch ( Exception e ) {
+					log.error( "DirectoryProvider raises an exception on stop() ", e );
+				}
+			}
+		}
+	}
+
+	public Set<Class<?>> getClassesInDirectoryProvider(DirectoryProvider<?> directoryProvider) {
+		return Collections.unmodifiableSet( dirProviderData.get( directoryProvider ).getClasses() );
+	}
+
+	public Map<Class<?>, DocumentBuilderIndexedEntity<?>> getDocumentBuildersIndexedEntities() {
+		return documentBuildersIndexedEntities;
+	}
+
+	@SuppressWarnings("unchecked")
+	public <T> DocumentBuilderIndexedEntity<T> getDocumentBuilderIndexedEntity(Class<T> entityType) {
+		return ( DocumentBuilderIndexedEntity<T> ) documentBuildersIndexedEntities.get( entityType );
+	}
+
+	@SuppressWarnings("unchecked")
+	public <T> DocumentBuilderContainedEntity<T> getDocumentBuilderContainedEntity(Class<T> entityType) {
+		return ( DocumentBuilderContainedEntity<T> ) documentBuildersContainedEntities.get( entityType );
+	}
+
+	public Set<DirectoryProvider<?>> getDirectoryProviders() {
+		return this.dirProviderData.keySet();
+	}
+
+	public Worker getWorker() {
+		return worker;
+	}
+
+	public void setBackendQueueProcessorFactory(BackendQueueProcessorFactory backendQueueProcessorFactory) {
+		throw new AssertionFailure( "ImmutableSearchFactory is immutable: should never be called");
+	}
+
+	public OptimizerStrategy getOptimizerStrategy(DirectoryProvider<?> provider) {
+		return dirProviderData.get( provider ).getOptimizerStrategy();
+	}
+
+	public LuceneIndexingParameters getIndexingParameters(DirectoryProvider<?> provider) {
+		return dirProviderIndexingParams.get( provider );
+	}
+
+	public ReaderProvider getReaderProvider() {
+		return readerProvider;
+	}
+
+	public DirectoryProvider[] getDirectoryProviders(Class<?> entity) {
+		DocumentBuilderIndexedEntity<?> documentBuilder = getDocumentBuilderIndexedEntity( entity );
+		return documentBuilder == null ? null : documentBuilder.getDirectoryProviders();
+	}
+
+	public void optimize() {
+		Set<Class<?>> clazzs = getDocumentBuildersIndexedEntities().keySet();
+		for ( Class clazz : clazzs ) {
+			optimize( clazz );
+		}
+	}
+
+	public void optimize(Class entityType) {
+		if ( !getDocumentBuildersIndexedEntities().containsKey( entityType ) ) {
+			throw new SearchException( "Entity not indexed: " + entityType );
+		}
+		List<LuceneWork> queue = new ArrayList<LuceneWork>( 1 );
+		queue.add( new OptimizeLuceneWork( entityType ) );
+		getBackendQueueProcessorFactory().getProcessor( queue ).run();
+	}
+
+	public Analyzer getAnalyzer(String name) {
+		final Analyzer analyzer = analyzers.get( name );
+		if ( analyzer == null ) {
+			throw new SearchException( "Unknown Analyzer definition: " + name );
+		}
+		return analyzer;
+	}
+
+	public Analyzer getAnalyzer(Class<?> clazz) {
+		if ( clazz == null ) {
+			throw new IllegalArgumentException( "A class has to be specified for retrieving a scoped analyzer" );
+		}
+
+		DocumentBuilderIndexedEntity<?> builder = documentBuildersIndexedEntities.get( clazz );
+		if ( builder == null ) {
+			throw new IllegalArgumentException(
+					"Entity for which to retrieve the scoped analyzer is not an @Indexed entity: " + clazz.getName()
+			);
+		}
+
+		return builder.getAnalyzer();
+	}
+
+	public QueryContextBuilder buildQueryBuilder() {
+		return new ConnectedQueryContextBuilder( this );
+	}
+
+	public FilterCachingStrategy getFilterCachingStrategy() {
+		return filterCachingStrategy;
+	}
+
+	public FilterDef getFilterDefinition(String name) {
+		return filterDefinitions.get( name );
+	}
+
+	public ReentrantLock getDirectoryProviderLock(DirectoryProvider<?> dp) {
+		return this.dirProviderData.get( dp ).getDirLock();
+	}
+
+	public int getFilterCacheBitResultsSize() {
+		return cacheBitResultsSize;
+	}
+
+	public Set<Class<?>> getIndexedTypesPolymorphic(Class<?>[] classes) {
+		return indexHierarchy.getIndexedClasses( classes );
+	}
+	
+	public BatchBackend makeBatchBackend(MassIndexerProgressMonitor progressMonitor) {
+		BatchBackend batchBackend;
+		String impl = configurationProperties.getProperty( Environment.BATCH_BACKEND );
+		if ( StringHelper.isEmpty( impl ) || "LuceneBatch".equalsIgnoreCase( impl ) ) {
+			batchBackend = new LuceneBatchBackend();
+		}
+		else {
+			batchBackend = PluginLoader.instanceFromName( BatchBackend.class, impl, ImmutableSearchFactory.class,
+					"batchbackend" );
+		}
+		Properties batchBackendConfiguration = new MaskedProperty(
+				this.configurationProperties, Environment.BATCH_BACKEND );
+		batchBackend.initialize( batchBackendConfiguration, progressMonitor, this );
+		return batchBackend;
+	}
+
+	public Similarity getSimilarity(DirectoryProvider<?> provider) {
+		Similarity similarity = dirProviderData.get( provider ).getSimilarity();
+		if ( similarity == null ) throw new SearchException( "Assertion error: a similarity should be defined for each provider" );
+		return similarity;
+	}
+
+	public boolean isExclusiveIndexUsageEnabled(DirectoryProvider<?> provider) {
+		return dirProviderData.get( provider ).isExclusiveIndexUsage();
+	}
+
+	public ErrorHandler getErrorHandler() {
+		return errorHandler;
+	}
+
+	public SearchFactoryImplementor getUninitializedSearchFactory() {
+		return this;
+	}
+}

Added: search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/MutableSearchFactory.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/MutableSearchFactory.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/MutableSearchFactory.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -0,0 +1,147 @@
+package org.hibernate.search.impl;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.search.Similarity;
+
+import org.hibernate.search.backend.BackendQueueProcessorFactory;
+import org.hibernate.search.backend.LuceneIndexingParameters;
+import org.hibernate.search.backend.Worker;
+import org.hibernate.search.backend.impl.batchlucene.BatchBackend;
+import org.hibernate.search.batchindexing.MassIndexerProgressMonitor;
+import org.hibernate.search.engine.DocumentBuilderContainedEntity;
+import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
+import org.hibernate.search.engine.FilterDef;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.hibernate.search.exception.ErrorHandler;
+import org.hibernate.search.filter.FilterCachingStrategy;
+import org.hibernate.search.query.dsl.v2.QueryContextBuilder;
+import org.hibernate.search.reader.ReaderProvider;
+import org.hibernate.search.store.DirectoryProvider;
+import org.hibernate.search.store.optimization.OptimizerStrategy;
+
+/**
+ * Factory delegating to a concrete implementation of another factory,
+ * Useful to swap one factory for another.
+ * Swapping factory is thread safe.
+ *
+ * @author Emmanuel Bernard
+ */
+public class MutableSearchFactory implements SearchFactoryImplementor {
+	private volatile SearchFactoryImplementor delegate;
+
+	void setDelegate(SearchFactoryImplementor delegate) {
+		this.delegate = delegate;
+	}
+
+	public BackendQueueProcessorFactory getBackendQueueProcessorFactory() {
+		return delegate.getBackendQueueProcessorFactory();
+	}
+
+	public Map<Class<?>, DocumentBuilderIndexedEntity<?>> getDocumentBuildersIndexedEntities() {
+		return delegate.getDocumentBuildersIndexedEntities();
+	}
+
+	public <T> DocumentBuilderIndexedEntity<T> getDocumentBuilderIndexedEntity(Class<T> entityType) {
+		return delegate.getDocumentBuilderIndexedEntity( entityType );
+	}
+
+	public <T> DocumentBuilderContainedEntity<T> getDocumentBuilderContainedEntity(Class<T> entityType) {
+		return delegate.getDocumentBuilderContainedEntity( entityType );
+	}
+
+	public Worker getWorker() {
+		return delegate.getWorker();
+	}
+
+	public OptimizerStrategy getOptimizerStrategy(DirectoryProvider<?> provider) {
+		return delegate.getOptimizerStrategy( provider );
+	}
+
+	public FilterCachingStrategy getFilterCachingStrategy() {
+		return delegate.getFilterCachingStrategy();
+	}
+
+	public FilterDef getFilterDefinition(String name) {
+		return delegate.getFilterDefinition( name );
+	}
+
+	public LuceneIndexingParameters getIndexingParameters(DirectoryProvider<?> provider) {
+		return delegate.getIndexingParameters( provider );
+	}
+
+	public String getIndexingStrategy() {
+		return delegate.getIndexingStrategy();
+	}
+
+	public void close() {
+		delegate.close();
+	}
+
+	public Set<Class<?>> getClassesInDirectoryProvider(DirectoryProvider<?> directoryProvider) {
+		return delegate.getClassesInDirectoryProvider( directoryProvider );
+	}
+
+	public Set<DirectoryProvider<?>> getDirectoryProviders() {
+		return delegate.getDirectoryProviders();
+	}
+
+	public ReentrantLock getDirectoryProviderLock(DirectoryProvider<?> dp) {
+		return delegate.getDirectoryProviderLock( dp );
+	}
+
+	public int getFilterCacheBitResultsSize() {
+		return delegate.getFilterCacheBitResultsSize();
+	}
+
+	public Set<Class<?>> getIndexedTypesPolymorphic(Class<?>[] classes) {
+		return delegate.getIndexedTypesPolymorphic( classes );
+	}
+
+	public BatchBackend makeBatchBackend(MassIndexerProgressMonitor progressMonitor) {
+		return delegate.makeBatchBackend( progressMonitor );
+	}
+
+	public Similarity getSimilarity(DirectoryProvider<?> directoryProvider) {
+		return delegate.getSimilarity( directoryProvider );
+	}
+
+	public boolean isExclusiveIndexUsageEnabled(DirectoryProvider<?> provider) {
+		return delegate.isExclusiveIndexUsageEnabled( provider );
+	}
+
+	public ErrorHandler getErrorHandler() {
+		return delegate.getErrorHandler();
+	}
+
+	public ReaderProvider getReaderProvider() {
+		return delegate.getReaderProvider();
+	}
+
+	public DirectoryProvider[] getDirectoryProviders(Class<?> entity) {
+		return delegate.getDirectoryProviders( entity );
+	}
+
+	public void optimize() {
+		delegate.optimize();
+	}
+
+	public void optimize(Class entityType) {
+		delegate.optimize( entityType );
+	}
+
+	public Analyzer getAnalyzer(String name) {
+		return delegate.getAnalyzer( name );
+	}
+
+	public Analyzer getAnalyzer(Class<?> clazz) {
+		return delegate.getAnalyzer( clazz );
+	}
+
+	public QueryContextBuilder buildQueryBuilder() {
+		return delegate.buildQueryBuilder();
+	}
+}

Copied: search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryBuilder.java (from rev 19833, search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java)
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryBuilder.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryBuilder.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -0,0 +1,445 @@
+package org.hibernate.search.impl;
+
+import java.beans.Introspector;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.search.Similarity;
+import org.slf4j.Logger;
+
+import org.hibernate.annotations.common.reflection.MetadataProvider;
+import org.hibernate.annotations.common.reflection.MetadataProviderInjector;
+import org.hibernate.annotations.common.reflection.ReflectionManager;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.java.JavaReflectionManager;
+import org.hibernate.search.Environment;
+import org.hibernate.search.spi.WorkerBuildContext;
+import org.hibernate.search.spi.WritableBuildContext;
+import org.hibernate.search.SearchException;
+import org.hibernate.search.annotations.AnalyzerDef;
+import org.hibernate.search.annotations.AnalyzerDefs;
+import org.hibernate.search.annotations.Factory;
+import org.hibernate.search.annotations.FullTextFilterDef;
+import org.hibernate.search.annotations.FullTextFilterDefs;
+import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.annotations.Key;
+import org.hibernate.search.backend.BackendQueueProcessorFactory;
+import org.hibernate.search.backend.LuceneIndexingParameters;
+import org.hibernate.search.backend.Worker;
+import org.hibernate.search.backend.WorkerFactory;
+import org.hibernate.search.backend.configuration.ConfigurationParseHelper;
+import org.hibernate.search.backend.impl.BatchedQueueingProcessor;
+import org.hibernate.search.cfg.SearchConfiguration;
+import org.hibernate.search.cfg.SearchMapping;
+import org.hibernate.search.engine.DocumentBuilderContainedEntity;
+import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
+import org.hibernate.search.engine.EntityState;
+import org.hibernate.search.engine.FilterDef;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.hibernate.search.exception.ErrorHandler;
+import org.hibernate.search.exception.impl.LogErrorHandler;
+import org.hibernate.search.filter.CachingWrapperFilter;
+import org.hibernate.search.filter.FilterCachingStrategy;
+import org.hibernate.search.filter.MRUFilterCachingStrategy;
+import org.hibernate.search.filter.ShardSensitiveOnlyFilter;
+import org.hibernate.search.reader.ReaderProvider;
+import org.hibernate.search.reader.ReaderProviderFactory;
+import org.hibernate.search.store.DirectoryProvider;
+import org.hibernate.search.store.DirectoryProviderFactory;
+import org.hibernate.search.store.optimization.OptimizerStrategy;
+import org.hibernate.search.util.LoggerFactory;
+import org.hibernate.search.util.PluginLoader;
+import org.hibernate.search.util.ReflectionHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Build a search factory
+ * @author Emmanuel Bernard
+ */
+public class SearchFactoryBuilder implements WritableBuildContext, WorkerBuildContext {
+	private static final Logger log = LoggerFactory.make();
+	SearchConfiguration cfg;
+	MutableSearchFactory rootFactory;
+
+	public SearchFactoryBuilder configuration(SearchConfiguration configuration) {
+		this.cfg = configuration;
+		return this;
+	}
+
+	public SearchFactoryBuilder rootFactory(MutableSearchFactory factory) {
+		this.rootFactory = factory;
+		return this;
+	}
+
+	//processing properties
+	ReflectionManager reflectionManager;
+	String indexingStrategy;
+	Map<Class<?>, DocumentBuilderIndexedEntity<?>> documentBuildersIndexedEntities;
+	Map<Class<?>, DocumentBuilderContainedEntity<?>> documentBuildersContainedEntities;
+	//keep track of the index modifiers per DirectoryProvider since multiple entity can use the same directory provider
+	Map<DirectoryProvider<?>, DirectoryProviderData> dirProviderData;
+	Worker worker;
+	ReaderProvider readerProvider;
+	BackendQueueProcessorFactory backendQueueProcessorFactory;
+	Map<String, FilterDef> filterDefinitions;
+	FilterCachingStrategy filterCachingStrategy;
+	Map<String, Analyzer> analyzers;
+	int cacheBitResultsSize;
+	Properties configurationProperties;
+	ErrorHandler errorHandler;
+	PolymorphicIndexHierarchy indexHierarchy;
+	Map<DirectoryProvider, LuceneIndexingParameters> dirProviderIndexingParams;
+
+	public SearchFactoryImplementor buildSearchFactory() {
+		createCleanFactoryState();
+
+		configurationProperties = cfg.getProperties();
+		errorHandler = createErrorHandler( configurationProperties );
+		reflectionManager = getReflectionManager(cfg);
+
+		final SearchMapping mapping = SearchMappingBuilder.getSearchMapping(cfg);
+		if ( mapping != null) {
+			if ( ! ( reflectionManager instanceof MetadataProviderInjector )) {
+				throw new SearchException("Programmatic mapping model used but ReflectionManager does not implement "
+						+ MetadataProviderInjector.class.getName() );
+			}
+			MetadataProviderInjector injector = (MetadataProviderInjector) reflectionManager;
+			MetadataProvider original = injector.getMetadataProvider();
+			injector.setMetadataProvider( new MappingModelMetadataProvider( original, mapping ) );
+		}
+
+		indexingStrategy = defineIndexingStrategy( cfg );//need to be done before the document builds
+		dirProviderIndexingParams = new HashMap<DirectoryProvider, LuceneIndexingParameters>();
+		initDocumentBuilders( cfg, reflectionManager );
+
+		Set<Class<?>> indexedClasses = documentBuildersIndexedEntities.keySet();
+		for ( DocumentBuilderIndexedEntity builder : documentBuildersIndexedEntities.values() ) {
+			builder.postInitialize( indexedClasses );
+		}
+		//not really necessary today
+		for ( DocumentBuilderContainedEntity builder : documentBuildersContainedEntities.values() ) {
+			builder.postInitialize( indexedClasses );
+		}
+		fillSimilarityMapping();
+
+		//build back end
+		this.worker = WorkerFactory.createWorker( cfg, this );
+		this.readerProvider = ReaderProviderFactory.createReaderProvider( cfg, this );
+		this.filterCachingStrategy = buildFilterCachingStrategy( cfg.getProperties() );
+		this.cacheBitResultsSize = ConfigurationParseHelper.getIntValue(
+				cfg.getProperties(), Environment.CACHE_DOCIDRESULTS_SIZE, CachingWrapperFilter.DEFAULT_SIZE
+		);
+		//TODO uncomment
+		SearchFactoryImplementor factory = new ImmutableSearchFactory( this );
+		rootFactory.setDelegate( factory );
+		return rootFactory;
+	}
+
+	private void fillSimilarityMapping() {
+		for ( DirectoryProviderData directoryConfiguration : dirProviderData.values() ) {
+			for ( Class<?> indexedType : directoryConfiguration.getClasses() ) {
+				DocumentBuilderIndexedEntity<?> documentBuilder = documentBuildersIndexedEntities.get( indexedType );
+				Similarity similarity = documentBuilder.getSimilarity();
+				Similarity prevSimilarity = directoryConfiguration.getSimilarity();
+				if ( prevSimilarity != null && ! prevSimilarity.getClass().equals( similarity.getClass() ) ) {
+					throw new SearchException( "Multiple entities are sharing the same index but are declaring an " +
+							"inconsistent Similarity. When overrriding default Similarity make sure that all types sharing a same index " +
+							"declare the same Similarity implementation." );
+				}
+				else {
+					directoryConfiguration.setSimilarity( similarity );
+				}
+			}
+		}
+	}
+
+	private static FilterCachingStrategy buildFilterCachingStrategy(Properties properties) {
+		FilterCachingStrategy filterCachingStrategy;
+		String impl = properties.getProperty( Environment.FILTER_CACHING_STRATEGY );
+		if ( StringHelper.isEmpty( impl ) || "mru".equalsIgnoreCase( impl ) ) {
+			filterCachingStrategy = new MRUFilterCachingStrategy();
+		}
+		else {
+			filterCachingStrategy = PluginLoader.instanceFromName( FilterCachingStrategy.class,
+					impl, ImmutableSearchFactory.class, "filterCachingStrategy" );
+		}
+		filterCachingStrategy.initialize( properties );
+		return filterCachingStrategy;
+	}
+
+	private void createCleanFactoryState() {
+		if ( rootFactory == null ) {
+			rootFactory = new MutableSearchFactory();
+			documentBuildersIndexedEntities = new HashMap<Class<?>, DocumentBuilderIndexedEntity<?>>();
+			documentBuildersContainedEntities = new HashMap<Class<?>, DocumentBuilderContainedEntity<?>>();
+			dirProviderData = new HashMap<DirectoryProvider<?>, DirectoryProviderData>();
+			filterDefinitions = new HashMap<String, FilterDef>();
+			indexHierarchy = new PolymorphicIndexHierarchy();
+		}
+	}
+
+	private void initDocumentBuilders(SearchConfiguration cfg, ReflectionManager reflectionManager) {
+		ConfigContext context = new ConfigContext( cfg );
+		Iterator<Class<?>> iter = cfg.getClassMappings();
+		DirectoryProviderFactory factory = new DirectoryProviderFactory();
+
+		initProgrammaticAnalyzers(context, reflectionManager);
+		initProgrammaticallyDefinedFilterDef(reflectionManager);
+
+		while ( iter.hasNext() ) {
+			Class mappedClass = iter.next();
+			if ( mappedClass == null ) {
+				continue;
+			}
+			@SuppressWarnings( "unchecked" )
+			XClass mappedXClass = reflectionManager.toXClass( mappedClass );
+			if ( mappedXClass == null ) {
+				continue;
+			}
+
+			if ( mappedXClass.isAnnotationPresent( Indexed.class ) ) {
+
+				if ( mappedXClass.isAbstract() ) {
+					log.warn( "Abstract classes can never insert index documents. Remove @Indexed." );
+					continue;
+				}
+
+				DirectoryProviderFactory.DirectoryProviders providers = factory.createDirectoryProviders(
+						mappedXClass, cfg, this, reflectionManager
+				);
+				//FIXME DocumentBuilderIndexedEntity needs to be built by a helper method receiving Class<T> to infer T properly
+				//XClass unfortunately is not (yet) genericized: TODO?
+				final DocumentBuilderIndexedEntity<?> documentBuilder = new DocumentBuilderIndexedEntity(
+						mappedXClass, context, providers.getProviders(), providers.getSelectionStrategy(),
+						reflectionManager
+				);
+
+				indexHierarchy.addIndexedClass( mappedClass );
+				documentBuildersIndexedEntities.put( mappedClass, documentBuilder );
+			}
+			else {
+				//FIXME DocumentBuilderIndexedEntity needs to be built by a helper method receiving Class<T> to infer T properly
+				//XClass unfortunately is not (yet) genericized: TODO?
+				final DocumentBuilderContainedEntity<?> documentBuilder = new DocumentBuilderContainedEntity(
+						mappedXClass, context, reflectionManager
+				);
+				//TODO enhance that, I don't like to expose EntityState
+				if ( documentBuilder.getEntityState() != EntityState.NON_INDEXABLE ) {
+					documentBuildersContainedEntities.put( mappedClass, documentBuilder );
+				}
+			}
+			bindFilterDefs( mappedXClass );
+			//TODO should analyzer def for classes at tyher sqme level???
+		}
+		analyzers = context.initLazyAnalyzers();
+		factory.startDirectoryProviders();
+	}
+
+	private void bindFilterDefs(XClass mappedXClass) {
+		FullTextFilterDef defAnn = mappedXClass.getAnnotation( FullTextFilterDef.class );
+		if ( defAnn != null ) {
+			bindFilterDef( defAnn, mappedXClass );
+		}
+		FullTextFilterDefs defsAnn = mappedXClass.getAnnotation( FullTextFilterDefs.class );
+		if ( defsAnn != null ) {
+			for ( FullTextFilterDef def : defsAnn.value() ) {
+				bindFilterDef( def, mappedXClass );
+			}
+		}
+	}
+
+	private void bindFilterDef(FullTextFilterDef defAnn, XClass mappedXClass) {
+		if ( filterDefinitions.containsKey( defAnn.name() ) ) {
+			throw new SearchException(
+					"Multiple definition of @FullTextFilterDef.name=" + defAnn.name() + ": "
+							+ mappedXClass.getName()
+			);
+		}
+
+		bindFullTextFilterDef(defAnn);
+	}
+
+	private void bindFullTextFilterDef(FullTextFilterDef defAnn) {
+		FilterDef filterDef = new FilterDef( defAnn );
+		if ( filterDef.getImpl().equals( ShardSensitiveOnlyFilter.class ) ) {
+			//this is a placeholder don't process regularly
+			filterDefinitions.put( defAnn.name(), filterDef );
+			return;
+		}
+		try {
+			filterDef.getImpl().newInstance();
+		}
+		catch ( IllegalAccessException e ) {
+			throw new SearchException( "Unable to create Filter class: " + filterDef.getImpl().getName(), e );
+		}
+		catch ( InstantiationException e ) {
+			throw new SearchException( "Unable to create Filter class: " + filterDef.getImpl().getName(), e );
+		}
+		for ( Method method : filterDef.getImpl().getMethods() ) {
+			if ( method.isAnnotationPresent( Factory.class ) ) {
+				if ( filterDef.getFactoryMethod() != null ) {
+					throw new SearchException(
+							"Multiple @Factory methods found" + defAnn.name() + ": "
+									+ filterDef.getImpl().getName() + "." + method.getName()
+					);
+				}
+				ReflectionHelper.setAccessible( method );
+				filterDef.setFactoryMethod( method );
+			}
+			if ( method.isAnnotationPresent( Key.class ) ) {
+				if ( filterDef.getKeyMethod() != null ) {
+					throw new SearchException(
+							"Multiple @Key methods found" + defAnn.name() + ": "
+									+ filterDef.getImpl().getName() + "." + method.getName()
+					);
+				}
+				ReflectionHelper.setAccessible( method );
+				filterDef.setKeyMethod( method );
+			}
+
+			String name = method.getName();
+			if ( name.startsWith( "set" ) && method.getParameterTypes().length == 1 ) {
+				filterDef.addSetter( Introspector.decapitalize( name.substring( 3 ) ), method );
+			}
+		}
+		filterDefinitions.put( defAnn.name(), filterDef );
+	}
+
+	private void initProgrammaticAnalyzers(ConfigContext context, ReflectionManager reflectionManager) {
+		final Map defaults = reflectionManager.getDefaults();
+
+		if (defaults != null) {
+			AnalyzerDef[] defs = (AnalyzerDef[]) defaults.get( AnalyzerDefs.class );
+			if ( defs != null ) {
+				for (AnalyzerDef def : defs) {
+					context.addAnalyzerDef( def );
+				}
+			}
+		}
+	}
+
+	private void initProgrammaticallyDefinedFilterDef(ReflectionManager reflectionManager) {
+		@SuppressWarnings("unchecked") Map defaults = reflectionManager.getDefaults();
+		FullTextFilterDef[] filterDefs = (FullTextFilterDef[]) defaults.get( FullTextFilterDefs.class);
+		if (filterDefs != null && filterDefs.length != 0) {
+			for (FullTextFilterDef defAnn : filterDefs) {
+				if ( filterDefinitions.containsKey( defAnn.name() ) ) {
+					throw new SearchException("Multiple definition of @FullTextFilterDef.name=" + defAnn.name());
+				}
+				bindFullTextFilterDef(defAnn);
+			}
+		}
+	}
+
+	private static ErrorHandler createErrorHandler(Properties configuration) {
+		boolean sync = BatchedQueueingProcessor.isConfiguredAsSync( configuration );
+		String errorHandlerClassName = configuration.getProperty( Environment.ERROR_HANDLER );
+		if ( StringHelper.isEmpty( errorHandlerClassName ) ) {
+			return new LogErrorHandler();
+		}
+		else if ( errorHandlerClassName.trim().equals( "log" ) ) {
+			return new LogErrorHandler();
+		}
+		else {
+			return PluginLoader.instanceFromName( ErrorHandler.class, errorHandlerClassName,
+				ImmutableSearchFactory.class, "Error Handler" );
+		}
+	}
+
+	private ReflectionManager getReflectionManager(SearchConfiguration cfg) {
+		ReflectionManager reflectionManager = cfg.getReflectionManager();
+		if ( reflectionManager == null ) {
+			reflectionManager = new JavaReflectionManager();
+		}
+		return reflectionManager;
+	}
+
+	private static String defineIndexingStrategy(SearchConfiguration cfg) {
+		String indexingStrategy = cfg.getProperties().getProperty( Environment.INDEXING_STRATEGY, "event" );
+		if ( !( "event".equals( indexingStrategy ) || "manual".equals( indexingStrategy ) ) ) {
+			throw new SearchException( Environment.INDEXING_STRATEGY + " unknown: " + indexingStrategy );
+		}
+		return indexingStrategy;
+	}
+
+	public void addOptimizerStrategy(DirectoryProvider<?> provider, OptimizerStrategy optimizerStrategy) {
+		DirectoryProviderData data = dirProviderData.get( provider );
+		if ( data == null ) {
+			data = new DirectoryProviderData();
+			dirProviderData.put( provider, data );
+		}
+		data.setOptimizerStrategy( optimizerStrategy );
+	}
+
+	public void addIndexingParameters(DirectoryProvider<?> provider, LuceneIndexingParameters indexingParams) {
+		dirProviderIndexingParams.put( provider, indexingParams );
+	}
+
+	public void addClassToDirectoryProvider(Class<?> entity, DirectoryProvider<?> directoryProvider, boolean exclusiveIndexUsage) {
+		DirectoryProviderData data = dirProviderData.get( directoryProvider );
+		if ( data == null ) {
+			data = new DirectoryProviderData();
+			dirProviderData.put( directoryProvider, data );
+		}
+		data.getClasses().add( entity );
+		data.setExclusiveIndexUsage( exclusiveIndexUsage );
+	}
+
+	public SearchFactoryImplementor getUninitializedSearchFactory() {
+		return rootFactory;
+	}
+
+	public String getIndexingStrategy() {
+		return indexingStrategy;
+	}
+
+	public Set<DirectoryProvider<?>> getDirectoryProviders() {
+		return this.dirProviderData.keySet();
+	}
+
+	public void setBackendQueueProcessorFactory(BackendQueueProcessorFactory backendQueueProcessorFactory) {
+		this.backendQueueProcessorFactory = backendQueueProcessorFactory;
+	}
+
+	public OptimizerStrategy getOptimizerStrategy(DirectoryProvider<?> provider) {
+		return dirProviderData.get( provider ).getOptimizerStrategy();
+	}
+
+	public Set<Class<?>> getClassesInDirectoryProvider(DirectoryProvider<?> directoryProvider) {
+		return Collections.unmodifiableSet( dirProviderData.get( directoryProvider ).getClasses() );
+	}
+
+	public LuceneIndexingParameters getIndexingParameters(DirectoryProvider<?> provider) {
+		return dirProviderIndexingParams.get( provider );
+	}
+
+	public ReentrantLock getDirectoryProviderLock(DirectoryProvider<?> dp) {
+		return this.dirProviderData.get( dp ).getDirLock();
+	}
+
+	public Similarity getSimilarity(DirectoryProvider<?> provider) {
+		Similarity similarity = dirProviderData.get( provider ).getSimilarity();
+		if ( similarity == null ) throw new SearchException( "Assertion error: a similarity should be defined for each provider" );
+		return similarity;
+	}
+
+	public boolean isExclusiveIndexUsageEnabled(DirectoryProvider<?> provider) {
+		return dirProviderData.get( provider ).isExclusiveIndexUsage();
+	}
+
+	public ErrorHandler getErrorHandler() {
+		return errorHandler;
+	}
+
+	@SuppressWarnings("unchecked")
+	public <T> DocumentBuilderIndexedEntity<T> getDocumentBuilderIndexedEntity(Class<T> entityType) {
+		return ( DocumentBuilderIndexedEntity<T> ) documentBuildersIndexedEntities.get( entityType );
+	}
+}

Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java	2010-06-28 12:31:04 UTC (rev 19833)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -1,663 +0,0 @@
-/* $Id$
- * 
- * Hibernate, Relational Persistence for Idiomatic Java
- * 
- * Copyright (c) 2009, 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.impl;
-
-import java.beans.Introspector;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.search.Similarity;
-import org.hibernate.annotations.common.reflection.MetadataProvider;
-import org.hibernate.annotations.common.reflection.MetadataProviderInjector;
-import org.hibernate.annotations.common.reflection.ReflectionManager;
-import org.hibernate.annotations.common.reflection.XClass;
-import org.hibernate.annotations.common.reflection.java.JavaReflectionManager;
-import org.hibernate.search.Environment;
-import org.hibernate.search.spi.WritableBuildContext;
-import org.hibernate.search.spi.WorkerBuildContext;
-import org.hibernate.search.SearchException;
-import org.hibernate.search.Version;
-import org.hibernate.search.annotations.AnalyzerDef;
-import org.hibernate.search.annotations.AnalyzerDefs;
-import org.hibernate.search.annotations.Factory;
-import org.hibernate.search.annotations.FullTextFilterDef;
-import org.hibernate.search.annotations.FullTextFilterDefs;
-import org.hibernate.search.annotations.Indexed;
-import org.hibernate.search.annotations.Key;
-import org.hibernate.search.backend.BackendQueueProcessorFactory;
-import org.hibernate.search.backend.LuceneIndexingParameters;
-import org.hibernate.search.backend.LuceneWork;
-import org.hibernate.search.backend.OptimizeLuceneWork;
-import org.hibernate.search.backend.Worker;
-import org.hibernate.search.backend.WorkerFactory;
-import org.hibernate.search.backend.configuration.ConfigurationParseHelper;
-import org.hibernate.search.backend.configuration.MaskedProperty;
-import org.hibernate.search.backend.impl.BatchedQueueingProcessor;
-import org.hibernate.search.backend.impl.batchlucene.BatchBackend;
-import org.hibernate.search.backend.impl.batchlucene.LuceneBatchBackend;
-import org.hibernate.search.batchindexing.MassIndexerProgressMonitor;
-import org.hibernate.search.cfg.SearchConfiguration;
-import org.hibernate.search.cfg.SearchMapping;
-import org.hibernate.search.engine.DocumentBuilderContainedEntity;
-import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
-import org.hibernate.search.engine.EntityState;
-import org.hibernate.search.engine.FilterDef;
-import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.hibernate.search.filter.CachingWrapperFilter;
-import org.hibernate.search.filter.FilterCachingStrategy;
-import org.hibernate.search.filter.MRUFilterCachingStrategy;
-import org.hibernate.search.filter.ShardSensitiveOnlyFilter;
-import org.hibernate.search.query.dsl.v2.QueryContextBuilder;
-import org.hibernate.search.query.dsl.v2.impl.ConnectedQueryContextBuilder;
-import org.hibernate.search.reader.ReaderProvider;
-import org.hibernate.search.reader.ReaderProviderFactory;
-import org.hibernate.search.store.DirectoryProvider;
-import org.hibernate.search.store.DirectoryProviderFactory;
-import org.hibernate.search.store.optimization.OptimizerStrategy;
-import org.hibernate.search.util.LoggerFactory;
-import org.hibernate.search.util.PluginLoader;
-import org.hibernate.search.util.ReflectionHelper;
-import org.hibernate.util.StringHelper;
-import org.slf4j.Logger;
-import org.hibernate.search.exception.ErrorHandler;
-import org.hibernate.search.exception.impl.LogErrorHandler;
-
-/**
- * @author Emmanuel Bernard
- */
-public class SearchFactoryImpl implements SearchFactoryImplementor, WritableBuildContext, WorkerBuildContext {
-
-	static {
-		Version.touch();
-	}
-
-	private static final Logger log = LoggerFactory.make();
-
-	private final Map<Class<?>, DocumentBuilderIndexedEntity<?>> documentBuildersIndexedEntities = new HashMap<Class<?>, DocumentBuilderIndexedEntity<?>>();
-	private final Map<Class<?>, DocumentBuilderContainedEntity<?>> documentBuildersContainedEntities = new HashMap<Class<?>, DocumentBuilderContainedEntity<?>>();
-	//keep track of the index modifiers per DirectoryProvider since multiple entity can use the same directory provider
-	private final Map<DirectoryProvider<?>, DirectoryProviderData> dirProviderData = new HashMap<DirectoryProvider<?>, DirectoryProviderData>();
-	private final Worker worker;
-	private final ReaderProvider readerProvider;
-	private BackendQueueProcessorFactory backendQueueProcessorFactory;
-	private final Map<String, FilterDef> filterDefinitions = new HashMap<String, FilterDef>();
-	private final FilterCachingStrategy filterCachingStrategy;
-	private Map<String, Analyzer> analyzers;
-	private final AtomicBoolean stopped = new AtomicBoolean( false );
-	private final int cacheBitResultsSize;
-	private final Properties configurationProperties;
-	private final ErrorHandler errorHandler;
-
-	private final PolymorphicIndexHierarchy indexHierarchy = new PolymorphicIndexHierarchy();
-
-	/*
-	 * Used as a barrier (piggyback usage) between initialization and subsequent usage of searchFactory in different threads
-	 * this is due to our use of the initialize pattern is a few areas
-	 * subsequent reads on volatiles should be very cheap on most platform especially since we don't write after init
-	 *
-	 * This volatile is meant to be written after initialization
-	 * and read by all subsequent methods accessing the SearchFactory state
-	 * read to be as barrier != 0. If barrier == 0 we have a race condition, but is not likely to happen.
-	 */
-	private volatile short barrier;
-
-	/**
-	 * Each directory provider (index) can have its own performance settings.
-	 */
-	private Map<DirectoryProvider, LuceneIndexingParameters> dirProviderIndexingParams =
-			new HashMap<DirectoryProvider, LuceneIndexingParameters>();
-	private final String indexingStrategy;
-
-
-	public BackendQueueProcessorFactory getBackendQueueProcessorFactory() {
-		if ( barrier != 0 ) {
-		} //read barrier
-		return backendQueueProcessorFactory;
-	}
-
-	public void setBackendQueueProcessorFactory(BackendQueueProcessorFactory backendQueueProcessorFactory) {
-		//no need to set a barrier, we init in the same thread as the init one
-		this.backendQueueProcessorFactory = backendQueueProcessorFactory;
-	}
-
-	public SearchFactoryImpl(SearchConfiguration cfg) {
-		this.configurationProperties = cfg.getProperties();
-		this.errorHandler = createErrorHandler( configurationProperties );
-		ReflectionManager reflectionManager = getReflectionManager(cfg);
-		final SearchMapping mapping = SearchMappingBuilder.getSearchMapping(cfg);
-		if ( mapping != null) {
-			if ( ! ( reflectionManager instanceof MetadataProviderInjector)) {
-				throw new SearchException("Programmatic mapping model used but ReflectionManager does not implement "
-						+ MetadataProviderInjector.class.getName() );
-			}
-			MetadataProviderInjector injector = (MetadataProviderInjector) reflectionManager;
-			MetadataProvider original = injector.getMetadataProvider();
-			injector.setMetadataProvider( new MappingModelMetadataProvider( original, mapping ) );
-			
-		}
-		
-		this.indexingStrategy = defineIndexingStrategy( cfg ); //need to be done before the document builds
-		initDocumentBuilders( cfg, reflectionManager );
-
-		Set<Class<?>> indexedClasses = documentBuildersIndexedEntities.keySet();
-		for ( DocumentBuilderIndexedEntity builder : documentBuildersIndexedEntities.values() ) {
-			builder.postInitialize( indexedClasses );
-		}
-		//not really necessary today
-		for ( DocumentBuilderContainedEntity builder : documentBuildersContainedEntities.values() ) {
-			builder.postInitialize( indexedClasses );
-		}
-		fillSimilarityMapping();
-		this.worker = WorkerFactory.createWorker( cfg, this );
-		this.readerProvider = ReaderProviderFactory.createReaderProvider( cfg, this );
-		this.filterCachingStrategy = buildFilterCachingStrategy( cfg.getProperties() );
-		this.cacheBitResultsSize = ConfigurationParseHelper.getIntValue(
-				cfg.getProperties(), Environment.CACHE_DOCIDRESULTS_SIZE, CachingWrapperFilter.DEFAULT_SIZE
-		);
-		this.barrier = 1; //write barrier
-	}
-
-	private void fillSimilarityMapping() {
-		for ( DirectoryProviderData directoryConfiguration : dirProviderData.values() ) {
-			for ( Class<?> indexedType : directoryConfiguration.getClasses() ) {
-				DocumentBuilderIndexedEntity<?> documentBuilder = documentBuildersIndexedEntities.get( indexedType );
-				Similarity similarity = documentBuilder.getSimilarity();
-				Similarity prevSimilarity = directoryConfiguration.getSimilarity();
-				if ( prevSimilarity != null && ! prevSimilarity.getClass().equals( similarity.getClass() ) ) {
-					throw new SearchException( "Multiple entities are sharing the same index but are declaring an " + 
-							"inconsistent Similarity. When overrriding default Similarity make sure that all types sharing a same index " +
-							"declare the same Similarity implementation." );
-				}
-				else {
-					directoryConfiguration.setSimilarity( similarity );
-				}
-			}
-		}
-	}
-
-	private ReflectionManager getReflectionManager(SearchConfiguration cfg) {
-		ReflectionManager reflectionManager = cfg.getReflectionManager();
-		if ( reflectionManager == null ) {
-			reflectionManager = new JavaReflectionManager();
-		}
-		return reflectionManager;
-	}
-
-	private static String defineIndexingStrategy(SearchConfiguration cfg) {
-		String indexingStrategy = cfg.getProperties().getProperty( Environment.INDEXING_STRATEGY, "event" );
-		if ( !( "event".equals( indexingStrategy ) || "manual".equals( indexingStrategy ) ) ) {
-			throw new SearchException( Environment.INDEXING_STRATEGY + " unknown: " + indexingStrategy );
-		}
-		return indexingStrategy;
-	}
-
-	public String getIndexingStrategy() {
-		if ( barrier != 0 ) {
-		} //read barrier
-		return indexingStrategy;
-	}
-
-	public void close() {
-		if ( barrier != 0 ) {
-		} //read barrier
-		if ( stopped.compareAndSet( false, true ) ) {  //make sure we only sop once
-			try {
-				worker.close();
-			}
-			catch ( Exception e ) {
-				log.error( "Worker raises an exception on close()", e );
-			}
-
-			try {
-				readerProvider.destroy();
-			}
-			catch ( Exception e ) {
-				log.error( "ReaderProvider raises an exception on destroy()", e );
-			}
-
-			//TODO move directory provider cleaning to DirectoryProviderFactory
-			for ( DirectoryProvider dp : getDirectoryProviders() ) {
-				try {
-					dp.stop();
-				}
-				catch ( Exception e ) {
-					log.error( "DirectoryProvider raises an exception on stop() ", e );
-				}
-			}
-		}
-	}
-
-	public void addClassToDirectoryProvider(Class<?> clazz, DirectoryProvider<?> directoryProvider, boolean exclusiveIndexUsage) {
-		//no need to set a read barrier, we only use this class in the init thread
-		DirectoryProviderData data = dirProviderData.get( directoryProvider );
-		if ( data == null ) {
-			data = new DirectoryProviderData();
-			dirProviderData.put( directoryProvider, data );
-		}
-		data.getClasses().add( clazz );
-		data.setExclusiveIndexUsage( exclusiveIndexUsage );
-	}
-
-	public Set<Class<?>> getClassesInDirectoryProvider(DirectoryProvider<?> directoryProvider) {
-		if ( barrier != 0 ) {
-		} //read barrier
-		return Collections.unmodifiableSet( dirProviderData.get( directoryProvider ).getClasses() );
-	}
-
-	private void bindFilterDefs(XClass mappedXClass) {
-		FullTextFilterDef defAnn = mappedXClass.getAnnotation( FullTextFilterDef.class );
-		if ( defAnn != null ) {
-			bindFilterDef( defAnn, mappedXClass );
-		}
-		FullTextFilterDefs defsAnn = mappedXClass.getAnnotation( FullTextFilterDefs.class );
-		if ( defsAnn != null ) {
-			for ( FullTextFilterDef def : defsAnn.value() ) {
-				bindFilterDef( def, mappedXClass );
-			}
-		}
-	}
-	
-	
-	private void initProgrammaticallyDefinedFilterDef(ReflectionManager reflectionManager) {
-		@SuppressWarnings("unchecked") Map defaults = reflectionManager.getDefaults();
-		FullTextFilterDef[] filterDefs = (FullTextFilterDef[]) defaults.get(FullTextFilterDefs.class);
-		if (filterDefs != null && filterDefs.length != 0) {
-			for (FullTextFilterDef defAnn : filterDefs) {
-				if ( filterDefinitions.containsKey( defAnn.name() ) ) {
-					throw new SearchException("Multiple definition of @FullTextFilterDef.name=" + defAnn.name());
-				}
-				bindFullTextFilterDef(defAnn);
-			}
-		}
-	}
-
-	private void bindFilterDef(FullTextFilterDef defAnn, XClass mappedXClass) {
-		if ( filterDefinitions.containsKey( defAnn.name() ) ) {
-			throw new SearchException(
-					"Multiple definition of @FullTextFilterDef.name=" + defAnn.name() + ": "
-							+ mappedXClass.getName()
-			);
-		}
-
-		bindFullTextFilterDef(defAnn);
-	}
-
-	private void bindFullTextFilterDef(FullTextFilterDef defAnn) {
-		FilterDef filterDef = new FilterDef( defAnn );
-		if ( filterDef.getImpl().equals( ShardSensitiveOnlyFilter.class ) ) {
-			//this is a placeholder don't process regularly
-			filterDefinitions.put( defAnn.name(), filterDef );
-			return;
-		}
-		try {
-			filterDef.getImpl().newInstance();
-		}
-		catch ( IllegalAccessException e ) {
-			throw new SearchException( "Unable to create Filter class: " + filterDef.getImpl().getName(), e );
-		}
-		catch ( InstantiationException e ) {
-			throw new SearchException( "Unable to create Filter class: " + filterDef.getImpl().getName(), e );
-		}
-		for ( Method method : filterDef.getImpl().getMethods() ) {
-			if ( method.isAnnotationPresent( Factory.class ) ) {
-				if ( filterDef.getFactoryMethod() != null ) {
-					throw new SearchException(
-							"Multiple @Factory methods found" + defAnn.name() + ": "
-									+ filterDef.getImpl().getName() + "." + method.getName()
-					);
-				}
-				ReflectionHelper.setAccessible( method );
-				filterDef.setFactoryMethod( method );
-			}
-			if ( method.isAnnotationPresent( Key.class ) ) {
-				if ( filterDef.getKeyMethod() != null ) {
-					throw new SearchException(
-							"Multiple @Key methods found" + defAnn.name() + ": "
-									+ filterDef.getImpl().getName() + "." + method.getName()
-					);
-				}
-				ReflectionHelper.setAccessible( method );
-				filterDef.setKeyMethod( method );
-			}
-
-			String name = method.getName();
-			if ( name.startsWith( "set" ) && method.getParameterTypes().length == 1 ) {
-				filterDef.addSetter( Introspector.decapitalize( name.substring( 3 ) ), method );
-			}
-		}
-		filterDefinitions.put( defAnn.name(), filterDef );
-	}
-
-
-	public Map<Class<?>, DocumentBuilderIndexedEntity<?>> getDocumentBuildersIndexedEntities() {
-		if ( barrier != 0 ) {
-		} //read barrier
-		return documentBuildersIndexedEntities;
-	}
-
-	@SuppressWarnings("unchecked")
-	public <T> DocumentBuilderIndexedEntity<T> getDocumentBuilderIndexedEntity(Class<T> entityType) {
-		if ( barrier != 0 ) {
-		} //read barrier
-		return ( DocumentBuilderIndexedEntity<T> ) documentBuildersIndexedEntities.get( entityType );
-	}
-
-	@SuppressWarnings("unchecked")
-	public <T> DocumentBuilderContainedEntity<T> getDocumentBuilderContainedEntity(Class<T> entityType) {
-		if ( barrier != 0 ) {
-		} //read barrier
-		return ( DocumentBuilderContainedEntity<T> ) documentBuildersContainedEntities.get( entityType );
-	}
-
-	public Set<DirectoryProvider<?>> getDirectoryProviders() {
-		if ( barrier != 0 ) {
-		} //read barrier
-		return this.dirProviderData.keySet();
-	}
-
-	public Worker getWorker() {
-		if ( barrier != 0 ) {
-		} //read barrier
-		return worker;
-	}
-
-	public void addOptimizerStrategy(DirectoryProvider<?> provider, OptimizerStrategy optimizerStrategy) {
-		//no need to set a read barrier, we run this method on the init thread
-		DirectoryProviderData data = dirProviderData.get( provider );
-		if ( data == null ) {
-			data = new DirectoryProviderData();
-			dirProviderData.put( provider, data );
-		}
-		data.setOptimizerStrategy( optimizerStrategy );
-	}
-
-	public void addIndexingParameters(DirectoryProvider<?> provider, LuceneIndexingParameters indexingParams) {
-		//no need to set a read barrier, we run this method on the init thread
-		dirProviderIndexingParams.put( provider, indexingParams );
-	}
-
-	public OptimizerStrategy getOptimizerStrategy(DirectoryProvider<?> provider) {
-		if ( barrier != 0 ) {
-		} //read barrier
-		return dirProviderData.get( provider ).getOptimizerStrategy();
-	}
-
-	public LuceneIndexingParameters getIndexingParameters(DirectoryProvider<?> provider) {
-		if ( barrier != 0 ) {
-		} //read barrier
-		return dirProviderIndexingParams.get( provider );
-	}
-
-	public ReaderProvider getReaderProvider() {
-		if ( barrier != 0 ) {
-		} //read barrier
-		return readerProvider;
-	}
-
-	public DirectoryProvider[] getDirectoryProviders(Class<?> entity) {
-		if ( barrier != 0 ) {
-		} //read barrier
-		DocumentBuilderIndexedEntity<?> documentBuilder = getDocumentBuilderIndexedEntity( entity );
-		return documentBuilder == null ? null : documentBuilder.getDirectoryProviders();
-	}
-
-	public void optimize() {
-		if ( barrier != 0 ) {
-		} //read barrier
-		Set<Class<?>> clazzs = getDocumentBuildersIndexedEntities().keySet();
-		for ( Class clazz : clazzs ) {
-			optimize( clazz );
-		}
-	}
-
-	public void optimize(Class entityType) {
-		if ( barrier != 0 ) {
-		} //read barrier
-		if ( !getDocumentBuildersIndexedEntities().containsKey( entityType ) ) {
-			throw new SearchException( "Entity not indexed: " + entityType );
-		}
-		List<LuceneWork> queue = new ArrayList<LuceneWork>( 1 );
-		queue.add( new OptimizeLuceneWork( entityType ) );
-		getBackendQueueProcessorFactory().getProcessor( queue ).run();
-	}
-
-	public Analyzer getAnalyzer(String name) {
-		if ( barrier != 0 ) {
-		} //read barrier
-		final Analyzer analyzer = analyzers.get( name );
-		if ( analyzer == null ) {
-			throw new SearchException( "Unknown Analyzer definition: " + name );
-		}
-		return analyzer;
-	}
-
-	public Analyzer getAnalyzer(Class<?> clazz) {
-		if ( clazz == null ) {
-			throw new IllegalArgumentException( "A class has to be specified for retrieving a scoped analyzer" );
-		}
-
-		DocumentBuilderIndexedEntity<?> builder = documentBuildersIndexedEntities.get( clazz );
-		if ( builder == null ) {
-			throw new IllegalArgumentException(
-					"Entity for which to retrieve the scoped analyzer is not an @Indexed entity: " + clazz.getName()
-			);
-		}
-
-		return builder.getAnalyzer();
-	}
-
-	public QueryContextBuilder buildQueryBuilder() {
-		return new ConnectedQueryContextBuilder( this );
-	}
-
-	private void initDocumentBuilders(SearchConfiguration cfg, ReflectionManager reflectionManager) {
-		ConfigContext context = new ConfigContext( cfg );
-		Iterator<Class<?>> iter = cfg.getClassMappings();
-		DirectoryProviderFactory factory = new DirectoryProviderFactory();
-
-		initProgrammaticAnalyzers(context, reflectionManager);
-		initProgrammaticallyDefinedFilterDef(reflectionManager);
-
-		while ( iter.hasNext() ) {
-			Class mappedClass = iter.next();
-			if ( mappedClass == null ) {
-				continue;
-			}
-			@SuppressWarnings( "unchecked" )
-			XClass mappedXClass = reflectionManager.toXClass( mappedClass );
-			if ( mappedXClass == null ) {
-				continue;
-			}
-
-			if ( mappedXClass.isAnnotationPresent( Indexed.class ) ) {
-
-				if ( mappedXClass.isAbstract() ) {
-					log.warn( "Abstract classes can never insert index documents. Remove @Indexed." );
-					continue;
-				}
-
-				DirectoryProviderFactory.DirectoryProviders providers = factory.createDirectoryProviders(
-						mappedXClass, cfg, this, reflectionManager
-				);
-				//FIXME DocumentBuilderIndexedEntity needs to be built by a helper method receiving Class<T> to infer T properly
-				//XClass unfortunately is not (yet) genericized: TODO?
-				final DocumentBuilderIndexedEntity<?> documentBuilder = new DocumentBuilderIndexedEntity(
-						mappedXClass, context, providers.getProviders(), providers.getSelectionStrategy(),
-						reflectionManager
-				);
-
-				indexHierarchy.addIndexedClass( mappedClass );
-				documentBuildersIndexedEntities.put( mappedClass, documentBuilder );
-			}
-			else {
-				//FIXME DocumentBuilderIndexedEntity needs to be built by a helper method receiving Class<T> to infer T properly
-				//XClass unfortunately is not (yet) genericized: TODO?
-				final DocumentBuilderContainedEntity<?> documentBuilder = new DocumentBuilderContainedEntity(
-						mappedXClass, context, reflectionManager
-				);
-				//TODO enhance that, I don't like to expose EntityState
-				if ( documentBuilder.getEntityState() != EntityState.NON_INDEXABLE ) {
-					documentBuildersContainedEntities.put( mappedClass, documentBuilder );
-				}
-			}
-			bindFilterDefs( mappedXClass );
-			//TODO should analyzer def for classes at tyher sqme level???
-		}
-		analyzers = context.initLazyAnalyzers();
-		factory.startDirectoryProviders();
-	}
-
-	private void initProgrammaticAnalyzers(ConfigContext context, ReflectionManager reflectionManager) {
-		final Map defaults = reflectionManager.getDefaults();
-
-		if (defaults != null) {
-			AnalyzerDef[] defs = (AnalyzerDef[]) defaults.get( AnalyzerDefs.class );
-			if ( defs != null ) {
-				for (AnalyzerDef def : defs) {
-					context.addAnalyzerDef( def );
-				}
-			}
-		}
-	}
-
-	private static FilterCachingStrategy buildFilterCachingStrategy(Properties properties) {
-		FilterCachingStrategy filterCachingStrategy;
-		String impl = properties.getProperty( Environment.FILTER_CACHING_STRATEGY );
-		if ( StringHelper.isEmpty( impl ) || "mru".equalsIgnoreCase( impl ) ) {
-			filterCachingStrategy = new MRUFilterCachingStrategy();
-		}
-		else {
-			filterCachingStrategy = PluginLoader.instanceFromName( FilterCachingStrategy.class,
-					impl, SearchFactoryImpl.class, "filterCachingStrategy" );
-		}
-		filterCachingStrategy.initialize( properties );
-		return filterCachingStrategy;
-	}
-
-	public FilterCachingStrategy getFilterCachingStrategy() {
-		if ( barrier != 0 ) {
-		} //read barrier
-		return filterCachingStrategy;
-	}
-
-	public FilterDef getFilterDefinition(String name) {
-		if ( barrier != 0 ) {
-		} //read barrier
-		return filterDefinitions.get( name );
-	}
-
-	public ReentrantLock getDirectoryProviderLock(DirectoryProvider<?> dp) {
-		if ( barrier != 0 ) {
-		} //read barrier
-		return this.dirProviderData.get( dp ).getDirLock();
-	}
-
-	public void addDirectoryProvider(DirectoryProvider<?> provider, boolean exclusiveIndexUsage) {
-		//no need to set a barrier we use this method in the init thread
-		DirectoryProviderData dirConfiguration = new DirectoryProviderData();
-		dirConfiguration.setExclusiveIndexUsage( exclusiveIndexUsage );
-		this.dirProviderData.put( provider, dirConfiguration );
-	}
-
-	public int getFilterCacheBitResultsSize() {
-		if ( barrier != 0 ) {
-		} //read barrier
-		return cacheBitResultsSize;
-	}
-
-	public Set<Class<?>> getIndexedTypesPolymorphic(Class<?>[] classes) {
-		if ( barrier != 0 ) {
-		} //read barrier
-		return indexHierarchy.getIndexedClasses( classes );
-	}
-	
-	public BatchBackend makeBatchBackend(MassIndexerProgressMonitor progressMonitor) {
-		BatchBackend batchBackend;
-		String impl = configurationProperties.getProperty( Environment.BATCH_BACKEND );
-		if ( StringHelper.isEmpty( impl ) || "LuceneBatch".equalsIgnoreCase( impl ) ) {
-			batchBackend = new LuceneBatchBackend();
-		}
-		else {
-			batchBackend = PluginLoader.instanceFromName( BatchBackend.class, impl, SearchFactoryImpl.class,
-					"batchbackend" );
-		}
-		Properties batchBackendConfiguration = new MaskedProperty(
-				this.configurationProperties, Environment.BATCH_BACKEND );
-		batchBackend.initialize( batchBackendConfiguration, progressMonitor, this );
-		return batchBackend;
-	}
-
-	public Similarity getSimilarity(DirectoryProvider<?> provider) {
-		if ( barrier != 0 ) {
-		} //read barrier
-		Similarity similarity = dirProviderData.get( provider ).getSimilarity();
-		if ( similarity == null ) throw new SearchException( "Assertion error: a similarity should be defined for each provider" );
-		return similarity;
-	}
-
-	public boolean isExclusiveIndexUsageEnabled(DirectoryProvider<?> provider) {
-		if ( barrier != 0 ) {
-		} //read barrier
-		return dirProviderData.get( provider ).isExclusiveIndexUsage();
-	}
-
-	/**
-	 * @param configuration
-	 * @return the configured ErrorHandler
-	 * @since 3.2
-	 */
-	private static ErrorHandler createErrorHandler(Properties configuration) {
-		boolean sync = BatchedQueueingProcessor.isConfiguredAsSync( configuration );
-		String errorHandlerClassName = configuration.getProperty( Environment.ERROR_HANDLER );
-		if ( StringHelper.isEmpty( errorHandlerClassName ) ) {
-			return new LogErrorHandler();
-		}
-		else if ( errorHandlerClassName.trim().equals( "log" ) ) {
-			return new LogErrorHandler();
-		}
-		else {
-			return PluginLoader.instanceFromName( ErrorHandler.class, errorHandlerClassName,
-				SearchFactoryImpl.class, "Error Handler" );
-		}
-	}
-
-	public ErrorHandler getErrorHandler() {
-		return errorHandler;
-	}
-
-	public SearchFactoryImplementor getUninitializedSearchFactory() {
-		return this;
-	}
-}

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/spi/BuildContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/spi/BuildContext.java	2010-06-28 12:31:04 UTC (rev 19833)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/spi/BuildContext.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -1,6 +1,7 @@
 package org.hibernate.search.spi;
 
 import java.util.Set;
+import java.util.concurrent.locks.ReentrantLock;
 
 import org.hibernate.search.engine.SearchFactoryImplementor;
 import org.hibernate.search.store.DirectoryProvider;
@@ -12,7 +13,8 @@
  */
 public interface BuildContext {
 	/**
-	 * Returns the SessionFactoryImplementor instance. Do not use until after the initialize method is fully executed.
+	 * Returns the SessionFactoryImplementor instance. Do not use until after the initialize and/or stard method is
+	 * fully executed.
 	 * Implementations should not cache values provided by the SessionFactoryImplementor but rather access them
 	 * each time: when the configuration is dynamically updated, new changes are available through the
 	 * SearchFactoryImplementor
@@ -35,4 +37,11 @@
 	String getIndexingStrategy();
 
 	Set<DirectoryProvider<?>> getDirectoryProviders();
+
+	/**
+	 * This method cannot be used in intialize methods. start methods can use it though.
+	 * @param provider
+	 * @return
+	 */
+	ReentrantLock getDirectoryProviderLock(DirectoryProvider<?> provider);
 }

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/spi/WorkerBuildContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/spi/WorkerBuildContext.java	2010-06-28 12:31:04 UTC (rev 19833)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/spi/WorkerBuildContext.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -7,6 +7,7 @@
 
 import org.hibernate.search.backend.BackendQueueProcessorFactory;
 import org.hibernate.search.backend.LuceneIndexingParameters;
+import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
 import org.hibernate.search.exception.ErrorHandler;
 import org.hibernate.search.store.DirectoryProvider;
 import org.hibernate.search.store.optimization.OptimizerStrategy;
@@ -22,8 +23,8 @@
 	public OptimizerStrategy getOptimizerStrategy(DirectoryProvider<?> provider);
 	Set<Class<?>> getClassesInDirectoryProvider(DirectoryProvider<?> provider);
 	LuceneIndexingParameters getIndexingParameters(DirectoryProvider<?> directoryProvider);
-	ReentrantLock getDirectoryProviderLock(DirectoryProvider<?> provider);
 	Similarity getSimilarity(DirectoryProvider<?> directoryProvider);
 	boolean isExclusiveIndexUsageEnabled(DirectoryProvider<?> directoryProvider);
 	ErrorHandler getErrorHandler();
+	<T> DocumentBuilderIndexedEntity<T> getDocumentBuilderIndexedEntity(Class<T> managedType);
 }

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/store/FSMasterDirectoryProvider.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/store/FSMasterDirectoryProvider.java	2010-06-28 12:31:04 UTC (rev 19833)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/store/FSMasterDirectoryProvider.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -70,7 +70,8 @@
 	//variables having visibility granted by a read of "current"
 	private FSDirectory directory;
 	private String indexName;
-	private SearchFactoryImplementor searchFactory;
+	//get rid of it after start()
+	private BuildContext context;
 	private long copyChunkSize;
 
 	//variables needed between initialize and start (used by same thread: no special care needed)
@@ -79,6 +80,7 @@
 	private String directoryProviderName;
 	private Properties properties;
 	private TriggerTask task;
+	private Lock directoryProviderLock;
 
 	public void initialize(String directoryProviderName, Properties properties, BuildContext context) {
 		this.properties = properties;
@@ -96,12 +98,14 @@
 			throw new SearchException( "Unable to initialize index: " + directoryProviderName, e );
 		}
 		copyChunkSize = DirectoryProviderHelper.getCopyBufferSize( directoryProviderName, properties );
-		this.searchFactory = context.getUninitializedSearchFactory();
+		this.context = context;
 		current = 0; //write to volatile to publish all state
 	}
 
 	public void start() {
 		int currentLocal = 0;
+		this.directoryProviderLock = this.context.getDirectoryProviderLock( this );
+		this.context = null;
 		try {
 			//copy to source
 			if ( new File( sourceDir, CURRENT1 ).exists() ) {
@@ -126,7 +130,7 @@
 		catch (IOException e) {
 			throw new SearchException( "Unable to initialize index: " + directoryProviderName, e );
 		}
-		task = new FSMasterDirectoryProvider.TriggerTask( indexDir, sourceDir, this );
+		task = new FSMasterDirectoryProvider.TriggerTask( indexDir, sourceDir );
 		long period = DirectoryProviderHelper.getRefreshPeriod( properties, directoryProviderName );
 		timer.scheduleAtFixedRate( task, period, period );
 		this.current = currentLocal; //write to volatile to publish all state
@@ -182,9 +186,9 @@
 		private final ExecutorService executor;
 		private final FSMasterDirectoryProvider.CopyDirectory copyTask;
 
-		public TriggerTask(File source, File destination, DirectoryProvider<FSDirectory> directoryProvider) {
+		public TriggerTask(File source, File destination) {
 			executor = Executors.newSingleThreadExecutor();
-			copyTask = new FSMasterDirectoryProvider.CopyDirectory( source, destination, directoryProvider );
+			copyTask = new FSMasterDirectoryProvider.CopyDirectory( source, destination );
 		}
 
 		public void run() {
@@ -205,12 +209,10 @@
 		private final File source;
 		private final File destination;
 		private final AtomicBoolean inProgress = new AtomicBoolean( false );
-		private final Lock directoryProviderLock;
 
-		public CopyDirectory(File source, File destination, DirectoryProvider<FSDirectory> directoryProvider) {
+		public CopyDirectory(File source, File destination) {
 			this.source = source;
 			this.destination = destination;
-			this.directoryProviderLock = searchFactory.getDirectoryProviderLock( directoryProvider );
 		}
 
 		public void run() {

Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/SearchTestCase.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/SearchTestCase.java	2010-06-28 12:31:04 UTC (rev 19833)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/SearchTestCase.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -49,8 +49,8 @@
 import org.hibernate.search.Search;
 import org.hibernate.search.SearchFactory;
 import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.engine.SearchFactoryImplementor;
 import org.hibernate.search.event.FullTextIndexEventListener;
-import org.hibernate.search.impl.SearchFactoryImpl;
 import org.hibernate.search.store.RAMDirectoryProvider;
 import org.hibernate.tool.hbm2ddl.SchemaExport;
 
@@ -70,7 +70,7 @@
 
 	private static File indexDir;
 	
-	private SearchFactoryImpl searchFactory;
+	private SearchFactoryImplementor searchFactory;
 
 	static {
 		String buildDir = System.getProperty( "build.dir" );
@@ -139,7 +139,7 @@
 		if ( searchFactory == null ) {
 			Session session = openSession();
 			FullTextSession fullTextSession = Search.getFullTextSession( session );
-			searchFactory = (SearchFactoryImpl) fullTextSession.getSearchFactory();
+			searchFactory = ( SearchFactoryImplementor) fullTextSession.getSearchFactory();
 			fullTextSession.close();
 		}
 		return searchFactory;

Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/ConfigurationReadTestCase.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/ConfigurationReadTestCase.java	2010-06-28 12:31:04 UTC (rev 19833)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/ConfigurationReadTestCase.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -31,7 +31,6 @@
 import org.hibernate.search.SearchException;
 import org.hibernate.search.backend.configuration.IndexWriterSetting;
 import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.hibernate.search.impl.SearchFactoryImpl;
 import org.hibernate.search.store.RAMDirectoryProvider;
 import org.hibernate.search.test.SearchTestCase;
 import org.hibernate.search.util.FileHelper;
@@ -58,7 +57,7 @@
 	protected void setUp() throws Exception {
 		super.setUp();
 		FullTextSession fullTextSession = Search.getFullTextSession( openSession() );
-		searchFactory = (SearchFactoryImpl) fullTextSession.getSearchFactory();
+		searchFactory = (SearchFactoryImplementor) fullTextSession.getSearchFactory();
 		fullTextSession.close();
 		FileHelper.delete( getBaseIndexDir() );
 		getBaseIndexDir().mkdirs();

Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/CustomBackendTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/CustomBackendTest.java	2010-06-28 12:31:04 UTC (rev 19833)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/CustomBackendTest.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -30,7 +30,7 @@
 import org.hibernate.search.backend.BackendQueueProcessorFactory;
 import org.hibernate.search.backend.impl.blackhole.BlackHoleBackendQueueProcessorFactory;
 import org.hibernate.search.backend.impl.lucene.LuceneBackendQueueProcessorFactory;
-import org.hibernate.search.impl.SearchFactoryImpl;
+import org.hibernate.search.engine.SearchFactoryImplementor;
 import org.hibernate.search.test.util.FullTextSessionBuilder;
 
 /**
@@ -50,7 +50,7 @@
 		FullTextSession ftSession = builder
 			.setProperty( "hibernate.search.worker.backend", name )
 			.openFullTextSession();
-		SearchFactoryImpl searchFactory = (SearchFactoryImpl) ftSession.getSearchFactory();
+		SearchFactoryImplementor searchFactory = ( SearchFactoryImplementor) ftSession.getSearchFactory();
 		ftSession.close();
 		assertEquals( backendType, searchFactory.getBackendQueueProcessorFactory().getClass() );
 		builder.close();

Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/errorhandling/LuceneErrorHandlingTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/errorhandling/LuceneErrorHandlingTest.java	2010-06-28 12:31:04 UTC (rev 19833)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/errorhandling/LuceneErrorHandlingTest.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -29,8 +29,8 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 import junit.framework.Assert;
+import org.apache.lucene.index.IndexWriter;
 
-import org.apache.lucene.index.IndexWriter;
 import org.hibernate.search.Environment;
 import org.hibernate.search.FullTextSession;
 import org.hibernate.search.Search;
@@ -43,9 +43,9 @@
 import org.hibernate.search.backend.impl.lucene.DpSelectionVisitor;
 import org.hibernate.search.backend.impl.lucene.works.LuceneWorkDelegate;
 import org.hibernate.search.batchindexing.MassIndexerProgressMonitor;
+import org.hibernate.search.engine.SearchFactoryImplementor;
 import org.hibernate.search.exception.ErrorHandler;
 import org.hibernate.search.exception.impl.LogErrorHandler;
-import org.hibernate.search.impl.SearchFactoryImpl;
 import org.hibernate.search.test.Document;
 import org.hibernate.search.test.SearchTestCase;
 
@@ -63,11 +63,11 @@
 	static final AtomicInteger workcounter = new AtomicInteger();
 	
 	public void testErrorHandling() {
-		SearchFactoryImpl searchFactoryImpl = getSearchFactoryImpl();
-		ErrorHandler errorHandler = searchFactoryImpl.getErrorHandler();
+		SearchFactoryImplementor searchFactory = getSearchFactoryImpl();
+		ErrorHandler errorHandler = searchFactory.getErrorHandler();
 		Assert.assertTrue( errorHandler instanceof MockErrorHandler );
 		MockErrorHandler mockErrorHandler = (MockErrorHandler)errorHandler;
-		BackendQueueProcessorFactory queueProcessorFactory = searchFactoryImpl.getBackendQueueProcessorFactory();
+		BackendQueueProcessorFactory queueProcessorFactory = searchFactory.getBackendQueueProcessorFactory();
 		List<LuceneWork> queue = new ArrayList<LuceneWork>();
 		queue.add( new HarmlessWork( "firstWork" ) );
 		queue.add( new HarmlessWork( "secondWork" ) );
@@ -114,11 +114,11 @@
 		cfg.setProperty( Environment.ERROR_HANDLER, MockErrorHandler.class.getName() );
 	}
 	
-	protected SearchFactoryImpl getSearchFactoryImpl() {
+	protected SearchFactoryImplementor getSearchFactoryImpl() {
 		FullTextSession s = Search.getFullTextSession( openSession() );
 		s.close();
 		SearchFactory searchFactory = s.getSearchFactory();
-		return (SearchFactoryImpl) searchFactory;
+		return (SearchFactoryImplementor) searchFactory;
 	}
 	
 	/**

Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdTest.java	2010-06-28 12:31:04 UTC (rev 19833)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdTest.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -28,10 +28,11 @@
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.TopDocs;
+
 import org.hibernate.search.backend.Work;
 import org.hibernate.search.backend.WorkType;
 import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.hibernate.search.impl.SearchFactoryImpl;
+import org.hibernate.search.impl.SearchFactoryBuilder;
 import org.hibernate.search.store.DirectoryProvider;
 import org.hibernate.search.test.SearchTestCase;
 
@@ -41,7 +42,7 @@
 public class ProvidedIdTest extends junit.framework.TestCase {
 
 	public void testProvidedId() throws Exception {
-		SearchFactoryImplementor sf = new SearchFactoryImpl( new StandaloneConf() );
+		SearchFactoryImplementor sf = new SearchFactoryBuilder().configuration( new StandaloneConf() ).buildSearchFactory();
 
 		ProvidedIdPerson person1 = new ProvidedIdPerson();
 		person1.setName( "Big Goat" );

Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/jgroups/common/JGroupsCommonTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/jgroups/common/JGroupsCommonTest.java	2010-06-28 12:31:04 UTC (rev 19833)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/jgroups/common/JGroupsCommonTest.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -46,7 +46,8 @@
  * </code>
  * @author Lukasz Moren
  */
-public class JGroupsCommonTest extends MultipleSessionsSearchTestCase {
+public class
+		JGroupsCommonTest extends MultipleSessionsSearchTestCase {
 
 	private static final String DEFAULT_JGROUPS_CONFIGURATION_FILE = "flush-udp.xml";
 

Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/worker/duplication/WorkDuplicationTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/worker/duplication/WorkDuplicationTest.java	2010-06-28 12:31:04 UTC (rev 19833)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/worker/duplication/WorkDuplicationTest.java	2010-06-28 12:32:47 UTC (rev 19834)
@@ -24,23 +24,24 @@
  */
 package org.hibernate.search.test.worker.duplication;
 
+import java.util.ArrayList;
 import java.util.List;
-import java.util.ArrayList;
 
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
-import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.TopDocs;
+
 import org.hibernate.Transaction;
 import org.hibernate.search.FullTextQuery;
 import org.hibernate.search.FullTextSession;
-import org.hibernate.search.backend.WorkType;
-import org.hibernate.search.backend.LuceneWork;
 import org.hibernate.search.backend.AddLuceneWork;
 import org.hibernate.search.backend.DeleteLuceneWork;
+import org.hibernate.search.backend.LuceneWork;
+import org.hibernate.search.backend.WorkType;
 import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
-import org.hibernate.search.impl.SearchFactoryImpl;
+import org.hibernate.search.engine.SearchFactoryImplementor;
 import org.hibernate.search.reader.ReaderProvider;
 import org.hibernate.search.store.DirectoryProvider;
 import org.hibernate.search.test.SearchTestCase;
@@ -123,7 +124,7 @@
 	@SuppressWarnings( "unchecked" )
 	public void testAddWorkGetReplacedByDeleteWork() throws Exception {
 		FullTextSession fullTextSession = org.hibernate.search.Search.getFullTextSession( openSession() );
-		SearchFactoryImpl searchFactory = ( SearchFactoryImpl ) fullTextSession.getSearchFactory();
+		SearchFactoryImplementor searchFactory = ( SearchFactoryImplementor ) fullTextSession.getSearchFactory();
 		DocumentBuilderIndexedEntity builder = searchFactory.getDocumentBuilderIndexedEntity( SpecialPerson.class );
 
 		// create test entity



More information about the hibernate-commits mailing list