Project

General

Profile

Download (8.49 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.HashMap;
14
import java.util.List;
15
import java.util.Map;
16
import java.util.UUID;
17

    
18
import org.apache.logging.log4j.LogManager;
19
import org.apache.logging.log4j.Logger;
20
import org.vaadin.viritin.fields.LazyComboBox.FilterableCountProvider;
21

    
22
import com.vaadin.data.Property.ValueChangeListener;
23
import com.vaadin.ui.AbstractField;
24
import com.vaadin.ui.Field;
25

    
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;
34

    
35
/**
36
 * IMPORTANT !!!
37
 *
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.
40
 *
41
 * @author a.kohlbecker
42
 * @since Jun 7, 2017
43
 *
44
 */
45
public class TaxonNameStringFilterablePagingProvider implements FilterableStringRepresentationPagingProvider<UUID>, FilterableCountProvider {
46

    
47
    private final static Logger logger = LogManager.getLogger();
48

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

    
51
    private int pageSize = 20;
52

    
53
    private INameService service;
54

    
55
    private MatchMode matchMode = MatchMode.BEGINNING;
56

    
57
    private List<OrderHint> orderHints = OrderHint.ORDER_BY_TITLE_CACHE.asList();
58

    
59
    List<String> initStrategy = DEFAULT_INIT_STRATEGY;
60

    
61
    private TaxonNamePartsFilter namePartsFilter = new TaxonNamePartsFilter();
62

    
63
    private Map<AbstractField<String>, ValueChangeListener> registeredToFields = new HashMap<>();
64

    
65
    private Map<String, UUID> lastPagedEntityUUIDs;
66

    
67

    
68
    public TaxonNameStringFilterablePagingProvider(INameService service) {
69
        this(service, Rank.GENUS(), null);
70
    }
71

    
72
    public TaxonNameStringFilterablePagingProvider(INameService service, Rank rank) {
73
        this(service, rank, null);
74
    }
75

    
76
    public TaxonNameStringFilterablePagingProvider(INameService service, Rank rank, MatchMode matchMode) {
77
        super();
78
        this.service = service;
79
        if(matchMode != null){
80
            this.matchMode = matchMode;
81
        }
82
        namePartsFilter.setRank(rank);
83
    }
84

    
85
    public void listenToFields(AbstractField<String> genusOrUninomialField, AbstractField<String> infraGenericEpithetField,
86
            AbstractField<String> specificEpithetField, AbstractField<String> infraSpecificEpithetField){
87

    
88
        unlistenAllFields();
89

    
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()));
94
    }
95

    
96
    /**
97
     *
98
     */
99
    public void unlistenAllFields() {
100
        for(AbstractField<String> f : registeredToFields.keySet()){
101
            f.removeValueChangeListener(registeredToFields.get(f));
102
        }
103
        registeredToFields.clear();
104
    }
105

    
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);
112
        } else {
113
            throw new UnknownFieldException();
114
        }
115
    }
116

    
117
    public void updateFromFields(){
118
        for(AbstractField<String> f : registeredToFields.keySet()){
119
            ValueChangeListener listener = registeredToFields.get(f);
120
            listener.valueChange(new Field.ValueChangeEvent(f));
121
        }
122
    }
123

    
124
    /**
125
     * @param genusOrUninomialField
126
     */
127
    protected void registerNullSave(AbstractField<String> field, ValueChangeListener listener) {
128
        if(field != null){
129
            registeredToFields.put(field, listener);
130
            field.addValueChangeListener(listener);
131
        }
132
    }
133

    
134
    /**
135
     * @return the matchMode
136
     */
137
    protected MatchMode getMatchMode() {
138
        return matchMode;
139
    }
140

    
141
    /**
142
     * @param matchMode the matchMode to set
143
     */
144
    protected void setMatchMode(MatchMode matchMode) {
145
        this.matchMode = matchMode;
146
    }
147

    
148
    /**
149
     * @return the orderHints
150
     */
151
    protected List<OrderHint> getOrderHints() {
152
        return orderHints;
153
    }
154

    
155
    /**
156
     * @param orderHints the orderHints to set
157
     */
158
    protected void setOrderHints(List<OrderHint> orderHints) {
159
        this.orderHints = orderHints;
160
    }
161

    
162
    public TaxonNamePartsFilter getFilter(){
163
        return namePartsFilter;
164
    }
165

    
166
    /**
167
     * {@inheritDoc}
168
     */
169
    @Override
170
    public List<String> findEntities(int firstRow, String filter) {
171

    
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());
176
        }
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() + "]";
184
               }
185
               namePartStrings.add(namePartKey);
186
               lastPagedEntityUUIDs.put(namePartKey, tnp.getTaxonNameUuid());
187
        }
188
        return namePartStrings;
189
    }
190

    
191
    /**
192
     * {@inheritDoc}
193
     */
194
    @Override
195
    public int size(String filter) {
196

    
197
        Pager<TaxonNameParts> taxonNamePager = service.findTaxonNameParts(namePartsFilter, filter,  1, 0, null);
198
        if(logger.isTraceEnabled()){
199
            logger.trace("size() -  count: " + taxonNamePager.getCount().intValue());
200
        }
201
        return taxonNamePager.getCount().intValue();
202
    }
203

    
204
    /**
205
     * @return the pageSize
206
     */
207
    public int getPageSize() {
208
        return pageSize;
209
    }
210

    
211
    /**
212
     * @param pageSize the pageSize to set
213
     */
214
    public void setPageSize(int pageSize) {
215
        this.pageSize = pageSize;
216
    }
217

    
218
    /**
219
     * @return the lastPagedEntityUUIDs
220
     */
221
    public Map<String, UUID> getLastPagedEntityUUIDs() {
222
        return lastPagedEntityUUIDs;
223
    }
224

    
225

    
226
    public class UnknownFieldException extends Exception {
227

    
228
        private static final long serialVersionUID = 1L;
229
    }
230

    
231
    /**
232
     * {@inheritDoc}
233
     */
234
    @Override
235
    public UUID idFor(String stringRepresentation) {
236
        if(stringRepresentation == null){
237
            return null;
238
        }
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);
243
            }
244
        }
245
        return lastPagedEntityUUIDs.get(stringRepresentation);
246
    }
247

    
248
    /**
249
     * {@inheritDoc}
250
     */
251
    @Override
252
    public void clearIdCache() {
253
        lastPagedEntityUUIDs = null;
254
    }
255

    
256
    /**
257
     * @param asList
258
     * @return
259
     */
260
    public void excludeNames(TaxonName ... excludedTaxonNames) {
261
        namePartsFilter.getExludedNamesUuids();
262
        for(TaxonName n : excludedTaxonNames){
263
            namePartsFilter.getExludedNamesUuids().add(n.getUuid());
264
        }
265
    }
266
}
(11-11/13)