[hibernate-commits] Hibernate SVN: r15606 - in search/trunk/src: java/org/hibernate/search/backend/impl/lucene/works and 4 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Mon Nov 24 06:39:53 EST 2008


Author: hardy.ferentschik
Date: 2008-11-24 06:39:52 -0500 (Mon, 24 Nov 2008)
New Revision: 15606

Added:
   search/trunk/src/java/org/hibernate/search/engine/DocumentBuilder.java
Modified:
   search/trunk/src/java/org/hibernate/search/ProjectionConstants.java
   search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/DeleteWorkDelegate.java
   search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/PurgeAllWorkDelegate.java
   search/trunk/src/java/org/hibernate/search/engine/DocumentBuilderContainedEntity.java
   search/trunk/src/java/org/hibernate/search/engine/DocumentExtractor.java
   search/trunk/src/java/org/hibernate/search/query/FullTextQueryImpl.java
   search/trunk/src/test/org/hibernate/search/test/jms/master/JMSMasterTest.java
   search/trunk/src/test/org/hibernate/search/test/query/ProjectionQueryTest.java
Log:
HSEARCH-285 & HSEARCH-296

Introduced a DocumetBuilder interface containing the CLASS_FIELDNAME constant. Deprecated the interface.

Also introduced ProjectionConstant.OBJECT_CLASS in order to project indexed class type

Modified: search/trunk/src/java/org/hibernate/search/ProjectionConstants.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/ProjectionConstants.java	2008-11-23 10:48:59 UTC (rev 15605)
+++ search/trunk/src/java/org/hibernate/search/ProjectionConstants.java	2008-11-24 11:39:52 UTC (rev 15606)
@@ -2,13 +2,13 @@
 package org.hibernate.search;
 
 /**
- * Define Projection constants
+ * Defined projection constants.
  *
  * @author Emmanuel Bernard
  */
 public interface ProjectionConstants {
 	/**
-	 * Represtnts the Hibernate Entity returned in a search.
+	 * Represents the Hibernate entity returned in a search.
 	 */
 	public String THIS = "__HSearch_This";
 
@@ -53,7 +53,8 @@
 	public String EXPLANATION = "__HSearch_Explanation";
 
 	/**
-	 * Object class
+	 * Represents the Hibernate entity class returned in a search. In contrast to the other constants this constant
+	 * represents an actual field value of the underlying Lucene document and hence can directly be used in queries.
 	 */
-	//TODO OBJECT CLASS
+	public String OBJECT_CLASS = "_hibernate_class";
 }

Modified: search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/DeleteWorkDelegate.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/DeleteWorkDelegate.java	2008-11-23 10:48:59 UTC (rev 15605)
+++ search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/DeleteWorkDelegate.java	2008-11-24 11:39:52 UTC (rev 15606)
@@ -16,6 +16,7 @@
 import org.hibernate.search.backend.Workspace;
 import org.hibernate.search.backend.impl.lucene.IndexInteractionType;
 import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
