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

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Tue Dec 8 06:19:43 EST 2009


Author: epbernard
Date: 2009-12-08 06:19:42 -0500 (Tue, 08 Dec 2009)
New Revision: 18157

Added:
   search/trunk/src/main/java/org/hibernate/search/impl/SearchMappingBuilder.java
   search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticSearchMappingFactory.java
Modified:
   search/trunk/src/main/docbook/en-US/modules/mapping.xml
   search/trunk/src/main/java/org/hibernate/search/Environment.java
   search/trunk/src/main/java/org/hibernate/search/cfg/SearchConfigurationFromHibernateCore.java
   search/trunk/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java
   search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java
Log:
HSEARCH-429 Add Environment.MODEL_MAPPING (hibernate.search.model_mapping) to pass a SearchMapping configuration via configuration (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 12:43:06 UTC (rev 18156)
+++ search/trunk/src/main/docbook/en-US/modules/mapping.xml	2009-12-08 11:19:42 UTC (rev 18157)
@@ -1548,17 +1548,18 @@
     <classname>SearchMapping</classname> object. This object is passed to
     Hibernate Search via a property set to the <classname>Configuration
     </classname>object. The property key is
-    <literal>hibernate.search.mapping_model</literal>.</para>
+    <literal>hibernate.search.mapping_model</literal> or it's tpye-safe representation
+    <classname>Environment.MODEL_MAPPING</classname>.</para>
 
     <programlisting>SearchMapping mapping = new SearchMapping();
 [...]
-configuration.setProperty( "hibernate.search.mapping_model", mapping );
+configuration.setProperty( Environment.MODEL_MAPPING, mapping );
 
 //or in JPA
 SearchMapping mapping = new SearchMapping();
 [...]
 Map&lt;String,String&gt; properties = new HashMap&lt;String,String)(1);
-properties.put( "hibernate.search.mapping_model", mapping );
+properties.put( Environment.MODEL_MAPPING, mapping );
 EntityManagerFactory emf = Persistence.createEntityManagerFactory( "userPU", properties );</programlisting>
 
     <para>The <classname>SearchMapping</classname> is the root object which
@@ -1597,7 +1598,7 @@
            .indexed()
                .indexName("Address_Index"); //optional
 
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping );</programlisting>
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping );</programlisting>
 
           <para>As you can see you must first create a
           <classname>SearchMapping</classname> object which is the root object
@@ -1637,7 +1638,7 @@
                .documentId()
                    .name("id");
 
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping);</programlisting>
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping);</programlisting>
 
           <para>The above is equivalent to annotating a property in the entity
           as <classname>@DocumentId</classname> as seen in the following
@@ -1693,7 +1694,7 @@
             .documentId()
                 .name("id");
 
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping );</programlisting>
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping );</programlisting>
 
           <para>The analyzer mapping defined above is equivalent to the
           annotation model using <classname>@AnalyzerDef</classname> in
@@ -1772,7 +1773,7 @@
                 .analyzer("en")
                 .store(Store.NO);
 
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping );</programlisting>
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping );</programlisting>
 
           <para>The previous example can effectively been seen as annotating
           your entity with <classname>@FullTextFilterDef</classname> like
@@ -1847,7 +1848,7 @@
                 .name("address_data")
                 .analyzer("en");</emphasis>
 
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping );</programlisting>
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping );</programlisting>
 
           <para>The above example of marking fields as indexable is equivalent
           to defining fields using <classname>@Field</classname> as seen
@@ -1920,7 +1921,7 @@
             <emphasis role="bold">.indexEmbedded()
                 .prefix("catalog.items"); //optional</emphasis>
 
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping );</programlisting>
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping );</programlisting>
 
           <para>The next example shows the same definition using annotation
           (<classname>@IndexEmbedded</classname>):</para>
@@ -1980,7 +1981,7 @@
         .property("productCatalog", ElementType.METHOD)
             <emphasis role="bold">.containedIn()</emphasis>;
 
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping );</programlisting>
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping );</programlisting>
 
           <para>This is equivalent to defining
           <classname>@ContainedIn</classname> in your entity:</para>
