[hibernate-commits] Hibernate SVN: r10611 - in branches/Lucene_Integration/HibernateExt/metadata/src: java/org/hibernate/lucene java/org/hibernate/lucene/bridge test/org/hibernate/lucene/test

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Oct 18 18:09:39 EDT 2006


Author: epbernard
Date: 2006-10-18 18:09:34 -0400 (Wed, 18 Oct 2006)
New Revision: 10611

Added:
   branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/DocumentId.java
   branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Field.java
   branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Index.java
   branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Store.java
   branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/IdFieldBridge.java
Modified:
   branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/DocumentBuilder.java
   branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Keyword.java
   branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Text.java
   branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Unstored.java
   branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/FieldBridge.java
   branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/String2FieldBridgeAdaptor.java
   branches/Lucene_Integration/HibernateExt/metadata/src/test/org/hibernate/lucene/test/Document.java
Log:
ANN-383 adjust to the Lucene 2 APIs (deprecate the old annotations)
Use of idBridge to remove an element from the index
ANN-468 IdFieldBridge (but the String2FieldBridgeAdaptor is broken

Modified: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/DocumentBuilder.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/DocumentBuilder.java	2006-10-18 16:14:49 UTC (rev 10610)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/DocumentBuilder.java	2006-10-18 22:09:34 UTC (rev 10611)
@@ -18,6 +18,7 @@
 import org.hibernate.cfg.annotations.Version;
 import org.hibernate.lucene.bridge.BridgeFactory;
 import org.hibernate.lucene.bridge.FieldBridge;
+import org.hibernate.lucene.bridge.IdFieldBridge;
 import org.hibernate.lucene.event.LuceneEventListener;
 import org.hibernate.lucene.store.DirectoryProvider;
 import org.hibernate.lucene.util.BinderHelper;
@@ -51,6 +52,11 @@
     private final List<XMember> textGetters = new ArrayList<XMember>();
     private final List<String> textNames = new ArrayList<String>();
     private final List<FieldBridge> textBridges = new ArrayList<FieldBridge>();
+    private final List<String> fieldNames = new ArrayList<String>();
+    private final List<XMember> fieldGetters = new ArrayList<XMember>();
+    private final List<FieldBridge> fieldBridges = new ArrayList<FieldBridge>();
+    private final List<Field.Store> fieldStore = new ArrayList<Field.Store>();
+    private final List<Field.Index> fieldIndex = new ArrayList<Field.Index>();
 
     private final XClass beanClass;
     private final DirectoryProvider directoryProvider;
@@ -58,10 +64,11 @@
     private final Analyzer analyzer;
     private Float idBoost;
     public static final String CLASS_FIELDNAME = "_hibernate_class";
-    private FieldBridge idBridge;
+    private IdFieldBridge idBridge;
     private Set<Class> mappedSubclasses = new HashSet<Class>();
     private ReflectionManager reflectionManager;
 
+
     public DocumentBuilder(XClass clazz, Analyzer analyzer, DirectoryProvider directory, ReflectionManager reflectionManager) {
         this.beanClass = clazz;
         this.analyzer = analyzer;
@@ -85,7 +92,7 @@
         }
 
         if ( idKeywordName == null ) {
-            throw new HibernateException( "No id Keyword for: " + clazz.getName() );
+            throw new HibernateException( "No document id for: " + clazz.getName() );
         }
     }
 
@@ -96,7 +103,13 @@
             if ( keywordAnn.id() ) {
                 idKeywordName = name;
                 idBoost = getBoost( member );
-                idBridge = BridgeFactory.guessType( member );
+                FieldBridge fieldBridge = BridgeFactory.guessType( member );
+                if ( fieldBridge instanceof IdFieldBridge ) {
+                    idBridge = (IdFieldBridge) fieldBridge;
+                }
+                else {
+                    throw new HibernateException( "Bridge for document id does not implement IdFieldBridge: " + member.getName() );
+                }
             }
             else {
                 setAccessible( member );
@@ -121,9 +134,63 @@
             textNames.add( BinderHelper.getAttributeName( member, textAnn.name() ) );
             textBridges.add( BridgeFactory.guessType( member ) );
         }
