[hibernate-commits] Hibernate SVN: r14199 - in search/trunk/src: java/org/hibernate/search/engine and 4 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Fri Nov 16 07:43:51 EST 2007


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;
+	}
+}




More information about the hibernate-commits mailing list