[hibernate-commits] Hibernate SVN: r18153 - in search/trunk/src: main/java/org/hibernate/search/cfg and 2 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Mon Dec 7 07:17:05 EST 2009


Author: epbernard
Date: 2009-12-07 07:17:04 -0500 (Mon, 07 Dec 2009)
New Revision: 18153

Added:
   search/trunk/src/main/java/org/hibernate/search/cfg/ClassBridgeMapping.java
   search/trunk/src/test/java/org/hibernate/search/test/configuration/CatDeptsFieldsClassBridge.java
   search/trunk/src/test/java/org/hibernate/search/test/configuration/Departments.java
   search/trunk/src/test/java/org/hibernate/search/test/configuration/EquipmentType.java
Modified:
   search/trunk/src/main/docbook/en-US/modules/mapping.xml
   search/trunk/src/main/java/org/hibernate/search/cfg/EntityDescriptor.java
   search/trunk/src/main/java/org/hibernate/search/cfg/EntityMapping.java
   search/trunk/src/main/java/org/hibernate/search/impl/MappingModelMetadataProvider.java
   search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java
Log:
HSEARCH-411 Add Class level bridge (Amin Mohammed-Coleman)

Modified: search/trunk/src/main/docbook/en-US/modules/mapping.xml
===================================================================
--- search/trunk/src/main/docbook/en-US/modules/mapping.xml	2009-12-07 08:55:15 UTC (rev 18152)
+++ search/trunk/src/main/docbook/en-US/modules/mapping.xml	2009-12-07 12:17:04 UTC (rev 18153)
@@ -2153,5 +2153,70 @@
             </example></para>
         </example></para>
     </section>
+
+    <section>
+      <title>Mapping class bridge</title>
+
+      <para>The annotation model provides a
+      <classname>@ClassBridge</classname> which enables you to modify the
+      lucene document, this feature is also available using the programmatic
+      appraoch. This is shown in the next example:</para>
+
+      <example>
+        <title>Defining class briges using API</title>
+
+        <programlisting>SearchMapping mapping = new SearchMapping();
+
+mapping
+    .entity(Departments.class)
+<emphasis>       .classBridge(CatDeptsFieldsClassBridge.class)
+         .name("branchnetwork")
+         .index(Index.TOKENIZED)
+         .store(Store.YES)
+         .param("sepChar", " ")
+      .classBridge(EquipmentType.class)
+         .name("equiptype")
+         .index(Index.TOKENIZED)
+         .store(Store.YES)
+         .param("C", "Cisco")
+         .param("D", "D-Link")
+         .param("K", "Kingston")
+         .param("3", "3Com")</emphasis>
+      .indexed();
+
+cfg.getProperties().put( "hibernate.search.mapping_model", mapping );
+
+</programlisting>
+
+        <para>The above is similar to using <classname>@ClassBridge
+        </classname>as seen in the next example:<example>
+            <title>Using @ClassBridge</title>
+
+            <programlisting>@Entity
+ at Indexed
+ at ClassBridges ( {
+  @ClassBridge(name="branchnetwork",
+     index= Index.TOKENIZED,
+     store= Store.YES,
+     impl = CatDeptsFieldsClassBridge.class,
+     params = @Parameter( name="sepChar", value=" " ) ),
+  @ClassBridge(name="equiptype",
+     index= Index.TOKENIZED,
+     store= Store.YES,
+     impl = EquipmentType.class,
+     params = {@Parameter( name="C", value="Cisco" ),
+        @Parameter( name="D", value="D-Link" ),
+        @Parameter( name="K", value="Kingston" ),
+        @Parameter( name="3", value="3Com" )
+   })
+})
+public class Departments {
+
+....
+
+}</programlisting>
+          </example> </para>
+      </example>
+    </section>
   </section>
-</chapter>
\ No newline at end of file
+</chapter>

