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
.HashMap
;
14 import java
.util
.List
;
16 import java
.util
.UUID
;
18 import org
.apache
.logging
.log4j
.LogManager
;
19 import org
.apache
.logging
.log4j
.Logger
;
20 import org
.vaadin
.viritin
.fields
.LazyComboBox
.FilterableCountProvider
;
22 import com
.vaadin
.data
.Property
.ValueChangeListener
;
23 import com
.vaadin
.ui
.AbstractField
;
24 import com
.vaadin
.ui
.Field
;
26 import eu
.etaxonomy
.cdm
.api
.service
.INameService
;
27 import eu
.etaxonomy
.cdm
.api
.service
.pager
.Pager
;
28 import eu
.etaxonomy
.cdm
.api
.util
.TaxonNamePartsFilter
;
29 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
30 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
31 import eu
.etaxonomy
.cdm
.persistence
.dto
.TaxonNameParts
;
32 import eu
.etaxonomy
.cdm
.persistence
.query
.MatchMode
;
33 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
;
38 * The string representations returned as rankSpecificNamePart must be unique in the database since these are being used as weak references between e.g.
39 * genus name and the TaxonName entity for this genus.
41 * @author a.kohlbecker
45 public class TaxonNameStringFilterablePagingProvider
implements FilterableStringRepresentationPagingProvider
<UUID
>, FilterableCountProvider
{
47 private static final Logger logger
= LogManager
.getLogger();
49 private static final List
<String
> DEFAULT_INIT_STRATEGY
= Arrays
.asList("$");
51 private int pageSize
= 20;
53 private INameService service
;
55 private MatchMode matchMode
= MatchMode
.BEGINNING
;
57 private List
<OrderHint
> orderHints
= OrderHint
.ORDER_BY_TITLE_CACHE
.asList();
59 List
<String
> initStrategy
= DEFAULT_INIT_STRATEGY
;
61 private TaxonNamePartsFilter namePartsFilter
= new TaxonNamePartsFilter();
63 private Map
<AbstractField
<String
>, ValueChangeListener
> registeredToFields
= new HashMap
<>();
65 private Map
<String
, UUID
> lastPagedEntityUUIDs
;
68 public TaxonNameStringFilterablePagingProvider(INameService service
) {
69 this(service
, Rank
.GENUS(), null);
72 public TaxonNameStringFilterablePagingProvider(INameService service
, Rank rank
) {
73 this(service
, rank
, null);
76 public TaxonNameStringFilterablePagingProvider(INameService service
, Rank rank
, MatchMode matchMode
) {
78 this.service
= service
;
79 if(matchMode
!= null){
80 this.matchMode
= matchMode
;
82 namePartsFilter
.setRank(rank
);
85 public void listenToFields(AbstractField
<String
> genusOrUninomialField
, AbstractField
<String
> infraGenericEpithetField
,
86 AbstractField
<String
> specificEpithetField
, AbstractField
<String
> infraSpecificEpithetField
){
90 registerNullSave(genusOrUninomialField
, e
-> namePartsFilter
.setGenusOrUninomial(genusOrUninomialField
.getValue()));
91 registerNullSave(infraGenericEpithetField
, e
-> namePartsFilter
.setGenusOrUninomial(infraGenericEpithetField
.getValue()));
92 registerNullSave(specificEpithetField
, e
-> namePartsFilter
.setGenusOrUninomial(specificEpithetField
.getValue()));
93 registerNullSave(infraSpecificEpithetField
, e
-> namePartsFilter
.setGenusOrUninomial(infraSpecificEpithetField
.getValue()));
99 public void unlistenAllFields() {
100 for(AbstractField
<String
> f
: registeredToFields
.keySet()){
101 f
.removeValueChangeListener(registeredToFields
.get(f
));
103 registeredToFields
.clear();
106 public void replaceFields(AbstractField
<String
> unlistenField
, AbstractField
<String
> listenToField
) throws UnknownFieldException
{
107 if(registeredToFields
.containsKey(unlistenField
)){
108 ValueChangeListener listener
= registeredToFields
.get(unlistenField
);
109 unlistenField
.removeValueChangeListener(listener
);
110 registeredToFields
.remove(unlistenField
);
111 registerNullSave(listenToField
, listener
);
113 throw new UnknownFieldException();
117 public void updateFromFields(){
118 for(AbstractField
<String
> f
: registeredToFields
.keySet()){
119 ValueChangeListener listener
= registeredToFields
.get(f
);
120 listener
.valueChange(new Field
.ValueChangeEvent(f
));
125 * @param genusOrUninomialField
127 protected void registerNullSave(AbstractField
<String
> field
, ValueChangeListener listener
) {
129 registeredToFields
.put(field
, listener
);
130 field
.addValueChangeListener(listener
);
135 * @return the matchMode
137 protected MatchMode
getMatchMode() {
142 * @param matchMode the matchMode to set
144 protected void setMatchMode(MatchMode matchMode
) {
145 this.matchMode
= matchMode
;
149 * @return the orderHints
151 protected List
<OrderHint
> getOrderHints() {
156 * @param orderHints the orderHints to set
158 protected void setOrderHints(List
<OrderHint
> orderHints
) {
159 this.orderHints
= orderHints
;
162 public TaxonNamePartsFilter
getFilter(){
163 return namePartsFilter
;
170 public List
<String
> findEntities(int firstRow
, String filter
) {
172 Integer pageIndex
= firstRow
/ pageSize
;
173 Pager
<TaxonNameParts
> taxonNamePager
= service
.findTaxonNameParts(namePartsFilter
, filter
, pageSize
, pageIndex
, orderHints
);
174 if(logger
.isTraceEnabled()){
175 logger
.trace("findEntities() - page: " + taxonNamePager
.getCurrentIndex() + "/" + taxonNamePager
.getPagesAvailable() + " totalRecords: " + taxonNamePager
.getCount() + "\n" + taxonNamePager
.getRecords());
177 List
<String
> namePartStrings
= new ArrayList
<>(taxonNamePager
.getRecords().size());
178 lastPagedEntityUUIDs
= new HashMap
<>(taxonNamePager
.getRecords().size());
179 for(TaxonNameParts tnp
: taxonNamePager
.getRecords()){
180 String rankSpecificNamePart
= tnp
.rankSpecificNamePart();
181 String namePartKey
= rankSpecificNamePart
;
182 if(lastPagedEntityUUIDs
.containsKey(namePartKey
)){
183 namePartKey
= rankSpecificNamePart
+ " DUPLICATE[" + tnp
.getTaxonNameUuid() + "]";
185 namePartStrings
.add(namePartKey
);
186 lastPagedEntityUUIDs
.put(namePartKey
, tnp
.getTaxonNameUuid());
188 return namePartStrings
;
195 public int size(String filter
) {
197 Pager
<TaxonNameParts
> taxonNamePager
= service
.findTaxonNameParts(namePartsFilter
, filter
, 1, 0, null);
198 if(logger
.isTraceEnabled()){
199 logger
.trace("size() - count: " + taxonNamePager
.getCount().intValue());
201 return taxonNamePager
.getCount().intValue();
205 * @return the pageSize
207 public int getPageSize() {
212 * @param pageSize the pageSize to set
214 public void setPageSize(int pageSize
) {
215 this.pageSize
= pageSize
;
219 * @return the lastPagedEntityUUIDs
221 public Map
<String
, UUID
> getLastPagedEntityUUIDs() {
222 return lastPagedEntityUUIDs
;
226 public class UnknownFieldException
extends Exception
{
228 private static final long serialVersionUID
= 1L;
235 public UUID
idFor(String stringRepresentation
) {
236 if(stringRepresentation
== null){
239 if(lastPagedEntityUUIDs
== null || !lastPagedEntityUUIDs
.containsKey(stringRepresentation
)){
240 int pages
= Math
.max(1, size(stringRepresentation
));
241 for(int i
= 0; i
< pages
; i
++){
242 findEntities(i
, stringRepresentation
);
245 return lastPagedEntityUUIDs
.get(stringRepresentation
);
252 public void clearIdCache() {
253 lastPagedEntityUUIDs
= null;
260 public void excludeNames(TaxonName
... excludedTaxonNames
) {
261 namePartsFilter
.getExludedNamesUuids();
262 for(TaxonName n
: excludedTaxonNames
){
263 namePartsFilter
.getExludedNamesUuids().add(n
.getUuid());