Project

General

Profile

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

    
11
import java.util.ArrayList;
12
import java.util.List;
13
import java.util.Set;
14
import java.util.UUID;
15

    
16
import org.joda.time.DateTime;
17

    
18
import eu.etaxonomy.cdm.common.CdmUtils;
19
import eu.etaxonomy.cdm.format.taxon.TaxonRelationshipFormatter;
20
import eu.etaxonomy.cdm.model.common.Language;
21
import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
22
import eu.etaxonomy.cdm.model.taxon.Taxon;
23
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
24
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
25
import eu.etaxonomy.cdm.model.term.Representation;
26
import eu.etaxonomy.cdm.persistence.dto.TermDto;
27
import eu.etaxonomy.cdm.strategy.cache.TagEnum;
28
import eu.etaxonomy.cdm.strategy.cache.TaggedCacheHelper;
29
import eu.etaxonomy.cdm.strategy.cache.TaggedText;
30

    
31
/**
32
 * DTO to transfer a list of taxon relationships for a given taxon.
33
 *
34
 * @author a.mueller
35
 * @since 15.08.2018
36
 */
37
public class TaxonRelationshipsDTO {
38

    
39
    private static final String SENSU_SEPARATOR = ", ";
40

    
41
    public class TaxonRelationDTO{
42

    
43
        private boolean doubtful = false;
44
        private boolean misapplication = false;
45
        private boolean synonym = false;
46
        private Direction direction;
47
        private UUID taxonUuid;
48
        private String cache;
49
        private List<TaggedText> taggedText;
50
        //TODO maybe this will be changed in future
51
        private TermDto type;
52
        private UUID typeUuid;
53
        private SourceDTO sec;
54
        private SourceDTO relSec;
55

    
56

    
57
        public TaxonRelationDTO(TaxonRelationship relation, Direction direction, List<Language> languages) {
58
            Taxon relatedTaxon = direction == Direction.relatedTo? relation.getToTaxon()
59
                    : relation.getFromTaxon();
60
            this.taxonUuid = relatedTaxon.getUuid();
61
            this.doubtful = relation.isDoubtful();
62
            this.direction = direction;
63
            TaxonRelationshipType relType = relation.getType();
64

    
65
            if (relType != null){
66
                this.misapplication = relType.isMisappliedNameOrInvalidDesignation();
67
                this.synonym = relType.isAnySynonym();
68
                this.typeUuid = relType.getUuid();
69
//                TODO there must be a better DTO which also includes
70
                Set<Representation> representations = direction.isDirect() ? relType.getRepresentations() : relType.getInverseRepresentations();
71
                TermDto termDto = TermDto.fromTerm(relType, representations);
72
                this.type = termDto;
73
//                TODO localize
74
//                termDto.localize(representation_L10n);
75
            }
76
            List<TaggedText> tags = new TaxonRelationshipFormatter().getTaggedText(
77
                    relation, direction == Direction.relatedFrom, languages);
78
            this.taggedText = tags;
79
            this.setCache(TaggedCacheHelper.createString(tags));
80
        }
81

    
82

    
83
        public UUID getTaxonUuid() {
84
            return taxonUuid;
85
        }
86
        public void setTaxonUuid(UUID taxonUuid) {
87
            this.taxonUuid = taxonUuid;
88
        }
89
        public boolean isDoubtful() {
90
            return doubtful;
91
        }
92
        public void setDoubtful(boolean doubtful) {
93
            this.doubtful = doubtful;
94
        }
95

    
96
        public Direction getDirection() {
97
            return direction;
98
        }
99
        public void setDirection(Direction direction) {
100
            this.direction = direction;
101
        }
102

    
103

    
104

    
105
        @Override
106
        public String toString(){
107
            return taxonUuid == null? super.toString() : taxonUuid.toString();
108
        }
109

    
110
        public String getCache() {
111
            return cache;
112
        }
113
        public void setCache(String cache) {
114
            this.cache = cache;
115
        }
116

    
117
        public List<TaggedText> getTaggedText() {
118
            return taggedText;
119
        }
120
//        public void setTaggedText(List<TaggedText> taggedText) {
121
//            this.taggedText = taggedText;
122
//        }
123

    
124
        public boolean isMisapplication() {
125
            return misapplication;
126
        }
127
        public void setMisapplication(boolean misapplication) {
128
            this.misapplication = misapplication;
129
        }
130

    
131
        public boolean isSynonym() {
132
            return synonym;
133
        }
134
        public void setSynonym(boolean synonym) {
135
            this.synonym = synonym;
136
        }
137

    
138
        public TermDto getType() {
139
            return type;
140
        }
141
        public void setType(TermDto type) {
142
            this.type = type;
143
        }
144

    
145

    
146
        /**
147
         * @return the typeUuid
148
         */
149
        public UUID getTypeUuid() {
150
            return typeUuid;
151
        }
152

    
153

    
154
        /**
155
         * @param typeUuid the typeUuid to set
156
         */
157
        public void setTypeUuid(UUID typeUuid) {
158
            this.typeUuid = typeUuid;
159
        }
160

    
161
    }
162

    
163
    private List<TaxonRelationDTO> relations = new ArrayList<>();
164

    
165
    private List<List<TaggedText>> misapplications = new ArrayList<>();
166

    
167
    private DateTime date = DateTime.now();
168

    
169
    //** ******************* CONSTRUCTOR **************************/
170

    
171
    public TaxonRelationshipsDTO() {}
172

    
173
//    public TaxonRelationshipsDTO(UUID taxonUuid) {
174
//        IncludedTaxon originalTaxon = new TaxonRelationshipsDTO(taxonUuid, false);
175
//        includedTaxa.add(originalTaxon);
176
//    }
177

    
178
 // ************************** GETTER / SETTER  ***********************/
179

    
180
    public List<TaxonRelationDTO> getRelations() {
181
        return relations;
182
    }
183

    
184
    public void setIncludedTaxa(List<TaxonRelationDTO> relations) {
185
        this.relations = relations;
186
    }
187

    
188
    public void addRelation(TaxonRelationDTO relation){
189
        relations.add(relation);
190
    }
191

    
192
    /**
193
     * @param relation
194
     * @param direction
195
     */
196
    public TaxonRelationDTO addRelation(TaxonRelationship relation, Direction direction, List<Language> languages) {
197
        TaxonRelationDTO newRelation = new TaxonRelationDTO(relation, direction, languages);
198
        relations.add(newRelation);
199
        return newRelation;
200
    }
201

    
202

    
203
    /**
204
     *
205
     */
206
    public void createMisapplicationString() {
207
        List<List<TaggedText>> result = new ArrayList<>();
208

    
209
        for (TaxonRelationDTO relation: relations){
210
            if (relation.isMisapplication()){
211
                List<TaggedText> tags = relation.getTaggedText();
212

    
213
                boolean isDuplicate = false;
214
                for (List<TaggedText> existing: result){
215
                    isDuplicate = mergeIfDuplicate(existing, tags);
216
                    if (isDuplicate){
217
                        break;
218
                    }
219
                }
220
                if (!isDuplicate){
221
                    List<TaggedText> newTags = new ArrayList<>(tags.size());
222
                    newTags.addAll(tags);
223
                    result.add(newTags);
224
                }
225
            }
226
        }
227
        this.setMisapplications(result);
228
    }
229

    
230
    /**
231
     * Checks if all tags are equal, except for the sensuReference tags
232
     * @param existing
233
     * @param tags
234
     * @return
235
     */
236
    private boolean mergeIfDuplicate(List<TaggedText> first, List<TaggedText> second) {
237
        int i = 0;
238
        int j = 0;
239
        int sensuEndInFirst = -1;
240
        int sensuStartInSecond = -1;
241
        int senusEndInSecond = -1;
242

    
243
        boolean sensuHandled = false;
244
        boolean isDuplicate = true;
245
        while (isDuplicate && i < first.size() && j< second.size()){
246
            if (tagEqualsMisapplied(first.get(i), second.get(i))){
247
                i++;j++;
248
            }else if (!sensuHandled){
249
                while (i < first.size() && tagIsSensu(first.get(i))){
250
                    i++;
251
                    sensuEndInFirst = i;
252
                }
253
                sensuStartInSecond = j;
254
                while (j< second.size() && tagIsSensu(second.get(j))){
255
                    j++;
256
                    senusEndInSecond = j;
257
                }
258
                sensuHandled = true;
259
            }else{
260
                isDuplicate = false;
261
                i++;j++; //not really necessary
262
            }
263

    
264
        }
265
        isDuplicate = isDuplicate && i == first.size() && j == second.size();
266
        if (isDuplicate && sensuEndInFirst > -1 && sensuStartInSecond > -1){
267
            first.addAll(sensuEndInFirst, second.subList(sensuStartInSecond, senusEndInSecond));
268
            first.add(sensuEndInFirst, TaggedText.NewSeparatorInstance(SENSU_SEPARATOR));
269
            return true;
270
        }else{
271
            return false;
272
        }
273
    }
274

    
275
    /**
276
     * @param taggedText
277
     * @return
278
     */
279
    private boolean tagIsSensu(TaggedText tag) {
280
        if (tag.getType() == TagEnum.secReference ||
281
                tag.getType() == TagEnum.secMicroReference ||
282
                isSensuSeparator(tag)){
283
            return true;
284
        }
285
        return false;
286
    }
287

    
288
    /**
289
     * @param tag
290
     * @return
291
     */
292
    private boolean isSensuSeparator(TaggedText tag) {
293
        if (SENSU_SEPARATOR.equals(tag.getText())
294
                && tag.getType() == TagEnum.separator) {
295
            return true;
296
        }
297
        return false;
298
    }
299

    
300
    /**
301
     * @param x
302
     * @param y
303
     * @return
304
     */
305
    private boolean tagEqualsMisapplied(TaggedText x, TaggedText y) {
306
        if (CdmUtils.nullSafeEqual(x.getText(),y.getText())
307
                && x.getType().equals(y.getType())
308
                && CdmUtils.nullSafeEqual(x.getEntityReference(),y.getEntityReference())){
309
            return true;
310
        }else{
311
            return false;
312
        }
313
    }
314

    
315
    public DateTime getDate() {
316
        return date;
317
    }
318
    public void setDate(DateTime date) {
319
        this.date = date;
320
    }
321

    
322
    public int getSize(){
323
        return relations.size();
324
    }
325
//
326
//    public boolean contains(UUID taxonUuid) {
327
//        for (TaxonRelationDTO relation: relations){
328
//            if (taxon.taxonUuid.equals(taxonUuid)){
329
//                return true;
330
//            }
331
//        }
332
//        return false;
333
//    }
334

    
335
    @Override
336
    public String toString(){
337
        String result = "";
338
        for (TaxonRelationDTO relation : relations){
339
            result += relation.toString() + ",";
340
        }
341
        if (result.length() > 0){
342
            result = result.substring(0, result.length() - 1);
343
        }
344

    
345
        result = "[" + result + "]";
346
        return result;
347
    }
348

    
349
    /**
350
     * @return the misapplications
351
     */
352
    public List<List<TaggedText>> getMisapplications() {
353
        return misapplications;
354
    }
355

    
356
    /**
357
     * @param misapplications the misapplications to set
358
     */
359
    public void setMisapplications(List<List<TaggedText>> misapplications) {
360
        this.misapplications = misapplications;
361
    }
362

    
363

    
364
}
(29-29/30)