Project

General

Profile

Download (9.04 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.logging.log4j.LogManager;
16
import org.apache.logging.log4j.Logger;
17
import org.hibernate.Session;
18
import org.hibernate.criterion.Criterion;
19
import org.vaadin.viritin.fields.LazyComboBox.FilterableCountProvider;
20
import org.vaadin.viritin.fields.LazyComboBox.FilterablePagingProvider;
21

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

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

    
35
    private final static Logger logger = LogManager.getLogger();
36

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

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

    
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
        clearSession(); // clear the session from remains of previous service calls, see issue #7559
134
        if(!restrictions.isEmpty()){
135
            List<Restriction<?>> preparedRestrictions = prepareRestrictions(filter, matchMode);
136
            page = service.findByTitleWithRestrictions(
137
                    type,
138
                    filter,
139
                    matchMode,
140
                    preparedRestrictions,
141
                    pageSize,
142
                    pageIndex ,
143
                    orderHints,
144
                    initStrategy
145
                    );
146
        } else {
147
            page = service.findByTitle(
148
                    type,
149
                    filter,
150
                    matchMode,
151
                    criteria,
152
                    pageSize,
153
                    pageIndex ,
154
                    orderHints,
155
                    initStrategy
156
                    );
157
        }
158

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

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

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

    
174
        checkNotMixed();
175

    
176
        Pager<V> page;
177

    
178
        clearSession(); // clear the session from remains of previous service calls, see issue #7559
179
        if(!restrictions.isEmpty()){
180
            // Logger.getLogger("org.hibernate.SQL").setLevel(Level.TRACE);
181
            List<Restriction<?>> preparedRestrictions = prepareRestrictions(filter, matchMode);
182
            page = service.findByTitleWithRestrictions(
183
                    type,
184
                    filter,
185
                    matchMode,
186
                    preparedRestrictions,
187
                    1,
188
                    0,
189
                    null,
190
                    null
191
                  );
192
        } else {
193
            page = service.findByTitle(
194
                    type,
195
                    filter,
196
                    matchMode,
197
                    criteria,
198
                    1,
199
                    0,
200
                    null,
201
                    null
202
                  );
203
        }
204

    
205

    
206
        if(logger.isTraceEnabled()){
207
            logger.trace("size() -  count: " + page.getCount().intValue());
208
        }
209
        return page.getCount().intValue();
210
    }
211

    
212
    /**
213
     * see issue #7559
214
     */
215
    public void clearSession() {
216
        Session session = service.getSession();
217
        if(session.isOpen()){
218
            session.clear();
219
        }
220
    }
221

    
222
    /**
223
     * @return
224
     */
225
    private List<Restriction<?>> prepareRestrictions(String filter, MatchMode matchMode) {
226
        List<Restriction<?>> prepared = new ArrayList<>(restrictions.size());
227
        for(Restriction<?> r : restrictions) {
228
            List<Object> values = new ArrayList<>(r.getValues().size());
229
            for(Object v : r.getValues()){
230
                if(v instanceof String){
231
                    String expandedValue = ((String)v).replace(QUERY_STRING_PLACEHOLDER, matchMode.queryStringFrom(filter));
232
                    values.add(expandedValue);
233
                } else {
234
                    values.add(v);
235
                }
236
            }
237
            prepared.add(new Restriction(r.getPropertyName(), r.getOperator(), r.getMatchMode(), values.toArray(new Object[values.size()])));
238
        }
239
        return prepared;
240
    }
241

    
242
    /**
243
     *
244
     */
245
    protected void checkNotMixed() {
246
        if(!restrictions.isEmpty() && !criteria.isEmpty()){
247
            throw new RuntimeException("Citeria and Restrictions must not be used at the same time");
248
        }
249
    }
250

    
251
    /**
252
     * @return the pageSize
253
     */
254
    public int getPageSize() {
255
        return pageSize;
256
    }
257

    
258
    /**
259
     * @param pageSize the pageSize to set
260
     */
261
    public void setPageSize(int pageSize) {
262
        this.pageSize = pageSize;
263
    }
264

    
265
    /**
266
     * @return the initStrategy
267
     */
268
    public List<String> getInitStrategy() {
269
        return initStrategy;
270
    }
271

    
272
    /**
273
     * @param initStrategy the initStrategy to set
274
     */
275
    public void setInitStrategy(List<String> initStrategy) {
276
        this.initStrategy = initStrategy;
277
    }
278

    
279
    /**
280
     * The list of criteria is initially empty.
281
     *
282
     * @return the criteria
283
     */
284
    public List<Criterion> getCriteria() {
285
        return criteria;
286
    }
287

    
288
    public void addCriterion(Criterion criterion){
289
        criteria.add(criterion);
290
    }
291

    
292
    /**
293
     * The list of restrictions is initially empty.
294
     * <p>
295
     * Occurrences of the {@link QUERY_STRING_PLACEHOLDER} in the value
296
     * of String type Restrictions will be replaced by the <code>filter</code> parameter passed to the paging provider.
297
     *
298
     *
299
     * @return the restrictions
300
     */
301
    public List<Restriction<?>> getRestrictions() {
302
        return restrictions;
303
    }
304

    
305
    /**
306
     * Occurrences of the {@link QUERY_STRING_PLACEHOLDER} in the value
307
     * of String type Restrictions will be replaced by the <code>filter</code> parameter passed to the paging provider.
308
     *
309
     * @param restriction
310
     */
311
    public void addRestriction(Restriction<?> restriction){
312
        restrictions.add(restriction);
313
    }
314
}
(3-3/13)