Minor problems discovered whilst refactoring CATE:
authorben.clark <ben.clark@localhost>
Thu, 12 Mar 2009 16:59:28 +0000 (16:59 +0000)
committerben.clark <ben.clark@localhost>
Thu, 12 Mar 2009 16:59:28 +0000 (16:59 +0000)
Corrections to User / Group / Authority impl
Changes due to upgrade of hibernate-search

.gitattributes
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/ISearchableDao.java [new file with mode: 0644]
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/ITermVocabularyDao.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/description/IDescriptionElementDao.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/AlternativeSpellingSuggestionParser.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/common/GroupDaoImpl.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/common/TermVocabularyDaoImpl.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/description/DescriptionElementDaoImpl.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonAlternativeSpellingSuggestionParser.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImpl.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/taxon/ITaxonDao.java

index f99f7205a367ed46bdd4fba72385bed1775d9647..099a301895ef1ec478672a9dae57163ecdd03bf8 100644 (file)
@@ -1216,6 +1216,7 @@ cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/IOrdere
 cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/IOriginalSourceDao.java -text
 cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/IReferencedEntityDao.java -text
 cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/IRepresentationDao.java -text
+cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/ISearchableDao.java -text
 cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/ITermVocabularyDao.java -text
 cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/ITitledDao.java -text
 cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/IUserDao.java -text
diff --git a/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/ISearchableDao.java b/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/ISearchableDao.java
new file mode 100644 (file)
index 0000000..304fc57
--- /dev/null
@@ -0,0 +1,54 @@
+package eu.etaxonomy.cdm.persistence.dao.common;\r
+\r
+import java.util.List;\r
+\r
+import eu.etaxonomy.cdm.model.common.CdmBase;\r
+\r
+public interface ISearchableDao<T extends CdmBase> {\r
+       \r
+       /**\r
+        * Returns a count of T instances where the default field matches the String queryString (as interpreted by the Lucene QueryParser)\r
+        * \r
+        * @param queryString\r
+        * @return a count of the matching entities\r
+        * @see <a href="http://lucene.apache.org/java/2_4_0/queryparsersyntax.html">Apache Lucene - Query Parser Syntax</a>\r
+        */\r
+       public int count(String queryString);\r
+       \r
+       /**\r
+        * Returns a List of T instances where the default field matches the String queryString (as interpreted by the Lucene QueryParser)\r
+        * \r
+        * @param queryString\r
+        * @param pageSize The maximum number of entities returned (can be null for all matching entities)\r
+        * @param pageNumber The offset (in pageSize chunks) from the start of the result set (0 - based)\r
+        * @return a List T instances\r
+        * @see <a href="http://lucene.apache.org/java/2_4_0/queryparsersyntax.html">Apache Lucene - Query Parser Syntax</a>\r
+        */\r
+       public List<T> search(String queryString, Integer pageSize, Integer pageNumber);\r
+       \r
+       /**\r
+        * Suggest a query that will return hits based upon an existing lucene query string (that is presumably misspelt and returns no hits)\r
+        * Used to implement "did you mean?"-type functionality using the lucene spellchecker.\r
+        * \r
+        * @param string Query string to check\r
+        * @return a suggested query string that will return hits or null if no such alternative spelling can be found.\r
+        */\r
+       public String suggestQuery(String string);\r
+       \r
+       /**\r
+        * Removes all TaxonBase entities from the index\r
+        */\r
+       public void purgeIndex();\r
+\r
+       /**\r
+        * Index all T entities currently in the database (useful in concert with purgeIndex() to (re-)create\r
+        * indexes or in the  case of corrupt indexes / mismatch between \r
+        * the database and the free-text indices) \r
+        */\r
+       public void rebuildIndex();\r
+       \r
+       /**\r
+        * Calls optimize on the relevant index (useful periodically to increase response times on the free-text search)\r
+        */\r
+       public void optimizeIndex();\r
+}\r
index 1af741c8d354163d0298d5292a1ee2d64eda056f..2ef1e094206f814127543ed2e2cabbb319be0497 100644 (file)
@@ -39,4 +39,6 @@ public interface ITermVocabularyDao extends IVersionableDao<TermVocabulary<Defin
         * @return a List of terms\r
         */\r
        public <T extends DefinedTermBase> List<T> getTerms(TermVocabulary<T> termVocabulary, Integer pageSize, Integer pageNumber);\r
+       \r
+       public <T extends DefinedTermBase> TermVocabulary<T> findByUri(String termSourceUri, Class<T> clazz);\r
 }\r
