Project

General

Profile

Download (24 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.vaadin.util.converter;
10

    
11
import java.util.ArrayList;
12
import java.util.Collection;
13
import java.util.Collections;
14
import java.util.Comparator;
15
import java.util.HashMap;
16
import java.util.LinkedHashMap;
17
import java.util.LinkedList;
18
import java.util.List;
19
import java.util.Map;
20
import java.util.Optional;
21
import java.util.Set;
22

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

    
40
/**
41
 * Manages a collection of {@link TypeDesignationBase TypeDesignations} for the same same typified name.
42
 *
43
 * Type designations are ordered by the base type which is a {@link TaxonName} for {@link NameTypeDesignation NameTypeDesignations} or
44
 * in case of {@link SpecimenTypeDesignation SpecimenTypeDesignations} the  associate {@link FieldUnit} or the {@link DerivedUnit}
45
 * if the former is missing. The type designations per base type are furthermore ordered by the {@link TypeDesignationStatusBase}.
46
 *
47
 * The TypeDesignationConverter also provides string representations of the whole ordered set of all
48
 * {@link TypeDesignationBase TypeDesignations} and of the TypeDesignationWorkingSets:
49
 * <ul>
50
 *  <li>{@link #print()})
51
 *  <li>{@link #getOrderdTypeDesignationWorkingSets()} ... {@link TypeDesignationWorkingSet#getRepresentation()}
52
 * </ul>
53
 * Prior using the representations you need to trigger their generation by calling {@link #buildString()}
54
 *
55
 * @author a.kohlbecker
56
 * @since Mar 10, 2017
57
 *
58
 */
59
public class TypeDesignationConverter {
60

    
61

    
62
    private static final String TYPE_STATUS_SEPARATOR = "; ";
63

    
64
    private static final String TYPE_SEPARATOR = "; ";
65

    
66
    private static final String TYPE_DESIGNATION_SEPARATOR = ", ";
67

    
68
    private Collection<TypeDesignationBase> typeDesignations;
69

    
70
    private int workingSetIdAutoIncrement = 0;
71

    
72
    /**
73
     * Groups the EntityReferences for each of the TypeDesignations by the according TypeDesignationStatus.
74
     * The TypeDesignationStatusBase keys are already ordered by the term order defined in the vocabulary.
75
     */
76
    private LinkedHashMap<TypedEntityReference, TypeDesignationWorkingSet> orderedByTypesByBaseEntity;
77

    
78
    private EntityReference typifiedName;
79

    
80
    private String finalString = null;
81

    
82
    final NullTypeDesignationStatus NULL_STATUS = new NullTypeDesignationStatus();
83

    
84
    private List<String> probelms = new ArrayList<>();
85

    
86
    /**
87
     * @param taxonName
88
     * @throws RegistrationValidationException
89
     *
90
     */
91
    public TypeDesignationConverter(CdmBase containgEntity, Collection<TypeDesignationBase> typeDesignations) throws RegistrationValidationException {
92
        this.typeDesignations = typeDesignations;
93
        Map<TypedEntityReference, TypeDesignationWorkingSet> byBaseEntityByTypeStatus = new HashMap<>();
94
        typeDesignations.forEach(td -> mapTypeDesignation(containgEntity, byBaseEntityByTypeStatus, td));
95
        orderedByTypesByBaseEntity = orderByTypeByBaseEntity(byBaseEntityByTypeStatus);
96
        this.typifiedName = findTypifiedName();
97
    }
98

    
99

    
100
    private void mapTypeDesignation(CdmBase containgEntity, Map<TypedEntityReference, TypeDesignationWorkingSet> byBaseEntityByTypeStatus,
101
            TypeDesignationBase<?> td){
102

    
103
        TypeDesignationStatusBase<?> status = td.getTypeStatus();
104

    
105
        try {
106
            final IdentifiableEntity<?> baseEntity = baseEntity(td);
107
            final TypedEntityReference<IdentifiableEntity<?>> baseEntityReference = makeEntityReference(baseEntity);
108

    
109
            EntityReference typeDesignationEntityReference = new EntityReference(td.getId(), stringify(td));
110

    
111
            TypeDesignationWorkingSet typedesignationWorkingSet;
112
            if(!byBaseEntityByTypeStatus.containsKey(baseEntityReference)){
113
                TypedEntityReference containigEntityReference = new TypedEntityReference(containgEntity.getClass(), containgEntity.getId(), containgEntity.toString());
114
                byBaseEntityByTypeStatus.put(baseEntityReference, new TypeDesignationWorkingSet(containigEntityReference, baseEntity, baseEntityReference));
115
            }
116

    
117
            typedesignationWorkingSet = byBaseEntityByTypeStatus.get(baseEntityReference);
118
            typedesignationWorkingSet.insert(status, typeDesignationEntityReference);
119
        } catch (DataIntegrityException e){
120
            probelms.add(e.getMessage());
121
        }
122
    }
123

    
124
    /**
125
     * @param td
126
     * @return
127
     * @throws DataIntegrityException
128
     */
129
    protected IdentifiableEntity<?> baseEntity(TypeDesignationBase<?> td) throws DataIntegrityException {
130

    
131
        IdentifiableEntity<?> baseEntity = null;
132
        if(td  instanceof SpecimenTypeDesignation){
133
            SpecimenTypeDesignation std = (SpecimenTypeDesignation) td;
134
            FieldUnit fu = findFieldUnit(std);
135
            if(fu != null){
136
                baseEntity = fu;
137
            } else if(((SpecimenTypeDesignation) td).getTypeSpecimen() != null){
138
                baseEntity = ((SpecimenTypeDesignation) td).getTypeSpecimen();
139
            }
140
        } else if(td instanceof NameTypeDesignation){
141
            baseEntity = ((NameTypeDesignation)td).getTypeName();
142
        }
143
        if(baseEntity == null) {
144
            throw new DataIntegrityException("Incomplete TypeDesignation, no type missin in " + td.toString());
145
        }
146
        return baseEntity;
147
    }
148

    
149
    /**
150
     * @param td
151
     * @return
152
     */
153
    protected TypedEntityReference<IdentifiableEntity<?>> makeEntityReference(IdentifiableEntity<?> baseEntity) {
154
;
155
        String label = "";
156
        if(baseEntity  instanceof FieldUnit){
157
                label = ((FieldUnit)baseEntity).getTitleCache();
158
        }
159

    
160
        TypedEntityReference<IdentifiableEntity<?>> baseEntityReference = new TypedEntityReference(baseEntity.getClass(), baseEntity.getId(), label);
161

    
162
        return baseEntityReference;
163
    }
164

    
165

    
166
    private LinkedHashMap<TypedEntityReference, TypeDesignationWorkingSet> orderByTypeByBaseEntity(
167
            Map<TypedEntityReference, TypeDesignationWorkingSet> stringsByTypeByBaseEntity){
168

    
169
       // order the FieldUnit TypeName keys
170
       List<TypedEntityReference> baseEntityKeyList = new LinkedList<>(stringsByTypeByBaseEntity.keySet());
171
       Collections.sort(baseEntityKeyList, new Comparator<TypedEntityReference>(){
172
        /**
173
         * Sorts the base entities (TypedEntityReference) in the following order:
174
         *
175
         * 1. FieldUnits
176
         * 2. DerivedUnit (in case of missing FieldUnit we expect the base type to be DerivedUnit)
177
         * 3. NameType
178
         *
179
         * {@inheritDoc}
180
         */
181
        @Override
182
        public int compare(TypedEntityReference o1, TypedEntityReference o2) {
183

    
184
            Class type1 = o1.getType();
185
            Class type2 = o2.getType();
186

    
187
            if(!type1.equals(type2)) {
188
                if(type1.equals(FieldUnit.class) || type2.equals(FieldUnit.class)){
189
                    // FieldUnits first
190
                    return type1.equals(FieldUnit.class) ? -1 : 1;
191
                } else {
192
                    // name types last (in case of missing FieldUnit we expect the base type to be DerivedUnit which comes into the middle)
193
                    return type2.equals(TaxonName.class) ? -1 : 1;
194
                }
195
            } else {
196
                return o1.getLabel().compareTo(o2.getLabel());
197
            }
198
        }});
199

    
200
       // new LinkedHashMap for the ordered FieldUnitOrTypeName keys
201
       LinkedHashMap<TypedEntityReference, TypeDesignationWorkingSet> stringsOrderedbyBaseEntityOrderdByType = new LinkedHashMap<>(stringsByTypeByBaseEntity.size());
202

    
203
       for(TypedEntityReference baseEntityRef : baseEntityKeyList){
204

    
205
           TypeDesignationWorkingSet typeDesignationWorkingSet = stringsByTypeByBaseEntity.get(baseEntityRef);
206
           // order the TypeDesignationStatusBase keys
207
            List<TypeDesignationStatusBase<?>> keyList = new LinkedList<>(typeDesignationWorkingSet.keySet());
208
            Collections.sort(keyList, new Comparator<TypeDesignationStatusBase>() {
209
                @SuppressWarnings("unchecked")
210
                @Override
211
                public int compare(TypeDesignationStatusBase o1, TypeDesignationStatusBase o2) {
212
                    // fix inverted order of cdm terms by -1*
213
                    return -1 * o1.compareTo(o2);
214
                }
215
            });
216
            // new LinkedHashMap for the ordered TypeDesignationStatusBase keys
217
            TypeDesignationWorkingSet orderedStringsByOrderedTypes = new TypeDesignationWorkingSet(typeDesignationWorkingSet.getContainigEntityReference(),
218
                    typeDesignationWorkingSet.getBaseEntity(),
219
                    baseEntityRef);
220
            orderedStringsByOrderedTypes.setWorkingSetId(typeDesignationWorkingSet.workingSetId); // preserve original workingSetId
221
            keyList.forEach(key -> orderedStringsByOrderedTypes.put(key, typeDesignationWorkingSet.get(key)));
222
            stringsOrderedbyBaseEntityOrderdByType.put(baseEntityRef, orderedStringsByOrderedTypes);
223
       }
224

    
225
        return stringsOrderedbyBaseEntityOrderdByType;
226
    }
227

    
228
    /*
229
    private LinkedHashMap<TypedEntityReference, LinkedHashMap<String, Collection<EntityReference>>> buildOrderedRepresentations(){
230

    
231
        orderedStringsByOrderedTypes.keySet().forEach(
232
                key -> orderedRepresentations.put(
233
                        getTypeDesignationStytusLabel(key),
234
                        orderedStringsByOrderedTypes.get(key))
235
                );
236
        return orderedRepresentations;
237
    }
238
*/
239

    
240
    public TypeDesignationConverter buildString(){
241

    
242
        if(finalString == null){
243

    
244
            finalString = "";
245
            if(getTypifiedNameCache() != null){
246
                finalString += getTypifiedNameCache() + " ";
247
            }
248

    
249
            int typeCount = 0;
250
            for(TypedEntityReference baseEntityRef : orderedByTypesByBaseEntity.keySet()) {
251
                StringBuilder sb = new StringBuilder();
252
                if(typeCount++ > 0){
253
                    sb.append(TYPE_SEPARATOR);
254
                }
255
                boolean isNameTypeDesignation = false;
256
                if(SpecimenOrObservationBase.class.isAssignableFrom(baseEntityRef.getType())){
257
                    sb.append("Type: ");
258
                } else {
259
                    sb.append("NameType: ");
260
                    isNameTypeDesignation = true;
261
                }
262
                if(!baseEntityRef.getLabel().isEmpty()){
263
                    sb.append(baseEntityRef.getLabel()).append(" ");
264
                }
265
                TypeDesignationWorkingSet typeDesignationWorkingSet = orderedByTypesByBaseEntity.get(baseEntityRef);
266
                if(!isNameTypeDesignation ){
267
                    sb.append("(");
268
                }
269
                int typeStatusCount = 0;
270
                for(TypeDesignationStatusBase<?> typeStatus : typeDesignationWorkingSet.keySet()) {
271
                    if(typeStatusCount++  > 0){
272
                        sb.append(TYPE_STATUS_SEPARATOR);
273
                    }
274
                    boolean isPlural = typeDesignationWorkingSet.get(typeStatus).size() > 1;
275
                    if(!typeStatus.equals(NULL_STATUS)) {
276
                        sb.append(typeStatus.getLabel());
277
                        if(isPlural){
278
                            sb.append("s: ");
279
                        } else {
280
                            sb.append(", ");
281
                        }
282
                    }
283
                    int typeDesignationCount = 0;
284
                    for(EntityReference typeDesignationEntityReference : typeDesignationWorkingSet.get(typeStatus)) {
285
                        if(typeDesignationCount++  > 0){
286
                            sb.append(TYPE_DESIGNATION_SEPARATOR);
287
                        }
288
                        sb.append(typeDesignationEntityReference.getLabel());
289
                    }
290
                }
291
                if(!isNameTypeDesignation ){
292
                    sb.append(")");
293
                }
294
                typeDesignationWorkingSet.setRepresentation(sb.toString());
295
                finalString += typeDesignationWorkingSet.getRepresentation();
296
            }
297

    
298
        }
299
        return this;
300
    }
301

    
302
    /**
303
     * FIXME use the validation framework validators and to store the validation problems!!!
304
     *
305
     * @return
306
     * @throws RegistrationValidationException
307
     */
308
    private EntityReference findTypifiedName() throws RegistrationValidationException {
309

    
310
        List<String> problems = new ArrayList<>();
311

    
312
        TaxonName typifiedName = null;
313

    
314
        for(TypeDesignationBase<?> typeDesignation : typeDesignations){
315
            typeDesignation.getTypifiedNames();
316
            if(typeDesignation.getTypifiedNames().isEmpty()){
317

    
318
                //TODO instead throw RegistrationValidationException()
319
                problems.add("Missing typifiedName in " + typeDesignation.toString());
320
                continue;
321
            }
322
            if(typeDesignation.getTypifiedNames().size() > 1){
323
              //TODO instead throw RegistrationValidationException()
324
                problems.add("Multiple typifiedName in " + typeDesignation.toString());
325
                continue;
326
            }
327
            if(typifiedName == null){
328
                // remember
329
                typifiedName = typeDesignation.getTypifiedNames().iterator().next();
330
            } else {
331
                // compare
332
                TaxonName otherTypifiedName = typeDesignation.getTypifiedNames().iterator().next();
333
                if(typifiedName.getId() != otherTypifiedName.getId()){
334
                  //TODO instead throw RegistrationValidationException()
335
                    problems.add("Multiple typifiedName in " + typeDesignation.toString());
336
                }
337
            }
338

    
339
        }
340
        if(!problems.isEmpty()){
341
            // FIXME use the validation framework
342
            throw new RegistrationValidationException("Inconsistent type designations", problems);
343
        }
344

    
345
        if(typifiedName != null){
346
            return new EntityReference(typifiedName.getId(), typifiedName.getTitleCache());
347
        }
348
        return null;
349
    }
350

    
351

    
352
    /**
353
     * @return the title cache of the typifying name or <code>null</code>
354
     */
355
    public String getTypifiedNameCache() {
356
        if(typifiedName != null){
357
            return typifiedName.getLabel();
358
        }
359
        return null;
360
    }
361

    
362
    /**
363
     * @return the title cache of the typifying name or <code>null</code>
364
     */
365
    public EntityReference getTypifiedName() {
366

    
367
       return typifiedName;
368
    }
369

    
370
    /**
371
     * @return
372
     */
373
    public Collection<TypeDesignationBase> getTypeDesignations() {
374
        return typeDesignations;
375
    }
376

    
377
    /**
378
     * @param ref
379
     * @return
380
     */
381
    public TypeDesignationBase findTypeDesignation(EntityReference typeDesignationRef) {
382
        for(TypeDesignationBase td : typeDesignations){
383
            if(td.getId() == typeDesignationRef.getId()){
384
                return td;
385
            }
386
        }
387
        // TODO Auto-generated method stub
388
        return null;
389
    }
390

    
391

    
392
    public LinkedHashMap<TypedEntityReference, TypeDesignationWorkingSet> getOrderdTypeDesignationWorkingSets() {
393
        return orderedByTypesByBaseEntity;
394
    }
395

    
396
    /**
397
     * @param td
398
     * @return
399
     */
400
    private String stringify(TypeDesignationBase td) {
401

    
402
        if(td instanceof NameTypeDesignation){
403
            return stringify((NameTypeDesignation)td);
404
        } else {
405
            return stringify((SpecimenTypeDesignation)td, false);
406
        }
407
    }
408

    
409

    
410
    /**
411
     * @param td
412
     * @return
413
     */
414
    protected String stringify(NameTypeDesignation td) {
415

    
416
        StringBuffer sb = new StringBuffer();
417

    
418
        if(td.getTypeName() != null){
419
            sb.append(td.getTypeName().getTitleCache());
420
        }
421
        if(td.getCitation() != null){
422
            sb.append(" ").append(td.getCitation().getTitleCache());
423
            if(td.getCitationMicroReference() != null){
424
                sb.append(":").append(td.getCitationMicroReference());
425
            }
426
        }
427
        if(td.isNotDesignated()){
428
            sb.append(" not designated");
429
        }
430
        if(td.isRejectedType()){
431
            sb.append(" rejected");
432
        }
433
        if(td.isConservedType()){
434
            sb.append(" conserved");
435
        }
436
        return sb.toString();
437
    }
438

    
439
    /**
440
     * @param td
441
     * @return
442
     */
443
    private String stringify(SpecimenTypeDesignation td, boolean useFullTitleCache) {
444
        String  result = "";
445

    
446
        if(useFullTitleCache){
447
            if(td.getTypeSpecimen() != null){
448
                String nameTitleCache = td.getTypeSpecimen().getTitleCache();
449
                if(getTypifiedNameCache() != null){
450
                    nameTitleCache = nameTitleCache.replace(getTypifiedNameCache(), "");
451
                }
452
                result += nameTitleCache;
453
            }
454
        } else {
455
            if(td.getTypeSpecimen() != null){
456
                DerivedUnit du = td.getTypeSpecimen();
457
                if(du.isProtectedTitleCache()){
458
                    result += du.getTitleCache();
459
                } else {
460
                    DerivedUnitFacadeCacheStrategy cacheStrategy = new DerivedUnitFacadeCacheStrategy();
461
                    result += cacheStrategy.getTitleCache(du, true);
462
                }
463
            }
464
        }
465

    
466
        if(td.getCitation() != null){
467
            result += " " + td.getCitation().getTitleCache();
468
            if(td.getCitationMicroReference() != null){
469
                result += " :" + td.getCitationMicroReference();
470
            }
471
        }
472
        if(td.isNotDesignated()){
473
            result += " not designated";
474
        }
475

    
476
        return result;
477
    }
478

    
479
    /**
480
     * @param td
481
     * @return
482
     * @deprecated
483
     */
484
    @Deprecated
485
    private FieldUnit findFieldUnit(SpecimenTypeDesignation td) {
486

    
487
        DerivedUnit du = td.getTypeSpecimen();
488
        return findFieldUnit(du);
489
    }
490

    
491
    private FieldUnit findFieldUnit(DerivedUnit du) {
492

    
493
        if(du == null || du.getOriginals() == null){
494
            return null;
495
        }
496
        @SuppressWarnings("rawtypes")
497
        Set<SpecimenOrObservationBase> originals = du.getDerivedFrom().getOriginals();
498
        @SuppressWarnings("rawtypes")
499
        Optional<SpecimenOrObservationBase> fieldUnit = originals.stream()
500
                .filter(original -> original instanceof FieldUnit).findFirst();
501
        if (fieldUnit.isPresent()) {
502
            return (FieldUnit) fieldUnit.get();
503
        } else {
504
            for (@SuppressWarnings("rawtypes")
505
            SpecimenOrObservationBase sob : originals) {
506
                if (sob instanceof DerivedUnit) {
507
                    FieldUnit fu = findFieldUnit((DerivedUnit) sob);
508
                    if (fu != null) {
509
                        return fu;
510
                    }
511
                }
512
            }
513
        }
514

    
515
        return null;
516
    }
517

    
518
    public String print() {
519
        return finalString;
520
    }
521

    
522
    /**
523
     * Groups the EntityReferences for TypeDesignations by the according TypeDesignationStatus.
524
     * The TypeDesignationStatusBase keys can be ordered by the term order defined in the vocabulary.
525
     */
526
    public class TypeDesignationWorkingSet extends LinkedHashMap<TypeDesignationStatusBase<?>, Collection<EntityReference>> {
527

    
528
        private static final long serialVersionUID = -1329007606500890729L;
529

    
530
        String workingSetRepresentation = null;
531

    
532
        TypedEntityReference<?> containigEntityReference;
533

    
534
        TypedEntityReference<IdentifiableEntity<?>> baseEntityReference;
535

    
536
        IdentifiableEntity<?> baseEntity;
537

    
538
        List<DerivedUnit> derivedUnits = null;
539

    
540
        int workingSetId = workingSetIdAutoIncrement++;
541

    
542
        /**
543
         * @param baseEntityReference
544
         */
545
        public TypeDesignationWorkingSet(TypedEntityReference<? extends VersionableEntity> containigEntityReference, IdentifiableEntity<?> baseEntity, TypedEntityReference<IdentifiableEntity<?>> baseEntityReference) {
546
            this.containigEntityReference = containigEntityReference;
547
            this.baseEntity = baseEntity;
548
            this.baseEntityReference = baseEntityReference;
549
        }
550

    
551
        /**
552
         * @return
553
         */
554
        public IdentifiableEntity<?> getBaseEntity() {
555
            return baseEntity;
556
        }
557

    
558
        public List<EntityReference> getTypeDesignations() {
559
            List<EntityReference> typeDesignations = new ArrayList<>();
560
            this.values().forEach(typeDesignationReferences -> typeDesignationReferences.forEach(td -> typeDesignations.add(td)));
561
            return typeDesignations;
562
        }
563

    
564
        /**
565
         * @param status
566
         * @param typeDesignationEntityReference
567
         */
568
        public void insert(TypeDesignationStatusBase<?> status, EntityReference typeDesignationEntityReference) {
569

    
570
            if(status == null){
571
                status = NULL_STATUS;
572
            }
573
            if(!containsKey(status)){
574
                put(status, new ArrayList<EntityReference>());
575
            }
576
            get(status).add(typeDesignationEntityReference);
577
        }
578

    
579
        /**
580
         * @return the workingSetId
581
         */
582
        public int getWorkingSetId() {
583
            return workingSetId;
584
        }
585

    
586
        /**
587
         * @param workingSetId the workingSetId to set
588
         */
589
        public void setWorkingSetId(int workingSetId) {
590
            this.workingSetId = workingSetId;
591
        }
592

    
593
        public String getRepresentation() {
594
            return workingSetRepresentation;
595
        }
596

    
597
        public void setRepresentation(String representation){
598
            this.workingSetRepresentation = representation;
599
        }
600

    
601
        /**
602
         * A reference to the entity which is the common base entity for all TypeDesignations in this workingset.
603
         * For a {@link SpecimenTypeDesignation} this is usually the {@link FieldUnit} if it is present. Otherwise it can also be
604
         * a {@link DerivedUnit} or something else depending on the specific use case.
605
         *
606
         * @return the baseEntityReference
607
         */
608
        public TypedEntityReference getBaseEntityReference() {
609
            return baseEntityReference;
610
        }
611

    
612
        /**
613
         * A reference to the entity which contains the TypeDesignations bundled in this working set.
614
         * This can be for example a {@link TaxonName} or a {@link Registration} entity.
615
         *
616
         * @return the baseEntityReference
617
         */
618
        public TypedEntityReference getContainigEntityReference() {
619
            return containigEntityReference;
620
        }
621

    
622
        @Override
623
        public String toString(){
624
            if(workingSetRepresentation != null){
625
                return workingSetRepresentation;
626
            } else {
627
                return super.toString();
628
            }
629
        }
630

    
631
        /**
632
         * @return
633
         */
634
        public boolean isSpecimenTypeDesigationWorkingSet() {
635
            return SpecimenOrObservationBase.class.isAssignableFrom(baseEntityReference.getType());
636
        }
637

    
638
    }
639

    
640
    @SuppressWarnings({ "deprecation", "serial" })
641
    class NullTypeDesignationStatus extends TypeDesignationStatusBase<NullTypeDesignationStatus>{
642

    
643
        /**
644
         * {@inheritDoc}
645
         */
646
        @Override
647
        public void resetTerms() {
648
            // empty
649

    
650
        }
651

    
652
        /**
653
         * {@inheritDoc}
654
         */
655
        @Override
656
        protected void setDefaultTerms(TermVocabulary<NullTypeDesignationStatus> termVocabulary) {
657
            // empty
658
        }
659

    
660

    
661

    
662
    }
663

    
664
}
(5-5/6)