+
+        DocumentId documentIdAnn = member.getAnnotation( DocumentId.class );
+        if ( documentIdAnn != null ) {
+            if ( idKeywordName != null ) {
+                throw new AssertionFailure( "Two document id assigned: "
+                    + idKeywordName + " and " + BinderHelper.getAttributeName( member, documentIdAnn.name() ) );
+            }
+            idKeywordName = BinderHelper.getAttributeName( member, documentIdAnn.name() );
+            FieldBridge fieldBridge = BridgeFactory.guessType( member );
+            if ( fieldBridge instanceof IdFieldBridge ) {
+                idBridge = (IdFieldBridge) fieldBridge;
+            }
+            else {
+                throw new HibernateException( "Bridge for document id does not implement IdFieldBridge: " + member.getName() );
+            }
+            idBoost = getBoost( member );
+        }
+
+        org.hibernate.lucene.Field fieldAnn = member.getAnnotation( org.hibernate.lucene.Field.class );
+        if ( fieldAnn != null ) {
+            setAccessible( member );
+            fieldGetters.add( member );
+            fieldNames.add( BinderHelper.getAttributeName( member, fieldAnn.name() ) );
+            fieldStore.add( getStore( fieldAnn.store() ) );
+            fieldIndex.add( getIndex( fieldAnn.index() ) );
+            fieldBridges.add( BridgeFactory.guessType( member ) );
+        }
     }
 
+    private Field.Store getStore(Store store) {
+        switch( store ) {
+            case NO:
+                return Field.Store.NO;
+            case YES:
+                return Field.Store.YES;
+            case COMPRESS:
+                return Field.Store.COMPRESS;
+            default:
+                throw new AssertionFailure( "Unexpected Store: " + store );
+        }
+    }
 
+    private Field.Index getIndex(Index index) {
+        switch( index ) {
+            case NO:
+                return Field.Index.NO;
+            case NO_NORMS:
+                return Field.Index.NO_NORMS;
+            case TOKENIZED:
+                return Field.Index.TOKENIZED;
+            case UN_TOKENISED:
+                return Field.Index.UN_TOKENIZED;
+            default:
+                throw new AssertionFailure( "Unexpected Index: " + index );
+        }
+    }
+
     private Float getBoost(XAnnotatedElement element) {
         if ( element == null ) return null;
         Boost boost = element.getAnnotation( Boost.class );
@@ -180,11 +247,19 @@
                     Field.Index.TOKENIZED, getBoost( member )
             );
         }
+        for ( int i = 0; i < fieldNames.size(); i++ ) {
+            XMember member = fieldGetters.get( i );
+            Object value = getMemberValue( instance, member );
+            fieldBridges.get( i ).set(
+                    fieldNames.get( i ), value, doc, fieldStore.get( i ),
+                    fieldIndex.get( i ), getBoost( member )
+            );
+        }
         return doc;
     }
 
     public Term getTerm(Serializable id) {
-        return new Term( idKeywordName, id.toString() );
+        return new Term( idKeywordName, idBridge.objectToString( id ) );
     }
 
     public DirectoryProvider getDirectoryProvider() {
@@ -201,7 +276,7 @@
         }
     }
 
