2 * Copyright (C) 2017 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
9 package eu
.etaxonomy
.cdm
.service
;
11 import java
.util
.ArrayList
;
12 import java
.util
.Arrays
;
13 import java
.util
.List
;
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
;
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
;
30 * @author a.kohlbecker
33 public class CdmFilterablePagingProvider
<T
extends IdentifiableEntity
, V
extends T
>
34 implements FilterablePagingProvider
<V
>, FilterableCountProvider
{
36 private static final Logger logger
= LogManager
.getLogger();
38 private static final List
<String
> DEFAULT_INIT_STRATEGY
= Arrays
.asList("$");
40 public static final String QUERY_STRING_PLACEHOLDER
= "{query-string}";
42 private int pageSize
= 20;
44 private IIdentifiableEntityService
<T
> service
;
46 private Class
<V
> type
= null;
48 private MatchMode matchMode
= MatchMode
.ANYWHERE
;
50 private List
<OrderHint
> orderHints
= OrderHint
.ORDER_BY_TITLE_CACHE
.asList();
52 private List
<String
> initStrategy
= DEFAULT_INIT_STRATEGY
;
54 private List
<Criterion
> criteria
= new ArrayList
<>();
56 private List
<Restriction
<?
>> restrictions
= new ArrayList
<>();
58 protected MatchMode
getMatchMode() {
61 protected void setMatchMode(MatchMode matchMode
) {
62 this.matchMode
= matchMode
;
65 protected List
<OrderHint
> getOrderHints() {
68 protected void setOrderHints(List
<OrderHint
> orderHints
) {
69 this.orderHints
= orderHints
;
73 * With defaults for matchMode = MatchMode.ANYWHERE and orderHints = OrderHint.ORDER_BY_TITLE_CACHE
75 public CdmFilterablePagingProvider(IIdentifiableEntityService
<T
> service
) {
80 * With defaults for matchMode = MatchMode.ANYWHERE and orderHints = OrderHint.ORDER_BY_TITLE_CACHE
82 public CdmFilterablePagingProvider(IIdentifiableEntityService
<T
> service
, Class
<V
> type
) {
85 this.service
= service
;
87 // LogUtils.setLevel("org.hibernate.SQL", Level.TRACE);
90 public CdmFilterablePagingProvider(IIdentifiableEntityService
<T
> service
, MatchMode matchMode
, List
<OrderHint
> orderHints
) {
91 this(service
, null, matchMode
, orderHints
);
94 public <S
extends T
> CdmFilterablePagingProvider(IIdentifiableEntityService
<T
> service
, Class
<V
> type
, MatchMode matchMode
, List
<OrderHint
> orderHints
) {
96 this.service
= service
;
97 this.matchMode
= matchMode
;
98 this.orderHints
= orderHints
;
100 // LogUtils.setLevel("org.hibernate.SQL", Level.TRACE);
104 public List
<V
> findEntities(int firstRow
, String filter
) {
108 Integer pageIndex
= firstRow
/ pageSize
;
110 clearSession(); // clear the session from remains of previous service calls, see issue #7559
111 if(!restrictions
.isEmpty()){
112 List
<Restriction
<?
>> preparedRestrictions
= prepareRestrictions(filter
, matchMode
);
113 page
= service
.findByTitleWithRestrictions(
117 preparedRestrictions
,
124 page
= service
.findByTitle(
136 if(logger
.isTraceEnabled()){
137 logger
.trace("findEntities() - page: " + page
.getCurrentIndex() + "/" + page
.getPagesAvailable() + " totalRecords: " + page
.getCount() + "\n" + page
.getRecords());
140 // LogUtils.setLevel("org.hibernate.SQL", Level.TRACE);
141 return page
.getRecords();
145 public int size(String filter
) {
149 clearSession(); // clear the session from remains of previous service calls, see issue #7559
151 if(!restrictions
.isEmpty()){
152 // LogUtils.setLevel("org.hibernate.SQL", Level.TRACE);
153 List
<Restriction
<?
>> preparedRestrictions
= prepareRestrictions(filter
, matchMode
);
154 count
= service
.countByTitleWithRestrictions(type
, filter
, matchMode
, preparedRestrictions
);
156 count
= service
.countByTitle(type
, filter
, matchMode
, criteria
);
160 if(logger
.isTraceEnabled()){
161 logger
.trace("size() - count: " + count
);
163 return Long
.valueOf(count
).intValue();
169 public void clearSession() {
170 Session session
= service
.getSession();
171 if(session
.isOpen()){
176 private List
<Restriction
<?
>> prepareRestrictions(String filter
, MatchMode matchMode
) {
177 List
<Restriction
<?
>> prepared
= new ArrayList
<>(restrictions
.size());
178 for(Restriction
<?
> r
: restrictions
) {
179 List
<Object
> values
= new ArrayList
<>(r
.getValues().size());
180 for(Object v
: r
.getValues()){
181 if(v
instanceof String
){
182 String expandedValue
= ((String
)v
).replace(QUERY_STRING_PLACEHOLDER
, matchMode
.queryStringFrom(filter
));
183 values
.add(expandedValue
);
188 prepared
.add(new Restriction
<>(r
.getPropertyName(), r
.getOperator(), r
.getMatchMode(), values
.toArray(new Object
[values
.size()])));
193 protected void checkNotMixed() {
194 if(!restrictions
.isEmpty() && !criteria
.isEmpty()){
195 throw new RuntimeException("Citeria and Restrictions must not be used at the same time");
199 public int getPageSize() {
203 public void setPageSize(int pageSize
) {
204 this.pageSize
= pageSize
;
207 public List
<String
> getInitStrategy() {
211 public void setInitStrategy(List
<String
> initStrategy
) {
212 this.initStrategy
= initStrategy
;
216 * The list of criteria is initially empty.
218 * @return the criteria
220 public List
<Criterion
> getCriteria() {
224 public void addCriterion(Criterion criterion
){
225 criteria
.add(criterion
);
229 * The list of restrictions is initially empty.
231 * Occurrences of the {@link QUERY_STRING_PLACEHOLDER} in the value
232 * of String type Restrictions will be replaced by the <code>filter</code> parameter passed to the paging provider.
235 * @return the restrictions
237 public List
<Restriction
<?
>> getRestrictions() {
242 * Occurrences of the {@link QUERY_STRING_PLACEHOLDER} in the value
243 * of String type Restrictions will be replaced by the <code>filter</code> parameter passed to the paging provider.
247 public void addRestriction(Restriction
<?
> restriction
){
248 restrictions
.add(restriction
);