Oui oui j'avais bien compris, je plaisantais :-)
J'avais une autre question tant que j'y étais, par rapport à la gestion
transactionnelle des opérations Lucene, y a t il quelque chose de prévu
?
> -----Message d'origine-----
> De : Emmanuel Bernard [mailto:[EMAIL PROTECTED]
> Envoyé : vendredi 13 octobre 2006 16:00
> À : Richard Hallier
> Objet : Re: Hibernate Lucene & fields
>
> je parlais des Bridges pour toutes les propriétés
>
> Richard Hallier wrote:
> >
> > Développé dans l'avion? J'espère que tu as fait un vol long
> courrier
> > ;-) Tiens moi au courant pour le patch.
> > Richard
> >
> > > -----Message d'origine-----
> > > De : Emmanuel Bernard [mailto:[EMAIL PROTECTED]
> > > Envoyé : vendredi 13 octobre 2006 01:36 À : Richard
> Hallier Objet :
> > > Re: Hibernate Lucene & fields
> > >
> > > Si, je viens de le développer dans l'avion aujourd'hui ;-) Merci
> > > pour le patch je vais regarder ca demain
> > >
> > > Richard Hallier wrote:
> > > >
> > > > Salut Emmanuel,
> > > > Tu trouveras le patch en question en pièce jointe.
> > > > J'ai rajouté une classe de test plutot sommaire, cela
> > > peut-etre amélioré.
> > > >
> > > > J'ai une question. J'ai vu que la conversion (hors identifiant)
> > > > des properties des entités en valeur lucene se fait par
> une simple
> > > > conversion texte, alors que tu as mis en place pour la
> gestion de
> > > > l'identifiant un bridge. Ce concept de "converter" ne
> > > pourrait il pas
> > > > etre appliqué à toute conversion (pas seulement l'id) en
> > > valeur Lucene?
> > > >
> > > > Richard.
> > > >
> > > > > -----Message d'origine-----
> > > > > De : Emmanuel Bernard [mailto:[EMAIL PROTECTED] Envoyé :
> > > > > mercredi 11 octobre 2006 05:24 À :
> > > [EMAIL PROTECTED] Objet
> > > > > : Hibernate Lucene & fields
> > > > >
> > > > > Hi,
> > > > > I bet you're French so I'll switch to it.
> > > > >
> > > > > J'ai pensé au code qui permettrait d'annoter les attributs.
> > > > > En fait je voudrais utiliser une abstraction que l'on a
> > > écrit pour
> > > > > Hibernate Annotations. Cela abstrait le code de la résolution
> > > > > Generics de Java 5 et des propriétés vs attributs.
> > > > >
> > > > > Quand tu commences le patch, regarde
> > > > > org.hibernate.validator.ClassValidator, les accès aux
> > > annotations se
> > > > > font via ReflectionManager reflectionManager = new
> > > JavaXFactory();
> > > > > dans la methode
> > > > > ClassValidator.initValidator(...)
> > > > >
> > > > > Si tu as des questions, n'hésites pas à me demander.
> > > > >
> > > > > Emmanuel
> > > > >
> > > >
> > > >
> > >
> --------------------------------------------------------------------
> > > --
> > > > --
> > > >
> > > > Index:
> > > >
> > >
> C:/dev/source/workspace1.5/HibernateExt/metadata/src/test/org/hibern
> > > at
> > > > e/lucene/test/FieldMappingTest.java
> > > >
> ==================================================================
> > > > =
> > > > ---
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/test/org/
> > > hibernate/lucene/test/FieldMappingTest.java (revision 0)
> > > > +++
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/test/org/
> > > hibernate/lucene/test/FieldMappingTest.java (revision 0)
> > > > @@ -0,0 +1,191 @@
> > > > +//$Id: LuceneTest.java 10014 2006-06-12 09:56:27 -0700
> > > (lun., 12 juin
> > > > +2006) epbernard $ package org.hibernate.lucene.test;
> > > > +
> > > > +import java.io.File;
> > > > +import java.util.List;
> > > > +
> > > > +import org.apache.lucene.analysis.StopAnalyzer;
> > > > +import org.apache.lucene.analysis.standard.StandardAnalyzer;
> > > > +import org.apache.lucene.index.IndexReader;
> > > > +import org.apache.lucene.index.Term; import
> > > > +org.apache.lucene.index.TermDocs; import
> > > > +org.apache.lucene.queryParser.QueryParser;
> > > > +import org.apache.lucene.search.Hits; import
> > > > +org.apache.lucene.search.IndexSearcher;
> > > > +import org.apache.lucene.search.Query; import
> > > org.hibernate.Session;
> > > > +import org.hibernate.event.PostDeleteEventListener;
> > > > +import org.hibernate.event.PostInsertEventListener;
> > > > +import org.hibernate.event.PostUpdateEventListener;
> > > > +import org.hibernate.lucene.Environment; import
> > > > +org.hibernate.lucene.store.FSDirectoryProvider;
> > > > +import org.hibernate.lucene.event.LuceneEventListener;
> > > > +
> > > > +/**
> > > > + * @author Richard Hallier
> > > > + */
> > > > +public class FieldMappingTest extends TestCase {
> > > > +
> > > > +
> > > > + protected void setUp() throws Exception {
> > > > + File sub = getBaseIndexDir();
> > > > + sub.mkdir();
> > > > + File[] files = sub.listFiles();
> > > > + for (File file : files) {
> > > > + if ( file.isDirectory() ) {
> > > > + delete( file );
> > > > + }
> > > > + }
> > > > + //super.setUp(); //we need a fresh session
> > > factory each time for index set up
> > > > + buildSessionFactory( getMappings(),
> > > getAnnotatedPackages(), getXmlFiles() );
> > > > + }
> > > > +
> > > > + private File getBaseIndexDir() {
> > > > + File current = new File( "." );
> > > > + File sub = new File( current, "indextemp" );
> > > > + return sub;
> > > > + }
> > > > +
> > > > + protected void tearDown() throws Exception {
> > > > + super.tearDown();
> > > > + File sub = getBaseIndexDir();
> > > > + delete( sub );
> > > > + }
> > > > +
> > > > + private void delete(File sub) {
> > > > + if ( sub.isDirectory() ) {
> > > > + for ( File file : sub.listFiles() ) {
> > > > + delete( file );
> > > > + }
> > > > + sub.delete();
> > > > + }
> > > > + else {
> > > > + sub.delete();
> > > > + }
> > > > + }
> > > > +
> > > > + public void testEventIntegration() throws Exception {
> > > > +
> > > > +
> > > > + Session s = getSessions().openSession();
> > > > + s.getTransaction().begin();
> > > > + s.persist(
> > > > + new Document2( "Hibernate in
> > > Action", "Object/relational mapping with Hibernate", "blah blah
> > > blah" )
> > > > + );
> > > > + s.getTransaction().commit();
> > > > + s.close();
> > > > + IndexReader reader = IndexReader.open( new
> > > File( getBaseIndexDir(), "Documents" ) );
> > > > + try {
> > > > + int num = reader.numDocs();
> > > > + assertEquals( 1, num );
> > > > + TermDocs docs = reader.termDocs( new
> > > Term( "Abstract", "Hibernate" ) );
> > > > + org.apache.lucene.document.Document doc
> > > = reader.document( docs.doc() );
> > > > + assertFalse( docs.next() );
> > > > + docs = reader.termDocs( new Term(
> > > "Title", "Action" ) );
> > > > + doc = reader.document( docs.doc() );
> > > > + assertFalse( docs.next() );
> > > > + assertEquals( "1", doc.getField( "id"
> > ).stringValue() );
> > > > + }
> > > > + finally {
> > > > + reader.close();
> > > > + }
> > > > +
> > > > + s = getSessions().openSession();
> > > > + s.getTransaction().begin();
> > > > + Document2 entity = (Document2) s.get(
> > > Document2.class, new Long( 1 ) );
> > > > + entity.setSummary( "Object/relational mapping
> > > with EJB3" );
> > > > + s.persist( new Document2( "Seam in Action", "",
> > > "blah blah blah blah" ) );
> > > > + s.getTransaction().commit();
> > > > + s.close();
> > > > +
> > > > + reader = IndexReader.open( new File(
> > > getBaseIndexDir(), "Documents" ) );
> > > > + try {
> > > > + int num = reader.numDocs();
> > > > + assertEquals( 2, num );
> > > > + TermDocs docs = reader.termDocs( new
> > > Term( "Abstract", "EJB3" ) );
> > > > + org.apache.lucene.document.Document doc
> > > = reader.document( docs.doc() );
> > > > + assertFalse( docs.next() );
> > > > + }
> > > > + finally {
> > > > + reader.close();
> > > > + }
> > > > +
> > > > + s = getSessions().openSession();
> > > > + s.getTransaction().begin();
> > > > + s.delete( entity );
> > > > + s.getTransaction().commit();
> > > > + s.close();
> > > > +
> > > > + reader = IndexReader.open( new File(
> > > getBaseIndexDir(), "Documents" ) );
> > > > + try {
> > > > + int num = reader.numDocs();
> > > > + assertEquals( 1, num );
> > > > + TermDocs docs = reader.termDocs( new
> > > Term( "Title", "Seam" ) );
> > > > + org.apache.lucene.document.Document doc
> > > = reader.document( docs.doc() );
> > > > + assertFalse( docs.next() );
> > > > + assertEquals( "2", doc.getField( "id"
> > ).stringValue() );
> > > > + }
> > > > + finally {
> > > > + reader.close();
> > > > + }
> > > > +
> > > > + s = getSessions().openSession();
> > > > + s.getTransaction().begin();
> > > > + s.delete( s.createCriteria( Document2.class
> > > ).uniqueResult() );
> > > > + s.getTransaction().commit();
> > > > + s.close();
> > > > + }
> > > > +
> > > > + public void testBoost() throws Exception {
> > > > + Session s = getSessions().openSession();
> > > > + s.getTransaction().begin();
> > > > + s.persist(
> > > > + new Document2( "Hibernate in
> > > Action", "Object and Relational", "blah blah blah" )
> > > > + );
> > > > + s.persist(
> > > > + new Document2( "Object and
> > > Relational", "Hibernate in Action", "blah blah blah" )
> > > > + );
> > > > + s.getTransaction().commit();
> > > > + s.close();
> > > > +
> > > > + IndexSearcher searcher = new IndexSearcher( new
> > > File( getBaseIndexDir(), "Documents" ).getCanonicalPath() );
> > > > + try {
> > > > + QueryParser qp = new QueryParser( "id",
> > > new StandardAnalyzer() );
> > > > + Query query = qp.parse( "title:Action
> > > OR Abstract:Action" );
> > > > + Hits hits = searcher.search( query );
> > > > + assertEquals( 2, hits.length() );
> > > > + assertTrue( hits.score( 0 ) == 2 *
> > > hits.score( 1 ) );
> > > > + assertEquals( "Hibernate in Action",
> > > hits.doc( 0 ).get( "title" ) );
> > > > + }
> > > > + finally {
> > > > + if ( searcher != null ) searcher.close();
> > > > + }
> > > > +
> > > > +
> > > > + s = getSessions().openSession();
> > > > + s.getTransaction().begin();
> > > > + List list = s.createQuery( "from Document2"
> ).list();
> > > > + for ( Document2 document :
> (List<Document2>) list ) {
> > > > + s.delete( document );
> > > > + }
> > > > + s.getTransaction().commit();
> > > > + s.close();
> > > > + }
> > > > +
> > > > + protected Class[] getMappings() {
> > > > + return new Class[]{Document2.class};
> > > > + }
> > > > +
> > > > + protected void
> configure(org.hibernate.cfg.Configuration cfg) {
> > > > + File sub = getBaseIndexDir();
> > > > + cfg.setProperty(
> > > "hibernate.lucene.default.indexBase", sub.getAbsolutePath() );
> > > > + cfg.setProperty(
> > > "hibernate.lucene.Clock.directory_provider",
> > > FSDirectoryProvider.class.getName() );
> > > > + cfg.setProperty( Environment.ANALYZER_CLASS,
> > > StopAnalyzer.class.getName() );
> > > > + LuceneEventListener del = new LuceneEventListener();
> > > > + > > >
cfg.getEventListeners().setPostCommitDeleteEventListeners(
> > > new PostDeleteEventListener[]{del} );
> > > > + > > >
cfg.getEventListeners().setPostCommitUpdateEventListeners(
> > > new PostUpdateEventListener[]{del} );
> > > > + > > >
cfg.getEventListeners().setPostCommitInsertEventListeners(
> > > new PostInsertEventListener[]{del} );
> > > > + }
> > > > +
> > > > +}
> > > > +
> > > > Index:
> > > >
> > >
> C:/dev/source/workspace1.5/HibernateExt/metadata/src/test/org/hibern
> > > at
> > > > e/lucene/test/Document2.java
> > > >
> ==================================================================
> > > > =
> > > > ---
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/test/org/
> > > hibernate/lucene/test/Document2.java (revision 0)
> > > > +++
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/test/org/
> > > hibernate/lucene/test/Document2.java (revision 0)
> > > > @@ -0,0 +1,75 @@
> > > > +//$Id: Document.java 10566 2006-10-11 04:01:11Z epbernard
> > > $ package
> > > > +org.hibernate.lucene.test;
> > > > +
> > > > +import javax.persistence.Entity;
> > > > +import javax.persistence.GeneratedValue; import
> > > javax.persistence.Id;
> > > > +import javax.persistence.Lob;
> > > > +
> > > > +import org.hibernate.lucene.Indexed; import
> > > > +org.hibernate.lucene.Keyword; import
> org.hibernate.lucene.Text;
> > > > +import org.hibernate.lucene.Unstored; import
> > > > +org.hibernate.lucene.Boost;
> > > > +
> > > > [EMAIL PROTECTED]
> > > > [EMAIL PROTECTED](index = "Documents")
> > > > +public class Document2 {
> > > > + @Id
> > > > + @GeneratedValue
> > > > + @Keyword(id = true)
> > > > + private Long id;
> > > > +
> > > > + @Text
> > > > + @Boost(2)
> > > > + private String title;
> > > > + > > > > + @Unstored(name = "Abstract")
> > > > + private String summary;
> > > > +
> > > > + @Lob
> > > > + @Unstored
> > > > + private String text;
> > > > +
> > > > + Document2() {
> > > > + }
> > > > +
> > > > + public Document2(String title, String summary,
> String text) {
> > > > + super();
> > > > + this.summary = summary;
> > > > + this.text = text;
> > > > + this.title = title;
> > > > + }
> > > > +
> > > > + public Long getId() {
> > > > + return id;
> > > > + }
> > > > +
> > > > + public void setId(Long id) {
> > > > + this.id = id;
> > > > + }
> > > > +
> > > > + public String getTitle() {
> > > > + return title;
> > > > + }
> > > > +
> > > > + public void setTitle(String title) {
> > > > + this.title = title;
> > > > + }
> > > > +
> > > > + public String getSummary() {
> > > > + return summary;
> > > > + }
> > > > +
> > > > + public void setSummary(String summary) {
> > > > + this.summary = summary;
> > > > + }
> > > > +
> > > > + public String getText() {
> > > > + return text;
> > > > + }
> > > > +
> > > > + public void setText(String text) {
> > > > + this.text = text;
> > > > + }
> > > > +}
> > > > Index:
> > > >
> > >
> C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/hibern
> > > at
> > > > e/lucene/event/LuceneEventListener.java
> > > >
> ==================================================================
> > > > =
> > > > ---
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/
> > > hibernate/lucene/event/LuceneEventListener.java > (revision
10571)
> > > > +++
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/
> > > hibernate/lucene/event/LuceneEventListener.java > (working
copy)
> > > > @@ -99,13 +99,10 @@
> > > > PersistentClass clazz = (PersistentClass)
> iter.next();
> > > > Class<?> mappedClass = clazz.getMappedClass();
> > > > if (mappedClass != null) {
> > > > - if
> > > (mappedClass.isAnnotationPresent(Indexed.class)) {
> > > > - DirectoryProvider provider =
> > > factory.createDirectoryProvider(mappedClass, cfg);
> > > > - final DocumentBuilder<Object>
> > > documentBuilder = new DocumentBuilder<Object>(
> > > > - (Class<Object>) mappedClass,
> > > analyzer, provider
> > > > - );
> > > > - if (!indexLock.containsKey(provider)) {
> > > > - indexLock.put(provider, new
> > > ReentrantLock());
> > > > + final DocumentBuilder documentBuilder =
> > > DocumentBuilder.createDocumentBuilder(mappedClass, analyzer,
> > > factory, cfg);
> > > > + if(documentBuilder!=null) {
> > > > + if
> > > (!indexLock.containsKey(documentBuilder.getDirectoryProvider())) {
> > > > + > > > >
+ indexLock.put(documentBuilder.getDirectoryProvider(), new
> > > > + ReentrantLock());
> > > > }
> > > > documentBuilders.put(mappedClass,
> > > documentBuilder);
> > > > }
> > > > Index:
> > > >
> > >
> C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/hibern
> > > at
> > > > e/lucene/Unstored.java
> > > >
> ==================================================================
> > > > =
> > > > ---
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/
> > > hibernate/lucene/Unstored.java (revision 10571)
> > > > +++
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/
> > > hibernate/lucene/Unstored.java (working copy)
> > > > @@ -8,7 +8,7 @@
> > > > import java.lang.annotation.Target;
> > > >
> > > > @Retention(RetentionPolicy.RUNTIME)
> > > > [EMAIL PROTECTED](ElementType.METHOD)
> > > > [EMAIL PROTECTED]({ElementType.METHOD, ElementType.FIELD})
> > > > @Documented
> > > > /**
> > > > * Specifies that a property of an entity is a Lucene
> > > > Index:
> > > >
> > >
> C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/hibern
> > > at
> > > > e/lucene/Keyword.java
> > > >
> ==================================================================
> > > > =
> > > > ---
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/
> > > hibernate/lucene/Keyword.java (revision 10571)
> > > > +++
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/
> > > hibernate/lucene/Keyword.java (working copy)
> > > > @@ -8,7 +8,7 @@
> > > > import java.lang.annotation.Target;
> > > >
> > > > @Retention(RetentionPolicy.RUNTIME)
> > > > [EMAIL PROTECTED](ElementType.METHOD)
> > > > [EMAIL PROTECTED]({ElementType.METHOD, ElementType.FIELD})
> > > > @Documented
> > > > /**
> > > > * Specifies that a property of an entity is a Lucene
> > > > Index:
> > > >
> > >
> C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/hibern
> > > at
> > > > e/lucene/Text.java
> > > >
> ==================================================================
> > > > =
> > > > ---
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/
> > > hibernate/lucene/Text.java (revision 10571)
> > > > +++
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/
> > > hibernate/lucene/Text.java (working copy)
> > > > @@ -8,7 +8,7 @@
> > > > import java.lang.annotation.Target;
> > > >
> > > > @Retention(RetentionPolicy.RUNTIME)
> > > > [EMAIL PROTECTED](ElementType.METHOD)
> > > > [EMAIL PROTECTED]({ElementType.METHOD, ElementType.FIELD})
> > > > @Documented
> > > > /**
> > > > * Specifies that a property of an entity is a Lucene
> > > > Index:
> > > >
> > >
> C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/hibern
> > > at
> > > > e/lucene/DocumentBuilder.java
> > > >
> ==================================================================
> > > > =
> > > > ---
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/
> > > hibernate/lucene/DocumentBuilder.java (revision 10571)
> > > > +++
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/
> > > hibernate/lucene/DocumentBuilder.java (working copy)
> > > > @@ -2,10 +2,6 @@
> > > > package org.hibernate.lucene;
> > > >
> > > > import java.io.Serializable;
> > > > -import java.lang.reflect.AccessibleObject;
> > > > -import java.lang.reflect.AnnotatedElement;
> > > > -import java.lang.reflect.Member;
> > > > -import java.lang.reflect.Method;
> > > > import java.lang.reflect.Modifier; import
> java.util.ArrayList; > > > > import java.util.Collections; @@ -17,31
+13,46 @@ import
> > > > org.apache.lucene.document.Document;
> > > > import org.apache.lucene.document.Field; import
> > > > org.apache.lucene.index.Term; -import
> > > org.hibernate.AssertionFailure;
> > > > import org.hibernate.HibernateException;
> > > > +import org.hibernate.cfg.Configuration;
> > > > import org.hibernate.cfg.annotations.Version;
> > > > import org.hibernate.lucene.bridge.BridgeFactory;
> > > > import org.hibernate.lucene.bridge.FieldBridge;
> > > > import org.hibernate.lucene.event.LuceneEventListener;
> > > > import org.hibernate.lucene.store.DirectoryProvider;
> > > > +import org.hibernate.lucene.store.DirectoryProviderFactory;
> > > > import org.hibernate.lucene.util.BinderHelper;
> > > > +import org.hibernate.reflection.ReflectionManager;
> > > > +import org.hibernate.reflection.XAnnotatedElement;
> > > > +import org.hibernate.reflection.XClass; import
> > > > +org.hibernate.reflection.XMember;
> > > > +import org.hibernate.reflection.XMethod; import
> > > > +org.hibernate.reflection.XProperty;
> > > > +import org.hibernate.reflection.java.JavaXFactory;
> > > > import org.hibernate.util.ReflectHelper;
> > > >
> > > > -//TODO handle attribute (only getters are handled currently)
> > > > +/**
> > > > + * Set up and provide a manager for indexes classes
> > > > + *
> > > > + * @author Gavin King
> > > > + * @author Emmanuel Bernard
> > > > + * @author Sylvain Vieujot
> > > > + */
> > > > public class DocumentBuilder<T> {
> > > >
> > > > static {
> > > > Version.touch(); //touch version
> > > > }
> > > >
> > > > - private final List<Member> keywordGetters = new
> > > ArrayList<Member>();
> > > > + private final List<XMember> keywordGetters = new
> > > > + ArrayList<XMember>();
> > > > private final List<String> keywordNames = new
> > > ArrayList<String>();
> > > > - private final List<Member> unstoredGetters = new
> > > ArrayList<Member>();
> > > > + private final List<XMember> unstoredGetters = new
> > > > + ArrayList<XMember>();
> > > > private final List<String> unstoredNames = new
> > > ArrayList<String>();
> > > > - private final List<Member> textGetters = new
> > > ArrayList<Member>();
> > > > + private final List<XMember> textGetters = new
> > > > + ArrayList<XMember>();
> > > > private final List<String> textNames = new
> > > > ArrayList<String>();
> > > >
> > > > private final Class<T> beanClass;
> > > > + > > > > private final DirectoryProvider
directoryProvider;
> > > > private String idKeywordName;
> > > > private final Analyzer analyzer; @@ -50,40 +61,30 @@
> > > > private FieldBridge idBridge;
> > > > private Set<Class> mappedSubclasses = new HashSet<Class>();
> > > >
> > > > - public DocumentBuilder(Class<T> clazz, Analyzer
> > > analyzer, DirectoryProvider directory) {
> > > > - this.beanClass = clazz;
> > > > + private ReflectionManager reflectionManager = new
> > > JavaXFactory();
> > > > +
> > > > + private DocumentBuilder(Class<T> clazz, Analyzer analyzer,
> > > > +DirectoryProvider directory) {
> > > > +
> > > > + XClass beanXClass =
> reflectionManager.toXClass( clazz );
> > > > + if( !beanXClass.isAnnotationPresent(Indexed.class))
> > > > + throw new IllegalArgumentException();
> > > > + > > > > + this.beanClass = clazz;
> > > > this.analyzer = analyzer;
> > > > this.directoryProvider = directory;
> > > >
> > > > - for (Class currClass = clazz; currClass != null;
> > > currClass = currClass.getSuperclass()) {
> > > > - Method[] methods = currClass.getDeclaredMethods();
> > > > - for (int i = 0; i < methods.length; i++) {
> > > > - Method method = methods[i];
> > > > - Keyword keywordAnn =
> > > method.getAnnotation(Keyword.class);
> > > > - if (keywordAnn != null) {
> > > > - String name =
> > > BinderHelper.getAttributeName(method, keywordAnn.name());
> > > > - if (keywordAnn.id()) {
> > > > - idKeywordName = name;
> > > > - idBoost = getBoost(method);
> > > > - idBridge =
> BridgeFactory.guessType(method);
> > > > - } else {
> > > > - setAccessible(method);
> > > > - keywordGetters.add(method);
> > > > - keywordNames.add(name);
> > > > - }
> > > > - }
> > > > - Unstored unstoredAnn =
> > > method.getAnnotation(Unstored.class);
> > > > - if (unstoredAnn != null) {
> > > > - setAccessible(method);
> > > > - unstoredGetters.add(method);
> > > > - > > >
unstoredNames.add(BinderHelper.getAttributeName(method,
> > > unstoredAnn.name()));
> > > > - }
> > > > - Text textAnn =
> method.getAnnotation(Text.class);
> > > > - if (textAnn != null) {
> > > > - textGetters.add(method);
> > > > - > > >
textNames.add(BinderHelper.getAttributeName(method,
> > > textAnn.name()));
> > > > - }
> > > > - }
> > > > +
> > > > + for (XClass currClass = beanXClass; currClass !=
> > > null; currClass = currClass.getSuperclass()) {
> > > > + List<XMethod> methods =
> > > currClass.getDeclaredMethods();
> > > > + for ( XMethod method : methods ) {
> > > > + >
createMemberLuceneAttribute( method );
> > > > + }
> > > > +
> > > > + // No filter applied = default filter (
> > > no transient, no static fields)
> > > > + List<XProperty> fields =
> > > currClass.getDeclaredProperties("field");
> > > > + for ( XProperty field : fields ) {
> > > > + > createMemberLuceneAttribute( field
);
> > > > + }
> > > > }
> > > >
> > > > if (idKeywordName == null) { @@ -91,42 +92,84 @@
> > > > }
> > > > }
> > > >
> > > > + public static <S> DocumentBuilder<S>
> > > createDocumentBuilder(Class<S> clazz, Analyzer analyzer,
> > > DirectoryProviderFactory factory, Configuration cfg)
> > > > + {
> > > > + DocumentBuilder<S> result = null;
> > > > + > > > > + try {
> > > > + result = new DocumentBuilder<S>(clazz,
> > > analyzer, factory.createDirectoryProvider(clazz, cfg));
> > > > + }
> > > > + catch (Exception e) {
> > > > + }
> > > > + > > > > + return result;
> > > > + } > > > >
> > > > - private Float getBoost(AnnotatedElement element) {
> > > > + private void createMemberLuceneAttribute(XMember member) {
> > > > + Keyword keywordAnn =
> > > member.getAnnotation(Keyword.class);
> > > > + if (keywordAnn != null) {
> > > > + String name =
> > > BinderHelper.getAttributeName(member, keywordAnn.name());
> > > > + if (keywordAnn.id()) {
> > > > + idKeywordName = name;
> > > > + idBoost = getBoost(member);
> > > > + idBridge = BridgeFactory.guessType(member);
> > > > + } else {
> > > > + setAccessible(member);
> > > > + keywordGetters.add(member);
> > > > + keywordNames.add(name);
> > > > + }
> > > > + }
> > > > +
> > > > + Unstored unstoredAnn =
> > > member.getAnnotation(Unstored.class);
> > > > + if (unstoredAnn != null) {
> > > > + setAccessible(member);
> > > > + unstoredGetters.add(member);
> > > > + > > >
unstoredNames.add(BinderHelper.getAttributeName(member,
> > > unstoredAnn.name()));
> > > > + }
> > > > +
> > > > + Text textAnn = member.getAnnotation(Text.class);
> > > > + if (textAnn != null) {
> > > > + setAccessible(member);
> > > > + textGetters.add(member);
> > > > + > > >
textNames.add(BinderHelper.getAttributeName(member,
> > > textAnn.name()));
> > > > + }
> > > > + }
> > > > +
> > > > + private Float getBoost(XAnnotatedElement element) {
> > > > if (element == null) return null;
> > > > Boost boost = element.getAnnotation(Boost.class);
> > > > return boost != null ?
> Float.valueOf(boost.value()) : null;
> > > > }
> > > >
> > > > - private Object getValue(Member member, T bean) {
> > > > - try {
> > > > - if (member instanceof java.lang.reflect.Field) {
> > > > - return ((java.lang.reflect.Field)
> > > member).get(bean);
> > > > - } else if (member instanceof Method) {
> > > > - return ((Method) member).invoke(bean);
> > > > - } else {
> > > > - throw new AssertionFailure("Unexpected
> > > member: " + member.getClass().getName());
> > > > - }
> > > > - }
> > > > - catch (Exception e) {
> > > > - throw new IllegalStateException("Could not get
> > > property value", e);
> > > > - }
> > > > + private Object getMemberValue(XMember member, T bean) {
> > > > + Object value;
> > > > + try {
> > > > + value = member.invoke( bean );
> > > > + }
> > > > + catch (Exception e) {
> > > > + throw new IllegalStateException( "Could
> > > not get property value", e );
> > > > + }
> > > > + return value;
> > > > }
> > > >
> > > > public Document getDocument(T instance, Serializable id) {
> > > > + XClass xClazz =
> > > reflectionManager.toXClass(instance.getClass());
> > > > + > > > > Document doc = new Document();
> > > > - Float boost = getBoost(instance.getClass());
> > > > + Float boost = getBoost(xClazz);
> > > > if (boost != null) {
> > > > doc.setBoost(boost.floatValue());
> > > > }
> > > > +
> > > > {
> > > > - Field classField = new Field(CLASS_FIELDNAME,
> > > instance.getClass().getName(), Field.Store.YES, Field.Index.NO);
> > > > + Field classField = new Field(CLASS_FIELDNAME,
> > > > + xClazz.getName(), Field.Store.YES, Field.Index.NO);
> > > > doc.add(classField);
> > > > idBridge.set(idKeywordName, id, doc,
> > > Field.Store.YES, Field.Index.UN_TOKENIZED, idBoost);
> > > > }
> > > > + > > > > for (int i = 0; i <
keywordNames.size(); i++) {
> > > > - Member member = keywordGetters.get(i);
> > > > - Object value = getValue(member, instance);
> > > > + XMember member = keywordGetters.get(i);
> > > > + Object value = getMemberValue(member, instance);
> > > > if (value != null) {
> > > > Field field = new
> > > Field(keywordNames.get(i), toString(value), Field.Store.YES,
> > > Field.Index.UN_TOKENIZED);
> > > > boostField(field, member); @@ -134,8 +177,8 @@
> > > > }
> > > > }
> > > > for (int i = 0; i < textNames.size(); i++) {
> > > > - Member member = textGetters.get(i);
> > > > - Object value = getValue(member, instance);
> > > > + XMember member = textGetters.get(i);
> > > > + Object value = getMemberValue(member, instance);
> > > > if (value != null) {
> > > > Field field = new Field(textNames.get(i),
> > > toString(value), Field.Store.YES, Field.Index.TOKENIZED);
> > > > boostField(field, member); @@ -143,8 +186,8 @@
> > > > }
> > > > }
> > > > for (int i = 0; i < unstoredNames.size(); i++) {
> > > > - Member member = unstoredGetters.get(i);
> > > > - Object value = getValue(member, instance);
> > > > + XMember member = unstoredGetters.get(i);
> > > > + Object value = getMemberValue(member, instance);
> > > > if (value != null) {
> > > > Field field = new
> > > Field(unstoredNames.get(i), toString(value), Field.Store.NO,
> > > Field.Index.TOKENIZED);
> > > > boostField(field, member); @@ -155,8 +198,8 @@
> > > > return doc;
> > > > }
> > > >
> > > > - private void boostField(Field field, Member member) {
> > > > - Float boost = getBoost((AnnotatedElement) member);
> > > > + private void boostField(Field field, XMember member) {
> > > > + Float boost = getBoost(member);
> > > > if (boost != null) field.setBoost(boost.floatValue());
> > > > }
> > > >
> > > > @@ -176,11 +219,11 @@
> > > > return analyzer;
> > > > }
> > > >
> > > > - private static void setAccessible(Member member) {
> > > > - if (!Modifier.isPublic(member.getModifiers())) {
> > > > - ((AccessibleObject) member).setAccessible(true);
> > > > - }
> > > > - }
> > > > + private static void setAccessible(XMember member) {
> > > > + if ( !Modifier.isPublic( member.getModifiers() ) ) {
> > > > + member.setAccessible( true );
> > > > + }
> > > > + }
> > > >
> > > > public FieldBridge getIdBridge() {
> > > > return idBridge;
> > > > Index:
> > > >
> > >
> C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/hibern
> > > at
> > > > e/lucene/Boost.java
> > > >
> ==================================================================
> > > > =
> > > > ---
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/
> > > hibernate/lucene/Boost.java (revision 10571)
> > > > +++
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/
> > > hibernate/lucene/Boost.java (working copy)
> > > > @@ -13,7 +13,7 @@
> > > > * @author Emmanuel Bernard
> > > > */
> > > > @Retention(RetentionPolicy.RUNTIME)
> > > > [EMAIL PROTECTED]({ElementType.TYPE, ElementType.METHOD})
> > > > [EMAIL PROTECTED]({ElementType.TYPE, ElementType.METHOD,
> > > > +ElementType.FIELD})
> > > > @Documented
> > > > public @interface Boost {
> > > > float value();
> > > > Index:
> > > >
> > >
> C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/hibern
> > > at
> > > > e/lucene/bridge/BridgeFactory.java
> > > >
> ==================================================================
> > > > =
> > > > ---
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/
> > > hibernate/lucene/bridge/BridgeFactory.java (revision 10571)
> > > > +++
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/
> > > hibernate/lucene/bridge/BridgeFactory.java (working copy)
> > > > @@ -1,8 +1,6 @@
> > > > //$Id: $
> > > > package org.hibernate.lucene.bridge;
> > > >
> > > > -import java.lang.reflect.AnnotatedElement;
> > > > -import java.lang.reflect.Member;
> > > > import java.util.Date;
> > > > import java.util.HashMap;
> > > > import java.util.Map;
> > > > @@ -10,6 +8,8 @@
> > > > import org.hibernate.HibernateException; import
> > > > org.hibernate.annotations.Parameter;
> > > > import org.hibernate.lucene.util.BinderHelper;
> > > > +import org.hibernate.reflection.XClass; import
> > > > +org.hibernate.reflection.XMember;
> > > >
> > > > /**
> > > > * @author Emmanuel Bernard
> > > > @@ -62,9 +62,9 @@
> > > > return new String2FieldBridgeAdaptor( date );
> > > > }
> > > >
> > > > - public static FieldBridge guessType(Member member) {
> > > > + public static FieldBridge guessType(XMember member) {
> > > > FieldBridge bridge = null;
> > > > - org.hibernate.lucene.FieldBridge bridgeAnn = (
> > > (AnnotatedElement) member ).getAnnotation(
> > > org.hibernate.lucene.FieldBridge.class );
> > > > + org.hibernate.lucene.FieldBridge bridgeAnn =
> > > member.getAnnotation(
> > > > +org.hibernate.lucene.FieldBridge.class );
> > > > if (bridgeAnn != null) {
> > > > Class impl = bridgeAnn.impl();
> > > > try {
> > > > @@ -89,7 +89,7 @@
> > > > }
> > > > else {
> > > > //find in built-ins
> > > > - Class<?> returnType =
> > > BinderHelper.getReturnType( member );
> > > > + XClass returnType =
> > > BinderHelper.getReturnType( member );
> > > > bridge = builtInBridges.get(
> > > returnType.getName() );
> > > > }
> > > > if (bridge == null) throw new
> > > HibernateException("Unable to guess
> > > > FieldBridge for " + BinderHelper.getAttributeName(member) );
> > > > Index:
> > > >
> > >
> C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/hibern
> > > at
> > > > e/lucene/util/BinderHelper.java
> > > >
> ==================================================================
> > > > =
> > > > ---
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/
> > > hibernate/lucene/util/BinderHelper.java (revision 10571)
> > > > +++
> > > C:/dev/source/workspace1.5/HibernateExt/metadata/src/java/org/
> > > hibernate/lucene/util/BinderHelper.java (working copy)
> > > > @@ -1,11 +1,13 @@
> > > > //$Id: $
> > > > package org.hibernate.lucene.util;
> > > >
> > > > -import java.lang.reflect.Method;
> > > > -import java.lang.reflect.Member;
> > > > -import java.lang.reflect.Field;
> > > > import java.beans.Introspector;
> > > >
> > > > +import org.hibernate.AssertionFailure; import
> > > > +org.hibernate.reflection.XClass; import
> > > > +org.hibernate.reflection.XMember;
> > > > +import org.hibernate.reflection.XMethod; import
> > > > +org.hibernate.reflection.XProperty;
> > > > import org.hibernate.util.StringHelper;
> > > >
> > > > /**
> > > > @@ -15,37 +17,41 @@
> > > >
> > > > private BinderHelper() {}
> > > >
> > > > - public static String getAttributeName(Member member) {
> > > > + public static String getAttributeName(XMember member) {
> > > > return getAttributeName( member, null );
> > > > }
> > > > /**
> > > > * Get attribute name out of member unless overriden by
> > > <code>name</code>
> > > > */
> > > > - //TODO move to reflection layer
> > > > - public static String getAttributeName(Member member,
> > > String name) {
> > > > - if( StringHelper.isNotEmpty( name ) ) return
> > > name; //explicit field name
> > > > - if (member instanceof Field ) {
> > > > - return ( (Field) member ).getName();
> > > > + public static String getAttributeName(XMember member,
> > > String name) {
> > > > + return StringHelper.isNotEmpty( name ) ? name :
> > > getPropertyName(member);
> > > > + }
> > > > +
> > > > + public static XClass getReturnType(XMember member) {
> > > > + return member.getType();
> > > > + }
> > > > + > > > > + // Could be located in a better place, shared
method
> > > with ClassValidator
> > > > + public static String getPropertyName(XMember member) {
> > > > + //Do no try to cache the result in a map, it's
> > > actually much slower (2.x time)
> > > > + String propertyName;
> > > > + if ( XProperty.class.isAssignableFrom(
> > > member.getClass() ) ) {
> > > > + propertyName = member.getName();
> > > > }
> > > > - else {
> > > > - //decapitalize
> > > > - String methodName = ( (Method)
> > > member).getName();
> > > > - //FIXME we probably should exclude
> > > methods not starting with "get" nor "is"
> > > > - int startIndex = 3;
> > > > - if( methodName.startsWith("is") ) {
> > > > - startIndex = 2;
> > > > + else if ( XMethod.class.isAssignableFrom(
> > > member.getClass() ) ) {
> > > > + propertyName = member.getName();
> > > > + if ( propertyName.startsWith( "is" ) ) {
> > > > + propertyName =
> > > Introspector.decapitalize( propertyName.substring(
> > > > +2 ) );
> > > > }
> > > > - return Introspector.decapitalize(
> > > methodName.substring( startIndex ) );
> > > > + else if ( propertyName.startsWith(
> "get" ) ) {
> > > > + propertyName =
> > > Introspector.decapitalize( propertyName.substring( 3 ) );
> > > > + }
> > > > + //do nothing for non getter method, in
> > > case someone want to
> > > > +validate a PO Method
> > > > }
> > > > - }
> > > > -
> > > > - //TODO move to reflection layer
> > > > - public static Class<?> getReturnType(Member member) {
> > > > - if (member instanceof Field) {
> > > > - return ( (Field) member ).getType();
> > > > - }
> > > > else {
> > > > - return ( (Method) member ).getReturnType();
> > > > + throw new AssertionFailure( "Unexpected
> > > member: " +
> > > > +member.getClass().getName() );
> > > > }
> > > > + return propertyName;
> > > > }
> > > > +
> > > > }
> > > > > > >
> >
>