[hibernate-commits] Hibernate SVN: r19866 - search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Jun 30 09:41:20 EDT 2010


Author: epbernard
Date: 2010-06-30 09:41:20 -0400 (Wed, 30 Jun 2010)
New Revision: 19866

Added:
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/IncrementalSearchConfiguration.java
Modified:
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryBuilder.java
Log:
HSEARCH-397 SearchFactoryBuilder contract for mutable SearchFactories

Create contract to add new classes and update an SearchFactory

Added: search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/IncrementalSearchConfiguration.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/IncrementalSearchConfiguration.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/IncrementalSearchConfiguration.java	2010-06-30 13:41:20 UTC (rev 19866)
@@ -0,0 +1,53 @@
+package org.hibernate.search.impl;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.hibernate.annotations.common.reflection.ReflectionManager;
+import org.hibernate.annotations.common.reflection.java.JavaReflectionManager;
+import org.hibernate.search.cfg.SearchConfiguration;
+import org.hibernate.search.cfg.SearchMapping;
+
+/**
+ * @author Emmanuel Bernard
+ */
+class IncrementalSearchConfiguration implements SearchConfiguration {
+	private final ReflectionManager reflectionManager = new JavaReflectionManager();
+	private final List<Class<?>> classes;
+	private final Map<String, Class<?>> classesByName = new HashMap<String, Class<?>>();
+	private Properties properties;
+
+	public IncrementalSearchConfiguration(List<Class<?>> classes, Properties properties) {
+		this.properties = properties;
+		this.classes = classes;
+		for ( Class<?> entity : classes ) {
+			classesByName.put( entity.getName(), entity );
+		}
+	}
+	public Iterator<Class<?>> getClassMappings() {
+		return classes.iterator();
+	}
+
+	public Class<?> getClassMapping(String name) {
+		return classesByName.get( name );
+	}
+
+	public String getProperty(String propertyName) {
+		return properties.getProperty(propertyName );
+	}
+
+	public Properties getProperties() {
+		return properties;
+	}
+
+	public ReflectionManager getReflectionManager() {
+		return reflectionManager;
+	}
+
+	public SearchMapping getProgrammaticMapping() {
+		return null;
+	}
+}

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryBuilder.java	2010-06-30 13:40:44 UTC (rev 19865)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryBuilder.java	2010-06-30 13:41:20 UTC (rev 19866)
@@ -2,9 +2,11 @@
 
 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;
@@ -12,6 +14,8 @@
 
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.search.Similarity;
+
+import org.hibernate.search.backend.UpdatableBackendQueueProcessorFactory;
 import org.hibernate.search.spi.WorkerBuildContext;
 import org.hibernate.search.spi.WritableBuildContext;
 import org.hibernate.search.spi.internals.DirectoryProviderData;
@@ -65,10 +69,11 @@
  * Build a search factory
  * @author Emmanuel Bernard
  */