@@ -2061,7 +2062,7 @@
     .property("lastUpdated", ElementType.FIELD)
         <emphasis role="bold">.calendarBridge(Resolution.DAY)</emphasis>;
 
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping );</programlisting>
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping );</programlisting>
 
           <para>See below for defining the above using
           <classname>@CalendarBridge</classname> and
@@ -2122,7 +2123,7 @@
                 <emphasis role="bold">.bridge( ConcatStringBridge.class )
                     .param( "size", "4" )</emphasis>;
  
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping );</programlisting>
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping );</programlisting>
 
           <para>The above can equally be defined using annotations, as seen in
           the next example.</para>
@@ -2182,7 +2183,7 @@
          .param("3", "3Com")</emphasis>
       .indexed();
 
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping );
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping );
 
 </programlisting>
 

Modified: search/trunk/src/main/java/org/hibernate/search/Environment.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/Environment.java	2009-12-07 12:43:06 UTC (rev 18156)
+++ search/trunk/src/main/java/org/hibernate/search/Environment.java	2009-12-08 11:19:42 UTC (rev 18157)
@@ -110,5 +110,10 @@
 	 * This is an index-scoped property and defaults to false.
 	 */
 	public static final String EXCLUSIVE_INDEX_USE = "exclusive_index_use";
+
+	/**
+	 *
+	 */
+	public static final String MODEL_MAPPING = "hibernate.search.model_mapping";
 	
 }

