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,