index 139742d86f6eb5dd5ac995d73a393178b0a7d3e3..64ccc72ce0e67fc4eca2caab98da0302c3de32f1 100644 (file)
@@ -6,8 +6,9 @@ import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
 import eu.etaxonomy.cdm.model.description.TextData;
 import eu.etaxonomy.cdm.model.media.Media;
 import eu.etaxonomy.cdm.persistence.dao.common.IAnnotatableDao;
+import eu.etaxonomy.cdm.persistence.dao.common.ISearchableDao;
 
-public interface IDescriptionElementDao extends IAnnotatableDao<DescriptionElementBase> {
+public interface IDescriptionElementDao extends IAnnotatableDao<DescriptionElementBase>,ISearchableDao<DescriptionElementBase> {
        /**
         * This query is designed to search the the descriptions. 
         * This is complicated somewhat by the 1 ... n relation between
@@ -62,21 +63,4 @@ public interface IDescriptionElementDao extends IAnnotatableDao<DescriptionEleme
      * @return a count of media instances
      */
        public int countMedia(DescriptionElementBase descriptionElement);
-       
-       /**
-        * Removes all DescriptionElementBase entities from the index
-        */
-       public void purgeIndex();
-
-       /**
-        * Index all DescriptionElementBase entities currenly in the database (useful in concert with purgeIndex() to (re-)create
-        * indexes or in the  case of corrupt indexes / mismatch between 
-        * the database and the free-text indices) 
-        */
-       public void rebuildIndex();
-       
-       /**
-        * Calls optimize on the relevant index (useful periodically to increase response times on the free-text search)
-        */
-       public void optimizeIndex();
 }
index 3118299343998156884587c0c01a88eba0e2c5e7..f482fdc09b5213d967da2f4a409223633ddd3173 100644 (file)
@@ -41,35 +41,35 @@ import org.hibernate.search.reader.ReaderProvider;
 import org.hibernate.search.store.DirectoryProvider;\r
 import org.springframework.beans.factory.annotation.Autowired;\r
 import org.springframework.orm.hibernate3.support.HibernateDaoSupport;\r
-import org.springmodules.lucene.index.factory.IndexFactory;\r
-import org.springmodules.lucene.index.factory.LuceneIndexWriter;\r
 \r
 import eu.etaxonomy.cdm.model.common.CdmBase;\r
 import eu.etaxonomy.cdm.persistence.dao.IAlternativeSpellingSuggestionParser;\r
 \r
 \r
 public abstract class AlternativeSpellingSuggestionParser<T extends CdmBase> extends HibernateDaoSupport  implements\r
-               IAlternativeSpellingSuggestionParser {\r
+IAlternativeSpellingSuggestionParser {\r
        private static Log log = LogFactory.getLog(AlternativeSpellingSuggestionParser.class);\r
-       \r
+\r
        private String defaultField;\r
-       protected IndexFactory indexFactory;\r
        protected Directory directory;\r
        private Class<T> type;\r
-       \r
+       private Class<? extends T> indexedClasses[];\r
+\r
        public AlternativeSpellingSuggestionParser(Class<T> type) {\r
                this.type = type;\r
        }\r
-       \r
+\r
+       public void setIndexedClasses(Class<? extends T> indexedClasses[]) {\r
+               this.indexedClasses = indexedClasses;\r
+       }\r
+\r
        public abstract void setDirectory(Directory directory);\r
-       \r
-       public abstract void setIndexFactory(IndexFactory indexFactory);\r
-       \r
+\r
        @Autowired\r
        public void setHibernateSessionFactory(SessionFactory sessionFactory) {\r
                super.setSessionFactory(sessionFactory);\r
        }\r
-       \r
+\r
        public void setDefaultField(String defaultField) {\r
                this.defaultField = defaultField;\r
        }\r
@@ -84,7 +84,7 @@ public abstract class AlternativeSpellingSuggestionParser<T extends CdmBase> ext
                Query query = querySuggester.parse(queryString);\r
                return querySuggester.hasSuggestedQuery() ? query : null;\r
        }\r
-       \r
+\r
        private class QuerySuggester extends QueryParser {\r
                private boolean suggestedQuery = false;\r
                public QuerySuggester(String field, Analyzer analyzer) {\r
@@ -94,7 +94,7 @@ public abstract class AlternativeSpellingSuggestionParser<T extends CdmBase> ext
                        // Copied from org.apache.lucene.queryParser.QueryParser\r
                        // replacing construction of TermQuery with call to getTermQuery()\r
                        // which finds close matches.\r
-                   TokenStream source = getAnalyzer().tokenStream(field, new StringReader(queryText));\r
+                       TokenStream source = getAnalyzer().tokenStream(field, new StringReader(queryText));\r
                        Vector v = new Vector();\r
                        Token t;\r
 \r
@@ -127,9 +127,9 @@ public abstract class AlternativeSpellingSuggestionParser<T extends CdmBase> ext
                                return q;\r
                        }\r
                }\r
-               \r
+\r
                private Term getTerm(String field, String queryText) throws ParseException {\r
-                                               \r
+\r
                        try {\r
                                SpellChecker spellChecker = new SpellChecker(directory);\r
                                if (spellChecker.exist(queryText)) {\r
@@ -149,45 +149,41 @@ public abstract class AlternativeSpellingSuggestionParser<T extends CdmBase> ext
                        return suggestedQuery;\r
                }       \r
        }\r
-       \r
+\r
        public void refresh() {\r
-               \r
-               FullTextSession fullTextSession = Search.createFullTextSession(getSession());\r
+               FullTextSession fullTextSession = Search.getFullTextSession(getSession());\r
                SearchFactory searchFactory = fullTextSession.getSearchFactory();\r
-        DirectoryProvider directoryProvider = searchFactory.getDirectoryProviders(type)[0];\r
-        \r
-        ReaderProvider readerProvider = searchFactory.getReaderProvider();\r
-        \r
-               IndexReader indexReader = null;\r
-               LuceneIndexWriter indexWriter = null;\r
                try {\r
-                       try {\r
-                               indexWriter = indexFactory.getIndexWriter();\r
-                               indexReader = readerProvider.openReader(directoryProvider);\r
-\r
-                               log.debug("Creating new dictionary for words in " + defaultField + " docs " + indexReader.numDocs());\r
-                               Dictionary dictionary = new LuceneDictionary(indexReader, defaultField);\r
-                               \r
-                               if(log.isDebugEnabled()) {\r
-                                   Iterator iterator = dictionary.getWordsIterator();\r
-                                   while(iterator.hasNext()) {\r
-                                           log.debug("Indexing word " + iterator.next());\r
-                                   }\r
-                               }\r
-                               \r
-                   SpellChecker spellChecker = new SpellChecker(directory);\r
-                   spellChecker.indexDictionary(dictionary);\r
-                       } catch (CorruptIndexException cie) {\r
-                               log.error("Spellings index is corrupted", cie);\r
-                       } finally {\r
-                               if (indexReader != null) {\r
-                                       readerProvider.closeReader(indexReader);\r
-                               }\r
-                               if(indexWriter != null) {\r
-                    indexWriter.close();\r
-                }\r
+                       SpellChecker spellChecker = new SpellChecker(directory);\r
+\r
+                       for(Class<? extends T> indexedClass : indexedClasses) {\r
+                               DirectoryProvider directoryProvider = searchFactory.getDirectoryProviders(indexedClass)[0];\r
+                               ReaderProvider readerProvider = searchFactory.getReaderProvider();\r
+                               IndexReader indexReader = null;\r
+\r
+                               try {\r
+\r
+                                       indexReader = readerProvider.openReader(directoryProvider);\r
+                                       log.debug("Creating new dictionary for words in " + defaultField + " docs " + indexReader.numDocs());\r
+\r
+                                       Dictionary dictionary = new LuceneDictionary(indexReader, defaultField);\r
+                                       if(log.isDebugEnabled()) {\r
+                                               Iterator iterator = dictionary.getWordsIterator();\r
+                                               while(iterator.hasNext()) {\r
+                                                       log.debug("Indexing word " + iterator.next());\r
+                                               }\r
+                                       }\r
+\r
+                                       spellChecker.indexDictionary(dictionary);\r
+                               } catch (CorruptIndexException cie) {\r
+                                       log.error("Spellings index is corrupted", cie);\r
+                               } finally {\r
+                                       if (indexReader != null) {\r
+                                               readerProvider.closeReader(indexReader);\r
+                                       }\r
+                               } \r
                        } \r
-               } catch (IOException ioe) {\r
+               }catch (IOException ioe) {\r
                        log.error(ioe);\r
                }\r
        }\r
index 57b3293bcd83729bfaf64e465f56b392648ad316..4810b7a6cf6febb17b26f7a3b6c50c1038fecbbd 100644 (file)
@@ -17,7 +17,7 @@ public class GroupDaoImpl extends CdmEntityDaoBase<Group> implements IGroupDao {
        }\r
 \r
        public Group findGroupByName(String groupName) {\r
-               Query query = getSession().createQuery("select group from Group group where group.name = :name");\r
+               Query query = getSession().createQuery("select g from Group g where g.name = :name");\r
                query.setParameter("name",groupName);\r
                \r
                Group group = (Group)query.uniqueResult();\r
@@ -26,11 +26,11 @@ public class GroupDaoImpl extends CdmEntityDaoBase<Group> implements IGroupDao {
                  Hibernate.initialize(group.getMembers());\r
                }\r
                \r
-               return null;\r
+               return group;\r
        }\r
 \r
        public List<String> listNames(Integer pageSize, Integer pageNumber) {\r
-               Query query = getSession().createQuery("select group.name from Group group");\r
+               Query query = getSession().createQuery("select g.name from Group g");\r
                \r
                if(pageSize != null) {\r
                    query.setMaxResults(pageSize);\r
@@ -45,7 +45,7 @@ public class GroupDaoImpl extends CdmEntityDaoBase<Group> implements IGroupDao {
        }\r
 \r
        public List<String> listMembers(Group group, Integer pageSize,  Integer pageNumber) {\r
-               Query query = getSession().createQuery("select member.username from Group group join group.members member where group = :group");\r
+               Query query = getSession().createQuery("select m.username from Group g join g.members m where g = :group");\r
                query.setParameter("group", group);\r
                \r
                if(pageSize != null) {\r
index 0016c689052bae3b4904daa7a8a062266df9edbd..a452f440d5035b89bb6c6a2619e11d4890b62957 100644 (file)
@@ -81,5 +81,20 @@ public class TermVocabularyDaoImpl extends VersionableDaoBase<TermVocabulary<Def
                }\r
        }\r
 \r
+       public <T extends DefinedTermBase> TermVocabulary<T> findByUri(String termSourceUri, Class<T> clazz) {\r
+               AuditEvent auditEvent = getAuditEventFromContext();\r
+               if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
+               Query query = getSession().createQuery("select vocabulary from TermVocabulary vocabulary where vocabulary.termSourceUri= :termSourceUri");\r
+               query.setParameter("termSourceUri", termSourceUri);\r
+                \r
+                   return (TermVocabulary<T>)query.uniqueResult();\r
+               } else {\r
+                       AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(type,auditEvent.getRevisionNumber());\r
+                       query.add(AuditEntity.property("termSourceUri").eq(termSourceUri));\r
+                       \r
+                       return (TermVocabulary<T>)query.getSingleResult();\r
+               }\r
+       }\r
+\r
 \r
 }\r
index f07bf0c1f59d572443c984ffc9b39ad2abb2d816..908dfed1bc97a34822142bef76fd5878e7f7f7e5 100644 (file)
@@ -1,5 +1,6 @@
 package eu.etaxonomy.cdm.persistence.dao.hibernate.description;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.lucene.analysis.SimpleAnalyzer;
@@ -20,15 +21,25 @@ import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
 import eu.etaxonomy.cdm.model.description.TaxonDescription;
 import eu.etaxonomy.cdm.model.description.TextData;
 import eu.etaxonomy.cdm.model.media.Media;
+import eu.etaxonomy.cdm.model.taxon.Taxon;
+import eu.etaxonomy.cdm.model.taxon.TaxonBase;
 import eu.etaxonomy.cdm.persistence.dao.QueryParseException;
+import eu.etaxonomy.cdm.persistence.dao.common.ISearchableDao;
 import eu.etaxonomy.cdm.persistence.dao.description.IDescriptionElementDao;
 import eu.etaxonomy.cdm.persistence.dao.hibernate.common.AnnotatableDaoImpl;
 
 @Repository
 public class DescriptionElementDaoImpl extends AnnotatableDaoImpl<DescriptionElementBase> implements IDescriptionElementDao {
 
+       private String defaultField = "titleCache";
+       private String defaultSort = "titleCache_forSort";
+       
+       private Class<? extends DescriptionElementBase> indexedClasses[]; 
+
        public DescriptionElementDaoImpl() {
                super(DescriptionElementBase.class);
+               indexedClasses = new Class[1];
+               indexedClasses[0] = TextData.class;
        }
 
        public int countMedia(DescriptionElementBase descriptionElement) {
@@ -46,7 +57,7 @@ public class DescriptionElementDaoImpl extends AnnotatableDaoImpl<DescriptionEle
                try {
                        org.apache.lucene.search.Query query = queryParser.parse(queryString);
                        
-                       FullTextSession fullTextSession = Search.createFullTextSession(getSession());
+                       FullTextSession fullTextSession = Search.getFullTextSession(getSession());
                        org.hibernate.search.FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(query, TextData.class);
                        return  fullTextQuery.getResultSize();
                } catch (ParseException e) {
@@ -78,7 +89,7 @@ public class DescriptionElementDaoImpl extends AnnotatableDaoImpl<DescriptionEle
                try {
                        org.apache.lucene.search.Query query = queryParser.parse(queryString);
                        
-                       FullTextSession fullTextSession = Search.createFullTextSession(getSession());
+                       FullTextSession fullTextSession = Search.getFullTextSession(getSession());
                        org.hibernate.search.FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(query, TextData.class);
                        org.apache.lucene.search.Sort sort = new Sort(new SortField("inDescription.titleCache_forSort"));
                        fullTextQuery.setSort(sort);
@@ -114,26 +125,83 @@ public class DescriptionElementDaoImpl extends AnnotatableDaoImpl<DescriptionEle
        }
        
        public void purgeIndex() {
-               FullTextSession fullTextSession = Search.createFullTextSession(getSession());
-               
-               fullTextSession.purgeAll(type); // remove all description element base from indexes
-               // fullTextSession.flushToIndexes() not implemented in 3.0.0.GA
+               FullTextSession fullTextSession = Search.getFullTextSession(getSession());
+               for(Class clazz : indexedClasses) {
+                 fullTextSession.purgeAll(type); // remove all description element base from indexes
+               }
+               fullTextSession.flushToIndexes();
        }
 
        public void rebuildIndex() {
-               FullTextSession fullTextSession = Search.createFullTextSession(getSession());
+               FullTextSession fullTextSession = Search.getFullTextSession(getSession());
                
                for(DescriptionElementBase descriptionElementBase : list(null,null)) { // re-index all descriptionElements
                        Hibernate.initialize(descriptionElementBase.getInDescription());
                        Hibernate.initialize(descriptionElementBase.getFeature());
                        fullTextSession.index(descriptionElementBase);
                }
+               fullTextSession.flushToIndexes();
        }
        
        public void optimizeIndex() {
-               FullTextSession fullTextSession = Search.createFullTextSession(getSession());
+               FullTextSession fullTextSession = Search.getFullTextSession(getSession());
                SearchFactory searchFactory = fullTextSession.getSearchFactory();
-           searchFactory.optimize(type); // optimize the indices ()
+               for(Class clazz : indexedClasses) {
+               searchFactory.optimize(clazz); // optimize the indices ()
+               }
+           fullTextSession.flushToIndexes();
+       }
+
+       public int count(String queryString) {
+               checkNotInPriorView("DescriptionElementDaoImpl.count(String queryString)");
+        QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());
+               
+               try {
+                       org.apache.lucene.search.Query query = queryParser.parse(queryString);
+               
+                       FullTextSession fullTextSession = Search.getFullTextSession(this.getSession());
+                       org.hibernate.search.FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(query, type);
+                               
+                   return fullTextQuery.getResultSize();
+
+               } catch (ParseException e) {
+                       throw new QueryParseException(e, queryString);
+               }
+       }
+
+       public List<DescriptionElementBase> search(String queryString,  Integer pageSize, Integer pageNumber) {
+               checkNotInPriorView("DescriptionElementDaoImpl.search(String queryString, Integer pageSize,     Integer pageNumber)");
+               QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());
+               List<TaxonBase> results = new ArrayList<TaxonBase>();
+                
+               try {
+                       org.apache.lucene.search.Query query = queryParser.parse(queryString);
+                       
+                       FullTextSession fullTextSession = Search.getFullTextSession(getSession());
+                       
+                       org.hibernate.search.FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(query, type);
+                       
+                       org.apache.lucene.search.Sort sort = new Sort(new SortField(defaultSort));
+                       fullTextQuery.setSort(sort);
+                   
+                   if(pageSize != null) {
+                       fullTextQuery.setMaxResults(pageSize);
+                           if(pageNumber != null) {
+                               fullTextQuery.setFirstResult(pageNumber * pageSize);
+                           } else {
+                               fullTextQuery.setFirstResult(0);
+                           }
+                       }
+                   
+                   return (List<DescriptionElementBase>)fullTextQuery.list();
+
+               } catch (ParseException e) {
+                       throw new QueryParseException(e, queryString);
+               }
+       }
+
+       public String suggestQuery(String string) {
+               throw new UnsupportedOperationException("suggest query is not supported yet");
        }
 
 }
index 513ba2e267a88b99d137bb132a39f05054e234e6..11d0fae1df1e482979444066411ea08c7b7367f7 100644 (file)
@@ -5,8 +5,9 @@ import org.apache.lucene.store.Directory;
 import org.springframework.beans.factory.annotation.Autowired;\r
 import org.springframework.beans.factory.annotation.Qualifier;\r
 import org.springframework.stereotype.Component;\r
-import org.springmodules.lucene.index.factory.IndexFactory;\r
 \r
+import eu.etaxonomy.cdm.model.taxon.Synonym;\r
+import eu.etaxonomy.cdm.model.taxon.Taxon;\r
 import eu.etaxonomy.cdm.model.taxon.TaxonBase;\r
 import eu.etaxonomy.cdm.persistence.dao.hibernate.AlternativeSpellingSuggestionParser;\r
 \r
@@ -15,7 +16,11 @@ public class TaxonAlternativeSpellingSuggestionParser extends AlternativeSpellin
 \r
        public TaxonAlternativeSpellingSuggestionParser() {\r
                super(TaxonBase.class);\r
-               super.setDefaultField("name.persistentTitleCache");\r
+               Class<? extends TaxonBase> indexedClasses[] = new Class[2];\r
+               indexedClasses[0] = Taxon.class;\r
+               indexedClasses[1] = Synonym.class;\r
+               super.setIndexedClasses(indexedClasses);\r
+               super.setDefaultField("name.titleCache");\r
        }\r
 \r
        @Override\r
@@ -23,11 +28,4 @@ public class TaxonAlternativeSpellingSuggestionParser extends AlternativeSpellin
        public void setDirectory(@Qualifier("taxonSpellingDirectory")Directory directory) {\r
                this.directory = directory;\r
        }\r
-\r
-       @Override\r
-       @Autowired\r
-       public void setIndexFactory(@Qualifier("taxonSpellingIndex")IndexFactory indexFactory) {\r
-               this.indexFactory = indexFactory;\r
-       }\r
-\r
 }\r
index 742c8b800f1bfb7e0083a309d0a436dbfc8de9a6..72e170ab07f2e3afd1c0432b4b8af54ea9926f46 100644 (file)
@@ -63,6 +63,7 @@ import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;\r
 import eu.etaxonomy.cdm.model.view.AuditEvent;\r
 import eu.etaxonomy.cdm.persistence.dao.QueryParseException;\r
+import eu.etaxonomy.cdm.persistence.dao.common.ISearchableDao;\r
 import eu.etaxonomy.cdm.persistence.dao.common.ITitledDao;\r
 import eu.etaxonomy.cdm.persistence.dao.hibernate.AlternativeSpellingSuggestionParser;\r
 import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;\r
@@ -91,9 +92,16 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
        \r
        @SuppressWarnings("unused")\r
        private static final Logger logger = Logger.getLogger(TaxonDaoHibernateImpl.class);\r
+       \r
+       private String defaultField = "name.titleCache";\r
+       private String defaultSort = "name.titleCache_forSort";\r
+       private Class<? extends TaxonBase> indexedClasses[]; \r
 \r
        public TaxonDaoHibernateImpl() {\r
                super(TaxonBase.class);\r
+               indexedClasses = new Class[2];\r
+               indexedClasses[0] = Taxon.class;\r
+               indexedClasses[1] = Synonym.class;\r
        }\r
        \r
        @Autowired(required = false)   //TODO switched of because it caused problems when starting CdmApplicationController\r
@@ -409,7 +417,7 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                try {\r
                        org.apache.lucene.search.Query query = queryParser.parse(queryString);\r
                        \r
-                       FullTextSession fullTextSession = Search.createFullTextSession(this.getSession());\r
+                       FullTextSession fullTextSession = Search.getFullTextSession(this.getSession());\r
                        org.hibernate.search.FullTextQuery fullTextQuery = null;\r
                        \r
                        if(accepted == null) {\r
@@ -652,35 +660,28 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
 \r
        public List<TaxonBase> searchTaxa(String queryString, Boolean accepted, Integer pageSize, Integer pageNumber) {\r
                checkNotInPriorView("TaxonDaoHibernateImpl.searchTaxa(String queryString, Boolean accepted,     Integer pageSize, Integer pageNumber)");\r
-               QueryParser queryParser = new QueryParser("name.titleCache", new SimpleAnalyzer());\r
+               QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());\r
                List<TaxonBase> results = new ArrayList<TaxonBase>();\r
                 \r
                try {\r
                        org.apache.lucene.search.Query query = queryParser.parse(queryString);\r
                        \r
-                       FullTextSession fullTextSession = Search.createFullTextSession(getSession());\r
+                       FullTextSession fullTextSession = Search.getFullTextSession(getSession());\r
                        org.hibernate.search.FullTextQuery fullTextQuery = null;\r
-                       Criteria criteria = null;\r
                        \r
                        if(accepted == null) {\r
                                fullTextQuery = fullTextSession.createFullTextQuery(query, TaxonBase.class);\r
-                               criteria =  getSession().createCriteria( TaxonBase.class );\r
                        } else {\r
                                if(accepted) {\r
                                        fullTextQuery = fullTextSession.createFullTextQuery(query, Taxon.class);\r
-                                       criteria =  getSession().createCriteria( Taxon.class );\r
                                } else {\r
                                        fullTextQuery = fullTextSession.createFullTextQuery(query, Synonym.class);\r
-                                       criteria =  getSession().createCriteria( Synonym.class );\r
                                }\r
                        }\r
                        \r
-                       org.apache.lucene.search.Sort sort = new Sort(new SortField("name.titleCache_forSort"));\r
+                       org.apache.lucene.search.Sort sort = new Sort(new SortField(defaultSort));\r
                        fullTextQuery.setSort(sort);\r
                        \r
-                       criteria.setFetchMode( "name", FetchMode.JOIN );\r
-                   fullTextQuery.setCriteriaQuery(criteria);\r
-                   \r
                    if(pageSize != null) {\r
                        fullTextQuery.setMaxResults(pageSize);\r
                            if(pageNumber != null) {\r
@@ -690,7 +691,11 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                            }\r
                        }\r
                    \r
-                   return (List<TaxonBase>)fullTextQuery.list();\r
+                   List<TaxonBase> result = (List<TaxonBase>)fullTextQuery.list();\r
+                   for(TaxonBase taxonBase : result) {\r
+                       Hibernate.initialize(taxonBase.getName());\r
+                   }\r
+                   return result;\r
 \r
                } catch (ParseException e) {\r
                        throw new QueryParseException(e, queryString);\r
@@ -698,27 +703,30 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
        }\r
        \r
        public void purgeIndex() {\r
-               FullTextSession fullTextSession = Search.createFullTextSession(getSession());\r
-               \r
-               fullTextSession.purgeAll(type); // remove all taxon base from indexes\r
-               // fullTextSession.flushToIndexes() not implemented in 3.0.0.GA\r
+               FullTextSession fullTextSession = Search.getFullTextSession(getSession());\r
+               for(Class clazz : indexedClasses) {\r
+                   fullTextSession.purgeAll(clazz); // remove all taxon base from indexes\r
+               }\r
+               fullTextSession.flushToIndexes();\r
        }\r
 \r
        public void rebuildIndex() {\r
-               FullTextSession fullTextSession = Search.createFullTextSession(getSession());\r
+               FullTextSession fullTextSession = Search.getFullTextSession(getSession());\r
                \r
                for(TaxonBase taxonBase : list(null,null)) { // re-index all taxon base\r
                        Hibernate.initialize(taxonBase.getName());\r
                        fullTextSession.index(taxonBase);\r
                }\r
-               // fullTextSession.flushToIndexes() not implemented in 3.0.0.GA\r
+               fullTextSession.flushToIndexes();\r
        }\r
        \r
        public void optimizeIndex() {\r
-               FullTextSession fullTextSession = Search.createFullTextSession(getSession());\r
+               FullTextSession fullTextSession = Search.getFullTextSession(getSession());\r
                SearchFactory searchFactory = fullTextSession.getSearchFactory();\r
-           searchFactory.optimize(type); // optimize the indices ()\r
-           // fullTextSession.flushToIndexes() not implemented in 3.0.0.GA\r
+               for(Class clazz : indexedClasses) {\r
+               searchFactory.optimize(clazz); // optimize the indices ()\r
+               }\r
+           fullTextSession.flushToIndexes();\r
        }\r
 \r
        public String suggestQuery(String queryString) {\r
@@ -728,8 +736,7 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                        try {\r
 \r
                                alternativeSpellingSuggestionParser.parse(queryString);\r
-                               org.apache.lucene.search.Query alternativeQuery = alternativeSpellingSuggestionParser\r
-                                               .suggest(queryString);\r
+                               org.apache.lucene.search.Query alternativeQuery = alternativeSpellingSuggestionParser.suggest(queryString);\r
                                if (alternativeQuery != null) {\r
                                        alternativeQueryString = alternativeQuery\r
                                                        .toString("name.titleCache");\r
@@ -741,4 +748,56 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                }\r
                return alternativeQueryString;\r
        }\r
+\r
+       public int count(String queryString) {\r
+               checkNotInPriorView("TaxonDaoHibernateImpl.count(String queryString)");\r
+        QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());\r
+               \r
+               try {\r
+                       org.apache.lucene.search.Query query = queryParser.parse(queryString);\r
+               \r
+                       FullTextSession fullTextSession = Search.getFullTextSession(this.getSession());\r
+                       org.hibernate.search.FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(query, type);\r
+                               \r
+                   return fullTextQuery.getResultSize();\r
+\r
+               } catch (ParseException e) {\r
+                       throw new QueryParseException(e, queryString);\r
+               }\r
+       }\r
+\r
+       public List<TaxonBase> search(String queryString, Integer pageSize,     Integer pageNumber) {\r
+               checkNotInPriorView("TaxonDaoHibernateImpl.search(String queryString, Integer pageSize, Integer pageNumber)");\r
+               QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());\r
+               List<TaxonBase> results = new ArrayList<TaxonBase>();\r
+                \r
+               try {\r
+                       org.apache.lucene.search.Query query = queryParser.parse(queryString);\r
+                       \r
+                       FullTextSession fullTextSession = Search.getFullTextSession(getSession());\r
+                       \r
+                       org.hibernate.search.FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(query, type);\r
+                       \r
+                       org.apache.lucene.search.Sort sort = new Sort(new SortField(defaultSort));\r
+                       fullTextQuery.setSort(sort);\r
+                   \r
+                   if(pageSize != null) {\r
+                       fullTextQuery.setMaxResults(pageSize);\r
+                           if(pageNumber != null) {\r
+                               fullTextQuery.setFirstResult(pageNumber * pageSize);\r
+                           } else {\r
+                               fullTextQuery.setFirstResult(0);\r
+                           }\r
+                       }\r
+                   \r
+                   List<TaxonBase> result = (List<TaxonBase>)fullTextQuery.list();\r
+                   for(TaxonBase taxonBase : result) {\r
+                       Hibernate.initialize(taxonBase.getName());\r
+                   }\r
+                   return result;\r
+\r
+               } catch (ParseException e) {\r
+                       throw new QueryParseException(e, queryString);\r
+               }\r
+       }\r
 }
\ No newline at end of file
index e92f5c6ebbfd09634dc9b59f0839d0e3592f5cb1..9e00609c1e846eacd64796fc3dcc619109d49e45 100644 (file)
@@ -24,6 +24,7 @@ import eu.etaxonomy.cdm.model.taxon.TaxonBase;
 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;\r
 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;\r
 import eu.etaxonomy.cdm.persistence.dao.common.IIdentifiableDao;\r
+import eu.etaxonomy.cdm.persistence.dao.common.ISearchableDao;\r
 import eu.etaxonomy.cdm.persistence.dao.common.ITitledDao;\r
 import eu.etaxonomy.cdm.persistence.fetch.CdmFetch;\r
 \r
@@ -31,7 +32,7 @@ import eu.etaxonomy.cdm.persistence.fetch.CdmFetch;
  * @author a.mueller\r
  *\r
  */\r
-public interface ITaxonDao extends IIdentifiableDao<TaxonBase>, ITitledDao<TaxonBase> {\r
+public interface ITaxonDao extends IIdentifiableDao<TaxonBase>, ITitledDao<TaxonBase>, ISearchableDao<TaxonBase> {\r
        \r
        /**\r
         * Returns a count of TaxonBase instances (or Taxon instances, if accepted == true, or Synonym instance, if accepted == false) \r
@@ -245,30 +246,4 @@ public interface ITaxonDao extends IIdentifiableDao<TaxonBase>, ITitledDao<Taxon
         * @return a list of TaxonBase instances\r
         */\r
        public List<TaxonBase> findTaxaByName(Boolean accepted, String uninomial, String infragenericEpithet, String specificEpithet, String infraspecificEpithet, Rank rank, Integer pageSize, Integer pageNumber);\r
-\r
-       /**\r
-        * Suggest a query that will return hits based upon an existing lucene query string (that is presumably misspelt and returns no hits)\r
-        * Used to implement "did you mean?"-type functionality using the lucene spellchecker.\r
-        * \r
-        * @param string Query string to check\r
-        * @return a suggested query string that will return hits or null if no such alternative spelling can be found.\r
-        */\r
-       public String suggestQuery(String string);\r
-       \r
-       /**\r
-        * Removes all TaxonBase entities from the index\r
-        */\r
-       public void purgeIndex();\r
-\r
-       /**\r
-        * Index all TaxonBase entities currenly in the database (useful in concert with purgeIndex() to (re-)create\r
-        * indexes or in the  case of corrupt indexes / mismatch between \r
-        * the database and the free-text indices) \r
-        */\r
-       public void rebuildIndex();\r
-       \r
-       /**\r
-        * Calls optimize on the relevant index (useful periodically to increase response times on the free-text search)\r
-        */\r
-       public void optimizeIndex();\r
 }\r