Modified: search/trunk/src/main/java/org/hibernate/search/cfg/SearchConfigurationFromHibernateCore.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/cfg/SearchConfigurationFromHibernateCore.java	2009-12-07 12:43:06 UTC (rev 18156)
+++ search/trunk/src/main/java/org/hibernate/search/cfg/SearchConfigurationFromHibernateCore.java	2009-12-08 11:19:42 UTC (rev 18157)
@@ -80,7 +80,7 @@
 	}
 
 	public SearchMapping getProgrammaticMapping() {
-		return ( SearchMapping ) getProperties().get( "hibernate.search.mapping_model" );
+		return null;
 	}
 
 	private static class ClassIterator implements Iterator<Class<?>> {

Modified: search/trunk/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java	2009-12-07 12:43:06 UTC (rev 18156)
+++ search/trunk/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java	2009-12-08 11:19:42 UTC (rev 18157)
@@ -27,6 +27,7 @@
 import java.beans.Introspector;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -35,30 +36,26 @@
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
-import java.util.Arrays;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.locks.ReentrantLock;
 
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.search.Similarity;
-import org.slf4j.Logger;
-
+import org.hibernate.annotations.common.reflection.MetadataProvider;
+import org.hibernate.annotations.common.reflection.MetadataProviderInjector;
 import org.hibernate.annotations.common.reflection.ReflectionManager;
 import org.hibernate.annotations.common.reflection.XClass;
-import org.hibernate.annotations.common.reflection.MetadataProvider;
-import org.hibernate.annotations.common.reflection.MetadataProviderInjector;
 import org.hibernate.annotations.common.reflection.java.JavaReflectionManager;
-import org.hibernate.util.StringHelper;
 import org.hibernate.search.Environment;
 import org.hibernate.search.SearchException;
 import org.hibernate.search.Version;
+import org.hibernate.search.annotations.AnalyzerDef;
+import org.hibernate.search.annotations.AnalyzerDefs;
 import org.hibernate.search.annotations.Factory;
 import org.hibernate.search.annotations.FullTextFilterDef;
 import org.hibernate.search.annotations.FullTextFilterDefs;
 import org.hibernate.search.annotations.Indexed;
 import org.hibernate.search.annotations.Key;
-import org.hibernate.search.annotations.AnalyzerDef;
-import org.hibernate.search.annotations.AnalyzerDefs;
 import org.hibernate.search.backend.BackendQueueProcessorFactory;
 import org.hibernate.search.backend.LuceneIndexingParameters;
 import org.hibernate.search.backend.LuceneWork;
@@ -72,11 +69,11 @@
 import org.hibernate.search.batchindexing.MassIndexerProgressMonitor;
 import org.hibernate.search.cfg.SearchConfiguration;
 import org.hibernate.search.cfg.SearchMapping;
+import org.hibernate.search.engine.DocumentBuilderContainedEntity;
 import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
+import org.hibernate.search.engine.EntityState;
 import org.hibernate.search.engine.FilterDef;
 import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.hibernate.search.engine.EntityState;
-import org.hibernate.search.engine.DocumentBuilderContainedEntity;
 import org.hibernate.search.filter.CachingWrapperFilter;
 import org.hibernate.search.filter.FilterCachingStrategy;
 import org.hibernate.search.filter.MRUFilterCachingStrategy;
@@ -88,6 +85,8 @@
 import org.hibernate.search.store.optimization.OptimizerStrategy;
 import org.hibernate.search.util.LoggerFactory;
 import org.hibernate.search.util.PluginLoader;
+import org.hibernate.util.StringHelper;
+import org.slf4j.Logger;
 
 /**
  * @author Emmanuel Bernard
@@ -148,7 +147,18 @@
 
 	public SearchFactoryImpl(SearchConfiguration cfg) {
 		ReflectionManager reflectionManager = getReflectionManager(cfg);
-
+		final SearchMapping mapping = SearchMappingBuilder.getSearchMapping(cfg);
+		if ( mapping != null) {
+			if ( ! ( reflectionManager instanceof MetadataProviderInjector)) {
+				throw new SearchException("Programmatic mapping model used but ReflectionManager does not implement "
+						+ MetadataProviderInjector.class.getName() );
+			}
+			MetadataProviderInjector injector = (MetadataProviderInjector) reflectionManager;
+			MetadataProvider original = injector.getMetadataProvider();
+			injector.setMetadataProvider( new MappingModelMetadataProvider( original, mapping ) );
+			
+		}
+		
 		this.indexingStrategy = defineIndexingStrategy( cfg ); //need to be done before the document builds
 		initDocumentBuilders( cfg, reflectionManager );
 
@@ -171,6 +181,8 @@
 		this.barrier = 1; //write barrier
 	}
 
+
+
 	private void fillSimilarityMapping() {
 		for ( DirectoryProviderData directoryConfiguration : dirProviderData.values() ) {
 			for (Class<?> indexedType : directoryConfiguration.classes) {
@@ -194,17 +206,6 @@
 		if ( reflectionManager == null ) {
 			reflectionManager = new JavaReflectionManager();
 		}
-		final SearchMapping mapping = cfg.getProgrammaticMapping();
-		if ( mapping != null) {
-			if ( ! ( reflectionManager instanceof MetadataProviderInjector)) {
-				throw new SearchException("Programmatic mapping model used but ReflectionManager does not implement "
-						+ MetadataProviderInjector.class.getName() );
-			}
-			MetadataProviderInjector injector = (MetadataProviderInjector) reflectionManager;
-			MetadataProvider original = injector.getMetadataProvider();
-			injector.setMetadataProvider( new MappingModelMetadataProvider( original, mapping ) );
-			
-		}
 		return reflectionManager;
 	}
 

Added: search/trunk/src/main/java/org/hibernate/search/impl/SearchMappingBuilder.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/impl/SearchMappingBuilder.java	                        (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/impl/SearchMappingBuilder.java	2009-12-08 11:19:42 UTC (rev 18157)
@@ -0,0 +1,116 @@
+package org.hibernate.search.impl;
+
+import java.lang.reflect.Method;
+
+import org.hibernate.search.SearchException;
+import org.hibernate.search.Environment;
+import org.hibernate.search.cfg.SearchMapping;
+import org.hibernate.search.cfg.SearchConfiguration;
+import org.hibernate.search.annotations.Factory;
+import org.hibernate.search.util.LoggerFactory;
+import org.hibernate.annotations.common.util.ReflectHelper;
+
+import org.slf4j.Logger;
+
+/**
+ * package class extracting the SearchMappingFactory if needed
+ */
+class SearchMappingBuilder {
+	private static final Logger LOG = LoggerFactory.make();
+
+	private SearchMappingBuilder() {
+	}
+
+	/**
+	 * This factory method takes a SearchConfiguration object
+	 * and returns a SearchMapping object which defines
+	 * the programmatic model for indexing entites and fields.
+	 * 
+	 * Throws SearchException:
+	 * 1) No @Factory found
+	 * 2) Multiple @Factory found
+	 * 3) hibernate.search.model_mapping defines a class that cannot be found
+	 * 4) Cannot invoke the @Factory method to get new instance of SearchMapping
+	 * 
+	 * @param SearchConfigruation
+	 * @return SearchMapping
+	 */
+	public static SearchMapping getSearchMapping(SearchConfiguration cfg) {
+
+		//try SearchConfiguration object first and then properties
+		Object modelMappingProperty = cfg.getProgrammaticMapping();
+		if ( modelMappingProperty == null) {
+			modelMappingProperty = cfg.getProperties().get( Environment.MODEL_MAPPING );
+		}
+
+		if ( modelMappingProperty == null) {
+			return null;
+		}
+		SearchMapping mapping = null;
+		Object programmaticConfig = modelMappingProperty;
+		if (programmaticConfig instanceof SearchMapping) {
+			mapping = (SearchMapping) programmaticConfig;
+			return mapping;
+		}
+		Class<?> clazz = getProgrammaticMappingClass(programmaticConfig);
+		Method[] methods = clazz.getDeclaredMethods();
+		int count = 0;
+		for (Method method : methods) {
+			if (method.isAnnotationPresent(Factory.class)) {
+				count++;
+				makeMethodAccessibleIfRequired(method);
+				mapping = getNewInstanceOfSearchMapping(clazz, method);
+			}
+		}
+		validateMappingFactoryDefinition(count, clazz);
+		return mapping;
+	}
+
+	private static SearchMapping getNewInstanceOfSearchMapping(Class<?> clazz, Method method) {
+		SearchMapping mapping = null;
+		try {
+			LOG.debug("invoking factory method [ {}.{} ] to get search mapping instance", clazz.getName(), method.getName());
+			Object instance = clazz.newInstance();
+			mapping = (SearchMapping) method.invoke(instance);
+		} catch (Exception e) {
+			throw new SearchException("Unable to call the factory method: " + clazz.getName() + "." + method.getName(), e);
+		}
+		return mapping;
+	}
+
+	private static void makeMethodAccessibleIfRequired(Method method) {
+		if ( !method.isAccessible() ) {
+			method.setAccessible( true );
+		}
+	}
+	
+	private static void validateMappingFactoryDefinition(int count, Class<?> factory) {
+		if (count == 0) {
+			throw new SearchException("No @Factory method defined for building programmatic api on " + factory);
+		}
+		if (count > 1) {
+			throw new SearchException("Multiple @Factory methods defined. Only one factory method required. " + factory);
+		}
+	}
+
+	private static Class<?> getProgrammaticMappingClass(Object programmaticConfig) {
+		Class<?> clazz = null;
+		if (programmaticConfig instanceof String) {
+			final String className = ( String ) programmaticConfig;
+			try {
+				clazz = ReflectHelper.classForName( className, SearchMappingBuilder.class);
+			} catch (ClassNotFoundException e) {
+				throw new SearchException("Unable to find " + Environment.MODEL_MAPPING + "=" + className, e);
+			}
+		} else if (programmaticConfig instanceof Class){
+			clazz = (Class<?>) programmaticConfig;
+		}
+		else {
+			throw new SearchException(Environment.MODEL_MAPPING + " is of an unknown type: " + programmaticConfig.getClass() );
+		}
+		if (clazz == null) {
+			throw new SearchException("No programmatic factory defined");
+		}
+		return clazz;
+	}
+}

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 12:43:06 UTC (rev 18156)
+++ search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java	2009-12-08 11:19:42 UTC (rev 18157)
@@ -50,6 +50,7 @@
 import org.hibernate.search.FullTextQuery;
 import org.hibernate.search.FullTextSession;
 import org.hibernate.search.Search;
+import org.hibernate.search.Environment;
 import org.hibernate.search.annotations.FilterCacheModeType;
 import org.hibernate.search.annotations.Index;
 import org.hibernate.search.annotations.Resolution;
@@ -634,104 +635,9 @@
 	@Override
 	protected void configure(Configuration cfg) {
 		super.configure( cfg );
+		cfg.getProperties().put( Environment.MODEL_MAPPING, ProgrammaticSearchMappingFactory.class.getName() );
 		//cfg.setProperty( "hibernate.search.default.directory_provider", FSDirectoryProvider.class.getName() );
-		SearchMapping mapping = new SearchMapping();
 
-		mapping.fullTextFilterDef("security", SecurityFilterFactory.class).cache(FilterCacheModeType.INSTANCE_ONLY)
-				.analyzerDef( "ngram", StandardTokenizerFactory.class )
-					.filter( LowerCaseFilterFactory.class )
-					.filter( NGramFilterFactory.class )
-						.param( "minGramSize", "3" )
-						.param( "maxGramSize", "3" )
-				.analyzerDef( "en", StandardTokenizerFactory.class )
-					.filter( LowerCaseFilterFactory.class )
-					.filter( EnglishPorterFilterFactory.class )
-				.analyzerDef( "de", StandardTokenizerFactory.class )
-					.filter( LowerCaseFilterFactory.class )
-					.filter( GermanStemFilterFactory.class )
-				.entity( Address.class )
-					.indexed()
-					.similarity( DefaultSimilarity.class )
-					.boost( 2 )
-					.property( "addressId", ElementType.FIELD ).documentId().name( "id" )
-					.property("lastUpdated", ElementType.FIELD)
-						.field().name("last-updated")
-								.analyzer("en").store(Store.YES)
-								.calendarBridge(Resolution.DAY)
-					.property("dateCreated", ElementType.FIELD)
-						.field().name("date-created").index(Index.TOKENIZED)
-								.analyzer("en").store( Store.YES )
-								.dateBridge(Resolution.DAY)
-					.property("owner", ElementType.FIELD)
-						.field()
-					.property( "street1", ElementType.FIELD )
-						.field()
-						.field().name( "street1_ngram" ).analyzer( "ngram" )
-						.field()
-							.name( "street1_abridged" )
-							.bridge( ConcatStringBridge.class ).param( ConcatStringBridge.SIZE, "4" )
-					.property( "street2", ElementType.METHOD )
-						.field().name( "idx_street2" ).store( Store.YES ).boost( 2 )
-				.entity(ProvidedIdEntry.class).indexed()
-						.providedId().name("providedidentry").bridge(LongBridge.class)
-						.property("name", ElementType.FIELD)
-							.field().name("providedidentry.name").analyzer("en").index(Index.TOKENIZED).store(Store.YES)
-						.property("blurb", ElementType.FIELD)
-							.field().name("providedidentry.blurb").analyzer("en").index(Index.TOKENIZED).store(Store.YES)
-						.property("age", ElementType.FIELD)
-							.field().name("providedidentry.age").analyzer("en").index(Index.TOKENIZED).store(Store.YES)
-				.entity(ProductCatalog.class).indexed()
-					.similarity( DefaultSimilarity.class )
-					.boost( 2 )
-					.property( "id", ElementType.FIELD ).documentId().name( "id" )
-					.property("name", ElementType.FIELD)
-						.field().name("productCatalogName").index(Index.TOKENIZED).analyzer("en").store(Store.YES)
-					.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()
-				.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()
-					.property( "description", ElementType.METHOD )
-						.field()
-					.property( "language", ElementType.METHOD )
-						.analyzerDiscriminator(BlogEntry.BlogLangDiscriminator.class)
-					.property("dateCreated", ElementType.METHOD)
-						.field()
-							.name("blog-entry-created")
-								.analyzer("en")
-								.store(Store.YES)
-								.dateBridge(Resolution.DAY);
-		cfg.getProperties().put( "hibernate.search.mapping_model", mapping );
 	}
 
 	public void NotUseddefineMapping() {

Added: search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticSearchMappingFactory.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticSearchMappingFactory.java	                        (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticSearchMappingFactory.java	2009-12-08 11:19:42 UTC (rev 18157)
@@ -0,0 +1,123 @@
+package org.hibernate.search.test.configuration;
+
+import java.lang.annotation.ElementType;
+
+import org.apache.lucene.search.DefaultSimilarity;
+import org.apache.solr.analysis.EnglishPorterFilterFactory;
+import org.apache.solr.analysis.GermanStemFilterFactory;
+import org.apache.solr.analysis.LowerCaseFilterFactory;
+import org.apache.solr.analysis.NGramFilterFactory;
+import org.apache.solr.analysis.StandardTokenizerFactory;
+import org.hibernate.search.annotations.Factory;
+import org.hibernate.search.annotations.FilterCacheModeType;
+import org.hibernate.search.annotations.Index;
+import org.hibernate.search.annotations.Resolution;
+import org.hibernate.search.annotations.Store;
+import org.hibernate.search.bridge.builtin.LongBridge;
+import org.hibernate.search.cfg.ConcatStringBridge;
+import org.hibernate.search.cfg.SearchMapping;
+
+public class ProgrammaticSearchMappingFactory {
+		
+	@Factory
+	public SearchMapping build() {
+		SearchMapping mapping = new SearchMapping();
+
+		mapping.fullTextFilterDef("security", SecurityFilterFactory.class).cache(FilterCacheModeType.INSTANCE_ONLY)
+				.analyzerDef( "ngram", StandardTokenizerFactory.class )
+					.filter( LowerCaseFilterFactory.class )
+					.filter( NGramFilterFactory.class )
+						.param( "minGramSize", "3" )
+						.param( "maxGramSize", "3" )
+				.analyzerDef( "en", StandardTokenizerFactory.class )
+					.filter( LowerCaseFilterFactory.class )
+					.filter( EnglishPorterFilterFactory.class )
+				.analyzerDef( "de", StandardTokenizerFactory.class )
+					.filter( LowerCaseFilterFactory.class )
+					.filter( GermanStemFilterFactory.class )
+				.entity( Address.class )
+					.indexed()
+					.similarity( DefaultSimilarity.class )
+					.boost( 2 )
+					.property( "addressId", ElementType.FIELD ).documentId().name( "id" )
+					.property("lastUpdated", ElementType.FIELD)
+						.field().name("last-updated")
+								.analyzer("en").store(Store.YES)
+								.calendarBridge(Resolution.DAY)
+					.property("dateCreated", ElementType.FIELD)
+						.field().name("date-created").index(Index.TOKENIZED)
+								.analyzer("en").store( Store.YES )
+								.dateBridge(Resolution.DAY)
+					.property("owner", ElementType.FIELD)
+						.field()
+					.property( "street1", ElementType.FIELD )
+						.field()
+						.field().name( "street1_ngram" ).analyzer( "ngram" )
+						.field()
+							.name( "street1_abridged" )
+							.bridge( ConcatStringBridge.class ).param( ConcatStringBridge.SIZE, "4" )
+					.property( "street2", ElementType.METHOD )
+						.field().name( "idx_street2" ).store( Store.YES ).boost( 2 )
+				.entity(ProvidedIdEntry.class).indexed()
+						.providedId().name("providedidentry").bridge(LongBridge.class)
+						.property("name", ElementType.FIELD)
+							.field().name("providedidentry.name").analyzer("en").index(Index.TOKENIZED).store(Store.YES)
+						.property("blurb", ElementType.FIELD)
+							.field().name("providedidentry.blurb").analyzer("en").index(Index.TOKENIZED).store(Store.YES)
+						.property("age", ElementType.FIELD)
+							.field().name("providedidentry.age").analyzer("en").index(Index.TOKENIZED).store(Store.YES)
+				.entity(ProductCatalog.class).indexed()
+					.similarity( DefaultSimilarity.class )
+					.boost( 2 )
+					.property( "id", ElementType.FIELD ).documentId().name( "id" )
+					.property("name", ElementType.FIELD)
+						.field().name("productCatalogName").index(Index.TOKENIZED).analyzer("en").store(Store.YES)
+					.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()
+				.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()
+					.property( "description", ElementType.METHOD )
+						.field()
+					.property( "language", ElementType.METHOD )
+						.analyzerDiscriminator(BlogEntry.BlogLangDiscriminator.class)
+					.property("dateCreated", ElementType.METHOD)
+						.field()
+							.name("blog-entry-created")
+								.analyzer("en")
+								.store(Store.YES)
+								.dateBridge(Resolution.DAY);
+		return mapping;
+
+	}
+}



More information about the hibernate-commits mailing list