2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.cdm
.persistence
.dao
.hibernate
;
13 import java
.io
.IOException
;
14 import java
.io
.StringReader
;
15 import java
.util
.Vector
;
17 import org
.apache
.commons
.logging
.Log
;
18 import org
.apache
.commons
.logging
.LogFactory
;
19 import org
.apache
.lucene
.analysis
.Analyzer
;
20 import org
.apache
.lucene
.analysis
.Token
;
21 import org
.apache
.lucene
.analysis
.TokenStream
;
22 import org
.apache
.lucene
.analysis
.standard
.StandardAnalyzer
;
23 import org
.apache
.lucene
.index
.CorruptIndexException
;
24 import org
.apache
.lucene
.index
.IndexReader
;
25 import org
.apache
.lucene
.index
.IndexWriterConfig
;
26 import org
.apache
.lucene
.index
.Term
;
27 import org
.apache
.lucene
.queryparser
.classic
.ParseException
;
28 import org
.apache
.lucene
.queryparser
.classic
.QueryParser
;
29 import org
.apache
.lucene
.search
.PhraseQuery
;
30 import org
.apache
.lucene
.search
.Query
;
31 import org
.apache
.lucene
.search
.TermQuery
;
32 import org
.apache
.lucene
.search
.spell
.Dictionary
;
33 import org
.apache
.lucene
.search
.spell
.LuceneDictionary
;
34 import org
.apache
.lucene
.search
.spell
.SpellChecker
;
35 import org
.apache
.lucene
.store
.Directory
;
36 import org
.apache
.lucene
.util
.BytesRef
;
37 import org
.apache
.lucene
.util
.BytesRefIterator
;
38 import org
.hibernate
.SessionFactory
;
39 import org
.hibernate
.search
.FullTextSession
;
40 import org
.hibernate
.search
.Search
;
41 import org
.hibernate
.search
.SearchFactory
;
42 import org
.hibernate
.search
.indexes
.IndexReaderAccessor
;
43 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
44 import org
.springframework
.orm
.hibernate3
.support
.HibernateDaoSupport
;
46 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
47 import eu
.etaxonomy
.cdm
.persistence
.dao
.IAlternativeSpellingSuggestionParser
;
54 * @deprecated Use current methods for alternative spelling suggestions. This class is no longer supported
55 * after migration to hibernate 4.x.
58 public abstract class AlternativeSpellingSuggestionParser
<T
extends CdmBase
>
59 extends HibernateDaoSupport
60 implements IAlternativeSpellingSuggestionParser
{
61 private static Log log
= LogFactory
.getLog(AlternativeSpellingSuggestionParser
.class);
63 private String defaultField
;
64 protected Directory directory
;
65 private final Class
<T
> type
;
66 private Class
<?
extends T
> indexedClasses
[];
69 public AlternativeSpellingSuggestionParser(Class
<T
> type
) {
73 public void setIndexedClasses(Class
<?
extends T
> indexedClasses
[]) {
74 this.indexedClasses
= indexedClasses
;
77 public abstract void setDirectory(Directory directory
);
80 public void setHibernateSessionFactory(SessionFactory sessionFactory
) {
81 super.setSessionFactory(sessionFactory
);
84 public void setDefaultField(String defaultField
) {
85 this.defaultField
= defaultField
;
89 public Query
parse(String queryString
) throws ParseException
{
90 QueryParser queryParser
= new QueryParser(defaultField
, new StandardAnalyzer());
91 return queryParser
.parse(queryString
);
95 public Query
suggest(String queryString
) throws ParseException
{
96 QuerySuggester querySuggester
= new QuerySuggester(defaultField
, new StandardAnalyzer());
97 Query query
= querySuggester
.parse(queryString
);
98 return querySuggester
.hasSuggestedQuery() ? query
: null;
101 private class QuerySuggester
extends QueryParser
{
102 private boolean suggestedQuery
= false;
103 public QuerySuggester(String field
, Analyzer analyzer
) {
104 super(field
, analyzer
);
107 protected Query
getFieldQuery(String field
, String queryText
, boolean quoted
) throws ParseException
{
108 // Copied from org.apache.lucene.queryParser.QueryParser
109 // replacing construction of TermQuery with call to getTermQuery()
110 // which finds close matches.
112 source
= getAnalyzer().tokenStream(field
, new StringReader(queryText
));
113 Vector
<Object
> v
= new Vector
<Object
>();
119 // t = source.next();
121 //FIXME this is new after Hibernate 4 migration
122 //but completely unchecked and unsure if correct
124 boolean it
= source
.incrementToken();
125 t
= source
.getAttribute(Token
.class);
129 } catch (IOException e
) {
136 // OLD v.addElement(t.termText());
137 //FIXME unchecked #3344
138 //FIXME #4716 not sure if this implementation equals the old t.term()
139 String term
= new String(t
.buffer(), 0, t
.length());
145 } catch (IOException e
) {
151 } else if (v
.size() == 1) {
152 return new TermQuery(getTerm(field
, (String
) v
.elementAt(0)));
154 PhraseQuery q
= new PhraseQuery();
155 q
.setSlop(getPhraseSlop());
156 for (int i
= 0; i
< v
.size(); i
++) {
157 q
.add(getTerm(field
, (String
) v
.elementAt(i
)));
163 private Term
getTerm(String field
, String queryText
) throws ParseException
{
166 SpellChecker spellChecker
= new SpellChecker(directory
);
167 if (spellChecker
.exist(queryText
)) {
168 return new Term(field
, queryText
);
170 String
[] similarWords
= spellChecker
.suggestSimilar(queryText
, 1);
171 if (similarWords
.length
== 0) {
172 return new Term(field
, queryText
);
174 suggestedQuery
= true;
175 return new Term(field
, similarWords
[0]);
176 } catch (IOException e
) {
177 throw new ParseException(e
.getMessage());
180 public boolean hasSuggestedQuery() {
181 return suggestedQuery
;
186 public void refresh() {
187 FullTextSession fullTextSession
= Search
.getFullTextSession(getSession());
188 SearchFactory searchFactory
= fullTextSession
.getSearchFactory();
190 SpellChecker spellChecker
= new SpellChecker(directory
);
192 for(Class
<?
extends T
> indexedClass
: indexedClasses
) {
194 // DirectoryProvider<?> directoryProvider = searchFactory.getDirectoryProviders(indexedClass)[0];
195 // ReaderProvider readerProvider = searchFactory.getReaderProvider();
196 IndexReaderAccessor ira
= searchFactory
.getIndexReaderAccessor();
197 // IndexReader indexReader = ira.open(indexedClass);
198 IndexReader indexReader
= null;
202 indexReader
= ira
.open(indexedClass
);
203 // indexReader = readerProvider.openIndexReader(); // .openReader(directoryProvider);
204 log
.debug("Creating new dictionary for words in " + defaultField
+ " docs " + indexReader
.numDocs());
206 Dictionary dictionary
= new LuceneDictionary(indexReader
, defaultField
);
207 if(log
.isDebugEnabled()) {
208 BytesRefIterator iterator
= dictionary
.getEntryIterator();
210 while((bytesRef
= iterator
.next()) != null) {
211 log
.debug("Indexing word " + bytesRef
);
216 // OLD: spellChecker.indexDictionary(dictionary);
217 //FIXME preliminary for Hibernate 4 migration see # 3344
218 IndexWriterConfig config
= new IndexWriterConfig( new StandardAnalyzer());
219 boolean fullMerge
= true;
220 spellChecker
.indexDictionary(dictionary
, config
, fullMerge
);
222 } catch (CorruptIndexException cie
) {
223 log
.error("Spellings index is corrupted", cie
);
225 if (indexReader
!= null) {
226 // readerProvider.closeIndexReader(indexReader);
227 ira
.close(indexReader
);
231 }catch (IOException ioe
) {