Added: search/trunk/src/main/java/org/hibernate/search/cfg/ClassBridgeMapping.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/cfg/ClassBridgeMapping.java	                        (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/cfg/ClassBridgeMapping.java	2009-12-07 12:17:04 UTC (rev 18153)
@@ -0,0 +1,110 @@
+package org.hibernate.search.cfg;
+
+import java.lang.annotation.ElementType;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.solr.analysis.TokenizerFactory;
+import org.hibernate.search.annotations.Index;
+import org.hibernate.search.annotations.Store;
+import org.hibernate.search.annotations.TermVector;
+
+public class ClassBridgeMapping {
+	
+	private final SearchMapping mapping;
+	private final EntityDescriptor entity;
+	private final Map<String, Object> classBridge;
+	private final EntityMapping entityMapping;
+	
+	
+	public ClassBridgeMapping(SearchMapping mapping, EntityDescriptor entity, Class<?> impl, EntityMapping entityMapping) {
+		this.mapping = mapping;
+		this.entity = entity;
+		this.entityMapping = entityMapping;
+		this.classBridge = new HashMap<String,Object>();
+		entity.addClassBridgeDef(classBridge);
+		if (impl != null) {
+			this.classBridge.put("impl", impl);
+		}
+		
+	}
+	
+	public ClassBridgeMapping name(String name) {
+		this.classBridge.put("name", name);
+		return this;
+	}
+	
+	public ClassBridgeMapping store(Store store) {
+		this.classBridge.put("store", store);
+		return this;
+	}
+	
+	public ClassBridgeMapping index(Index index) {
+		this.classBridge.put("index", index);
+		return this;
+	}
+	
+	public ClassBridgeMapping termVector(TermVector termVector) {
+		this.classBridge.put("termVector", termVector);
+		return this;
+	}
+	
+	public ClassBridgeMapping boost(float boost) {
+		final Map<String, Object> boostAnn = new HashMap<String, Object>();
+		boostAnn.put( "value", boost );
+		classBridge.put( "boost", boostAnn );
+		return this;
+	}
+	
+	public ClassBridgeMapping analyzer(Class<?> analyzerClass) {
+		final Map<String, Object> analyzer = new HashMap<String, Object>();
+		analyzer.put( "impl", analyzerClass );
+		classBridge.put( "analyzer", analyzer );
+		return this;
+	}
+
+	public ClassBridgeMapping analyzer(String analyzerDef) {
+		final Map<String, Object> analyzer = new HashMap<String, Object>();
+		analyzer.put( "definition", analyzerDef );
+		classBridge.put( "analyzer", analyzer );
+		return this;
+	}
+	
+	
+	public ClassBridgeMapping param(String name, String value) {
+		Map<String, Object> param = SearchMapping.addElementToAnnotationArray(classBridge, "params");
+		param.put("name", name);
+		param.put("value", value);
+		return this;
+	}
+	
+	
+	public ClassBridgeMapping classBridge(Class<?> impl) {
+		return new ClassBridgeMapping(mapping, entity,impl,entityMapping );
+	}
+	
+	public FullTextFilterDefMapping fullTextFilterDef(String name, Class<?> impl) {
+		return new FullTextFilterDefMapping(mapping,name, impl);
+	}
+	
+	public PropertyMapping property(String name, ElementType type) {
+		return new PropertyMapping(name, type, entity, mapping);
+	}
+
+	public AnalyzerDefMapping analyzerDef(String name, Class<? extends TokenizerFactory> tokenizerFactory) {
+		return new AnalyzerDefMapping(name, tokenizerFactory, mapping);
+	}
+
+	public EntityMapping entity(Class<?> entityType) {
+		return new EntityMapping(entityType, mapping);
+	}
+
+	public ProvidedIdMapping providedId() {
+		return new ProvidedIdMapping(mapping,entity);
+	}
+
+	public IndexedMapping indexed() {
+		return new IndexedMapping(mapping, entity, entityMapping);
+	}
+	
+}

Modified: search/trunk/src/main/java/org/hibernate/search/cfg/EntityDescriptor.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/cfg/EntityDescriptor.java	2009-12-07 08:55:15 UTC (rev 18152)
+++ search/trunk/src/main/java/org/hibernate/search/cfg/EntityDescriptor.java	2009-12-07 12:17:04 UTC (rev 18153)
@@ -42,8 +42,8 @@
 	private Map<String, Object> analyzerDiscriminator;
 	private Set<Map<String, Object>> fullTextFilterDefs = new HashSet<Map<String, Object>>();
 	private Map<String,Object> providedId;
+	private Set<Map<String,Object>> classBridges = new HashSet<Map<String,Object>>();
 	
-	
 	public Map<String, Object> getIndexed() {
 		return indexed;
 	}
@@ -103,6 +103,14 @@
 	}
 
 	
