Project

General

Profile

Download (8.67 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 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.service;
10

    
11
import java.util.ArrayList;
12
import java.util.Arrays;
13
import java.util.List;
14

    
15
import org.apache.log4j.Level;
16
import org.apache.log4j.Logger;
17
import org.hibernate.criterion.Criterion;
18
import org.vaadin.viritin.fields.LazyComboBox.FilterableCountProvider;
19
import org.vaadin.viritin.fields.LazyComboBox.FilterablePagingProvider;
20

    
21
import eu.etaxonomy.cdm.api.service.IIdentifiableEntityService;
22
import eu.etaxonomy.cdm.api.service.pager.Pager;
23
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
24
import eu.etaxonomy.cdm.persistence.dao.common.Restriction;
25
import eu.etaxonomy.cdm.persistence.query.MatchMode;
26
import eu.etaxonomy.cdm.persistence.query.OrderHint;
27

    
28
/**
29
 * @author a.kohlbecker
30
 * @since Jun 7, 2017
31
 *
32
 */
33
public class CdmFilterablePagingProvider<T extends IdentifiableEntity, V extends T> implements FilterablePagingProvider<V>, FilterableCountProvider {
34

    
35

    
36
    private static final List<String> DEFAULT_INIT_STRATEGY = Arrays.asList("$");
37

    
38
    public static final String QUERY_STRING_PLACEHOLDER = "{query-string}";
39

    
40
    private static final Logger logger = Logger.getLogger(CdmFilterablePagingProvider.class);
41

    
42
    private int pageSize = 20;
43

    
44
    private IIdentifiableEntityService<T> service;
45

    
46
    private Class<V> type = null;
47

    
48
    private MatchMode matchMode = MatchMode.ANYWHERE;
49

    
50
    private List<OrderHint> orderHints = OrderHint.ORDER_BY_TITLE_CACHE.asList();
51

    
52
    List<String> initStrategy = DEFAULT_INIT_STRATEGY;
53

    
54
    private List<Criterion> criteria = new ArrayList<>();
55

    
56
    private List<Restriction<?>> restrictions = new ArrayList<>();
57

    
58

    
59
    /**
60
     * @return the matchMode
61
     */
62
    protected MatchMode getMatchMode() {
63
        return matchMode;
64
    }
65

    
66
    /**
67
     * @param matchMode the matchMode to set
68
     */
69
    protected void setMatchMode(MatchMode matchMode) {
70
        this.matchMode = matchMode;
71
    }
72

    
73
    /**
74
     * @return the orderHints
75
     */
76
    protected List<OrderHint> getOrderHints() {
77
        return orderHints;
78
    }
79

    
80
    /**
81
     * @param orderHints the orderHints to set
82
     */
83
    protected void setOrderHints(List<OrderHint> orderHints) {
84
        this.orderHints = orderHints;
85
    }
86

    
87
    /**
88
     * With defaults for matchMode = MatchMode.ANYWHERE and orderHints = OrderHint.ORDER_BY_TITLE_CACHE
89
     *
90
     */
91
    public CdmFilterablePagingProvider(IIdentifiableEntityService<T> service) {
92
        this(service, null);
93
    }
94

    
95
    /**
96
     * With defaults for matchMode = MatchMode.ANYWHERE and orderHints = OrderHint.ORDER_BY_TITLE_CACHE
97
     *
98
     */
99
    public CdmFilterablePagingProvider(IIdentifiableEntityService<T> service, Class<V> type) {
100
        super();
101
        this.type = type;
102
        this.service = service;
103

    
104
        // Logger.getLogger("org.hibernate.SQL").setLevel(Level.TRACE);
105
    }
106

    
107

    
108
    public CdmFilterablePagingProvider(IIdentifiableEntityService<T> service, MatchMode matchMode, List<OrderHint> orderHints) {
109
        this(service, null, matchMode, orderHints);
110
    }
111

    
112
    public <S extends T> CdmFilterablePagingProvider(IIdentifiableEntityService<T> service, Class<V> type, MatchMode matchMode, List<OrderHint> orderHints) {
113
        super();
114
        this.type = type;
115
        this.service = service;
116
        this.matchMode = matchMode;
117
        this.orderHints = orderHints;
118

    
119
        // Logger.getLogger("org.hibernate.SQL").setLevel(Level.TRACE);
120
    }
121

    
122
    /**
123
     * {@inheritDoc}
124
     */
125
    @SuppressWarnings("unchecked")
126
    @Override
127
    public List<V> findEntities(int firstRow, String filter) {
128

    
129
        checkNotMixed();
130

    
131
        Integer pageIndex = firstRow / pageSize;
132
        Pager<V> page;
133
        if(!restrictions.isEmpty()){
134
            List<Restriction<?>> preparedRestrictions = prepareRestrictions(filter, matchMode);
135
            page = (Pager<V>) service.findByTitleWithRestrictions(
136
                    type,
137
                    filter,
138
                    matchMode,
139
                    preparedRestrictions,
140
                    pageSize,
141
                    pageIndex ,
142
                    orderHints,
143
                    initStrategy
144
                    );
145
        } else {
146
            page = (Pager<V>) service.findByTitle(
147
                    type,
148
                    filter,
149
                    matchMode,
150
                    criteria,
151
                    pageSize,
152
                    pageIndex ,
153
                    orderHints,
154
                    initStrategy
155
                    );
156
        }
157

    
158
        if(logger.isTraceEnabled()){
159
            logger.trace("findEntities() - page: " + page.getCurrentIndex() + "/" + page.getPagesAvailable() + " totalRecords: " + page.getCount() + "\n" + page.getRecords());
160
        }
161

    
162
        Logger.getLogger("org.hibernate.SQL").setLevel(Level.WARN);
163
        return page.getRecords();
164
    }
165

    
166
    /**
167
     * {@inheritDoc}
168
     */
169
    @SuppressWarnings("unchecked")
170
    @Override
171
    public int size(String filter) {
172

    
173
        checkNotMixed();
174

    
175
        Pager<V> page;
176
        if(!restrictions.isEmpty()){
177

    
178
            Logger.getLogger("org.hibernate.SQL").setLevel(Level.TRACE);
179
            List<Restriction<?>> preparedRestrictions = prepareRestrictions(filter, matchMode);
180
            page = (Pager<V>) service.findByTitleWithRestrictions(
181
                    type,
182
                    filter,
183
                    matchMode,
184
                    preparedRestrictions,
185
                    1,
186
                    0,
187
                    null,
188
                    null
189
                  );
190
        } else {
191
            page = (Pager<V>) service.findByTitle(
192
                    type,
193
                    filter,
194
                    matchMode,
195
                    criteria,
196
                    1,
197
                    0,
198
                    null,
199
                    null
200
                  );
201
        }
202

    
203
        if(logger.isTraceEnabled()){
204
            logger.trace("size() -  count: " + page.getCount().intValue());
205
        }
206
        return page.getCount().intValue();
207
    }
208

    
209
    /**
210
     * @return
211
     */
212
    private List<Restriction<?>> prepareRestrictions(String filter, MatchMode matchMode) {
213
        List<Restriction<?>> prepared = new ArrayList<>(restrictions.size());
214
        for(Restriction<?> r : restrictions) {
215
            List<Object> values = new ArrayList<>(r.getValues().size());
216
            for(Object v : r.getValues()){
217
                if(v instanceof String){
218
                    String expandedValue = ((String)v).replace(QUERY_STRING_PLACEHOLDER, matchMode.queryStringFrom(filter));
219
                    values.add(expandedValue);
220
                } else {
221
                    values.add(v);
222
                }
223
            }
224
            prepared.add(new Restriction(r.getPropertyName(), r.getOperator(), r.getMatchMode(), values.toArray(new String[values.size()])));
225
        }
226
        return prepared;
227
    }
228

    
229
    /**
230
     *
231
     */
232
    protected void checkNotMixed() {
233
        if(!restrictions.isEmpty() && !criteria.isEmpty()){
234
            throw new RuntimeException("Citeria and Restrictions must not be used at the same time");
235
        }
236
    }
237

    
238
    /**
239
     * @return the pageSize
240
     */
241
    public int getPageSize() {
242
        return pageSize;
243
    }
244

    
245
    /**
246
     * @param pageSize the pageSize to set
247
     */
248
    public void setPageSize(int pageSize) {
249
        this.pageSize = pageSize;
250
    }
251

    
252
    /**
253
     * @return the initStrategy
254
     */
255
    public List<String> getInitStrategy() {
256
        return initStrategy;
257
    }
258

    
259
    /**
260
     * @param initStrategy the initStrategy to set
261
     */
262
    public void setInitStrategy(List<String> initStrategy) {
263
        this.initStrategy = initStrategy;
264
    }
265

    
266
    /**
267
     * The list of criteria is initially empty.
268
     *
269
     * @return the criteria
270
     */
271
    public List<Criterion> getCriteria() {
272
        return criteria;
273
    }
274

    
275
    public void addCriterion(Criterion criterion){
276
        criteria.add(criterion);
277
    }
278

    
279
    /**
280
     * The list of restrictions is initially empty.
281
     * <p>
282
     * Occurrences of the {@link QUERY_STRING_PLACEHOLDER} in the value
283
     * of String type Restrictions will be replaced by the <code>filter</code> parameter passed to the paging provider.
284
     *
285
     *
286
     * @return the restrictions
287
     */
288
    public List<Restriction<?>> getRestrictions() {
289
        return restrictions;
290
    }
291

    
292
    /**
293
     * Occurrences of the {@link QUERY_STRING_PLACEHOLDER} in the value
294
     * of String type Restrictions will be replaced by the <code>filter</code> parameter passed to the paging provider.
295
     *
296
     * @param restriction
297
     */
298
    public void addRestriction(Restriction<?> restriction){
299
        restrictions.add(restriction);
300
    }
301
}
(1-1/7)