Author: epbernard
Date: 2007-11-16 07:43:51 -0500 (Fri, 16 Nov 2007)
New Revision: 14199
Added:
search/trunk/src/test/org/hibernate/search/test/query/ProjectionToDelimStringResultTransformer.java
search/trunk/src/test/org/hibernate/search/test/query/ProjectionToMapResultTransformer.java
Modified:
search/trunk/src/java/org/hibernate/search/FullTextQuery.java
search/trunk/src/java/org/hibernate/search/engine/ProjectionLoader.java
search/trunk/src/java/org/hibernate/search/jpa/FullTextQuery.java
search/trunk/src/java/org/hibernate/search/jpa/impl/FullTextQueryImpl.java
search/trunk/src/java/org/hibernate/search/query/FullTextQueryImpl.java
search/trunk/src/test/org/hibernate/search/test/query/ProjectionQueryTest.java
Log:
HSEARCH-114 add resulttransformer
Modified: search/trunk/src/java/org/hibernate/search/FullTextQuery.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/FullTextQuery.java 2007-11-13 20:55:50 UTC
(rev 14198)
+++ search/trunk/src/java/org/hibernate/search/FullTextQuery.java 2007-11-16 12:43:51 UTC
(rev 14199)
@@ -5,6 +5,7 @@
import org.apache.lucene.search.Sort;
import org.hibernate.Criteria;
import org.hibernate.Query;
+import org.hibernate.transform.ResultTransformer;
/**
* The base interface for lucene powered searches.
@@ -91,4 +92,9 @@
*/
FullTextQuery setFetchSize(int i);
+ /**
+ * defines a result transformer used during projection, the Aliases provided are the
projection aliases.
+ */
+ FullTextQuery setResultTransformer(ResultTransformer transformer);
+
}
Modified: search/trunk/src/java/org/hibernate/search/engine/ProjectionLoader.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/engine/ProjectionLoader.java 2007-11-13
20:55:50 UTC (rev 14198)
+++ search/trunk/src/java/org/hibernate/search/engine/ProjectionLoader.java 2007-11-16
12:43:51 UTC (rev 14199)
@@ -5,6 +5,7 @@
import java.util.List;
import org.hibernate.Session;
+import org.hibernate.transform.ResultTransformer;
/**
* @author Emmanuel Bernard
@@ -14,12 +15,20 @@
private Session session;
private ObjectLoader objectLoader;
private Boolean projectThis;
+ private ResultTransformer transformer;
+ private String[] aliases;
public void init(Session session, SearchFactoryImplementor searchFactoryImplementor) {
this.session = session;
this.searchFactoryImplementor = searchFactoryImplementor;
}
+ public void init(Session session, SearchFactoryImplementor searchFactoryImplementor,
ResultTransformer transformer, String[] aliases) {
+ init( session, searchFactoryImplementor );
+ this.transformer = transformer;
+ this.aliases = aliases;
+ }
+
public Object load(EntityInfo entityInfo) {
initThisProjectionFlag( entityInfo );
if ( projectThis ) {
@@ -27,7 +36,12 @@
entityInfo.projection[index] = objectLoader.load( entityInfo );
}
}
- return entityInfo.projection;
+ if ( transformer != null ) {
+ return transformer.transformTuple( entityInfo.projection, aliases );
+ }
+ else {
+ return entityInfo.projection;
+ }
}
private void initThisProjectionFlag(EntityInfo entityInfo) {
@@ -56,7 +70,12 @@
}
}
for (EntityInfo entityInfo : entityInfos) {
- results.add( entityInfo.projection );
+ if ( transformer != null) {
+ results.add( transformer.transformTuple( entityInfo.projection, aliases ) );
+ }
+ else {
+ results.add( entityInfo.projection );
+ }
}
return results;
Modified: search/trunk/src/java/org/hibernate/search/jpa/FullTextQuery.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/jpa/FullTextQuery.java 2007-11-13 20:55:50
UTC (rev 14198)
+++ search/trunk/src/java/org/hibernate/search/jpa/FullTextQuery.java 2007-11-16 12:43:51
UTC (rev 14199)
@@ -6,6 +6,7 @@
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.Filter;
import org.hibernate.Criteria;
+import org.hibernate.transform.ResultTransformer;
import org.hibernate.search.ProjectionConstants;
import org.hibernate.search.FullTextFilter;
@@ -81,4 +82,11 @@
* Disable a given filter by its name
*/
void disableFullTextFilter(String name);
+
+ /**
+ *
+ * defines a result transformer used during projection
+ *
+ */
+ FullTextQuery setResultTransformer(ResultTransformer transformer);
}
Modified: search/trunk/src/java/org/hibernate/search/jpa/impl/FullTextQueryImpl.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/jpa/impl/FullTextQueryImpl.java 2007-11-13
20:55:50 UTC (rev 14198)
+++ search/trunk/src/java/org/hibernate/search/jpa/impl/FullTextQueryImpl.java 2007-11-16
12:43:51 UTC (rev 14199)
@@ -1,40 +1,41 @@
// $Id$
package org.hibernate.search.jpa.impl;
+import java.io.Serializable;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashSet;
import java.util.List;
-import java.util.Date;
-import java.util.Calendar;
import java.util.Set;
-import java.util.HashSet;
-import java.io.Serializable;
-import javax.persistence.Query;
-import javax.persistence.TemporalType;
+import javax.persistence.EntityExistsException;
+import javax.persistence.EntityNotFoundException;
import javax.persistence.FlushModeType;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
+import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
-import javax.persistence.EntityExistsException;
-import javax.persistence.EntityNotFoundException;
-import javax.persistence.OptimisticLockException;
+import javax.persistence.Query;
+import javax.persistence.TemporalType;
-import org.hibernate.search.jpa.FullTextQuery;
-import org.hibernate.search.SearchException;
-import org.hibernate.search.FullTextFilter;
+import org.apache.lucene.search.Filter;
+import org.apache.lucene.search.Sort;
import org.hibernate.Criteria;
-import org.hibernate.TypeMismatchException;
+import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
-import org.hibernate.StaleStateException;
import org.hibernate.ObjectNotFoundException;
-import org.hibernate.UnresolvableObjectException;
import org.hibernate.QueryException;
+import org.hibernate.Session;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.StaleStateException;
import org.hibernate.TransientObjectException;
-import org.hibernate.StaleObjectStateException;
-import org.hibernate.Session;
-import org.hibernate.FlushMode;
+import org.hibernate.TypeMismatchException;
+import org.hibernate.UnresolvableObjectException;
import org.hibernate.exception.ConstraintViolationException;
import org.hibernate.hql.QueryExecutionRequestException;
-import org.apache.lucene.search.Sort;
-import org.apache.lucene.search.Filter;
+import org.hibernate.search.FullTextFilter;
+import org.hibernate.search.SearchException;
+import org.hibernate.search.jpa.FullTextQuery;
+import org.hibernate.transform.ResultTransformer;
/**
* @author Emmanuel Bernard
@@ -80,6 +81,11 @@
query.disableFullTextFilter( name );
}
+ public FullTextQuery setResultTransformer(ResultTransformer transformer) {
+ query.setResultTransformer( transformer );
+ return this;
+ }
+
public List getResultList() {
try {
return query.list();
Modified: search/trunk/src/java/org/hibernate/search/query/FullTextQueryImpl.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/query/FullTextQueryImpl.java 2007-11-13
20:55:50 UTC (rev 14198)
+++ search/trunk/src/java/org/hibernate/search/query/FullTextQueryImpl.java 2007-11-16
12:43:51 UTC (rev 14199)
@@ -2,6 +2,7 @@
package org.hibernate.search.query;
import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -10,7 +11,6 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.lang.reflect.InvocationTargetException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -51,6 +51,7 @@
import org.hibernate.search.filter.FilterKey;
import org.hibernate.search.store.DirectoryProvider;
import org.hibernate.search.util.ContextHelper;
+import org.hibernate.transform.ResultTransformer;
/**
* Implementation of {@link org.hibernate.search.FullTextQuery}
@@ -71,6 +72,7 @@
private Filter filter;
private Criteria criteria;
private String[] indexProjection;
+ private ResultTransformer resultTransformer;
private SearchFactoryImplementor searchFactoryImplementor;
private Map<String, FullTextFilterImpl> filterDefinitions;
private int fetchSize = 1;
@@ -150,7 +152,7 @@
private Loader getLoader(Session session, SearchFactoryImplementor
searchFactoryImplementor) {
if ( indexProjection != null ) {
ProjectionLoader loader = new ProjectionLoader();
- loader.init( session, searchFactoryImplementor );
+ loader.init( session, searchFactoryImplementor, resultTransformer, indexProjection );
return loader;
}
if ( criteria != null ) {
@@ -241,7 +243,14 @@
infos.add( extractor.extract( hits, index ) );
}
Loader loader = getLoader( sess, searchFactoryImplementor );
- return loader.load( infos.toArray( new EntityInfo[infos.size()] ) );
+ List list = loader.load( infos.toArray( new EntityInfo[infos.size()] ) );
+ if ( resultTransformer == null || loader instanceof ProjectionLoader) {
+ //stay consistent with transformTuple which can only be executed during a projection
+ return list;
+ }
+ else {
+ return resultTransformer.transformList( list );
+ }
}
catch (IOException e) {
throw new HibernateException( "Unable to query Lucene index", e );
@@ -530,6 +539,13 @@
return this;
}
+ @Override
+ public FullTextQuery setResultTransformer(ResultTransformer transformer) {
+ super.setResultTransformer( transformer );
+ this.resultTransformer = transformer;
+ return this;
+ }
+
public int executeUpdate() throws HibernateException {
throw new HibernateException( "Not supported operation" );
}
Modified: search/trunk/src/test/org/hibernate/search/test/query/ProjectionQueryTest.java
===================================================================
---
search/trunk/src/test/org/hibernate/search/test/query/ProjectionQueryTest.java 2007-11-13
20:55:50 UTC (rev 14198)
+++
search/trunk/src/test/org/hibernate/search/test/query/ProjectionQueryTest.java 2007-11-16
12:43:51 UTC (rev 14199)
@@ -1,22 +1,23 @@
//$Id$
package org.hibernate.search.test.query;
+import java.io.Serializable;
+import java.util.Iterator;
import java.util.List;
-import java.util.Iterator;
-import java.io.Serializable;
+import java.util.Map;
import org.apache.lucene.analysis.StopAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
+import org.apache.lucene.document.Document;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Query;
-import org.apache.lucene.document.Document;
-import org.hibernate.Transaction;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.hibernate.search.SearchException;
-import org.hibernate.search.FullTextQuery;
import org.hibernate.search.test.SearchTestCase;
/**
@@ -48,16 +49,16 @@
projections.next();
Object[] projection = projections.get();
checkProjectionFirst( projection, s );
- assertTrue(projections.isFirst());
+ assertTrue( projections.isFirst() );
projections.last();
projection = projections.get();
checkProjectionLast( projection, s );
- assertTrue(projections.isLast());
+ assertTrue( projections.isLast() );
projections.next();
projection = projections.get();
- assertNull(projection);
+ assertNull( projection );
projections.previous();
projection = projections.get();
@@ -73,7 +74,7 @@
projections.scroll( -5 );
projection = projections.get();
- assertNull(projection);
+ assertNull( projection );
//cleanup
for (Object element : s.createQuery( "from " + Employee.class.getName()
).list()) s.delete( element );
@@ -81,11 +82,67 @@
s.close();
}
+ public void testResultTransformToDelimString() throws Exception {
+ FullTextSession s = Search.createFullTextSession( openSession() );
+ prepEmployeeIndex( s );
+
+ Transaction tx;
+ s.clear();
+ 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( "id", "lastname", "dept",
FullTextQuery.THIS, FullTextQuery.SCORE, FullTextQuery.BOOST, FullTextQuery.ID );
+ hibQuery.setResultTransformer( new ProjectionToDelimStringResultTransformer() );
+
+ List<String> result = (List<String>) hibQuery.list();
+ assertTrue( "incorrect transformation", result.get( 0 ).startsWith(
"1000, Griffin, ITech" ) );
+ assertTrue( "incorrect transformation", result.get( 1 ).startsWith(
"1002, Jimenez, ITech" ) );
+
+ //cleanup
+ for ( Object element : s.createQuery( "from " + Employee.class.getName()
).list() ) {
+ s.delete( element );
+ }
+ tx.commit();
+ s.close();
+ }
+
+ public void testResultTransformMap() throws Exception {
+ FullTextSession s = Search.createFullTextSession( openSession() );
+ prepEmployeeIndex( s );
+
+ Transaction tx;
+ s.clear();
+ 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( "id", "lastname", "dept",
FullTextQuery.THIS, FullTextQuery.SCORE, FullTextQuery.BOOST, FullTextQuery.DOCUMENT,
FullTextQuery.ID );
+
+ hibQuery.setResultTransformer( new ProjectionToMapResultTransformer() );
+
+ List transforms = hibQuery.list();
+ Map map = (Map) transforms.get( 1 );
+ assertEquals( "incorrect transformation", "ITech", map.get(
"dept" ) );
+ assertEquals( "incorrect transformation", 1002, map.get( "id" ) );
+ assertTrue( "incorrect transformation", map.get( FullTextQuery.DOCUMENT )
instanceof Document );
+ assertEquals( "incorrect transformation", "1002", ( (Document)
map.get( FullTextQuery.DOCUMENT ) ).get( "id" ) );
+
+ //cleanup
+ for (Object element : s.createQuery( "from " + Employee.class.getName()
).list()) {
+ s.delete( element );
+ }
+ tx.commit();
+ s.close();
+ }
+
private void checkProjectionFirst(Object[] projection, Session s) {
assertEquals( "id incorrect", 1000, projection[0] );
assertEquals( "lastname incorrect", "Griffin", projection[1] );
assertEquals( "dept incorrect", "ITech", projection[2] );
- assertEquals( "THIS incorrect", projection[3], s.get(Employee.class,
(Serializable) projection[0]) );
+ assertEquals( "THIS incorrect", projection[3], s.get( Employee.class,
(Serializable) projection[0] ) );
assertEquals( "SCORE incorrect", 1.0F, projection[4] );
assertEquals( "BOOST incorrect", 1.0F, projection[5] );
assertTrue( "DOCUMENT incorrect", projection[6] instanceof Document );
@@ -97,7 +154,7 @@
assertEquals( "id incorrect", 1004, projection[0] );
assertEquals( "lastname incorrect", "Whetbrook", projection[1] );
assertEquals( "dept incorrect", "ITech", projection[2] );
- assertEquals( "THIS incorrect", projection[3], s.get(Employee.class,
(Serializable) projection[0]) );
+ assertEquals( "THIS incorrect", projection[3], s.get( Employee.class,
(Serializable) projection[0] ) );
assertEquals( "SCORE incorrect", 1.0F, projection[4] );
assertEquals( "BOOST incorrect", 1.0F, projection[5] );
assertTrue( "DOCUMENT incorrect", projection[6] instanceof Document );
@@ -109,7 +166,7 @@
assertEquals( "id incorrect", 1003, projection[0] );
assertEquals( "lastname incorrect", "Stejskal", projection[1] );
assertEquals( "dept incorrect", "ITech", projection[2] );
- assertEquals( "THIS incorrect", projection[3], s.get(Employee.class,
(Serializable) projection[0]) );
+ assertEquals( "THIS incorrect", projection[3], s.get( Employee.class,
(Serializable) projection[0] ) );
assertEquals( "SCORE incorrect", 1.0F, projection[4] );
assertEquals( "BOOST incorrect", 1.0F, projection[5] );
assertTrue( "DOCUMENT incorrect", projection[6] instanceof Document );
@@ -137,7 +194,7 @@
assertNotNull( projection );
counter++;
assertEquals( "dept incorrect", "ITech", projection[2] );
- assertEquals( "THIS incorrect", projection[3], s.get(Employee.class,
(Serializable) projection[0]) );
+ assertEquals( "THIS incorrect", projection[3], s.get( Employee.class,
(Serializable) projection[0] ) );
assertEquals( "SCORE incorrect", 1.0F, projection[4] );
assertEquals( "BOOST incorrect", 1.0F, projection[5] );
assertTrue( "DOCUMENT incorrect", projection[6] instanceof Document );
@@ -173,7 +230,7 @@
assertEquals( "last name incorrect", "Jackson", projection[1] );
assertEquals( "dept incorrect", "Accounting", projection[2] );
assertEquals( "THIS incorrect", "Jackson", ( (Employee)
projection[3] ).getLastname() );
- assertEquals( "THIS incorrect", projection[3], s.get(Employee.class,
(Serializable) projection[0]) );
+ assertEquals( "THIS incorrect", projection[3], s.get( Employee.class,
(Serializable) projection[0] ) );
assertEquals( "SCORE incorrect", 1.0F, projection[4] );
assertEquals( "BOOST incorrect", 1.0F, projection[5] );
assertTrue( "DOCUMENT incorrect", projection[6] instanceof Document );
@@ -191,7 +248,7 @@
assertTrue( "DOCUMENT incorrect", projection[0] instanceof Document );
assertEquals( "DOCUMENT size incorrect", 4, ( (Document) projection[0]
).getFields().size() );
- assertEquals( "THIS incorrect", projection[1], s.get(Employee.class,
(Serializable) projection[4]) );
+ assertEquals( "THIS incorrect", projection[1], s.get( Employee.class,
(Serializable) projection[4] ) );
assertEquals( "SCORE incorrect", 1.0F, projection[2] );
assertNull( "BOOST not removed", projection[3] );
assertEquals( "ID incorrect", 1001, projection[4] );
Added:
search/trunk/src/test/org/hibernate/search/test/query/ProjectionToDelimStringResultTransformer.java
===================================================================
---
search/trunk/src/test/org/hibernate/search/test/query/ProjectionToDelimStringResultTransformer.java
(rev 0)
+++
search/trunk/src/test/org/hibernate/search/test/query/ProjectionToDelimStringResultTransformer.java 2007-11-16
12:43:51 UTC (rev 14199)
@@ -0,0 +1,23 @@
+package org.hibernate.search.test.query;
+
+import java.util.List;
+
+import org.hibernate.transform.ResultTransformer;
+
+/**
+ * @author John Griffin
+ */
+public class ProjectionToDelimStringResultTransformer implements ResultTransformer {
+
+ public Object transformTuple(Object[] tuple, String[] aliases) {
+ String s = tuple[0].toString();
+ for (int i = 1; i < tuple.length; i++) {
+ s = s + ", " + tuple[i].toString();
+ }
+ return s;
+ }
+
+ public List transformList(List collection) {
+ return collection;
+ }
+}
Added:
search/trunk/src/test/org/hibernate/search/test/query/ProjectionToMapResultTransformer.java
===================================================================
---
search/trunk/src/test/org/hibernate/search/test/query/ProjectionToMapResultTransformer.java
(rev 0)
+++
search/trunk/src/test/org/hibernate/search/test/query/ProjectionToMapResultTransformer.java 2007-11-16
12:43:51 UTC (rev 14199)
@@ -0,0 +1,28 @@
+package org.hibernate.search.test.query;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.transform.ResultTransformer;
+
+/**
+ * @author John Griffin
+ */
+public class ProjectionToMapResultTransformer implements ResultTransformer {
+
+ public Object transformTuple(Object[] tuple, String[] aliases) {
+ Map result = new HashMap( tuple.length );
+ for (int i = 0; i < tuple.length; i++) {
+ String key = aliases[i];
+ if ( key != null ) {
+ result.put( key, tuple[i] );
+ }
+ }
+ return result;
+ }
+
+ public List transformList(List collection) {
+ return collection;
+ }
+}