Project

General

Profile

Download (7.74 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2009 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

    
10
package eu.etaxonomy.cdm.persistence.query;
11

    
12
import java.util.Arrays;
13
import java.util.List;
14
import java.util.Map;
15

    
16
import org.apache.log4j.Logger;
17
import org.apache.lucene.search.SortField;
18
import org.hibernate.Criteria;
19
import org.hibernate.criterion.Order;
20
import org.hibernate.envers.query.AuditEntity;
21
import org.hibernate.envers.query.AuditQuery;
22

    
23
import eu.etaxonomy.cdm.hibernate.search.NomenclaturalSortOrderBrigde;
24
import eu.etaxonomy.cdm.model.agent.Institution;
25
import eu.etaxonomy.cdm.model.common.CdmBase;
26
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
27
import eu.etaxonomy.cdm.model.common.User;
28
import eu.etaxonomy.cdm.persistence.dao.common.OperationNotSupportedInPriorViewException;
29

    
30
public class OrderHint {
31

    
32
    public enum SortOrder {
33

    
34
        /**
35
         * items are sorted in increasing
36
         * order.
37
         */
38
        ASCENDING("asc"),
39
        /**
40
         * items are sorted in decreasing
41
         * order.
42
         */
43
        DESCENDING("desc");
44

    
45
        private String hql;
46

    
47
        private SortOrder(String hqlStr){
48
            hql = hqlStr;
49
        }
50

    
51
        public String toHql(){
52
            return hql;
53
        }
54
    }
55

    
56
    public static final Logger logger = Logger.getLogger(OrderHint.class);
57

    
58
    private final String propertyName;
59

    
60
    private final SortOrder sortOrder;
61

    
62
    public final String LUCENE_SCORE = "LUCENE_SCORE";
63

    
64
    public static final OrderHint ORDER_BY_ID = new OrderHint("id", SortOrder.ASCENDING);
65

    
66
    public static final OrderHint ORDER_BY_ID_DESC = new OrderHint("id", SortOrder.DESCENDING);
67

    
68
    public static final OrderHint ORDER_BY_USERNAME = new OrderHint("username", SortOrder.ASCENDING);
69

    
70
    public static final OrderHint ORDER_BY_USERNAME_DESC = new OrderHint("username", SortOrder.DESCENDING);
71

    
72
    public static final OrderHint ORDER_BY_NAME = new OrderHint("name", SortOrder.ASCENDING);
73

    
74
    public static final OrderHint ORDER_BY_NAME_DESC = new OrderHint("name", SortOrder.DESCENDING);
75

    
76
    public static final OrderHint ORDER_BY_TITLE_CACHE = new OrderHint("titleCache", SortOrder.ASCENDING);
77

    
78
    public static final OrderHint ORDER_BY_TITLE_CACHE_DESC = new OrderHint("titleCache", SortOrder.DESCENDING);
79

    
80
    public static final OrderHint NOMENCLATURAL_SORT_ORDER = new OrderHint(NomenclaturalSortOrderBrigde.NAME_SORT_FIELD_NAME, SortOrder.ASCENDING);
81

    
82
    public static final OrderHint NOMENCLATURAL_SORT_ORDER_DESC = new OrderHint(NomenclaturalSortOrderBrigde.NAME_SORT_FIELD_NAME, SortOrder.DESCENDING);
83

    
84
    public static final OrderHint BY_ORDER_INDEX = new OrderHint("orderIndex", SortOrder.ASCENDING);
85

    
86
    public static final OrderHint BY_ORDER_INDEX_DESC = new OrderHint("orderIndex", SortOrder.ASCENDING);
87

    
88

    
89
    public List<OrderHint> asList() {
90
        return Arrays.asList(new OrderHint[]{this});
91
    }
92

    
93
    /**
94
     * @param clazz
95
     * @return "by titleCache" for all IdentifiableEntitys otherwise "by id"
96
     */
97
    public static List<OrderHint> defaultOrderHintsFor(Class<? extends CdmBase> clazz) {
98
        if (clazz.isAssignableFrom(IdentifiableEntity.class)) {
99
            return ORDER_BY_TITLE_CACHE.asList();
100
        } else if(clazz.isAssignableFrom(User.class)){
101
            return ORDER_BY_USERNAME.asList();
102
        } else if(clazz.isAssignableFrom(Institution.class)){
103
            return ORDER_BY_NAME.asList();
104
        } else {
105
            return ORDER_BY_ID.asList();
106
        }
107
    }
108

    
109
    public OrderHint(String fieldName, SortOrder sortOrder) {
110
        super();
111
        this.propertyName = fieldName;
112
        this.sortOrder = sortOrder;
113
    }
114

    
115
    /**
116
     * The property of a bean
117
     * @return
118
     */
119
    public String getPropertyName() {
120
        return propertyName;
121
    }
122

    
123
    /**
124
     * possible sort orders are {@link SortOrder.ASCENDING} or {@link SortOrder.DESCENDING}
125
     * @return
126
     */
127
    public SortOrder getSortOrder() {
128
        return sortOrder;
129
    }
130

    
131
    public boolean isAscending(){
132
        return sortOrder.equals(SortOrder.ASCENDING);
133
    }
134

    
135
    /**
136
     * FIXME document this
137
     *
138
     * @param criteria
139
     * @param criteriaMap
140
     */
141
    public void add(Criteria criteria, Map<String, Criteria> criteriaMap) {
142
        if(getPropertyName().indexOf(".") != -1) {
143
            /**
144
             * Here we have to work a bit of magic as currently hibernate will
145
             * throw an error if we attempt to join the same association twice.
146
             *
147
             * http://opensource.atlassian.com/projects/hibernate/browse/HHH-879
148
             */
149

    
150
            String[] assocObjs = getPropertyName().split("\\.");
151
            String path = "";
152
            Criteria c = criteria;
153
            for(int i = 0; i < assocObjs.length - 1; i++) {
154
                path = path + assocObjs[i];
155
                if(criteriaMap.get(path) == null) {
156
                    c = c.createCriteria(assocObjs[i]);
157
                    criteriaMap.put(path, c);
158
                } else {
159
                    c = criteriaMap.get(path);
160
                }
161
                path = path + '.';
162
            }
163
            String propname = assocObjs[assocObjs.length - 1];
164
            if(isAscending()){
165
                c.addOrder(Order.asc(propname));
166
            } else {
167
                c.addOrder(Order.desc(propname));
168
            }
169
        } else {
170
            if(isAscending()){
171
                criteria.addOrder(Order.asc(getPropertyName()));
172
            } else {
173
                criteria.addOrder(Order.desc(getPropertyName()));
174
            }
175
        }
176
    }
177

    
178
    /**
179
     * FIXME document this
180
     *
181
     * @param query
182
     */
183
    public void add(AuditQuery query) {
184

    
185
        if(getPropertyName().indexOf('.', 0) >= 0){
186
            throw new OperationNotSupportedInPriorViewException("Sorting by related properties is not supported in the history view");
187
        } else {
188
            if(isAscending()){
189
                query.addOrder(AuditEntity.property(getPropertyName()).asc());
190
            } else {
191
                query.addOrder(AuditEntity.property(getPropertyName()).desc());
192
            }
193
        }
194
    }
195

    
196
    /**
197
     * Returns a hql order by clause element which can directly be used in hql queries.
198
     *
199
     * e.g.: "titleCache ASC"
200
     *
201
     * @return an hql order by clause element
202
     */
203
    public String toHql(){
204
        if(propertyName.equals(LUCENE_SCORE)){
205
            logger.error("LUCENE_SCORE not allowed in hql query");
206
        }
207
        return propertyName + " " + sortOrder.toHql();
208
    }
209

    
210
    /**
211
     * @return a Lucene {@link SortField} for the Lucene field type <code>Sting</code>
212
     */
213
    public SortField toSortField() {
214
        if(propertyName.equals(LUCENE_SCORE)){
215
            return SortField.FIELD_SCORE;
216
        }
217
        return new SortField(propertyName + "__sort", SortField.Type.STRING, sortOrder.equals(SortOrder.DESCENDING));
218
    }
219

    
220
    @Override
221
    public boolean equals(Object obj) {
222
        if (obj == this){
223
            return true;
224
        }
225
        if (obj == null){
226
            return false;
227
        }
228
        if (!OrderHint.class.isAssignableFrom(obj.getClass())){
229
            return false;
230
        }
231
        OrderHint orderHint= (OrderHint)obj;
232
        boolean propertyNameEqual = orderHint.getPropertyName().equals(this.getPropertyName());
233
        boolean sortOrderEqual = orderHint.getSortOrder().equals(this.getSortOrder());
234
        if (! propertyNameEqual || !sortOrderEqual){
235
                return false;
236
        }
237
        return true;
238
    }
239

    
240
    @Override
241
    public int hashCode() {
242
           int hashCode = 7;
243
           hashCode = 29 * hashCode + this.getPropertyName().hashCode() * this.getSortOrder().hashCode();
244
           return hashCode;
245
    }
246
}
(8-8/10)