-    public FieldBridge getIdBridge() {
+    public IdFieldBridge getIdBridge() {
         return idBridge;
     }
 

Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/DocumentId.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/DocumentId.java	2006-10-18 16:14:49 UTC (rev 10610)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/DocumentId.java	2006-10-18 22:09:34 UTC (rev 10611)
@@ -0,0 +1,22 @@
+//$Id: $
+package org.hibernate.lucene;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Documented;
+
+/**
+ * Declare a field as the document id. If set to a property, the property will be used
+ * TODO: If set to a class, the class itself will be passed to the FieldBridge
+ * Note that @{link org.hibernate.lucene.bridge.FieldBridge#get} must return the Entity id
+ *
+ * @author Emmanuel Bernard
+ */
+ at Retention( RetentionPolicy.RUNTIME)
+ at Target({ElementType.METHOD, ElementType.FIELD})
+ at Documented
+public @interface DocumentId {
+    String name() default "";
+}

Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Field.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Field.java	2006-10-18 16:14:49 UTC (rev 10610)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Field.java	2006-10-18 22:09:34 UTC (rev 10611)
@@ -0,0 +1,38 @@
+//$Id: $
+/**
+ * JavaDoc copy/pastle from the Apache Lucene project
+ * Available under the ASL 2.0 http://www.apache.org/licenses/LICENSE-2.0
+ */
+package org.hibernate.lucene;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Documented;
+
+/**
+ * Mark a property as indexable
+ *
+ * @author Emmanuel Bernard
+ */
+ at Retention( RetentionPolicy.RUNTIME)
+ at Target({ElementType.METHOD, ElementType.FIELD})
+ at Documented
+public @interface Field {
+    /**
+     * Field name, default to the JavaBean property name
+     */
+    String name() default "";
+
+    /**
+     * Should the value be stored in the document
+     */
+    Store store() default Store.NO;
+
+    /**
+     * Defines how the Field should be indexed
+     */
+    Index index();
+
+}

Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Index.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Index.java	2006-10-18 16:14:49 UTC (rev 10610)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Index.java	2006-10-18 22:09:34 UTC (rev 10611)
@@ -0,0 +1,29 @@
+//$Id: $
+package org.hibernate.lucene;
+
+/**
+     * Defines how an Field should be indexed
+ */
+public enum Index {
+    /** Do not index the field value. This field can thus not be searched,
+     * but one can still access its contents provided it is
+     * {@link Store stored}. */
+    NO,
+    /** Index the field's value so it can be searched. An Analyzer will be used
+     * to tokenize and possibly further normalize the text before its
+     * terms will be stored in the index. This is useful for common text.
+     */
+    TOKENIZED,
+    /** Index the field's value without using an Analyzer, so it can be searched.
+     * As no analyzer is used the value will be stored as a single term. This is
+     * useful for unique Ids like product numbers.
+     */
+    UN_TOKENISED,
+    /** Index the field's value without an Analyzer, and disable
+     * the storing of norms.  No norms means that index-time boosting
+     * and field length normalization will be disabled.  The benefit is
+     * less memory usage as norms take up one byte per indexed field
+     * for every document in the index.
+     */
+    NO_NORMS
+}

Modified: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Keyword.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Keyword.java	2006-10-18 16:14:49 UTC (rev 10610)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Keyword.java	2006-10-18 22:09:34 UTC (rev 10611)
@@ -13,7 +13,9 @@
 /**
  * Specifies that a property of an entity is a Lucene
  * keyword field
+ * @deprecated use @Field(index=Index.UN_TOKENIZED, store=Store.YES) or @DocumentId when id=true was used
  */
+ at Deprecated
 public @interface Keyword {
 	/**
 	 * The field name

Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Store.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Store.java	2006-10-18 16:14:49 UTC (rev 10610)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Store.java	2006-10-18 22:09:34 UTC (rev 10611)
@@ -0,0 +1,13 @@
+//$Id: $
+package org.hibernate.lucene;
+
+/**
+     * Whether or not the value is stored in the document
+ *
+ * @author Emmanuel Bernard
+ */
+public enum Store {
+    NO,
+    YES,
+    COMPRESS
+}

Modified: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Text.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Text.java	2006-10-18 16:14:49 UTC (rev 10610)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Text.java	2006-10-18 22:09:34 UTC (rev 10611)
@@ -13,7 +13,9 @@
 /**
  * Specifies that a property of an entity is a Lucene
  * text field
+ * @deprecated use @Field(index=Index.TOKENIZED, store=Store.YES)
  */
+ at Deprecated
 public @interface Text {
 	/**
 	 * The field name

Modified: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Unstored.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Unstored.java	2006-10-18 16:14:49 UTC (rev 10610)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/Unstored.java	2006-10-18 22:09:34 UTC (rev 10611)
@@ -13,7 +13,9 @@
 /**
  * Specifies that a property of an entity is a Lucene
  * unstored field
+ * @deprecated use @Field(index=Index.TOKENIZED, store=Store.NO)
  */
+ at Deprecated
 public @interface Unstored {
 	/**
 	 * The field name

Modified: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/FieldBridge.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/FieldBridge.java	2006-10-18 16:14:49 UTC (rev 10610)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/FieldBridge.java	2006-10-18 22:09:34 UTC (rev 10611)
@@ -13,6 +13,11 @@
 //TODO should show Field or document?
 //document is nice since I can save an object into several fields
 public interface FieldBridge {
-	Object get(String name, Document document);
-	void set(String name, Object value, Document document, Field.Store store, Field.Index index, Float boost);
+    /**
+     * Manipulate the document to index the given value.
+     * A common implementation is to add a Field <code>name</code> to the given document following
+     * the parameters (<code>store</code>, <code>index</code>, <code>boost</code>) if the
+     * <code>value></code> is not null
+     */
+    void set(String name, Object value, Document document, Field.Store store, Field.Index index, Float boost);
 }

Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/IdFieldBridge.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/IdFieldBridge.java	2006-10-18 16:14:49 UTC (rev 10610)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/IdFieldBridge.java	2006-10-18 22:09:34 UTC (rev 10611)
@@ -0,0 +1,29 @@
+//$Id: $
+package org.hibernate.lucene.bridge;
+
+import org.apache.lucene.document.Document;
+
+/**
+ * Any bridge expected to process a document id should implement this interface
+ *
+ * @author Emmanuel Bernard
+ */
+//FIXME rework the interface inheritance there are some common concepts with StringBridge
+public interface IdFieldBridge extends FieldBridge {
+    /**
+     * build the element from the Document
+     * This method is called when the bridge is used on a document id, If the Bridge is not expected to
+     * support document id, this method should raise an exception
+     * The return value is the Entity id
+     *
+     * @param name field name
+     * @param document document
+     */
+    Object get(String name, Document document);
+
+    /**
+	 * convert the object representation to a String
+     * The return String must not be null, it can be empty though
+	 */
+	String objectToString(Object object);
+}

Modified: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/String2FieldBridgeAdaptor.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/String2FieldBridgeAdaptor.java	2006-10-18 16:14:49 UTC (rev 10610)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/String2FieldBridgeAdaptor.java	2006-10-18 22:09:34 UTC (rev 10611)
@@ -10,7 +10,8 @@
  *
  * @author Emmanuel Bernard
  */
-public class String2FieldBridgeAdaptor implements FieldBridge {
+//FIXME all String2FieldBridgeAdaptor are not IdFieldBridge
+public class String2FieldBridgeAdaptor implements FieldBridge, IdFieldBridge {
 
 	private StringBridge stringBridge;
 
@@ -22,7 +23,11 @@
 		return stringBridge.stringToObject( field.stringValue() );
 	}
 
-	public void set(String name, Object value, Document document, Field.Store store, Field.Index index, Float boost) {
+    public String objectToString(Object object) {
+        return stringBridge.objectToString( object );
+    }
+
+    public void set(String name, Object value, Document document, Field.Store store, Field.Index index, Float boost) {
         String indexedString = stringBridge.objectToString(value);
         //Do not add fields on empty strings, seems a sensible default in most situations
         if ( StringHelper.isNotEmpty( indexedString ) ) {

Modified: branches/Lucene_Integration/HibernateExt/metadata/src/test/org/hibernate/lucene/test/Document.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/test/org/hibernate/lucene/test/Document.java	2006-10-18 16:14:49 UTC (rev 10610)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/test/org/hibernate/lucene/test/Document.java	2006-10-18 22:09:34 UTC (rev 10611)
@@ -11,6 +11,10 @@
 import org.hibernate.lucene.Text;
 import org.hibernate.lucene.Unstored;
 import org.hibernate.lucene.Boost;
+import org.hibernate.lucene.Field;
+import org.hibernate.lucene.Index;
+import org.hibernate.lucene.DocumentId;
+import org.hibernate.lucene.Store;
 
 @Entity
 @Indexed(index = "Documents")
@@ -32,8 +36,9 @@
 
 	@Id
 	@GeneratedValue
-	@Keyword(id = true)
-	public Long getId() {
+	//@Keyword(id = true)
+    @DocumentId
+    public Long getId() {
 		return id;
 	}
 
@@ -41,8 +46,9 @@
 		this.id = id;
 	}
 
-	@Text
-	@Boost(2)
+	//@Text
+    @Field( store = Store.YES, index = Index.TOKENIZED )
+    @Boost(2)
 	public String getTitle() {
 		return title;
 	}
@@ -51,8 +57,9 @@
 		this.title = title;
 	}
 
-	@Unstored(name = "Abstract")
-	public String getSummary() {
+	//@Unstored(name = "Abstract")
+    @Field( name="Abstract", store = Store.NO, index = Index.TOKENIZED )
+    public String getSummary() {
 		return summary;
 	}
 
@@ -61,8 +68,9 @@
 	}
 
 	@Lob
-	@Unstored
-	public String getText() {
+	//@Unstored
+    @Field( store = Store.NO, index = Index.TOKENIZED )
+    public String getText() {
 		return text;
 	}
 




More information about the hibernate-commits mailing list