+	public void addClassBridgeDef(Map<String,Object> classBridge) {
+		classBridges.add(classBridge);
+	}
+	
+	public Set<Map<String, Object>> getClassBridgeDefs() {
+		return classBridges;
+	}
+	
 	public void setProvidedId(Map<String, Object> providedId) {
 		this.providedId = providedId;
 	}
@@ -148,5 +156,5 @@
 			return result;
 		}
 	}
-	
+
 }

Modified: search/trunk/src/main/java/org/hibernate/search/cfg/EntityMapping.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/cfg/EntityMapping.java	2009-12-07 08:55:15 UTC (rev 18152)
+++ search/trunk/src/main/java/org/hibernate/search/cfg/EntityMapping.java	2009-12-07 12:17:04 UTC (rev 18153)
@@ -30,6 +30,7 @@
 
 import org.apache.solr.analysis.TokenizerFactory;
 import org.hibernate.search.analyzer.Discriminator;
+import org.hibernate.search.engine.BoostStrategy;
 
 /**
  * @author Emmanuel Bernard
@@ -85,8 +86,8 @@
 		return new EntityMapping(entityType, mapping);
 	}
 
-	public ProvidedIdMapping providedId() {
-		return new ProvidedIdMapping(mapping,entity);
+	public ClassBridgeMapping classBridge(Class<?> impl) {
+		return new ClassBridgeMapping(mapping, entity, impl, this);
 	}
 	
 }

Modified: search/trunk/src/main/java/org/hibernate/search/impl/MappingModelMetadataProvider.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/impl/MappingModelMetadataProvider.java	2009-12-07 08:55:15 UTC (rev 18152)
+++ search/trunk/src/main/java/org/hibernate/search/impl/MappingModelMetadataProvider.java	2009-12-07 12:17:04 UTC (rev 18153)
@@ -51,6 +51,8 @@
 import org.hibernate.search.annotations.AnalyzerDiscriminator;
 import org.hibernate.search.annotations.Boost;
 import org.hibernate.search.annotations.CalendarBridge;
+import org.hibernate.search.annotations.ClassBridge;
+import org.hibernate.search.annotations.ClassBridges;
 import org.hibernate.search.annotations.ContainedIn;
 import org.hibernate.search.annotations.DateBridge;
 import org.hibernate.search.annotations.DocumentId;
@@ -409,7 +411,6 @@
 			createCalendarBridge(property);
 		}
 
-		
 
 		private void createContainedIn(PropertyDescriptor property) {
 			if (property.getContainedIn() != null) {
@@ -477,8 +478,41 @@
 			if (entity.getProvidedId() != null) {
 				createProvidedId(entity);
 			}
+			
+			if (entity.getClassBridgeDefs().size() > 0) {
+				AnnotationDescriptor classBridgesAnn = new AnnotationDescriptor( ClassBridges.class );
+				ClassBridge[] classBridesDefArray  = createClassBridgesDefArray(entity.getClassBridgeDefs());
+				classBridgesAnn.setValue("value", classBridesDefArray);
+				annotations.put(ClassBridges.class, AnnotationFactory.create( classBridgesAnn ));
+			}
+			
 		}
 
+		private ClassBridge[] createClassBridgesDefArray(Set<Map<String, Object>> classBridgeDefs) {
+			ClassBridge[] classBridgeDefArray = new ClassBridge[classBridgeDefs.size()];
+			int index = 0;
+			for(Map<String,Object> classBridgeDef : classBridgeDefs) {
+				classBridgeDefArray[index] = createClassBridge(classBridgeDef);
+				index++;
+			}
+			
+			return classBridgeDefArray;
+		}
+
+		
+		private ClassBridge createClassBridge(Map<String, Object> classBridgeDef) {
+			AnnotationDescriptor annotation	= new AnnotationDescriptor( ClassBridge.class );
+			Set<Entry<String,Object>> entrySet = classBridgeDef.entrySet();
+			for (Entry<String, Object> entry : entrySet) {
+				if (entry.getKey().equals("params")) {
+					addParamsToAnnotation(annotation, entry);
+				} else {
+					annotation.setValue(entry.getKey(), entry.getValue());
+				}
+			}
+			return AnnotationFactory.create( annotation );
+		}
+
 		private void createProvidedId(EntityDescriptor entity) {
 			AnnotationDescriptor annotation	= new AnnotationDescriptor( ProvidedId.class );
 			Set<Entry<String,Object>> entrySet = entity.getProvidedId().entrySet();

Added: search/trunk/src/test/java/org/hibernate/search/test/configuration/CatDeptsFieldsClassBridge.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/configuration/CatDeptsFieldsClassBridge.java	                        (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/configuration/CatDeptsFieldsClassBridge.java	2009-12-07 12:17:04 UTC (rev 18153)
@@ -0,0 +1,66 @@
+/* $Id: CatDeptsFieldsClassBridge.java 17630 2009-10-06 13:38:43Z sannegrinovero $
+ * 
+ * Hibernate, Relational Persistence for Idiomatic Java
+ * 
+ * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat, Inc.
+ * 
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.search.test.configuration;
+
+import java.util.Map;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.hibernate.search.bridge.FieldBridge;
+import org.hibernate.search.bridge.LuceneOptions;
+import org.hibernate.search.bridge.ParameterizedBridge;
+
+/**
+ * @author John Griffin
+ */
+public class CatDeptsFieldsClassBridge implements FieldBridge, ParameterizedBridge {
+
+	private String sepChar;
+
+	@SuppressWarnings("unchecked")
+	public void setParameterValues(Map parameters) {
+		this.sepChar = (String) parameters.get( "sepChar" );
+	}
+
+	public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
+		// In this particular class the name of the new field was passed
+		// from the name field of the ClassBridge Annotation. This is not
+		// a requirement. It just works that way in this instance. The
+		// actual name could be supplied by hard coding it below.
+		Departments dep = (Departments) value;
+		String fieldValue1 = dep.getBranch();
+		if ( fieldValue1 == null ) {
+			fieldValue1 = "";
+		}
+		String fieldValue2 = dep.getNetwork();
+		if ( fieldValue2 == null ) {
+			fieldValue2 = "";
+		}
+		String fieldValue = fieldValue1 + sepChar + fieldValue2;
+		Field field = new Field( name, fieldValue, luceneOptions.getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector() );
+		field.setBoost( luceneOptions.getBoost() );
+		document.add( field );
+	}
+}

