[hibernate-commits] Hibernate SVN: r19871 - in search/trunk/hibernate-search/src: main/java/org/hibernate/search/impl and 1 other directories.

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


Author: epbernard
Date: 2010-06-30 09:44:30 -0400 (Wed, 30 Jun 2010)
New Revision: 19871

Added:
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/IncrementalSearchFactory.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/mutablefactory/C.java
Modified:
   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
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/mutablefactory/A.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/mutablefactory/MutableFactoryTest.java
Log:
HSEARCH-397 Add simpler IncrementalSearchFactory contract

For now, only allow entities addition

Added: search/trunk/hibernate-search/src/main/java/org/hibernate/search/IncrementalSearchFactory.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/IncrementalSearchFactory.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/IncrementalSearchFactory.java	2010-06-30 13:44:30 UTC (rev 19871)
@@ -0,0 +1,19 @@
+package org.hibernate.search;
+
+/**
+ * This contract is considered experimental
+ * Allow modifications of the SearchFactory internals
+ *
+ * As of today allow addition of new indexed classes.
+ *
+ * @author Emmanuel Bernard
+ */
+public interface IncrementalSearchFactory extends SearchFactory {
+	/**
+	 * Add the following classes to the SearchFactory
+	 *
+	 */
+	void addClasses(Class<?>... classes);
+
+	//TODO consider accepting SearchConfiguration or SearchMapping
+}

Modified: 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	2010-06-30 13:43:49 UTC (rev 19870)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/MutableSearchFactory.java	2010-06-30 13:44:30 UTC (rev 19871)
@@ -3,11 +3,13 @@
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.search.Similarity;
 
+import org.hibernate.search.IncrementalSearchFactory;
 import org.hibernate.search.backend.BackendQueueProcessorFactory;
 import org.hibernate.search.backend.LuceneIndexingParameters;
 import org.hibernate.search.backend.Worker;
@@ -33,8 +35,10 @@
  *
  * @author Emmanuel Bernard
  */
-public class MutableSearchFactory implements StateSearchFactoryImplementor {
+public class MutableSearchFactory implements StateSearchFactoryImplementor, IncrementalSearchFactory {
 	private volatile StateSearchFactoryImplementor delegate;
+	//lock to be acquired every time the underlying searchFactory is rebuilt
+	private final Lock mutating = new ReentrantLock( );
 
 	void setDelegate(StateSearchFactoryImplementor delegate) {
 		this.delegate = delegate;
@@ -179,4 +183,19 @@
 	public Map<DirectoryProvider<?>, DirectoryProviderData> getDirectoryProviderData() {
 		return delegate.getDirectoryProviderData();
 	}
+
+	public void addClasses(Class<?>... classes) {
+		//todo optimize the list of
+		final SearchFactoryBuilder builder = new SearchFactoryBuilder().rootFactory( this );
+		for (Class<?> type : classes) {
+			builder.addClass( type );
+		}
+		try {
+			mutating.lock();
+			builder.buildSearchFactory();
+		}
+		finally {
+			mutating.unlock();
+		}
+	}
 }

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:43:49 UTC (rev 19870)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryBuilder.java	2010-06-30 13:44:30 UTC (rev 19871)
@@ -5,6 +5,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -122,17 +123,13 @@
 	}
 
 	private SearchFactoryImplementor buildIncrementalSearchFactory() {
+		removeClassesAlreadyManaged();
+		if (classes.size() == 0) {
+			return rootFactory;
+		}
+
 		BuildContext buildContext = new BuildContext();
 		copyStateFromOldFactory(rootFactory);
-		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 );
@@ -168,6 +165,20 @@
 
 	}
 
