Project

General

Profile

« Previous | Next » 

Revision 22d82e8b

Added by Andreas Kohlbecker almost 7 years ago

ref #6719 improved TypeDesignationConverter

View differences:

src/main/java/eu/etaxonomy/cdm/vaadin/util/converter/TypeDesignationConverter.java
17 17
import java.util.LinkedList;
18 18
import java.util.List;
19 19
import java.util.Map;
20
import java.util.Optional;
21
import java.util.Set;
20 22

  
23
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacadeCacheStrategy;
24
import eu.etaxonomy.cdm.model.common.CdmBase;
21 25
import eu.etaxonomy.cdm.model.common.Language;
22 26
import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
23 27
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
......
25 29
import eu.etaxonomy.cdm.model.name.TaxonName;
26 30
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
27 31
import eu.etaxonomy.cdm.model.name.TypeDesignationStatusBase;
32
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
33
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
34
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
28 35
import eu.etaxonomy.cdm.vaadin.model.EntityReference;
36
import eu.etaxonomy.cdm.vaadin.model.TypedEntityReference;
29 37
import eu.etaxonomy.cdm.vaadin.view.registration.RegistrationValidationException;
30 38

  
31 39
/**
......
41 49
public class TypeDesignationConverter {
42 50

  
43 51

  
44
    private final String separator = ", ";
52
    private static final String TYPE_STATUS_SEPARATOR = "; ";
53

  
54
    private static final String TYPE_SEPARATOR = "; ";
55

  
56
    private static final String TYPE_DESIGNATION_SEPARATOR = ", ";
45 57

  
46 58
    private Collection<TypeDesignationBase> typeDesignations;
47 59

  
......
49 61
     * Groups the EntityReferences for each of the TypeDesignatinos by the according TypeDesignationStatus.
50 62
     * The TypeDesignationStatusBase keys are already ordered by the term order defined in the vocabulary.
51 63
     */
52
    private LinkedHashMap<TypeDesignationStatusBase<?>, Collection<EntityReference>> orderedStringsByOrderedTypes = new LinkedHashMap<>();
53

  
54
    /**
55
     * Groups the EntityReferences for each of the TypeDesignatinos by the label representations of the
56
     * according TypeDesignationStatus. The labels are ordered by the term order defined in the vocabulary.
57
     */
58
    private LinkedHashMap<String, Collection<EntityReference>> orderedRepresentations = new LinkedHashMap<>();
64
    private LinkedHashMap<TypedEntityReference, Map<TypeDesignationStatusBase<?>, Collection<EntityReference>>> orderedByTypesByBaseEntity;
59 65

  
60 66
    private EntityReference typifiedName;
61 67

  
62 68
    private String finalString = null;
63 69

  
64

  
65

  
66 70
    /**
67 71
     * @param taxonName
68 72
     * @throws RegistrationValidationException
......
70 74
     */
71 75
    public TypeDesignationConverter(Collection<TypeDesignationBase> typeDesignations) throws RegistrationValidationException {
72 76
        this.typeDesignations = typeDesignations;
73
        Map<TypeDesignationStatusBase<?>, Collection<EntityReference>> orderedStringsByType = new HashMap<>();
74
        typeDesignations.forEach(td -> putString(orderedStringsByType, td.getTypeStatus(), new EntityReference(td.getId(), stringify(td))));
75
        orderedStringsByOrderedTypes = orderedByType(orderedStringsByType);
76
        orderedRepresentations = buildOrderedRepresentations();
77
        Map<TypedEntityReference, Map<TypeDesignationStatusBase<?>, Collection<EntityReference>>> byBaseEntityByTypeStatus = new HashMap<>();
78
        typeDesignations.forEach(td -> mapTypeDesignation(byBaseEntityByTypeStatus, td));
79
        orderedByTypesByBaseEntity = orderByTypeByBaseEntity(byBaseEntityByTypeStatus);
77 80
        this.typifiedName = findTypifiedName();
78 81
    }