+import org.hibernate.search.engine.DocumentBuilder;
 import org.hibernate.search.util.LoggerFactory;
 
 /**
@@ -51,7 +52,7 @@
 		TermQuery idQueryTerm = new TermQuery( builder.getTerm( work.getId() ) );
 		entityDeletionQuery.add( idQueryTerm, BooleanClause.Occur.MUST );
 
-		Term classNameQueryTerm =  new Term( DocumentBuilderIndexedEntity.CLASS_FIELDNAME, entityType.getName() );
+		Term classNameQueryTerm =  new Term( DocumentBuilder.CLASS_FIELDNAME, entityType.getName() );
 		TermQuery classNameQuery = new TermQuery( classNameQueryTerm );
 		entityDeletionQuery.add( classNameQuery, BooleanClause.Occur.MUST );
 
@@ -88,7 +89,7 @@
 			String entityName = entityType.getName();
 			while ( termDocs.next() ) {
 				int docIndex = termDocs.doc();
-				if ( entityName.equals( reader.document( docIndex ).get( DocumentBuilderIndexedEntity.CLASS_FIELDNAME ) ) ) {
+				if ( entityName.equals( reader.document( docIndex ).get( DocumentBuilder.CLASS_FIELDNAME ) ) ) {
 					//remove only the one of the right class
 					//loop all to remove all the matches (defensive code)
 					reader.deleteDocument( docIndex );

Modified: search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/PurgeAllWorkDelegate.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/PurgeAllWorkDelegate.java	2008-11-23 10:48:59 UTC (rev 15605)
+++ search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/PurgeAllWorkDelegate.java	2008-11-24 11:39:52 UTC (rev 15606)
@@ -8,7 +8,7 @@
 import org.hibernate.search.SearchException;
 import org.hibernate.search.backend.LuceneWork;
 import org.hibernate.search.backend.impl.lucene.IndexInteractionType;
-import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
+import org.hibernate.search.engine.DocumentBuilder;
 import org.hibernate.search.util.LoggerFactory;
 
 /**
@@ -34,7 +34,7 @@
 	public void performWork(LuceneWork work, IndexWriter writer) {
 		log.trace( "purgeAll Lucene index using IndexWriter for type: {}", work.getEntityClass() );
 		try {
-			Term term = new Term( DocumentBuilderIndexedEntity.CLASS_FIELDNAME, work.getEntityClass().getName() );
+			Term term = new Term( DocumentBuilder.CLASS_FIELDNAME, work.getEntityClass().getName() );
 			writer.deleteDocuments( term );
 		}
 		catch (Exception e) {
@@ -45,7 +45,7 @@
 	public void performWork(LuceneWork work, IndexReader reader) {
 		log.trace( "purgeAll Lucene index using IndexReader for type: {}", work.getEntityClass() );
 		try {
-			Term term = new Term( DocumentBuilderIndexedEntity.CLASS_FIELDNAME, work.getEntityClass().getName() );
+			Term term = new Term( DocumentBuilder.CLASS_FIELDNAME, work.getEntityClass().getName() );
 			reader.deleteDocuments( term );
 		}
 		catch (Exception e) {

Added: search/trunk/src/java/org/hibernate/search/engine/DocumentBuilder.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/engine/DocumentBuilder.java	                        (rev 0)
+++ search/trunk/src/java/org/hibernate/search/engine/DocumentBuilder.java	2008-11-24 11:39:52 UTC (rev 15606)
@@ -0,0 +1,21 @@
+// $Id$
+package org.hibernate.search.engine;
+
+import org.hibernate.search.ProjectionConstants;
+
+/**
+ * Interface created to keep backwards compatibility.
+ *
+ * @deprecated As of release 3.1.0, replaced by {@link org.hibernate.search.ProjectionConstants}
+ * @author Hardy Ferentschik
+ */
+public interface DocumentBuilder {
+
+	/**
+	 * Lucene document field name containing the fully qualified classname of the indexed class.
+	 *
+	 * @deprecated As of release 3.1.0, replaced by {@link org.hibernate.search.ProjectionConstants#OBJECT_CLASS}
+	 */
+	@Deprecated
+	String CLASS_FIELDNAME = ProjectionConstants.OBJECT_CLASS;
+}


Property changes on: search/trunk/src/java/org/hibernate/search/engine/DocumentBuilder.java
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: search/trunk/src/java/org/hibernate/search/engine/DocumentBuilderContainedEntity.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/engine/DocumentBuilderContainedEntity.java	2008-11-23 10:48:59 UTC (rev 15605)
+++ search/trunk/src/java/org/hibernate/search/engine/DocumentBuilderContainedEntity.java	2008-11-24 11:39:52 UTC (rev 15606)
@@ -63,11 +63,9 @@
  * @author Richard Hallier
  * @author Hardy Ferentschik
  */
