[hibernate-commits] Hibernate SVN: r16207 - in search/trunk: src/java/org/hibernate/search/annotations and 3 other directories.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Sun Mar 22 22:11:37 EDT 2009
Author: epbernard
Date: 2009-03-22 22:11:36 -0400 (Sun, 22 Mar 2009)
New Revision: 16207
Added:
search/trunk/src/java/org/hibernate/search/cfg/AnalyzerDefMapping.java
search/trunk/src/java/org/hibernate/search/cfg/EntityDescriptor.java
search/trunk/src/java/org/hibernate/search/cfg/EntityMapping.java
search/trunk/src/java/org/hibernate/search/cfg/FieldMapping.java
search/trunk/src/java/org/hibernate/search/cfg/PropertyDescriptor.java
search/trunk/src/java/org/hibernate/search/cfg/PropertyMapping.java
search/trunk/src/java/org/hibernate/search/cfg/SearchMapping.java
search/trunk/src/java/org/hibernate/search/cfg/TokenFilterDefMapping.java
search/trunk/src/java/org/hibernate/search/impl/MappingModelMetadataProvider.java
search/trunk/src/test/org/hibernate/search/test/configuration/Address.java
search/trunk/src/test/org/hibernate/search/test/configuration/Country.java
search/trunk/src/test/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java
search/trunk/src/test/org/hibernate/search/test/configuration/User.java
Modified:
search/trunk/pom.xml
search/trunk/src/java/org/hibernate/search/annotations/Analyzer.java
search/trunk/src/java/org/hibernate/search/cfg/SearchConfiguration.java
search/trunk/src/java/org/hibernate/search/cfg/SearchConfigurationFromHibernateCore.java
search/trunk/src/java/org/hibernate/search/impl/FullTextSessionImpl.java
search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java
Log:
HSEARCH-352 inital commit for the programmatic mapping API
Modified: search/trunk/pom.xml
===================================================================
--- search/trunk/pom.xml 2009-03-23 01:53:05 UTC (rev 16206)
+++ search/trunk/pom.xml 2009-03-23 02:11:36 UTC (rev 16207)
@@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search</artifactId>
- <version>3.1.0.GA</version>
+ <version>3.2.0-SNAPSHOT</version>
<name>Hibernate Search</name>
<description>Hibernate Search</description>
<url>http://search.hibernate.org</url>
@@ -32,12 +32,12 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
- <version>3.3.1.GA</version>
+ <version>3.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
- <version>3.1.0.GA</version>
+ <version>3.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
@@ -198,13 +198,13 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
- <version>3.4.0.GA</version>
+ <version>3.5.0-SNAPSHOT</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
- <version>3.4.0.GA</version>
+ <version>3.5.0-SNAPSHOT</version>
<optional>true</optional>
</dependency>
<dependency>
Modified: search/trunk/src/java/org/hibernate/search/annotations/Analyzer.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/annotations/Analyzer.java 2009-03-23 01:53:05 UTC (rev 16206)
+++ search/trunk/src/java/org/hibernate/search/annotations/Analyzer.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -23,8 +23,7 @@
@Retention( RetentionPolicy.RUNTIME )
@Target( { ElementType.TYPE, ElementType.FIELD, ElementType.METHOD} )
@Documented
-
public @interface Analyzer {
- Class impl() default void.class;
+ Class<?> impl() default void.class;
String definition() default "";
}
Added: search/trunk/src/java/org/hibernate/search/cfg/AnalyzerDefMapping.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/AnalyzerDefMapping.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/cfg/AnalyzerDefMapping.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,55 @@
+package org.hibernate.search.cfg;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.solr.analysis.TokenizerFactory;
+import org.apache.solr.analysis.TokenFilterFactory;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class AnalyzerDefMapping {
+ private SearchMapping mapping;
+ private Map<String, Object> analyzerDef;
+ private Map<String, Object> tokenizer;
+
+ AnalyzerDefMapping(String name, Class<? extends TokenizerFactory> tokenizerFactory, SearchMapping mapping) {
+ this.mapping = mapping;
+ this.analyzerDef = new HashMap<String, Object>();
+ mapping.addAnalyzerDef(analyzerDef);
+ analyzerDef.put( "name", name );
+ tokenizer = new HashMap<String, Object>();
+ tokenizer.put( "factory", tokenizerFactory );
+ analyzerDef.put( "tokenizer", tokenizer );
+ }
+
+ /**
+ * @TokenizerDef(, ... params={@Parameter(name="name", value="value"), ...})
+ */
+ public AnalyzerDefMapping tokenizerParam(String name, String value) {
+ Map<String, Object> param = SearchMapping.addElementToAnnotationArray(tokenizer, "params");
+ param.put("name", name);
+ param.put("value", value);
+ return this;
+ }
+
+ /**
+ * @TokenFilterDef(factory=factory)
+ */
+ public TokenFilterDefMapping filter(Class<? extends TokenFilterFactory> factory) {
+ return new TokenFilterDefMapping(factory, analyzerDef, mapping);
+ }
+
+ public AnalyzerDefMapping analyzerDef(String name, Class<? extends TokenizerFactory> tokenizerFactory) {
+ return new AnalyzerDefMapping(name, tokenizerFactory, mapping);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType) {
+ return new EntityMapping(entityType, null, mapping);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType, String indexName) {
+ return new EntityMapping(entityType, indexName, mapping);
+ }
+}
Added: search/trunk/src/java/org/hibernate/search/cfg/EntityDescriptor.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/EntityDescriptor.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/cfg/EntityDescriptor.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,79 @@
+package org.hibernate.search.cfg;
+
+import java.lang.annotation.ElementType;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class EntityDescriptor {
+ private Class<?> entityType;
+ private Map<String, Object> indexed;
+ private Map<PropertyKey, PropertyDescriptor> properties = new HashMap<PropertyKey, PropertyDescriptor>();
+
+ public Map<String, Object> getIndexed() {
+ return indexed;
+ }
+
+ public EntityDescriptor(Class<?> entityType) {
+ this.entityType = entityType;
+ }
+
+ public void setIndexed(Map<String, Object> indexed) {
+ this.indexed = indexed;
+ }
+
+ PropertyDescriptor getProperty(String name, ElementType type) {
+ PropertyKey propertyKey = new PropertyKey( name, type );
+ PropertyDescriptor descriptor = properties.get( propertyKey );
+ if (descriptor == null) {
+ descriptor = new PropertyDescriptor(name, type);
+ properties.put(propertyKey, descriptor);
+ }
+ return descriptor;
+ }
+
+ public PropertyDescriptor getPropertyDescriptor(String name, ElementType type) {
+ return properties.get( new PropertyKey( name, type ) );
+ }
+
+
+ private static class PropertyKey {
+ private String name;
+ private ElementType type;
+
+ PropertyKey(String name, ElementType type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+
+ PropertyKey property = ( PropertyKey ) o;
+
+ if ( name != null ? !name.equals( property.name ) : property.name != null ) {
+ return false;
+ }
+ if ( type != property.type ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = name != null ? name.hashCode() : 0;
+ result = 31 * result + ( type != null ? type.hashCode() : 0 );
+ return result;
+ }
+ }
+}
Added: search/trunk/src/java/org/hibernate/search/cfg/EntityMapping.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/EntityMapping.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/cfg/EntityMapping.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,41 @@
+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.Indexed;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class EntityMapping {
+ private SearchMapping mapping;
+ private EntityDescriptor entity;
+
+ public EntityMapping(Class<?> entityType, String name, SearchMapping mapping) {
+ this.mapping = mapping;
+ entity = mapping.getEntity(entityType);
+ Map<String, Object> indexed = new HashMap<String, Object>();
+ if (name != null) indexed.put( "index", name );
+ entity.setIndexed(indexed);
+ }
+
+ 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 indexedClass(Class<?> entityType) {
+ return new EntityMapping(entityType, null, mapping);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType, String indexName) {
+ return new EntityMapping(entityType, indexName, mapping);
+ }
+}
Added: search/trunk/src/java/org/hibernate/search/cfg/FieldMapping.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/FieldMapping.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/cfg/FieldMapping.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,78 @@
+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;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class FieldMapping {
+ private SearchMapping mapping;
+ private EntityDescriptor entity;
+ private PropertyDescriptor property;
+ private Map<String, Object> field = new HashMap<String, Object>();
+
+ public FieldMapping(PropertyDescriptor property, EntityDescriptor entity, SearchMapping mapping) {
+ this.mapping = mapping;
+ this.entity = entity;
+ this.mapping = mapping;
+ this.property = property;
+ property.addField(field);
+ }
+
+ public FieldMapping name(String fieldName) {
+ field.put( "name", fieldName );
+ return this;
+ }
+
+ public FieldMapping store(Store store) {
+ field.put( "store", store );
+ return this;
+ }
+
+ public FieldMapping index(Index index) {
+ field.put( "index", index );
+ return this;
+ }
+
+ public FieldMapping analyzer(Class<?> analyzerClass) {
+ final Map<String, Object> analyzer = new HashMap<String, Object>();
+ analyzer.put( "impl", analyzerClass );
+ field.put( "analyzer", analyzer );
+ return this;
+ }
+
+ public FieldMapping analyzer(String analyzerDef) {
+ final Map<String, Object> analyzer = new HashMap<String, Object>();
+ analyzer.put( "definition", analyzerDef );
+ field.put( "analyzer", analyzer );
+ return this;
+ }
+
+ public FieldMapping field() {
+ return new FieldMapping(property, entity, mapping);
+ }
+
+ 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 indexedClass(Class<?> entityType) {
+ return new EntityMapping(entityType, null, mapping);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType, String indexName) {
+ return new EntityMapping(entityType, indexName, mapping);
+ }
+
+}
Added: search/trunk/src/java/org/hibernate/search/cfg/PropertyDescriptor.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/PropertyDescriptor.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/cfg/PropertyDescriptor.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,28 @@
+package org.hibernate.search.cfg;
+
+import java.lang.annotation.ElementType;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class PropertyDescriptor {
+ private ElementType type;
+ private String name;
+ private Set<Map<String, Object>> fields = new HashSet<Map<String, Object>>();
+
+ public PropertyDescriptor(String name, ElementType type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ public void addField(Map<String, Object> field) {
+ fields.add( field );
+ }
+
+ public Set<Map<String, Object>> getFields() {
+ return fields;
+ }
+}
Added: search/trunk/src/java/org/hibernate/search/cfg/PropertyMapping.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/PropertyMapping.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/cfg/PropertyMapping.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,40 @@
+package org.hibernate.search.cfg;
+
+import java.lang.annotation.ElementType;
+
+import org.apache.solr.analysis.TokenizerFactory;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class PropertyMapping {
+ private SearchMapping mapping;
+ private EntityDescriptor entity;
+ private PropertyDescriptor property;
+
+ public PropertyMapping(String name, ElementType type, EntityDescriptor entity, SearchMapping mapping) {
+ this.mapping = mapping;
+ this.entity = entity;
+ property = entity.getProperty(name, type);
+ }
+
+ public FieldMapping field() {
+ return new FieldMapping(property, entity, mapping);
+ }
+
+ 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 indexedClass(Class<?> entityType) {
+ return new EntityMapping(entityType, null, mapping);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType, String indexName) {
+ return new EntityMapping(entityType, indexName, mapping);
+ }
+}
Modified: search/trunk/src/java/org/hibernate/search/cfg/SearchConfiguration.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/SearchConfiguration.java 2009-03-23 01:53:05 UTC (rev 16206)
+++ search/trunk/src/java/org/hibernate/search/cfg/SearchConfiguration.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -52,5 +52,9 @@
*/
ReflectionManager getReflectionManager();
-
+ /**
+ * returns the programmatic configuration or null
+ * //TODO remove hard dep with solr classes
+ */
+ SearchMapping getProgrammaticMapping();
}
Modified: search/trunk/src/java/org/hibernate/search/cfg/SearchConfigurationFromHibernateCore.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/SearchConfigurationFromHibernateCore.java 2009-03-23 01:53:05 UTC (rev 16206)
+++ search/trunk/src/java/org/hibernate/search/cfg/SearchConfigurationFromHibernateCore.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -2,8 +2,8 @@
package org.hibernate.search.cfg;
import java.util.Iterator;
+import java.util.NoSuchElementException;
import java.util.Properties;
-import java.util.NoSuchElementException;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.java.JavaReflectionManager;
@@ -56,6 +56,10 @@
return reflectionManager;
}
+ public SearchMapping getProgrammaticMapping() {
+ return ( SearchMapping ) getProperties().get( "hibernate.search.mapping_model" );
+ }
+
private static class ClassIterator implements Iterator<Class<?>> {
private Iterator hibernatePersistentClassIterator;
private Class<?> future;
Added: search/trunk/src/java/org/hibernate/search/cfg/SearchMapping.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/SearchMapping.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/cfg/SearchMapping.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,67 @@
+package org.hibernate.search.cfg;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.solr.analysis.TokenizerFactory;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class SearchMapping {
+ private Set<Map<String, Object>> analyzerDefs = new HashSet<Map<String, Object>>();
+ private Map<Class<?>, EntityDescriptor> entities = new HashMap<Class<?>, EntityDescriptor>();
+
+ public Set<Map<String, Object>> getAnalyzerDefs() {
+ return analyzerDefs;
+ }
+
+ public EntityDescriptor getEntityDescriptor(Class<?> entityType) {
+ return entities.get( entityType );
+ }
+
+ public AnalyzerDefMapping analyzerDef(String name, Class<? extends TokenizerFactory> tokenizerFactory) {
+ return new AnalyzerDefMapping(name, tokenizerFactory, this);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType) {
+ return new EntityMapping(entityType, null, this);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType, String indexName) {
+ return new EntityMapping(entityType, indexName, this);
+ }
+
+ /**
+ * eg @Containing(things={@Thing(...), @Thing(...)}
+ * Map<String, Object> addedThing = addElementToAnnotationArray(containing, "things");
+ */
+ static Map<String, Object> addElementToAnnotationArray(Map<String, Object> containingAnnotation,
+ String attributeName) {
+ List<Map<String, Object>> array = (List<Map<String, Object>>) containingAnnotation.get( attributeName );
+ if ( array == null) {
+ array = new ArrayList<Map<String, Object>>();
+ containingAnnotation.put( attributeName, array );
+ }
+ Map<String, Object> param = new HashMap<String, Object>();
+ array.add( param );
+ return param;
+ }
+
+ void addAnalyzerDef(Map<String, Object> analyzerDef) {
+ analyzerDefs.add( analyzerDef );
+ }
+
+ EntityDescriptor getEntity(Class<?> entityType) {
+ EntityDescriptor entity = entities.get( entityType );
+ if (entity == null) {
+ entity = new EntityDescriptor(entityType);
+ entities.put( entityType, entity );
+ }
+ return entity;
+ }
+}
Added: search/trunk/src/java/org/hibernate/search/cfg/TokenFilterDefMapping.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/TokenFilterDefMapping.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/cfg/TokenFilterDefMapping.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,52 @@
+package org.hibernate.search.cfg;
+
+import java.util.Map;
+
+import org.apache.solr.analysis.TokenFilterFactory;
+import org.apache.solr.analysis.TokenizerFactory;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class TokenFilterDefMapping {
+ private Map<String, Object> filter;
+ private Map<String, Object> analyzerDef;
+ private SearchMapping mapping;
+
+ TokenFilterDefMapping(Class<? extends TokenFilterFactory> factory, Map<String, Object> analyzerDef, SearchMapping mapping) {
+ this.mapping = mapping;
+ this.analyzerDef = analyzerDef;
+ this.filter = SearchMapping.addElementToAnnotationArray( analyzerDef, "filters" );
+ filter.put( "factory", factory );
+ }
+
+ /**
+ * @TokenFilterDef(, ... params={@Parameter(name="name", value="value"), ...})
+ */
+ public TokenFilterDefMapping param(String name, String value) {
+ Map<String, Object> param = SearchMapping.addElementToAnnotationArray(filter, "params");
+ param.put("name", name);
+ param.put("value", value);
+ return this;
+ }
+
+ /**
+ * @TokenFilterDef(factory=factory)
+ */
+ public TokenFilterDefMapping filter(Class<? extends TokenFilterFactory> factory) {
+ return new TokenFilterDefMapping(factory, analyzerDef, mapping );
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType) {
+ return new EntityMapping(entityType, null, mapping);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType, String indexName) {
+ return new EntityMapping(entityType, indexName, mapping);
+ }
+
+ public AnalyzerDefMapping analyzerDef(String name, Class<? extends TokenizerFactory> tokenizerFactory) {
+ return new AnalyzerDefMapping(name, tokenizerFactory, mapping);
+ }
+
+}
Modified: search/trunk/src/java/org/hibernate/search/impl/FullTextSessionImpl.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/impl/FullTextSessionImpl.java 2009-03-23 01:53:05 UTC (rev 16206)
+++ search/trunk/src/java/org/hibernate/search/impl/FullTextSessionImpl.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -25,6 +25,7 @@
import org.hibernate.ScrollableResults;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
+import org.hibernate.UnknownProfileException;
import org.hibernate.classic.Session;
import org.hibernate.collection.PersistentCollection;
import org.hibernate.engine.EntityKey;
@@ -32,6 +33,7 @@
import org.hibernate.engine.QueryParameters;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.LoadQueryInfluencers;
import org.hibernate.engine.query.ParameterMetadata;
import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
import org.hibernate.event.EventListeners;
@@ -571,6 +573,10 @@
return sessionImplementor.isClosed();
}
+ public LoadQueryInfluencers getLoadQueryInfluencers() {
+ return sessionImplementor.getLoadQueryInfluencers();
+ }
+
public org.hibernate.Session getSession(EntityMode entityMode) {
return session.getSession( entityMode );
}
@@ -706,4 +712,16 @@
public void update(Object object) throws HibernateException {
session.update( object );
}
+
+ public boolean isFetchProfileEnabled(String name) throws UnknownProfileException {
+ return session.isFetchProfileEnabled( name );
+ }
+
+ public void enableFetchProfile(String name) throws UnknownProfileException {
+ session.enableFetchProfile( name );
+ }
+
+ public void disableFetchProfile(String name) throws UnknownProfileException {
+ session.disableFetchProfile( name );
+ }
}
Added: search/trunk/src/java/org/hibernate/search/impl/MappingModelMetadataProvider.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/impl/MappingModelMetadataProvider.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/impl/MappingModelMetadataProvider.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,220 @@
+package org.hibernate.search.impl;
+
+import java.util.Map;
+import java.util.List;
+import java.util.Set;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.beans.Introspector;
+
+import org.hibernate.annotations.common.reflection.MetadataProvider;
+import org.hibernate.annotations.common.reflection.AnnotationReader;
+import org.hibernate.annotations.common.reflection.ReflectionUtil;
+import org.hibernate.annotations.common.reflection.Filter;
+import org.hibernate.annotations.common.annotationfactory.AnnotationFactory;
+import org.hibernate.annotations.common.annotationfactory.AnnotationDescriptor;
+import org.hibernate.search.cfg.SearchMapping;
+import org.hibernate.search.cfg.EntityDescriptor;
+import org.hibernate.search.cfg.PropertyDescriptor;
+import org.hibernate.search.SearchException;
+import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.annotations.Analyzer;
+import org.hibernate.search.annotations.Fields;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class MappingModelMetadataProvider implements MetadataProvider {
+
+ private static final Filter FILTER = new Filter() {
+ public boolean returnStatic() {
+ return false;
+ }
+
+ public boolean returnTransient() {
+ return true;
+ }
+ };
+
+ private final MetadataProvider delegate;
+ private final SearchMapping mapping;
+ private final Map<AnnotatedElement, AnnotationReader> cache = new HashMap<AnnotatedElement, AnnotationReader>(100);
+
+ public MappingModelMetadataProvider(MetadataProvider delegate, SearchMapping mapping) {
+ this.delegate = delegate;
+ this.mapping = mapping;
+ }
+ public Map<Object, Object> getDefaults() {
+ return delegate.getDefaults();
+ }
+
+ public AnnotationReader getAnnotationReader(AnnotatedElement annotatedElement) {
+ AnnotationReader reader = cache.get(annotatedElement);
+ if (reader == null) {
+ reader = new MappingModelAnnotationReader( mapping, delegate, annotatedElement);
+ cache.put( annotatedElement, reader );
+ }
+ return reader;
+ }
+
+ private static class MappingModelAnnotationReader implements AnnotationReader {
+ private AnnotationReader delegate;
+ private SearchMapping mapping;
+ private transient Annotation[] annotationsArray;
+ private transient Map<Class<? extends Annotation>, Annotation> annotations;
+ private Class<?> entityType;
+ private ElementType elementType;
+ private String propertyName;
+
+ public MappingModelAnnotationReader(SearchMapping mapping, MetadataProvider delegate, AnnotatedElement el) {
+ this.delegate = delegate.getAnnotationReader( el );
+ this.mapping = mapping;
+ if ( el instanceof Class ) {
+ entityType = (Class) el;
+ }
+ else if ( el instanceof Field ) {
+ Field field = (Field) el;
+ entityType = field.getDeclaringClass();
+ propertyName = field.getName();
+ elementType = ElementType.FIELD;
+ }
+ else if ( el instanceof Method ) {
+ Method method = (Method) el;
+ entityType = method.getDeclaringClass();
+ propertyName = method.getName();
+ if ( ReflectionUtil.isProperty(
+ method,
+ null, //this is yukky!! we'd rather get the TypeEnvironment()
+ FILTER
+ ) ) {
+ if ( propertyName.startsWith( "get" ) ) {
+ propertyName = Introspector.decapitalize( propertyName.substring( "get".length() ) );
+ }
+ else if ( propertyName.startsWith( "is" ) ) {
+ propertyName = Introspector.decapitalize( propertyName.substring( "is".length() ) );
+ }
+ else {
+ throw new RuntimeException( "Method " + propertyName + " is not a property getter" );
+ }
+ elementType = ElementType.METHOD;
+ }
+ else {
+ throw new SearchException( "Error in programmatic mapping. Method " + propertyName + " is not a property getter" );
+ }
+ }
+ else {
+ entityType = null;
+ propertyName = null;
+ }
+ }
+
+ /**
+ * Consider the class to be free of Hibernate Search annotations. Does nto attempt to merge
+ * data.
+ * TODO do merge data? or safe-guard against errors
+ */
+ private void initAnnotations() {
+ if ( annotationsArray == null ) {
+ annotations = new HashMap<Class<? extends Annotation>, Annotation>();
+ delegatesAnnotationReading();
+ if (entityType != null) {
+ final EntityDescriptor entity = mapping.getEntityDescriptor( entityType );
+ if (entity != null) {
+ if (propertyName == null) {
+ //entityType overriding
+ createIndexed( entity );
+ }
+ else {
+ final PropertyDescriptor property = entity.getPropertyDescriptor( propertyName, elementType );
+ if (property != null) {
+ // property name overriding
+ createFields( property );
+ }
+ }
+ }
+ }
+ else {
+ delegatesAnnotationReading();
+ }
+
+ populateAnnotationArray();
+ }
+ }
+
+ private void createFields(PropertyDescriptor property) {
+ final Set<Map<String,Object>> fields = property.getFields();
+ List<org.hibernate.search.annotations.Field> fieldAnnotations =
+ new ArrayList<org.hibernate.search.annotations.Field>( fields.size() );
+ for(Map<String, Object> field : fields) {
+ AnnotationDescriptor fieldAnnotation = new AnnotationDescriptor( org.hibernate.search.annotations.Field.class );
+ for ( Map.Entry<String, Object> entry : field.entrySet() ) {
+ if ( entry.getKey().equals( "analyzer" ) ) {
+ AnnotationDescriptor analyzerAnnotation = new AnnotationDescriptor( Analyzer.class );
+ @SuppressWarnings( "unchecked" )
+ Map<String, Object> analyzer = (Map<String, Object>) entry.getValue();
+ for( Map.Entry<String, Object> analyzerEntry : analyzer.entrySet() ) {
+ analyzerAnnotation.setValue( analyzerEntry.getKey(), analyzerEntry.getValue() );
+ }
+ fieldAnnotation.setValue( "analyzer", AnnotationFactory.create( analyzerAnnotation ) );
+ }
+ else {
+ fieldAnnotation.setValue( entry.getKey(), entry.getValue() );
+ }
+ }
+ fieldAnnotations.add( (org.hibernate.search.annotations.Field) AnnotationFactory.create( fieldAnnotation ) );
+ }
+ AnnotationDescriptor fieldsAnnotation = new AnnotationDescriptor( Fields.class );
+
+ final org.hibernate.search.annotations.Field[] fieldArray =
+ new org.hibernate.search.annotations.Field[fieldAnnotations.size()];
+ fieldsAnnotation.setValue( "value", fieldAnnotations.toArray( fieldArray ));
+ annotations.put( Fields.class, AnnotationFactory.create( fieldsAnnotation ) );
+ }
+
+ private void createIndexed(EntityDescriptor entity) {
+ Class<? extends Annotation> annotationType = Indexed.class;
+ AnnotationDescriptor annotation = new AnnotationDescriptor( annotationType );
+ for ( Map.Entry<String, Object> entry : entity.getIndexed().entrySet() ) {
+ annotation.setValue( entry.getKey(), entry.getValue() );
+ }
+ annotations.put( annotationType, AnnotationFactory.create( annotation ) );
+ }
+
+ private void populateAnnotationArray() {
+ annotationsArray = new Annotation[ annotations.size() ];
+ int index = 0;
+ for( Annotation ann: annotations.values() ) {
+ annotationsArray[index] = ann;
+ index++;
+ }
+ }
+
+ private void delegatesAnnotationReading() {
+ for ( Annotation a : delegate.getAnnotations() ) {
+ annotations.put( a.annotationType(), a );
+ }
+ }
+
+ @SuppressWarnings( "unchecked" )
+ public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+ initAnnotations();
+ return (T) annotations.get( annotationType );
+ }
+
+ @SuppressWarnings( "unchecked" )
+ public <T extends Annotation> boolean isAnnotationPresent(Class<T> annotationType) {
+ initAnnotations();
+ return (T) annotations.get( annotationType ) != null;
+ }
+
+ public Annotation[] getAnnotations() {
+ initAnnotations();
+ return new Annotation[0]; //To change body of implemented methods use File | Settings | File Templates.
+ }
+ }
+}
Modified: search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java 2009-03-23 01:53:05 UTC (rev 16206)
+++ search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -21,6 +21,8 @@
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.annotations.common.util.StringHelper;
import org.hibernate.search.Environment;
@@ -39,6 +41,7 @@
import org.hibernate.search.backend.WorkerFactory;
import org.hibernate.search.backend.configuration.ConfigurationParseHelper;
import org.hibernate.search.cfg.SearchConfiguration;
+import org.hibernate.search.cfg.SearchMapping;
import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
import org.hibernate.search.engine.FilterDef;
import org.hibernate.search.engine.SearchFactoryImplementor;
@@ -111,10 +114,8 @@
}
public SearchFactoryImpl(SearchConfiguration cfg) {
- ReflectionManager reflectionManager = cfg.getReflectionManager();
- if ( reflectionManager == null ) {
- reflectionManager = new JavaReflectionManager();
- }
+ ReflectionManager reflectionManager = getReflectionManager(cfg);
+
this.indexingStrategy = defineIndexingStrategy( cfg ); //need to be done before the document builds
initDocumentBuilders( cfg, reflectionManager );
@@ -135,6 +136,25 @@
this.barrier = 1; //write barrier
}
+ private ReflectionManager getReflectionManager(SearchConfiguration cfg) {
+ ReflectionManager reflectionManager = cfg.getReflectionManager();
+ 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;
+ }
+
private static String defineIndexingStrategy(SearchConfiguration cfg) {
String indexingStrategy = cfg.getProperties().getProperty( Environment.INDEXING_STRATEGY, "event" );
if ( !( "event".equals( indexingStrategy ) || "manual".equals( indexingStrategy ) ) ) {
Added: search/trunk/src/test/org/hibernate/search/test/configuration/Address.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/configuration/Address.java (rev 0)
+++ search/trunk/src/test/org/hibernate/search/test/configuration/Address.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,44 @@
+package org.hibernate.search.test.configuration;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Entity
+public class Address {
+ @Id
+ @GeneratedValue
+ private Long id;
+ private String street1;
+ private String street2;
+ @ManyToOne
+ private Country country;
+
+ public String getStreet1() {
+ return street1;
+ }
+
+ public void setStreet1(String street1) {
+ this.street1 = street1;
+ }
+
+ public Country getCountry() {
+ return country;
+ }
+
+ public void setCountry(Country country) {
+ this.country = country;
+ }
+
+ public String getStreet2() {
+ return street2;
+ }
+
+ public void setStreet2(String street2) {
+ this.street2 = street2;
+ }
+}
Added: search/trunk/src/test/org/hibernate/search/test/configuration/Country.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/configuration/Country.java (rev 0)
+++ search/trunk/src/test/org/hibernate/search/test/configuration/Country.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,24 @@
+package org.hibernate.search.test.configuration;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Entity
+public class Country {
+ @Id
+ @GeneratedValue
+ private Long id;
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
Added: search/trunk/src/test/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java (rev 0)
+++ search/trunk/src/test/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,107 @@
+package org.hibernate.search.test.configuration;
+
+import java.lang.annotation.ElementType;
+
+import org.apache.solr.analysis.StandardTokenizerFactory;
+import org.apache.solr.analysis.SnowballPorterFilterFactory;
+import org.apache.solr.analysis.LowerCaseFilterFactory;
+import org.apache.solr.analysis.NGramFilterFactory;
+import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+
+import org.hibernate.search.cfg.SearchMapping;
+import org.hibernate.search.annotations.Store;
+import org.hibernate.search.annotations.Index;
+import org.hibernate.search.test.analyzer.inheritance.ISOLatin1Analyzer;
+import org.hibernate.search.test.SearchTestCase;
+import org.hibernate.search.FullTextSession;
+import org.hibernate.search.Search;
+import org.hibernate.search.FullTextQuery;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.Transaction;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class ProgrammaticMappingTest extends SearchTestCase {
+
+ public void testMapping() throws Exception{
+ Address address = new Address();
+ address.setStreet1( "3340 Peachtree Rd NE" );
+ address.setStreet2( "JBoss" );
+
+ FullTextSession s = Search.getFullTextSession( openSession() );
+ Transaction tx = s.beginTransaction();
+ s.persist( address );
+ tx.commit();
+
+ s.clear();
+
+ tx = s.beginTransaction();
+
+ QueryParser parser = new QueryParser( "id", new StandardAnalyzer() );
+ org.apache.lucene.search.Query luceneQuery = parser.parse( "street1:peachtree" );
+ FullTextQuery query = s.createFullTextQuery( luceneQuery ).setProjection( "idx_street2", FullTextQuery.THIS );
+ assertEquals( "Not properly indexed", 1, query.getResultSize() );
+ Object[] firstResult = (Object[]) query.list().get( 0 );
+ assertEquals( "@Field.store not respected", "JBoss", firstResult[0] );
+
+ s.delete( firstResult[1] );
+ tx.commit();
+ s.close();
+
+ }
+
+ @Override
+ protected void configure(Configuration cfg) {
+ super.configure( cfg );
+ SearchMapping mapping = new SearchMapping();
+ mapping.indexedClass( Address.class )
+ .property( "street1", ElementType.FIELD )
+ .field()
+ .property( "street2", ElementType.METHOD )
+ .field().name( "idx_street2" )
+ .store( Store.YES );
+ cfg.getProperties().put( "hibernate.search.mapping_model", mapping );
+ }
+
+ public void NotUseddefineMapping() {
+ SearchMapping mapping = new SearchMapping();
+ mapping.analyzerDef( "stem", StandardTokenizerFactory.class )
+ .tokenizerParam( "name", "value" )
+ .tokenizerParam( "name2", "value2" )
+ .filter( LowerCaseFilterFactory.class )
+ .filter( SnowballPorterFilterFactory.class)
+ .param("language", "English")
+ .analyzerDef( "ngram", StandardTokenizerFactory.class )
+ .tokenizerParam( "name", "value" )
+ .tokenizerParam( "name2", "value2" )
+ .filter( LowerCaseFilterFactory.class )
+ .filter( NGramFilterFactory.class)
+ .param("minGramSize", "3")
+ .param("maxGramSize", "3")
+ .indexedClass(Address.class, "Address_Index")
+ .property("street1", ElementType.FIELD)
+ .field()
+ .field()
+ .name("street1_iso")
+ .store( Store.YES )
+ .index( Index.TOKENIZED )
+ .analyzer( ISOLatin1Analyzer.class)
+ .field()
+ .name("street1_ngram")
+ .analyzer("ngram")
+ .indexedClass(User.class)
+ .property("name", ElementType.METHOD)
+ .field()
+ .analyzerDef( "minimal", StandardTokenizerFactory.class );
+
+ }
+
+ protected Class[] getMappings() {
+ return new Class[] {
+ Address.class,
+ Country.class
+ };
+ }
+}
\ No newline at end of file
Added: search/trunk/src/test/org/hibernate/search/test/configuration/User.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/configuration/User.java (rev 0)
+++ search/trunk/src/test/org/hibernate/search/test/configuration/User.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,16 @@
+package org.hibernate.search.test.configuration;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class User {
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
More information about the hibernate-commits
mailing list