Project

General

Profile

Download (4.01 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.hibernate.search;
10

    
11
import org.apache.commons.lang.StringUtils;
12
import org.apache.log4j.Logger;
13
import org.apache.lucene.document.Document;
14
import org.apache.lucene.document.Field;
15
import org.apache.lucene.document.SortedDocValuesField;
16
import org.apache.lucene.util.BytesRef;
17
import org.hibernate.search.bridge.LuceneOptions;
18

    
19
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
20
import eu.etaxonomy.cdm.model.name.NonViralName;
21
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
22
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
23

    
24
/**
25
 * Creates a special sort column to allows nomenclatorical ordering of taxa and names.
26
 * This class bridge can handle all {@link TaxonBase} and {@link NonViralName}s
27
 * instances. {@link ViralNames} are not supported!
28
 * <p>
29
 * Ignores the <code>name</code> parameter!
30
 * <p>
31
 * The order follows the hql equivalent:
32
 * <pre>order by
33
 *  t.name.genusOrUninomial,
34
 *  case when t.name.specificEpithet like '\"%\"'
35
 *      then 1
36
 *      else 0
37
 *   end,
38
 *   t.name.specificEpithet,
39
 *   t.name.rank desc,
40
 *   t.name.nameCache";
41
 * <pre>
42
 *
43
 * @author a.kohlbecker
44
 * @date Oct 9, 2013
45
 *
46
 */
47
public class NomenclaturalSortOrderBrigde extends AbstractClassBridge {
48

    
49
    private static final char PAD_CHAR = '0';
50

    
51
    public static final Logger logger = Logger.getLogger(NomenclaturalSortOrderBrigde.class);
52

    
53
    final static int MAX_FIELD_LENGTH = 50; // used to pab the strings, should be 255 set to 50 for debugging FIXME
54
    public final static String NAME_SORT_FIELD_NAME = "nomenclaturalOrder__sort";
55

    
56
    /* (non-Javadoc)
57
     * @see eu.etaxonomy.cdm.hibernate.search.AbstractClassBridge#set(java.lang.String, java.lang.Object, org.apache.lucene.document.Document, org.hibernate.search.bridge.LuceneOptions)
58
     */
59
    @Override
60
    public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
61
        NonViralName<?> n = null;
62

    
63
        if(value instanceof TaxonBase) {
64
            try {
65
                n = HibernateProxyHelper.deproxy(((TaxonBase) value).getName(), NonViralName.class);
66
                if (n == null){
67
                	return;
68
                }
69
            } catch (ClassCastException e) {
70
                logger.info(e);
71
                /* IGNORE */
72
            }
73

    
74
        }else if(value instanceof TaxonNameBase){
75
            n = (NonViralName)value;
76
        }
77
        if(n == null) {
78
            logger.error("Unsupported type: " + value.getClass().getName());
79
            return;
80
        }
81

    
82
        // compile sort field
83
        StringBuilder txt = new StringBuilder();
84

    
85
        if(n.isProtectedNameCache()){
86
            txt.append(n.getNameCache());
87
        } else {
88
            if(StringUtils.isNotBlank(n.getGenusOrUninomial())){
89
                txt.append(StringUtils.rightPad(n.getGenusOrUninomial(), MAX_FIELD_LENGTH, PAD_CHAR));
90
            }
91
            if(StringUtils.isNotBlank(n.getSpecificEpithet())){
92
                String matchQuotes = "\".*\"";
93
                if(n.getSpecificEpithet().matches(matchQuotes)){
94
                    txt.append("1");
95
                } else {
96
                    txt.append("0");
97
                }
98
                txt.append(StringUtils.rightPad(n.getSpecificEpithet(), MAX_FIELD_LENGTH, PAD_CHAR));
99
            } else {
100
                txt.append(StringUtils.rightPad("", MAX_FIELD_LENGTH, PAD_CHAR));
101
            }
102
            String rankStr = "99"; // default for no rank
103
            if(n.getRank() != null){
104
                rankStr = Integer.toString(n.getRank().getOrderIndex());
105
            }
106
            txt.append(StringUtils.rightPad(rankStr, 2, PAD_CHAR));
107
        }
108

    
109
        Field nameSortField = new SortedDocValuesField(NAME_SORT_FIELD_NAME, new BytesRef(txt.toString()));
110
        LuceneDocumentUtility.setOrReplaceDocValueField(nameSortField, document);
111
    }
112

    
113
}
(12-12/18)