-public class DocumentBuilderContainedEntity<T> {
+public class DocumentBuilderContainedEntity<T> implements DocumentBuilder {
 	private static final Logger log = LoggerFactory.make();
 
-	public static final String CLASS_FIELDNAME = "_hibernate_class";
-
 	protected final PropertiesMetadata metadata = new PropertiesMetadata();
 	protected final XClass beanClass;
 	protected String idKeywordName;
@@ -830,7 +828,7 @@
 	}
 
 	public static Class getDocumentClass(Document document) {
-		String className = document.get( DocumentBuilderContainedEntity.CLASS_FIELDNAME );
+		String className = document.get( CLASS_FIELDNAME );
 		try {
 			return ReflectHelper.classForName( className );
 		}

Modified: search/trunk/src/java/org/hibernate/search/engine/DocumentExtractor.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/engine/DocumentExtractor.java	2008-11-23 10:48:59 UTC (rev 15605)
+++ search/trunk/src/java/org/hibernate/search/engine/DocumentExtractor.java	2008-11-24 11:39:52 UTC (rev 15606)
@@ -13,6 +13,7 @@
 import org.apache.lucene.document.FieldSelector;
 
 import org.hibernate.search.ProjectionConstants;
+import org.hibernate.search.SearchException;
 import org.hibernate.search.query.QueryHits;
 
 /**
@@ -49,10 +50,9 @@
 			}
 		}
 
-
 		// set up the field selector. CLASS_FIELDNAME and id fields are needed on top of any projected fields
 		Map<String, FieldSelectorResult> fields = new HashMap<String, FieldSelectorResult>( 1 + idFieldNames.size() + projectionSize );
-		fields.put( DocumentBuilderIndexedEntity.CLASS_FIELDNAME, FieldSelectorResult.LOAD );
+		fields.put( DocumentBuilder.CLASS_FIELDNAME, FieldSelectorResult.LOAD );
 		for ( String idFieldName : idFieldNames ) {
 			fields.put( idFieldName, FieldSelectorResult.LOAD );
 		}
@@ -69,7 +69,9 @@
 		Serializable id = DocumentBuilderIndexedEntity.getDocumentId( searchFactoryImplementor, clazz, document );
 		Object[] projected = null;
 		if ( projection != null && projection.length > 0 ) {
-			projected = DocumentBuilderIndexedEntity.getDocumentFields( searchFactoryImplementor, clazz, document, projection );
+			projected = DocumentBuilderIndexedEntity.getDocumentFields(
+					searchFactoryImplementor, clazz, document, projection
+			);
 		}
 		return new EntityInfo( clazz, id, projected );
 	}
@@ -82,10 +84,11 @@
 		else {
 			doc = queryHits.doc( index );
 		}
-		//TODO if we are only looking for score (unlikely), avoid accessing doc (lazy load)
+
 		EntityInfo entityInfo = extract( doc );
 		Object[] eip = entityInfo.projection;
 
+		// TODO - if we are only looking for score (unlikely), avoid accessing doc (lazy load)
 		if ( eip != null && eip.length > 0 ) {
 			for ( int x = 0; x < projection.length; x++ ) {
 				if ( ProjectionConstants.SCORE.equals( projection[x] ) ) {
@@ -106,6 +109,9 @@
 				else if ( ProjectionConstants.EXPLANATION.equals( projection[x] ) ) {
 					eip[x] = queryHits.explain( index );
 				}
+				else if ( ProjectionConstants.OBJECT_CLASS.equals( projection[x] ) ) {
+						eip[x] = entityInfo.clazz;
+				}
 				else if ( ProjectionConstants.THIS.equals( projection[x] ) ) {
 					//THIS could be projected more than once
 					//THIS loading delayed to the Loader phase

Modified: search/trunk/src/java/org/hibernate/search/query/FullTextQueryImpl.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/query/FullTextQueryImpl.java	2008-11-23 10:48:59 UTC (rev 15605)
+++ search/trunk/src/java/org/hibernate/search/query/FullTextQueryImpl.java	2008-11-24 11:39:52 UTC (rev 15606)
@@ -50,6 +50,7 @@
 import org.hibernate.search.engine.ProjectionLoader;
 import org.hibernate.search.engine.QueryLoader;
 import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.hibernate.search.engine.DocumentBuilder;
 import org.hibernate.search.filter.ChainedFilter;
 import org.hibernate.search.filter.FilterKey;
 import org.hibernate.search.filter.StandardFilterKey;
@@ -550,7 +551,7 @@
 			//annihilate the scoring impact of DocumentBuilderIndexedEntity.CLASS_FIELDNAME
 			classFilter.setBoost( 0 );
 			for ( Class clazz : classesAndSubclasses ) {
-				Term t = new Term( DocumentBuilderIndexedEntity.CLASS_FIELDNAME, clazz.getName() );
+				Term t = new Term( DocumentBuilder.CLASS_FIELDNAME, clazz.getName() );
 				TermQuery termQuery = new TermQuery( t );
 				classFilter.add( termQuery, BooleanClause.Occur.SHOULD );
 			}

Modified: search/trunk/src/test/org/hibernate/search/test/jms/master/JMSMasterTest.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/jms/master/JMSMasterTest.java	2008-11-23 10:48:59 UTC (rev 15605)
+++ search/trunk/src/test/org/hibernate/search/test/jms/master/JMSMasterTest.java	2008-11-24 11:39:52 UTC (rev 15606)
@@ -23,7 +23,7 @@
 import org.hibernate.search.Environment;
 import org.hibernate.search.FullTextSession;
 import org.hibernate.search.Search;
-import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
+import org.hibernate.search.engine.DocumentBuilder;
 import org.hibernate.search.backend.AddLuceneWork;
 import org.hibernate.search.backend.LuceneWork;
 import org.hibernate.search.backend.impl.jms.JMSBackendQueueProcessorFactory;
@@ -54,7 +54,7 @@
 		s.close();
 		//create the work queue to send
 		Document doc = new Document();
-		Field field = new Field( DocumentBuilderIndexedEntity.CLASS_FIELDNAME, ts.getClass().getName(), Field.Store.YES, Field.Index.NOT_ANALYZED );
+		Field field = new Field( DocumentBuilder.CLASS_FIELDNAME, ts.getClass().getName(), Field.Store.YES, Field.Index.NOT_ANALYZED );
 		doc.add( field );
 		field = new Field("id", "1", Field.Store.YES, Field.Index.NOT_ANALYZED );
 		doc.add( field );

Modified: search/trunk/src/test/org/hibernate/search/test/query/ProjectionQueryTest.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/query/ProjectionQueryTest.java	2008-11-23 10:48:59 UTC (rev 15605)
+++ search/trunk/src/test/org/hibernate/search/test/query/ProjectionQueryTest.java	2008-11-24 11:39:52 UTC (rev 15606)
@@ -23,11 +23,41 @@
 import org.hibernate.search.test.SearchTestCase;
 
 /**
+ * Tests several aspects of projection queries.
+ *
  * @author Emmanuel Bernard
  * @author John Griffin
+ * @author Hardy Ferentschik
  */
 public class ProjectionQueryTest extends SearchTestCase {
 
+	/**
+	 * HSEARCH-296
+	 *
+	 * @throws Exception in case the test fails.
+	 */
+	public void testClassProjection() throws Exception {
+		FullTextSession s = Search.getFullTextSession( openSession() );
+		prepEmployeeIndex( s );
+
+		s.clear();
+		Transaction tx = s.beginTransaction();
+		QueryParser parser = new QueryParser( "dept", new StandardAnalyzer() );
+		Query query = parser.parse( "dept:ITech" );
+		org.hibernate.search.FullTextQuery hibQuery = s.createFullTextQuery( query, Employee.class );
+		hibQuery.setProjection( FullTextQuery.OBJECT_CLASS );
+
+		List result = hibQuery.list();
+		assertNotNull( result );
+
+		Object[] projection = ( Object[] ) result.get( 0 );
+		assertNotNull( projection );
+		assertEquals( "Wrong projected class", Employee.class, projection[0] );
+
+		tx.commit();
+		s.close();
+	}
+
 	public void testLuceneObjectsProjectionWithScroll() throws Exception {
 		FullTextSession s = Search.getFullTextSession( openSession() );
 		prepEmployeeIndex( s );
@@ -108,7 +138,7 @@
 		hibQuery.setProjection( "id", "lastname", "dept", FullTextQuery.THIS, FullTextQuery.SCORE, FullTextQuery.ID );
 		hibQuery.setResultTransformer( new ProjectionToDelimStringResultTransformer() );
 
-		@SuppressWarnings( "unchecked" )
+		@SuppressWarnings("unchecked")
 		List<String> result = hibQuery.list();
 		assertTrue( "incorrect transformation", result.get( 0 ).startsWith( "1000, Griffin, ITech" ) );
 		assertTrue( "incorrect transformation", result.get( 1 ).startsWith( "1002, Jimenez, ITech" ) );
@@ -436,7 +466,6 @@
 		s.close();
 	}
 
-
 	protected Class[] getMappings() {
 		return new Class[] {
 				Book.class,




More information about the hibernate-commits mailing list