79 82

  
80
    private LinkedHashMap<TypeDesignationStatusBase<?>, Collection<EntityReference>> orderedByType(Map<TypeDesignationStatusBase<?>, Collection<EntityReference>> orderedStringsByType){
81 83

  
82
        // 1. order by SpecimenType, NameType
84
    private void mapTypeDesignation(Map<TypedEntityReference, Map<TypeDesignationStatusBase<?>, Collection<EntityReference>>> byBaseEntityByTypeStatus,
85
            TypeDesignationBase<?> td){
86

  
87
        TypeDesignationStatusBase<?> status = td.getTypeStatus();
83 88

  
84
        // SpecimenTypes.........
85
        // Order SpecimenTypes by GatheringEvent
89
        final TypedEntityReference baseEntityReference = baseEntityReference(td);
86 90

  
87
        List<TypeDesignationStatusBase<?>> keyList = new LinkedList<>(orderedStringsByType.keySet());
91
        EntityReference typeDesignationEntityReference = new EntityReference(td.getId(), stringify(td));
88 92

  
89
        Collections.sort(keyList, new Comparator<TypeDesignationStatusBase>() {
90
            @Override
91
            public int compare(TypeDesignationStatusBase o1, TypeDesignationStatusBase o2) {
92
                // fix inverted order of cdm terms by -1*
93
                return -1 * o1.compareTo(o2);
93
        Map<TypeDesignationStatusBase<?>, Collection<EntityReference>> stringsOrderdByType;
94
        if(!byBaseEntityByTypeStatus.containsKey(baseEntityReference)){
95
            byBaseEntityByTypeStatus.put(baseEntityReference, new LinkedHashMap<>());
96
        }
97

  
98
        stringsOrderdByType = byBaseEntityByTypeStatus.get(baseEntityReference);
99

  
100
        // the cdm ordered term bases are ordered inverse, fixing this for here
101
        if(status == null){
102
            status = SpecimenTypeDesignationStatus.TYPE();
103
        }
104
        if(!stringsOrderdByType.containsKey(status)){
105
            stringsOrderdByType.put(status, new ArrayList<EntityReference>());
106
        }
107
        stringsOrderdByType.get(status).add(typeDesignationEntityReference);
108
    }
109

  
110
    /**
111
     * @param td
112
     * @return
113
     */
114
    protected TypedEntityReference baseEntityReference(TypeDesignationBase<?> td) {
115

  
116
        CdmBase baseEntity = null;
117
        String label = "";
118
        if(td  instanceof SpecimenTypeDesignation){
119
            SpecimenTypeDesignation std = (SpecimenTypeDesignation) td;
120
            FieldUnit fu = findFieldUnit(std);
121
            if(fu != null){
122
                baseEntity = fu;
123
                label = fu.getTitleCache();
124
            } else if(((SpecimenTypeDesignation) td).getTypeSpecimen() != null){
125
                baseEntity = ((SpecimenTypeDesignation) td).getTypeSpecimen();
126
                label = ""; // empty label to avoid repeating the DerivedUnit details
94 127
            }
95
        });
96
        // NameTypes.........
128
        } else if(td instanceof NameTypeDesignation){
129
            baseEntity = ((NameTypeDesignation)td).getTypeName();
130
            label = "";
131
        }
132
        if(baseEntity == null) {
133
            baseEntity = td;
134
            label = "INCOMPLETE DATA";
135
        }
136

  
137
        TypedEntityReference baseEntityReference = new TypedEntityReference(baseEntity.getClass(), baseEntity.getId(), label);
97 138

  
98
        keyList.forEach(key -> orderedStringsByOrderedTypes.put(key, orderedStringsByType.get(key)));
99
        return orderedStringsByOrderedTypes;
139
        return baseEntityReference;
100 140
    }
101 141

  
102
    private LinkedHashMap<String, Collection<EntityReference>> buildOrderedRepresentations(){
142

  
143
    private LinkedHashMap<TypedEntityReference, Map<TypeDesignationStatusBase<?>, Collection<EntityReference>>> orderByTypeByBaseEntity(
144
            Map<TypedEntityReference, Map<TypeDesignationStatusBase<?>, Collection<EntityReference>>> stringsByTypeByBaseEntity){
145

  
146
       // order the FieldUnit TypeName keys
147
       List<TypedEntityReference> baseEntityKeyList = new LinkedList<>(stringsByTypeByBaseEntity.keySet());
148
       Collections.sort(baseEntityKeyList, new Comparator<TypedEntityReference>(){
149
        @Override
150
        public int compare(TypedEntityReference o1, TypedEntityReference o2) {
151
            if(!o1.getType().equals(o2.getType())) {
152
                return o1.getType().equals(FieldUnit.class) ? -1 : 1;
153
            }
154
            return o1.getLabel().compareTo(o2.getLabel());
155
        }});
156

  
157
       // new LinkedHashMap for the ordered FieldUnitOrTypeName keys
158
       LinkedHashMap<TypedEntityReference, Map<TypeDesignationStatusBase<?>, Collection<EntityReference>>> stringsOrderedbyBaseEntityOrderdByType = new LinkedHashMap<>(stringsByTypeByBaseEntity.size());
159

  
160
       for(TypedEntityReference baseEntityRef : baseEntityKeyList){
161

  
162
           Map<TypeDesignationStatusBase<?>, Collection<EntityReference>> stringsByType = stringsByTypeByBaseEntity.get(baseEntityRef);
163
           // order the TypeDesignationStatusBase keys
164
            List<TypeDesignationStatusBase<?>> keyList = new LinkedList<>(stringsByType.keySet());
165
            Collections.sort(keyList, new Comparator<TypeDesignationStatusBase>() {
166
                @Override
167
                public int compare(TypeDesignationStatusBase o1, TypeDesignationStatusBase o2) {
168
                    // fix inverted order of cdm terms by -1*
169
                    return -1 * o1.compareTo(o2);
170
                }
171
            });
172
            // new LinkedHashMap for the ordered TypeDesignationStatusBase keys
173
            LinkedHashMap<TypeDesignationStatusBase<?>, Collection<EntityReference>> orderedStringsByOrderedTypes = new LinkedHashMap<>();
174
            keyList.forEach(key -> orderedStringsByOrderedTypes.put(key, stringsByType.get(key)));
175
            stringsOrderedbyBaseEntityOrderdByType.put(baseEntityRef, orderedStringsByOrderedTypes);
176
       }
177

  
178
        return stringsOrderedbyBaseEntityOrderdByType;
179
    }
180

  
181
    /*
182
    private LinkedHashMap<TypedEntityReference, LinkedHashMap<String, Collection<EntityReference>>> buildOrderedRepresentations(){
103 183

  
104 184
        orderedStringsByOrderedTypes.keySet().forEach(
105 185
                key -> orderedRepresentations.put(
......
108 188
                );
109 189
        return orderedRepresentations;
110 190
    }
191
*/
111 192

  
112 193
    public TypeDesignationConverter buildString(){
113 194

  
114
        StringBuilder sb = new StringBuilder();
115

  
116
        if(getTypifiedNameCache() != null){
117
            sb.append(getTypifiedNameCache()).append(": ");
118
        }
119

  
120
        List<String> keyList = new LinkedList<>(orderedRepresentations.keySet());
195
        if(finalString == null){
196
            StringBuilder sb = new StringBuilder();
121 197

  
198
            if(getTypifiedNameCache() != null){
199
                sb.append(getTypifiedNameCache()).append(" ");
200
            }
122 201

  
123
        keyList.forEach(key -> {
124
            sb.append(key).append(": ");
125
            orderedRepresentations.get(key).forEach(isAndString -> {
126
                sb.append(isAndString.getLabel());
127
                if(sb.length() > 0){
128
                    sb.append(separator);
202
            int typeCount = 0;
203
            for(TypedEntityReference baseEntityRef : orderedByTypesByBaseEntity.keySet()) {
204
                if(typeCount++ > 0){
205
                    sb.append(TYPE_SEPARATOR);
129 206
                }
130
            });
131
        });
207
                boolean isNameTypeDesignation = false;
208
                if(SpecimenOrObservationBase.class.isAssignableFrom(baseEntityRef.getType())){
209
                    sb.append("Type: ");
210
                } else {
211
                    sb.append("NameType: ");
212
                    isNameTypeDesignation = true;
213
                }
214
                if(!baseEntityRef.getLabel().isEmpty()){
215
                    sb.append(baseEntityRef.getLabel()).append(" ");
216
                }
217
                Map<TypeDesignationStatusBase<?>, Collection<EntityReference>> orderedRepresentations = orderedByTypesByBaseEntity.get(baseEntityRef);
218
                if(!isNameTypeDesignation ){
219
                    sb.append("(");
220
                }
221
                int typeStatusCount = 0;
222
                for(TypeDesignationStatusBase<?> typeStatus : orderedRepresentations.keySet()) {
223
                    if(typeStatusCount++  > 0){
224
                        sb.append(TYPE_STATUS_SEPARATOR);
225
                    }
226
                    boolean isPlural = orderedRepresentations.get(typeStatus).size() > 1;
227
                    sb.append(typeStatus.getLabel());
228
                    if(isPlural){
229
                        sb.append("s: ");
230
                    } else {
231
                        sb.append(", ");
232
                    }
233
                    int typeDesignationCount = 0;
234
                    for(EntityReference typeDesignationEntityReference : orderedRepresentations.get(typeStatus)) {
235
                        if(typeDesignationCount++  > 0){
236
                            sb.append(TYPE_DESIGNATION_SEPARATOR);
237
                        }
238
                        sb.append(typeDesignationEntityReference.getLabel());
239
                    };
240
                };
241
                if(!isNameTypeDesignation ){
242
                    sb.append(")");
243
                }
244
            };
132 245

  
133
        finalString  = sb.toString();
246
            finalString  = sb.toString();
247
        }
134 248
        return this;
135 249
    }
136 250

  
137
    public Map<String, Collection<EntityReference>> getOrderedTypeDesignationRepresentations() {
138
        return orderedRepresentations;
139
    }
140

  
141 251
    /**
142 252
     * FIXME use the validation framework validators and to store the validation problems!!!
143 253
     *
......
204 314
    public EntityReference getTypifiedName() {
205 315

  
206 316
       return typifiedName;
317
    }
318

  
319
    /**
320
     * @return
321
     */
322
    public Collection<TypeDesignationBase> getTypeDesignations() {
323
        return typeDesignations;
324
    }
207 325

  
326
    public LinkedHashMap<TypedEntityReference, Map<TypeDesignationStatusBase<?>, Collection<EntityReference>>> getOrderedTypeDesignations() {
327
        return orderedByTypesByBaseEntity;
208 328
    }
209 329

  
330

  
331

  
210 332
    /**
211 333
     * @param key
212 334
     * @return
......
230 352
        if(td instanceof NameTypeDesignation){
231 353
            return stringify((NameTypeDesignation)td);
232 354
        } else {
233
            return stringify((SpecimenTypeDesignation)td);
355
            return stringify((SpecimenTypeDesignation)td, false);
234 356
        }
235 357
    }
236 358

  
......
268 390
     * @param td
269 391
     * @return
270 392
     */
271
    private String stringify(SpecimenTypeDesignation td) {
272
        StringBuffer sb = new StringBuffer();
273

  
274
        if(td.getTypeSpecimen() != null){
275
            String nameTitleCache = td.getTypeSpecimen().getTitleCache();
276
            if(getTypifiedNameCache() != null){
277
                nameTitleCache = nameTitleCache.replace(getTypifiedNameCache(), "");
393
    private String stringify(SpecimenTypeDesignation td, boolean useFullTitleCache) {
394
        String  result = "";
395

  
396
        if(useFullTitleCache){
397
            if(td.getTypeSpecimen() != null){
398
                String nameTitleCache = td.getTypeSpecimen().getTitleCache();
399
                if(getTypifiedNameCache() != null){
400
                    nameTitleCache = nameTitleCache.replace(getTypifiedNameCache(), "");
401
                }
402
                result += nameTitleCache;
403
            }
404
        } else {
405
            if(td.getTypeSpecimen() != null){
406
                DerivedUnit du = td.getTypeSpecimen();
407
                if(du.isProtectedTitleCache()){
408
                    result += du.getTitleCache();
409
                } else {
410
                    DerivedUnitFacadeCacheStrategy cacheStrategy = new DerivedUnitFacadeCacheStrategy();
411
                    result += cacheStrategy.getTitleCache(du);
412
                }
278 413
            }
279
            sb.append(nameTitleCache);
280 414
        }
281 415

  
282 416
        if(td.getCitation() != null){
283
            sb.append(" ").append(td.getCitation().getTitleCache());
417
            result += " " + td.getCitation().getTitleCache();
284 418
            if(td.getCitationMicroReference() != null){
285
                sb.append(" :").append(td.getCitationMicroReference());
419
                result += " :" + td.getCitationMicroReference();
286 420
            }
287 421
        }
288 422
        if(td.isNotDesignated()){
289
            sb.append(" not designated");
423
            result += " not designated";
290 424
        }
291 425

  
292
        return sb.toString();
426
        return result;
293 427
    }
294 428

  
295
    private void putString(Map<TypeDesignationStatusBase<?>, Collection<EntityReference>> orderedStringsByType, TypeDesignationStatusBase<?> status, EntityReference idAndString){
296
        // the cdm orderd term bases are ordered invers, fixing this for here
297
        if(status == null){
298
            status = SpecimenTypeDesignationStatus.TYPE();
429
    /**
430
     * @param td
431
     * @return
432
     * @deprecated
433
     */
434
    @Deprecated
435
    private FieldUnit findFieldUnit(SpecimenTypeDesignation td) {
436

  
437
        DerivedUnit du = td.getTypeSpecimen();
438
        return findFieldUnit(du);
439
    }
440

  
441
    private FieldUnit findFieldUnit(DerivedUnit du) {
442

  
443
        if(du == null || du.getOriginals() == null){
444
            return null;
299 445
        }
300
        if(!orderedStringsByType.containsKey(status)){
301
            orderedStringsByType.put(status, new ArrayList<EntityReference>());
446
        @SuppressWarnings("rawtypes")
447
        Set<SpecimenOrObservationBase> originals = du.getDerivedFrom().getOriginals();
448
        @SuppressWarnings("rawtypes")
449
        Optional<SpecimenOrObservationBase> fieldUnit = originals.stream()
450
                .filter(original -> original instanceof FieldUnit).findFirst();
451
        if (fieldUnit.isPresent()) {
452
            return (FieldUnit) fieldUnit.get();
453
        } else {
454
            for (@SuppressWarnings("rawtypes")
455
            SpecimenOrObservationBase sob : originals) {
456
                if (sob instanceof DerivedUnit) {
457
                    FieldUnit fu = findFieldUnit((DerivedUnit) sob);
458
                    if (fu != null) {
459
                        return fu;
460
                    }
461
                }
462
            }
302 463
        }
303
        orderedStringsByType.get(status).add(idAndString);
464

  
465
        return null;
304 466
    }
305 467

  
306
    public String print(){
468

  
469
    public String print() {
307 470
        return finalString;
471
    }
472

  
473
/**
474
 *
475
 * @author a.kohlbecker
476
 * @since Jun 12, 2017
477
 *
478
 */
479
    public class FieldUnitOrTypeName {
480

  
481
        FieldUnit fieldUnit = null;
482

  
483
        TaxonName typeName = null;
484

  
485
        /**
486
         * @param fieldUnit
487
         * @param typeName
488
         */
489
        private FieldUnitOrTypeName(FieldUnit fieldUnit, TaxonName typeName) {
490
            this.fieldUnit = fieldUnit;
491
            this.typeName = typeName;
492
            if(fieldUnit != null && typeName != null){
493
                throw new RuntimeException("FieldUnitOrTypeName must not contain two non null fields");
494
            }
495

  
496
            if(fieldUnit == null && typeName == null){
497
                throw new NullPointerException("FieldUnitOrTypeName must not contain two null fields");
498
            }
499
        }
500

  
501
        /**
502
         * @return the fieldUnit
503
         */
504
        public FieldUnit getFieldUnit() {
505
            return fieldUnit;
506
        }
507

  
508
        /**
509
         * @return the typeName
510
         */
511
        public TaxonName getTypeName() {
512
            return typeName;
513
        }
514

  
515
        /**
516
         * @return the fieldUnit
517
         */
518
        public boolean isFieldUnit() {
519
            return fieldUnit != null;
520
        }
521

  
522
        /**
523
         * @return the typeName
524
         */
525
        public boolean isTypeName() {
526
            return typeName != null;
527
        }
528

  
529
        public int getEntitiyId() {
530
            if(isFieldUnit()){
531
                return fieldUnit.getId();
532
            } else {
533
                return typeName.getId();
534
            }
535
        }
536

  
537
        /**
538
         * @return
539
         */
540
        public String getTypeLabel() {
541
            if(isFieldUnit()){
542
                return "Type";
543
            } else {
544
                return "NameType";
545
            }
546
        }
547

  
548
        /**
549
         * @return
550
         */
551
        public String getTitleCache() {
552
            if(isFieldUnit()){
553
                return fieldUnit.getTitleCache();
554
            } else {
555
                return typeName.getTitleCache();
556
            }
557
        }
558

  
559
        public boolean matches(FieldUnit fieldUnit, TaxonName typeName){
560
            boolean fuMatch = this.fieldUnit == null && fieldUnit == null || this.fieldUnit.equals(fieldUnit);
561
            boolean nameMatch = this.typeName == null && typeName == null || this.typeName.equals(typeName);
562
            return fuMatch && nameMatch;
563
        }
564

  
565

  
566

  
567

  
308 568
    }
309 569
}

Also available in: Unified diff