Project

General

Profile

Download (8.12 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.io.Serializable;
13
import java.util.Arrays;
14
import java.util.List;
15
import java.util.Map;
16

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

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

    
31
public class OrderHint implements Serializable {
32

    
33
    private static final long serialVersionUID = -6638812694578112279L;
34

    
35
    public enum SortOrder {
36

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

    
48
        private String hql;
49

    
50
        private SortOrder(String hqlStr){
51
            hql = hqlStr;
52
        }
53

    
54
        public String toHql(){
55
            return hql;
56
        }
57
    }
58

    
59
    public static final Logger logger = LogManager.getLogger(OrderHint.class);
60

    
61
    private final String propertyName;
62

    
63
    private final SortOrder sortOrder;
64

    
65
    public final String LUCENE_SCORE = "LUCENE_SCORE";
66

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

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

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

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

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

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

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

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

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

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

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

    
89
    public static final OrderHint BY_ORDER_INDEX_DESC = new OrderHint("orderIndex", SortOrder.DESCENDING);
90

    
91
    public static final OrderHint BY_TREE_INDEX = new OrderHint("treeIndex", SortOrder.ASCENDING);
92

    
93
    public static final OrderHint BY_TREE_INDEX_DESC = new OrderHint("treeIndex", SortOrder.DESCENDING);
94

    
95
    public List<OrderHint> asList() {
96
        return Arrays.asList(new OrderHint[]{this});
97
    }
98

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

    
115
    public OrderHint(String fieldName, SortOrder sortOrder) {
116
        super();
117
        this.propertyName = fieldName;
118
        this.sortOrder = sortOrder;
119
    }
120

    
121
    /**
122
     * The property of a bean
123
     * @return
124
     */
125
    public String getPropertyName() {
126
        return propertyName;
127
    }
128

    
129
    /**
130
     * possible sort orders are {@link SortOrder.ASCENDING} or {@link SortOrder.DESCENDING}
131
     * @return
132
     */
133
    public SortOrder getSortOrder() {
134
        return sortOrder;
135
    }
136

    
137
    public boolean isAscending(){
138
        return sortOrder.equals(SortOrder.ASCENDING);
139
    }
140

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

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

    
184
    /**
185
     * FIXME document this
186
     *
187
     * @param query
188
     */
189
    public void add(AuditQuery query) {
190

    
191
        if(getPropertyName().indexOf('.', 0) >= 0){
192
            throw new OperationNotSupportedInPriorViewException("Sorting by related properties is not supported in the history view");
193
        } else {
194
            if(isAscending()){
195
                query.addOrder(AuditEntity.property(getPropertyName()).asc());
196
            } else {
197
                query.addOrder(AuditEntity.property(getPropertyName()).desc());
198
            }
199
        }
200
    }
201

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

    
216
    /**
217
     * @return a Lucene {@link SortField} for the Lucene field type <code>Sting</code>
218
     */
219
    public SortField toSortField() {
220
        if(propertyName.equals(LUCENE_SCORE)){
221
            return SortField.FIELD_SCORE;
222
        }
223
        return new SortField(propertyName + "__sort", SortField.Type.STRING, sortOrder.equals(SortOrder.DESCENDING));
224
    }
225

    
226
    @Override
227
    public boolean equals(Object obj) {
228
        if (obj == this){
229
            return true;
230
        }
231
        if (obj == null){
232
            return false;
233
        }
234
        if (!OrderHint.class.isAssignableFrom(obj.getClass())){
235
            return false;
236
        }
237
        OrderHint orderHint= (OrderHint)obj;
238
        boolean propertyNameEqual = orderHint.getPropertyName().equals(this.getPropertyName());
239
        boolean sortOrderEqual = orderHint.getSortOrder().equals(this.getSortOrder());
240
        if (! propertyNameEqual || !sortOrderEqual){
241
                return false;
242
        }
243
        return true;
244
    }
245

    
246
    @Override
247
    public int hashCode() {
248
           int hashCode = 7;
249
           hashCode = 29 * hashCode + this.getPropertyName().hashCode() * this.getSortOrder().hashCode();
250
           return hashCode;
251
    }
252
}
(8-8/10)