Project

General

Profile

Download (4.9 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Copyright (C) 2013 EDIT
3
 * European Distributed Institute of Taxonomy
4
 * http://www.e-taxonomy.eu
5
 *
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.
8
 */
9
package eu.etaxonomy.cdm.api.service.search;
10

    
11
import java.util.HashMap;
12
import java.util.Map;
13

    
14
import org.apache.lucene.analysis.Analyzer;
15
import org.apache.lucene.index.IndexReader;
16
import org.apache.lucene.queryparser.classic.QueryParser;
17
import org.apache.lucene.queryparser.complexPhrase.ComplexPhraseQueryParser;
18
import org.hibernate.SessionFactory;
19
import org.hibernate.search.Search;
20
import org.hibernate.search.SearchFactory;
21
import org.hibernate.search.indexes.IndexReaderAccessor;
22
import org.springframework.beans.factory.annotation.Autowired;
23
import org.springframework.stereotype.Component;
24

    
25
import eu.etaxonomy.cdm.model.common.CdmBase;
26
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
27
import eu.etaxonomy.cdm.model.description.TextData;
28
import eu.etaxonomy.cdm.model.taxon.Taxon;
29
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
30

    
31
/**
32
 * @author a.kohlbecker
33
 * @date Sep 18, 2013
34
 *
35
 */
36
@Component
37
public class LuceneIndexToolProviderImpl implements ILuceneIndexToolProvider {
38

    
39
    private final static String DEFAULT_QURERY_FIELD_NAME = "titleCache";
40

    
41
    @Autowired
42
    private SessionFactory sessionFactory;
43

    
44
    private final Map<Class<? extends CdmBase>, QueryParser> queryParsers = new HashMap<Class<? extends CdmBase>, QueryParser>();
45
    private final Map<Class<? extends CdmBase>, QueryParser> complexPhraseQueryParsers = new HashMap<Class<? extends CdmBase>, QueryParser>();
46

    
47
    /**
48
     * @param sessionfactory
49
     * @return
50
     */
51
    private SearchFactory getCurrentSearchFactory() {
52
        return Search.getFullTextSession(sessionFactory.getCurrentSession()).getSearchFactory();
53
    }
54

    
55

    
56
    /**
57
     * TODO the abstract base class DescriptionElementBase can not be used, so
58
     * we are using an arbitrary subclass to find the DirectoryProvider, future
59
     * versions of hibernate search my allow using abstract base classes see
60
     * {@link http://stackoverflow.com/questions/492184/how-do-you-find-all-subclasses-of-a-given-class-in-java}
61
     *
62
     * @param type must not be null
63
     * @return
64
     */
65
    protected Class<? extends CdmBase> pushAbstractBaseTypeDown(Class<? extends CdmBase> type) {
66
        if(type == null) {
67
            throw new NullPointerException("parameter type must not be null");
68
        }
69
        if (type.equals(DescriptionElementBase.class)) {
70
            return TextData.class;
71
        }
72
        if (type.equals(TaxonBase.class)) {
73
            return Taxon.class;
74
        }
75
//        if (type.equals(TaxonNameBase.class)) {
76
//            return NonViralName.class;
77
//        }
78
        return type;
79
    }
80

    
81
    @Override
82
    public IndexReader getIndexReaderFor(Class<? extends CdmBase> clazz) {
83
        IndexReader reader = getCurrentSearchFactory().getIndexReaderAccessor().open(pushAbstractBaseTypeDown(clazz));
84
        return reader;
85
    }
86

    
87
    @Override
88
    public QueryParser getQueryParserFor(Class<? extends CdmBase> clazz, boolean complexPhraseQuery) {
89
        if(!complexPhraseQuery){
90
            if(!queryParsers.containsKey(clazz)){
91
                Analyzer analyzer = getAnalyzerFor(clazz);
92
                QueryParser parser = new QueryParser(DEFAULT_QURERY_FIELD_NAME, analyzer);
93
                queryParsers.put(clazz, parser);
94
            }
95
            return queryParsers.get(clazz);
96
        } else {
97
            if(!complexPhraseQueryParsers.containsKey(clazz)){
98
                Analyzer analyzer = getAnalyzerFor(clazz);
99
                QueryParser parser = new ComplexPhraseQueryParser(DEFAULT_QURERY_FIELD_NAME, analyzer);
100
                complexPhraseQueryParsers.put(clazz, parser);
101
            }
102
            return complexPhraseQueryParsers.get(clazz);
103
        }
104
    }
105

    
106

    
107
    /**
108
     * <b>WARING</b> This method might return an Analyzer
109
     * which is not suitable for all fields of the lucene document. This method
110
     * internally uses the simplified method from {@link {
111
     * @link org.hibernate.search.SearchFactory#getAnalyzer(Class)}
112
     *
113
     * TODO implement method which allows to retrieve the correct Analyzer
114
     * per document field, this method will have another signature.
115
     *
116
     * @return the Analyzer suitable for the lucene index of the given
117
     *         <code>clazz</code>
118
     */
119
    @Override
120
    public Analyzer getAnalyzerFor(Class<? extends CdmBase> clazz) {
121
        Analyzer analyzer = getCurrentSearchFactory().getAnalyzer(pushAbstractBaseTypeDown(clazz));
122
        return analyzer;
123
    }
124

    
125
    @Override
126
    public QueryFactory newQueryFactoryFor(Class<? extends CdmBase> clazz){
127
        return new QueryFactory(this, pushAbstractBaseTypeDown(clazz));
128
    }
129

    
130
    @Override
131
    public IndexReaderAccessor getIndexReaderAccessor(){
132
        return getCurrentSearchFactory().getIndexReaderAccessor();
133
    }
134

    
135
}
(7-7/16)