+	private void removeClassesAlreadyManaged() {
+		Set<Class<?>> remove = new HashSet<Class<?>>();
+		final Map<Class<?>, DocumentBuilderContainedEntity<?>> containedEntities = rootFactory.getDocumentBuildersContainedEntities();
+		final Map<Class<?>, DocumentBuilderIndexedEntity<?>> indexedEntities = rootFactory.getDocumentBuildersIndexedEntities();	
+		for (Class<?> entity : classes) {
+			if ( indexedEntities.containsKey( entity ) || containedEntities.containsKey(entity) ) {
+				remove.add( entity );
+			}
+		}
+		for(Class<?> entity : remove) {
+			classes.remove( entity );
+		}
+	}
+
 	private void copyStateFromOldFactory(StateSearchFactoryImplementor stateFactory) {
 		indexingStrategy = stateFactory.getIndexingStrategy();
 		documentBuildersIndexedEntities = stateFactory.getDocumentBuildersIndexedEntities();

Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/mutablefactory/A.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/mutablefactory/A.java	2010-06-30 13:43:49 UTC (rev 19870)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/mutablefactory/A.java	2010-06-30 13:44:30 UTC (rev 19871)
@@ -16,6 +16,11 @@
 	private Integer id;
 	private String name;
 
+	public A(int id, String name) {
+		this.id = id;
+		this.name = name;
+	}
+
 	@DocumentId
 	public Integer getId() {
 		return id;

Copied: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/mutablefactory/C.java (from rev 19869, search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/mutablefactory/A.java)
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/mutablefactory/C.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/mutablefactory/C.java	2010-06-30 13:44:30 UTC (rev 19871)
@@ -0,0 +1,37 @@
+package org.hibernate.search.test.configuration.mutablefactory;
+
+import org.hibernate.search.annotations.DocumentId;
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Indexed;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Indexed
+public class C {
+	private Integer id;
+	private String name;
+
+	public C(Integer id, String name) {
+		this.id = id;
+		this.name = name;
+	}
+
+	@DocumentId
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	@Field
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+}

Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/mutablefactory/MutableFactoryTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/mutablefactory/MutableFactoryTest.java	2010-06-30 13:43:49 UTC (rev 19870)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/mutablefactory/MutableFactoryTest.java	2010-06-30 13:44:30 UTC (rev 19871)
@@ -6,6 +6,7 @@
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.TopDocs;
 
+import org.hibernate.search.IncrementalSearchFactory;
 import org.hibernate.search.backend.Work;
 import org.hibernate.search.backend.WorkType;
 import org.hibernate.search.engine.SearchFactoryImplementor;
@@ -28,7 +29,7 @@
 		sf.close();
 	}
 
-	public void testAddingClass() throws Exception {
+	public void testAddingClassFullModel() throws Exception {
 		ManualConfiguration configuration = new ManualConfiguration()
 				.addProperty( "hibernate.search.default.directory_provider", RAMDirectoryProvider.class.getName() );
 		//FIXME downcasting of MSF. create a getDelegate() ?
@@ -38,14 +39,9 @@
 				.addClass( A.class )
 				.buildSearchFactory();
 
-		A a = new A();
-		a.setId( 1 );
-		a.setName( "Emmanuel" );
-
 		ManualTransactionContext tc = new ManualTransactionContext();
 
-		Work<A> work = new Work<A>( a, 1, WorkType.INDEX );
-		sf.getWorker().performWork( work, tc );
+		doIndexWork( new A(1, "Emmanuel"), 1, sf, tc );
 
 		tc.end();
 
@@ -67,8 +63,7 @@
 
 		tc = new ManualTransactionContext();
 
-		Work<B> workB = new Work<B>( new B(1, "Noel"), 1, WorkType.INDEX );
-		sf.getWorker().performWork( workB, tc );
+		doIndexWork( new B(1, "Noel"), 1, sf, tc );
 
 		tc.end();
 
@@ -84,4 +79,64 @@
 
 		sf.close();
 	}
+
+	public void testAddingClassSimpleAPI() throws Exception {
+		ManualConfiguration configuration = new ManualConfiguration()
+				.addProperty( "hibernate.search.default.directory_provider", RAMDirectoryProvider.class.getName() );
+		//FIXME downcasting of MSF. create a getDelegate() ?
+		IncrementalSearchFactory sf = (IncrementalSearchFactory) new SearchFactoryBuilder().configuration( configuration ).buildSearchFactory();
+		SearchFactoryImplementor sfi = (SearchFactoryImplementor) sf;
+		sf.addClasses( A.class );
+
+		ManualTransactionContext tc = new ManualTransactionContext();
+
+		doIndexWork( new A(1, "Emmanuel"), 1, sfi, tc );
+
+		tc.end();
+
+		QueryParser parser = new QueryParser( SearchTestCase.getTargetLuceneVersion(), "name", SearchTestCase.standardAnalyzer );
+		Query luceneQuery = parser.parse( "Emmanuel" );
+
+		//we know there is only one DP
+		DirectoryProvider provider = sfi
+				.getDirectoryProviders( A.class )[0];
+		IndexSearcher searcher = new IndexSearcher( provider.getDirectory(), true );
+		TopDocs hits = searcher.search( luceneQuery, 1000 );
+		assertEquals( 1, hits.totalHits );
+
+		searcher.close();
+
+		sf.addClasses( B.class, C.class );
+
+		tc = new ManualTransactionContext();
+
+		doIndexWork( new B(1, "Noel"), 1, sfi, tc );
+		doIndexWork( new C(1, "Vincent"), 1, sfi, tc );
+
+		tc.end();
+
+		luceneQuery = parser.parse( "Noel" );
+
+		//we know there is only one DP
+		provider = sfi.getDirectoryProviders( B.class )[0];
+		searcher = new IndexSearcher( provider.getDirectory(), true );
+		hits = searcher.search( luceneQuery, 1000 );
+		assertEquals( 1, hits.totalHits );
+
+		luceneQuery = parser.parse( "Vincent" );
+		
+		provider = sfi.getDirectoryProviders( C.class )[0];
+		searcher = new IndexSearcher( provider.getDirectory(), true );
+		hits = searcher.search( luceneQuery, 1000 );
+		assertEquals( 1, hits.totalHits );
+
+		searcher.close();
+
+		sfi.close();
+	}
+
+	private void doIndexWork(Object entity, Integer id, SearchFactoryImplementor sfi, ManualTransactionContext tc) {
+		Work<?> work = new Work<Object>( entity, id, WorkType.INDEX );
+		sfi.getWorker().performWork( work, tc );
+	}
 }



More information about the hibernate-commits mailing list