Added: search/trunk/src/test/java/org/hibernate/search/test/configuration/Departments.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/configuration/Departments.java	                        (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/configuration/Departments.java	2009-12-07 12:17:04 UTC (rev 18153)
@@ -0,0 +1,96 @@
+/* $Id: Departments.java 17630 2009-10-06 13:38:43Z sannegrinovero $
+ * 
+ * Hibernate, Relational Persistence for Idiomatic Java
+ * 
+ * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat, Inc.
+ * 
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.search.test.configuration;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+/**
+ * This is just a simple copy of the Department entity to allow
+ * separation of the tests for ClassBridge and ClassBridges.
+ *
+ * @author John Griffin
+ */
+ at Entity
+public class Departments {
+	@Id
+	@GeneratedValue
+	private int deptsId;
+	
+	private String network;
+	private String manufacturer;
+	private String branchHead;
+	private String branch;
+	private Integer maxEmployees;
+
+	public int getDeptsId() {
+		return deptsId;
+	}
+
+	public void setDeptsId(int deptsId) {
+		this.deptsId = deptsId;
+	}
+
+	public String getBranchHead() {
+		return branchHead;
+	}
+
+	public void setBranchHead(String branchHead) {
+		this.branchHead = branchHead;
+	}
+
+	public String getNetwork() {
+		return network;
+	}
+
+	public void setNetwork(String network) {
+		this.network = network;
+	}
+
+	public String getBranch() {
+		return branch;
+	}
+
+	public void setBranch(String branch) {
+		this.branch = branch;
+	}
+
+	public Integer getMaxEmployees() {
+		return maxEmployees;
+	}
+
+	public void setMaxEmployees(Integer maxEmployees) {
+		this.maxEmployees = maxEmployees;
+	}
+
+	public String getManufacturer() {
+		return manufacturer;
+	}
+
+	public void setManufacturer(String manufacturer) {
+		this.manufacturer = manufacturer;
+	}
+}

Added: search/trunk/src/test/java/org/hibernate/search/test/configuration/EquipmentType.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/configuration/EquipmentType.java	                        (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/configuration/EquipmentType.java	2009-12-07 12:17:04 UTC (rev 18153)
@@ -0,0 +1,66 @@
+/* $Id: EquipmentType.java 17630 2009-10-06 13:38:43Z sannegrinovero $
+ * 
+ * Hibernate, Relational Persistence for Idiomatic Java
+ * 
+ * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat, Inc.
+ * 
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.search.test.configuration;
+
+import java.util.Map;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+
+import org.hibernate.search.bridge.FieldBridge;
+import org.hibernate.search.bridge.LuceneOptions;
+import org.hibernate.search.bridge.ParameterizedBridge;
+
+/**
+ * @author John Griffin
+ */
+ at SuppressWarnings("unchecked")
+public class EquipmentType implements FieldBridge, ParameterizedBridge {
+	private Map equips;
+
+	public void setParameterValues(Map parameters) {
+		// This map was defined by the parameters of the ClassBridge annotation.
+		this.equips = parameters;
+	}
+
+	public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
+		// In this particular class the name of the new field was passed
+		// from the name field of the ClassBridge Annotation. This is not
+		// a requirement. It just works that way in this instance. The
+		// actual name could be supplied by hard coding it below.
+		Departments deps = ( Departments ) value;
+		Field field;
+		String fieldValue1 = deps.getManufacturer();
+
+		if ( fieldValue1 != null ) {
+			String fieldValue = ( String ) equips.get( fieldValue1 );
+			field = new Field(
+					name, fieldValue, luceneOptions.getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector()
+			);
+			field.setBoost( luceneOptions.getBoost() );
+			document.add( field );
+		}
+	}
+}

Modified: search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java	2009-12-07 08:55:15 UTC (rev 18152)
+++ search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java	2009-12-07 12:17:04 UTC (rev 18153)
@@ -31,6 +31,7 @@
 import java.util.List;
 import java.util.TimeZone;
 
+import org.apache.lucene.analysis.SimpleAnalyzer;
 import org.apache.lucene.analysis.standard.StandardAnalyzer;
 import org.apache.lucene.queryParser.ParseException;
 import org.apache.lucene.queryParser.QueryParser;
@@ -63,12 +64,17 @@
 import org.hibernate.search.test.SearchTestCase;
 import org.hibernate.search.test.analyzer.inheritance.ISOLatin1Analyzer;
 import org.hibernate.search.test.id.providedId.ManualTransactionContext;
+import org.hibernate.search.util.LoggerFactory;
+import org.slf4j.Logger;
 
 /**
  * @author Emmanuel Bernard
  */
 public class ProgrammaticMappingTest extends SearchTestCase {
+	
+	private static final Logger log = LoggerFactory.make();
 
+	
 	public void testMapping() throws Exception{
 		Address address = new Address();
 		address.setStreet1( "3340 Peachtree Rd NE" );
@@ -507,6 +513,68 @@
 		s.close();
 	}
 	
+	@SuppressWarnings("unchecked")
+	public void testClassBridgeMapping() throws Exception {
+		org.hibernate.Session s = openSession();
+		Transaction tx = s.beginTransaction();
+		s.persist( getDepts1() );
+		s.persist( getDepts2() );
+		s.persist( getDepts3() );
+		s.persist( getDepts4() );
+		s.flush();
+		tx.commit();
+
+		tx = s.beginTransaction();
+		FullTextSession session = Search.getFullTextSession( s );
+
+		// The equipment field is the manufacturer field  in the
+		// Departments entity after being massaged by passing it
+		// through the EquipmentType class. This field is in
+		// the Lucene document but not in the Department entity itself.
+		QueryParser parser = new QueryParser( "equipment", new SimpleAnalyzer() );
+
+		// Check the second ClassBridge annotation
+		Query query = parser.parse( "equiptype:Cisco" );
+		org.hibernate.search.FullTextQuery hibQuery = session.createFullTextQuery( query, Departments.class );
+		List<Departments> result = hibQuery.list();
+		assertNotNull( result );
+		assertEquals( "incorrect number of results returned", 2, result.size() );
+		for (Departments d : result) {
+			assertEquals("incorrect manufacturer", "C", d.getManufacturer());
+		}
+
+		// No data cross-ups.
+		query = parser.parse( "branchnetwork:Kent Lewin" );
+		hibQuery = session.createFullTextQuery( query, Departments.class );
+		result = hibQuery.list();
+		assertNotNull( result );
+		assertTrue( "problem with field cross-ups", result.size() == 0 );
+
+		// Non-ClassBridge field.
+		parser = new QueryParser( "branchHead", new SimpleAnalyzer() );
+		query = parser.parse( "branchHead:Kent Lewin" );
+		hibQuery = session.createFullTextQuery( query, Departments.class );
+		result = hibQuery.list();
+		assertNotNull( result );
+		assertTrue( "incorrect entity returned, wrong branch head", result.size() == 1 );
+		assertEquals("incorrect entity returned", "Kent Lewin", ( result.get( 0 ) ).getBranchHead());
+
+		// Check other ClassBridge annotation.
+		parser = new QueryParser( "branchnetwork", new SimpleAnalyzer() );
+		query = parser.parse( "branchnetwork:st. george 1D" );
+		hibQuery = session.createFullTextQuery( query, Departments.class );
+		result = hibQuery.list();
+		assertNotNull( result );
+		assertEquals( "incorrect entity returned, wrong network", "1D", ( result.get( 0 ) ).getNetwork() );
+		assertEquals( "incorrect entity returned, wrong branch", "St. George", ( result.get( 0 ) ).getBranch() );
+		assertEquals( "incorrect number of results returned", 1, result.size() );
+
+		//cleanup
+		for (Object element : s.createQuery( "from " + Departments.class.getName() ).list()) s.delete( element );
+		tx.commit();
+		s.close();
+	}
+	
 	private int nbrOfMatchingResults(String field, String token, FullTextSession s) throws ParseException {
 		QueryParser parser = new QueryParser( field, new StandardAnalyzer() );
 		org.apache.lucene.search.Query luceneQuery = parser.parse( token );
@@ -514,6 +582,55 @@
 		return query.getResultSize();
 	}
 
+	
+	private Departments getDepts1() {
+		Departments depts = new Departments();
+
+		depts.setBranch( "Salt Lake City" );
+		depts.setBranchHead( "Kent Lewin" );
+		depts.setMaxEmployees( 100 );
+		depts.setNetwork( "1A" );
+		depts.setManufacturer( "C" );
+
+		return depts;
+	}
+
+	private Departments getDepts2() {
+		Departments depts = new Departments();
+
+		depts.setBranch( "Layton" );
+		depts.setBranchHead( "Terry Poperszky" );
+		depts.setMaxEmployees( 20 );
+		depts.setNetwork( "2B" );
+		depts.setManufacturer( "3" );
+
+		return depts;
+	}
+
+	private Departments getDepts3() {
+		Departments depts = new Departments();
+
+		depts.setBranch( "West Valley" );
+		depts.setBranchHead( "Pat Kelley" );
+		depts.setMaxEmployees( 15 );
+		depts.setNetwork( "3C" );
+		depts.setManufacturer( "D" );
+
+		return depts;
+	}
+
+	private Departments getDepts4() {
+		Departments depts = new Departments();
+
+		depts.setBranch( "St. George" );
+		depts.setBranchHead( "Spencer Stajskal" );
+		depts.setMaxEmployees( 10 );
+		depts.setNetwork( "1D" );
+		depts.setManufacturer( "C" );
+		return depts;
+	}
+	
+	
 	@Override
 	protected void configure(Configuration cfg) {
 		super.configure( cfg );
@@ -572,10 +689,35 @@
 					.property("items", ElementType.FIELD)
 						.indexEmbedded()
 				.entity(Item.class)
-						.property("description", ElementType.FIELD)
-							.field().name("description").analyzer("en").index(Index.TOKENIZED).store(Store.YES)
-						.property("productCatalog", ElementType.FIELD)
-							.containedIn()
+					.property("description", ElementType.FIELD)
+						.field().name("description").analyzer("en").index(Index.TOKENIZED).store(Store.YES)
+					.property("productCatalog", ElementType.FIELD)
+						.containedIn()
+				.entity(Departments.class)
+					.classBridge(CatDeptsFieldsClassBridge.class)
+						.name("branchnetwork")
+						.index(Index.TOKENIZED)
+						.store(Store.YES)
+						.param("sepChar", " ")
+					.classBridge(EquipmentType.class)
+						.name("equiptype")
+						.index(Index.TOKENIZED)
+						.store(Store.YES)
+							.param("C", "Cisco")
+							.param("D", "D-Link")
+							.param("K", "Kingston")
+							.param("3", "3Com")
+					  .indexed()
+					.property("deptsId", ElementType.FIELD)
+						.documentId().name("id")
+					.property("branchHead", ElementType.FIELD)
+						.field().store(Store.YES)
+					.property("network", ElementType.FIELD)
+						.field().store(Store.YES)
+					.property("branch", ElementType.FIELD)
+						.field().store(Store.YES)
+					.property("maxEmployees", ElementType.FIELD)
+						.field().index(Index.UN_TOKENIZED).store(Store.YES)
 				.entity( BlogEntry.class ).indexed()
 					.property( "title", ElementType.METHOD )
 						.field()
@@ -624,6 +766,9 @@
 				.analyzerDef( "minimal", StandardTokenizerFactory.class  );
 
 	}
+	
+	
+	
 
 	protected Class<?>[] getMappings() {
 		return new Class<?>[] {
@@ -632,8 +777,11 @@
 				BlogEntry.class,
 				ProvidedIdEntry.class,
 				ProductCatalog.class,
-				Item.class
+				Item.class,
+				Departments.class,
 				
 		};
 	}
+	
+	
 }



More information about the hibernate-commits mailing list