-public class SearchFactoryBuilder implements WritableBuildContext, WorkerBuildContext {
+public class SearchFactoryBuilder {
 	private static final Logger log = LoggerFactory.make();
-	SearchConfiguration cfg;
-	MutableSearchFactory rootFactory;
+	private SearchConfiguration cfg;
+	private MutableSearchFactory rootFactory;
+	private final List<Class<?>> classes = new ArrayList<Class<?>>();
 
 	public SearchFactoryBuilder configuration(SearchConfiguration configuration) {
 		this.cfg = configuration;
@@ -80,6 +85,11 @@
 		return this;
 	}
 
+	public SearchFactoryBuilder addClass(Class<?> clazz) {
+		classes.add( clazz );
+		return this;
+	}
+
 	//processing properties
 	ReflectionManager reflectionManager;
 	String indexingStrategy;
@@ -101,6 +111,9 @@
 
 	public SearchFactoryImplementor buildSearchFactory() {
 		if (rootFactory == null) {
+			if (classes.size() > 0) {
+				throw new SearchException( "Cannot add a class if the original SearchFactory is not passed");
+			}
 			return buildNewSearchFactory();
 		}
 		else {
@@ -109,9 +122,50 @@
 	}
 
 	private SearchFactoryImplementor buildIncrementalSearchFactory() {
+		BuildContext buildContext = new BuildContext();
 		copyStateFromOldFactory(rootFactory);
-		//FIXME next step for implementation
-		return null;
+		List<Class<?>> remove = new ArrayList<Class<?>>();
+		for (Class<?> entity : classes) {
+			if ( documentBuildersIndexedEntities.containsKey( entity ) || documentBuildersContainedEntities.containsKey(entity) ) {
+				remove.add( entity );
+			}
+		}
+		for(Class<?> entity : remove) {
+			classes.remove( entity );
+		}
+		//TODO we don't keep the reflectionManager. Is that an issue?
+		IncrementalSearchConfiguration cfg = new IncrementalSearchConfiguration( classes, configurationProperties );
+		reflectionManager = getReflectionManager( cfg );
+		//TODO programmatic mapping support
+
+		//FIXME The current initDocumentBuilders
+		initDocumentBuilders( cfg, reflectionManager, buildContext );
+
+		Set<Class<?>> indexedClasses = documentBuildersIndexedEntities.keySet();
+		for ( DocumentBuilderIndexedEntity builder : documentBuildersIndexedEntities.values() ) {
+			//FIXME improve this algorithm to deal with adding new classes to the class hierarchy.
+			//Today it seems only safe when a class outside the hierarchy is incrementally added.
+			builder.postInitialize( indexedClasses );
+		}
+		//not really necessary today
+		for ( DocumentBuilderContainedEntity builder : documentBuildersContainedEntities.values() ) {
+			builder.postInitialize( indexedClasses );
+		}
+		fillSimilarityMapping();
+
+		//update backend
+		final BackendQueueProcessorFactory backend = this.backendQueueProcessorFactory;
+		if ( backend instanceof UpdatableBackendQueueProcessorFactory) {
+			final UpdatableBackendQueueProcessorFactory updatableBackend = ( UpdatableBackendQueueProcessorFactory ) backend;
+			updatableBackend.updateDirectoryProviders( this.dirProviderData.keySet(), buildContext );
+		}
+		//safe for incremental init at least the ShredBufferReaderProvider
+		//this.readerProvider = ReaderProviderFactory.createReaderProvider( cfg, this );
+		StateSearchFactoryImplementor factory = new ImmutableSearchFactory( this );
+		rootFactory.setDelegate( factory );
+		return rootFactory;
+
+
 	}
 
 	private void copyStateFromOldFactory(StateSearchFactoryImplementor stateFactory) {
@@ -138,6 +192,7 @@
 		configurationProperties = cfg.getProperties();
 		errorHandler = createErrorHandler( configurationProperties );
 		reflectionManager = getReflectionManager(cfg);
+		BuildContext buildContext = new BuildContext();
 
 		final SearchMapping mapping = SearchMappingBuilder.getSearchMapping(cfg);
 		if ( mapping != null) {
@@ -152,7 +207,7 @@
 
 		indexingStrategy = defineIndexingStrategy( cfg );//need to be done before the document builds
 		dirProviderIndexingParams = new HashMap<DirectoryProvider, LuceneIndexingParameters>();
-		initDocumentBuilders( cfg, reflectionManager );
+		initDocumentBuilders( cfg, reflectionManager, buildContext );
 
 		Set<Class<?>> indexedClasses = documentBuildersIndexedEntities.keySet();
 		for ( DocumentBuilderIndexedEntity builder : documentBuildersIndexedEntities.values() ) {
@@ -165,8 +220,8 @@
 		fillSimilarityMapping();
 
 		//build back end
-		this.worker = WorkerFactory.createWorker( cfg, this );
-		this.readerProvider = ReaderProviderFactory.createReaderProvider( cfg, this );
+		this.worker = WorkerFactory.createWorker( cfg, buildContext );
+		this.readerProvider = ReaderProviderFactory.createReaderProvider( cfg, buildContext );
 		this.filterCachingStrategy = buildFilterCachingStrategy( cfg.getProperties() );
 		this.cacheBitResultsSize = ConfigurationParseHelper.getIntValue(
 				cfg.getProperties(), Environment.CACHE_DOCIDRESULTS_SIZE, CachingWrapperFilter.DEFAULT_SIZE
@@ -219,7 +274,11 @@
 		}
 	}
 
-	private void initDocumentBuilders(SearchConfiguration cfg, ReflectionManager reflectionManager) {
+	/*
+	 * Initialize the document builder
+	 * This algorithm seems to be safe for incremental search factories.
+	 */
+	private void initDocumentBuilders(SearchConfiguration cfg, ReflectionManager reflectionManager, BuildContext buildContext) {
 		ConfigContext context = new ConfigContext( cfg );
 		Iterator<Class<?>> iter = cfg.getClassMappings();
 		DirectoryProviderFactory factory = new DirectoryProviderFactory();
@@ -228,7 +287,7 @@
 		initProgrammaticallyDefinedFilterDef(reflectionManager);
 
 		while ( iter.hasNext() ) {
-			Class mappedClass = iter.next();
+			Class<?> mappedClass = iter.next();
 			if ( mappedClass == null ) {
 				continue;
 			}
@@ -246,7 +305,7 @@
 				}
 
 				DirectoryProviderFactory.DirectoryProviders providers = factory.createDirectoryProviders(
-						mappedXClass, cfg, this, reflectionManager
+						mappedXClass, cfg, buildContext, 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?
@@ -388,6 +447,10 @@
 
 	private ReflectionManager getReflectionManager(SearchConfiguration cfg) {
 		ReflectionManager reflectionManager = cfg.getReflectionManager();
+		return geReflectionManager( reflectionManager );
+	}
+
+	private ReflectionManager geReflectionManager(ReflectionManager reflectionManager) {
 		if ( reflectionManager == null ) {
 			reflectionManager = new JavaReflectionManager();
 		}
@@ -402,77 +465,80 @@
 		return indexingStrategy;
 	}
 
-	public void addOptimizerStrategy(DirectoryProvider<?> provider, OptimizerStrategy optimizerStrategy) {
-		DirectoryProviderData data = dirProviderData.get( provider );
-		if ( data == null ) {
-			data = new DirectoryProviderData();
-			dirProviderData.put( provider, data );
+	private class BuildContext implements WritableBuildContext, WorkerBuildContext {
+		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 );
 		}
-		data.setOptimizerStrategy( optimizerStrategy );
-	}
 
-	public void addIndexingParameters(DirectoryProvider<?> provider, LuceneIndexingParameters indexingParams) {
-		dirProviderIndexingParams.put( provider, indexingParams );
-	}
+		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 );
+		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 );
 		}
-		data.getClasses().add( entity );
-		data.setExclusiveIndexUsage( exclusiveIndexUsage );
-	}
 
-	public SearchFactoryImplementor getUninitializedSearchFactory() {
-		return rootFactory;
-	}
+		public SearchFactoryImplementor getUninitializedSearchFactory() {
+			return rootFactory;
+		}
 
-	public String getIndexingStrategy() {
-		return indexingStrategy;
-	}
+		public String getIndexingStrategy() {
+			return indexingStrategy;
+		}
 
-	public Set<DirectoryProvider<?>> getDirectoryProviders() {
-		return this.dirProviderData.keySet();
-	}
+		public Set<DirectoryProvider<?>> getDirectoryProviders() {
+			return SearchFactoryBuilder.this.dirProviderData.keySet();
+		}
 
-	public void setBackendQueueProcessorFactory(BackendQueueProcessorFactory backendQueueProcessorFactory) {
-		this.backendQueueProcessorFactory = backendQueueProcessorFactory;
-	}
+		public void setBackendQueueProcessorFactory(BackendQueueProcessorFactory backendQueueProcessorFactory) {
+			SearchFactoryBuilder.this.backendQueueProcessorFactory = backendQueueProcessorFactory;
+		}
 
-	public OptimizerStrategy getOptimizerStrategy(DirectoryProvider<?> provider) {
-		return dirProviderData.get( provider ).getOptimizerStrategy();
-	}
+		public OptimizerStrategy getOptimizerStrategy(DirectoryProvider<?> provider) {
+			return dirProviderData.get( provider ).getOptimizerStrategy();
+		}
 
-	public Set<Class<?>> getClassesInDirectoryProvider(DirectoryProvider<?> directoryProvider) {
-		return Collections.unmodifiableSet( dirProviderData.get( directoryProvider ).getClasses() );
-	}
+		public Set<Class<?>> getClassesInDirectoryProvider(DirectoryProvider<?> directoryProvider) {
+			return Collections.unmodifiableSet( dirProviderData.get( directoryProvider ).getClasses() );
+		}
 
-	public LuceneIndexingParameters getIndexingParameters(DirectoryProvider<?> provider) {
-		return dirProviderIndexingParams.get( provider );
-	}
+		public LuceneIndexingParameters getIndexingParameters(DirectoryProvider<?> provider) {
+			return dirProviderIndexingParams.get( provider );
+		}
 
-	public ReentrantLock getDirectoryProviderLock(DirectoryProvider<?> dp) {
-		return this.dirProviderData.get( dp ).getDirLock();
-	}
+		public ReentrantLock getDirectoryProviderLock(DirectoryProvider<?> dp) {
+			return SearchFactoryBuilder.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 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 boolean isExclusiveIndexUsageEnabled(DirectoryProvider<?> provider) {
+			return dirProviderData.get( provider ).isExclusiveIndexUsage();
+		}
 
-	public ErrorHandler getErrorHandler() {
-		return errorHandler;
-	}
+		public ErrorHandler getErrorHandler() {
+			return errorHandler;
+		}
 
-	@SuppressWarnings("unchecked")
-	public <T> DocumentBuilderIndexedEntity<T> getDocumentBuilderIndexedEntity(Class<T> entityType) {
-		return ( DocumentBuilderIndexedEntity<T> ) documentBuildersIndexedEntities.get( entityType );
+		@SuppressWarnings("unchecked")
+		public <T> DocumentBuilderIndexedEntity<T> getDocumentBuilderIndexedEntity(Class<T> entityType) {
+			return ( DocumentBuilderIndexedEntity<T> ) documentBuildersIndexedEntities.get( entityType );
+		}
+		
 	}
 }



More information about the hibernate-commits mailing list