fix #7083 possible to edit preferredStableUri of TypeSpecimens
[cdm-vaadin.git] / src / main / java / eu / etaxonomy / cdm / vaadin / util / converter / TypeDesignationSetManager.java
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.Arrays;
13 import java.util.Collection;
14 import java.util.Collections;
15 import java.util.Comparator;
16 import java.util.HashMap;
17 import java.util.LinkedHashMap;
18 import java.util.LinkedList;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Optional;
22 import java.util.Set;
23
24 import org.hibernate.search.hcore.util.impl.HibernateHelper;
25
26 import eu.etaxonomy.cdm.api.facade.DerivedUnitFacadeCacheStrategy;
27 import eu.etaxonomy.cdm.model.common.CdmBase;
28 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
29 import eu.etaxonomy.cdm.model.common.TermVocabulary;
30 import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
31 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
32 import eu.etaxonomy.cdm.model.name.TaxonName;
33 import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
34 import eu.etaxonomy.cdm.model.name.TypeDesignationStatusBase;
35 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
36 import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
37 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
38 import eu.etaxonomy.cdm.vaadin.model.EntityReference;
39 import eu.etaxonomy.cdm.vaadin.model.TypedEntityReference;
40 import eu.etaxonomy.cdm.vaadin.view.registration.RegistrationValidationException;
41
42 /**
43 * Manages a collection of {@link TypeDesignationBase TypeDesignations} for the same typified name.
44 *
45 * Type designations are ordered by the base type which is a {@link TaxonName} for {@link NameTypeDesignation NameTypeDesignations} or
46 * in case of {@link SpecimenTypeDesignation SpecimenTypeDesignations} the associate {@link FieldUnit} or the {@link DerivedUnit}
47 * if the former is missing. The type designations per base type are furthermore ordered by the {@link TypeDesignationStatusBase}.
48 *
49 * The TypeDesignationSetManager also provides string representations of the whole ordered set of all
50 * {@link TypeDesignationBase TypeDesignations} and of the TypeDesignationWorkingSets:
51 * <ul>
52 * <li>{@link #print()})
53 * <li>{@link #getOrderdTypeDesignationWorkingSets()} ... {@link TypeDesignationWorkingSet#getRepresentation()}
54 * </ul>
55 * Prior using the representations you need to trigger their generation by calling {@link #buildString()}
56 *
57 * @author a.kohlbecker
58 * @since Mar 10, 2017
59 *
60 */
61 public class TypeDesignationSetManager {
62
63
64 private static final String TYPE_STATUS_SEPARATOR = "; ";
65
66 private static final String TYPE_SEPARATOR = "; ";
67
68 private static final String TYPE_DESIGNATION_SEPARATOR = ", ";
69
70 private Collection<TypeDesignationBase> typeDesignations;
71
72 private int workingSetIdAutoIncrement = 0;
73
74 /**
75 * Groups the EntityReferences for each of the TypeDesignations by the according TypeDesignationStatus.
76 * The TypeDesignationStatusBase keys are already ordered by the term order defined in the vocabulary.
77 */
78 private LinkedHashMap<TypedEntityReference, TypeDesignationWorkingSet> orderedByTypesByBaseEntity;
79
80 private EntityReference typifiedNameRef;
81
82 private TaxonName typifiedName;
83
84 private String finalString = null;
85
86 final NullTypeDesignationStatus NULL_STATUS = new NullTypeDesignationStatus();
87
88 private List<String> probelms = new ArrayList<>();
89
90 private boolean printCitation = false;
91
92 /**
93 * @param containgEntity
94 * @param taxonName
95 * @throws RegistrationValidationException
96 *
97 */
98 public TypeDesignationSetManager(Collection<TypeDesignationBase> typeDesignations) throws RegistrationValidationException {
99 this.typeDesignations = typeDesignations;
100 findTypifiedName();
101 mapAndSort();
102 }
103
104 /**
105 * @param typifiedName2
106 */
107 public TypeDesignationSetManager(TaxonName typifiedName) {
108 this.typeDesignations = new ArrayList<>();
109 this.typifiedNameRef = new EntityReference(typifiedName.getId(), typifiedName.getTitleCache());
110 }
111
112 /**
113 * Add one or more TypeDesignations to the manager. This causes re-grouping and re-ordering
114 * of all managed TypeDesignations.
115 *
116 * @param containgEntity
117 * @param typeDesignations
118 */
119 public void addTypeDesigations(CdmBase containgEntity, TypeDesignationBase ... typeDesignations){
120 this.typeDesignations.addAll(Arrays.asList(typeDesignations));
121 mapAndSort();
122 }
123
124 /**
125 * Groups and orders all managed TypeDesignations.
126 *
127 * @param containgEntity
128 */
129 protected void mapAndSort() {
130 finalString = null;
131 Map<TypedEntityReference, TypeDesignationWorkingSet> byBaseEntityByTypeStatus = new HashMap<>();
132 this.typeDesignations.forEach(td -> mapTypeDesignation(byBaseEntityByTypeStatus, td));
133 orderedByTypesByBaseEntity = orderByTypeByBaseEntity(byBaseEntityByTypeStatus);
134 }
135
136
137 /**
138 *
139 * @param containgEntity
140 * @param byBaseEntityByTypeStatus
141 * @param td
142 */
143 private void mapTypeDesignation(Map<TypedEntityReference, TypeDesignationWorkingSet> byBaseEntityByTypeStatus,
144 TypeDesignationBase<?> td){
145
146 TypeDesignationStatusBase<?> status = td.getTypeStatus();
147
148 try {
149 final IdentifiableEntity<?> baseEntity = baseEntity(td);
150 final TypedEntityReference<IdentifiableEntity<?>> baseEntityReference = makeEntityReference(baseEntity);
151
152 EntityReference typeDesignationEntityReference = new EntityReference(td.getId(), stringify(td));
153
154 TypeDesignationWorkingSet typedesignationWorkingSet;
155 if(!byBaseEntityByTypeStatus.containsKey(baseEntityReference)){
156 byBaseEntityByTypeStatus.put(baseEntityReference, new TypeDesignationWorkingSet(baseEntity, baseEntityReference));
157 }
158
159 typedesignationWorkingSet = byBaseEntityByTypeStatus.get(baseEntityReference);
160 typedesignationWorkingSet.insert(status, typeDesignationEntityReference);
161 } catch (DataIntegrityException e){
162 probelms.add(e.getMessage());
163 }
164 }
165
166 /**
167 * @param td
168 * @return
169 * @throws DataIntegrityException
170 */
171 protected IdentifiableEntity<?> baseEntity(TypeDesignationBase<?> td) throws DataIntegrityException {
172
173 IdentifiableEntity<?> baseEntity = null;
174 if(td instanceof SpecimenTypeDesignation){
175 SpecimenTypeDesignation std = (SpecimenTypeDesignation) td;
176 FieldUnit fu = findFieldUnit(std);
177 if(fu != null){
178 baseEntity = fu;
179 } else if(((SpecimenTypeDesignation) td).getTypeSpecimen() != null){
180 baseEntity = ((SpecimenTypeDesignation) td).getTypeSpecimen();
181 }
182 } else if(td instanceof NameTypeDesignation){
183 baseEntity = ((NameTypeDesignation)td).getTypeName();
184 }
185 if(baseEntity == null) {
186 throw new DataIntegrityException("Incomplete TypeDesignation, no type missin in " + td.toString());
187 }
188 return baseEntity;
189 }
190
191 /**
192 * @param td
193 * @return
194 */
195 protected TypedEntityReference<IdentifiableEntity<?>> makeEntityReference(IdentifiableEntity<?> baseEntity) {
196
197 baseEntity = (IdentifiableEntity<?>) HibernateHelper.unproxy(baseEntity);
198 String label = "";
199 if(baseEntity instanceof FieldUnit){
200 label = ((FieldUnit)baseEntity).getTitleCache();
201 }
202
203 TypedEntityReference<IdentifiableEntity<?>> baseEntityReference = new TypedEntityReference(baseEntity.getClass(), baseEntity.getId(), label);
204
205 return baseEntityReference;
206 }
207
208
209 private LinkedHashMap<TypedEntityReference, TypeDesignationWorkingSet> orderByTypeByBaseEntity(
210 Map<TypedEntityReference, TypeDesignationWorkingSet> stringsByTypeByBaseEntity){
211
212 // order the FieldUnit TypeName keys
213 List<TypedEntityReference> baseEntityKeyList = new LinkedList<>(stringsByTypeByBaseEntity.keySet());
214 Collections.sort(baseEntityKeyList, new Comparator<TypedEntityReference>(){
215 /**
216 * Sorts the base entities (TypedEntityReference) in the following order:
217 *
218 * 1. FieldUnits
219 * 2. DerivedUnit (in case of missing FieldUnit we expect the base type to be DerivedUnit)
220 * 3. NameType
221 *
222 * {@inheritDoc}
223 */
224 @Override
225 public int compare(TypedEntityReference o1, TypedEntityReference o2) {
226
227 Class type1 = o1.getType();
228 Class type2 = o2.getType();
229
230 if(!type1.equals(type2)) {
231 if(type1.equals(FieldUnit.class) || type2.equals(FieldUnit.class)){
232 // FieldUnits first
233 return type1.equals(FieldUnit.class) ? -1 : 1;
234 } else {
235 // name types last (in case of missing FieldUnit we expect the base type to be DerivedUnit which comes into the middle)
236 return type2.equals(TaxonName.class) ? -1 : 1;
237 }
238 } else {
239 return o1.getLabel().compareTo(o2.getLabel());
240 }
241 }});
242
243 // new LinkedHashMap for the ordered FieldUnitOrTypeName keys
244 LinkedHashMap<TypedEntityReference, TypeDesignationWorkingSet> stringsOrderedbyBaseEntityOrderdByType = new LinkedHashMap<>(stringsByTypeByBaseEntity.size());
245
246 for(TypedEntityReference baseEntityRef : baseEntityKeyList){
247
248 TypeDesignationWorkingSet typeDesignationWorkingSet = stringsByTypeByBaseEntity.get(baseEntityRef);
249 // order the TypeDesignationStatusBase keys
250 List<TypeDesignationStatusBase<?>> keyList = new LinkedList<>(typeDesignationWorkingSet.keySet());
251 Collections.sort(keyList, new Comparator<TypeDesignationStatusBase>() {
252 @SuppressWarnings("unchecked")
253 @Override
254 public int compare(TypeDesignationStatusBase o1, TypeDesignationStatusBase o2) {
255 // fix inverted order of cdm terms by -1*
256 return -1 * o1.compareTo(o2);
257 }
258 });
259 // new LinkedHashMap for the ordered TypeDesignationStatusBase keys
260 TypeDesignationWorkingSet orderedStringsByOrderedTypes = new TypeDesignationWorkingSet(
261 typeDesignationWorkingSet.getBaseEntity(),
262 baseEntityRef);
263 orderedStringsByOrderedTypes.setWorkingSetId(typeDesignationWorkingSet.workingSetId); // preserve original workingSetId
264 keyList.forEach(key -> orderedStringsByOrderedTypes.put(key, typeDesignationWorkingSet.get(key)));
265 stringsOrderedbyBaseEntityOrderdByType.put(baseEntityRef, orderedStringsByOrderedTypes);
266 }
267
268 return stringsOrderedbyBaseEntityOrderdByType;
269 }
270
271 /*
272 private LinkedHashMap<TypedEntityReference, LinkedHashMap<String, Collection<EntityReference>>> buildOrderedRepresentations(){
273
274 orderedStringsByOrderedTypes.keySet().forEach(
275 key -> orderedRepresentations.put(
276 getTypeDesignationStytusLabel(key),
277 orderedStringsByOrderedTypes.get(key))
278 );
279 return orderedRepresentations;
280 }
281 */
282
283 public TypeDesignationSetManager buildString(){
284
285 if(finalString == null){
286
287 finalString = "";
288 if(getTypifiedNameCache() != null){
289 finalString += getTypifiedNameCache() + " ";
290 }
291
292 int typeCount = 0;
293 if(orderedByTypesByBaseEntity != null){
294 for(TypedEntityReference baseEntityRef : orderedByTypesByBaseEntity.keySet()) {
295 StringBuilder sb = new StringBuilder();
296 if(typeCount++ > 0){
297 sb.append(TYPE_SEPARATOR);
298 }
299 boolean isNameTypeDesignation = false;
300 if(SpecimenOrObservationBase.class.isAssignableFrom(baseEntityRef.getType())){
301 sb.append("Type: ");
302 } else {
303 sb.append("NameType: ");
304 isNameTypeDesignation = true;
305 }
306 if(!baseEntityRef.getLabel().isEmpty()){
307 sb.append(baseEntityRef.getLabel()).append(" ");
308 }
309 TypeDesignationWorkingSet typeDesignationWorkingSet = orderedByTypesByBaseEntity.get(baseEntityRef);
310 if(!isNameTypeDesignation ){
311 sb.append("(");
312 }
313 int typeStatusCount = 0;
314 for(TypeDesignationStatusBase<?> typeStatus : typeDesignationWorkingSet.keySet()) {
315 if(typeStatusCount++ > 0){
316 sb.append(TYPE_STATUS_SEPARATOR);
317 }
318 boolean isPlural = typeDesignationWorkingSet.get(typeStatus).size() > 1;
319 if(!typeStatus.equals(NULL_STATUS)) {
320 sb.append(typeStatus.getLabel());
321 if(isPlural){
322 sb.append("s: ");
323 } else {
324 sb.append(", ");
325 }
326 }
327 int typeDesignationCount = 0;
328 for(EntityReference typeDesignationEntityReference : typeDesignationWorkingSet.get(typeStatus)) {
329 if(typeDesignationCount++ > 0){
330 sb.append(TYPE_DESIGNATION_SEPARATOR);
331 }
332 sb.append(typeDesignationEntityReference.getLabel());
333 }
334 }
335 if(!isNameTypeDesignation ){
336 sb.append(")");
337 }
338 typeDesignationWorkingSet.setRepresentation(sb.toString());
339 finalString += typeDesignationWorkingSet.getRepresentation();
340 }
341 }
342 }
343 return this;
344 }
345
346 /**
347 * FIXME use the validation framework validators and to store the validation problems!!!
348 *
349 * @return
350 * @throws RegistrationValidationException
351 */
352 private void findTypifiedName() throws RegistrationValidationException {
353
354 List<String> problems = new ArrayList<>();
355
356 TaxonName typifiedName = null;
357
358 for(TypeDesignationBase<?> typeDesignation : typeDesignations){
359 typeDesignation.getTypifiedNames();
360 if(typeDesignation.getTypifiedNames().isEmpty()){
361
362 //TODO instead throw RegistrationValidationException()
363 problems.add("Missing typifiedName in " + typeDesignation.toString());
364 continue;
365 }
366 if(typeDesignation.getTypifiedNames().size() > 1){
367 //TODO instead throw RegistrationValidationException()
368 problems.add("Multiple typifiedName in " + typeDesignation.toString());
369 continue;
370 }
371 if(typifiedName == null){
372 // remember
373 typifiedName = typeDesignation.getTypifiedNames().iterator().next();
374 } else {
375 // compare
376 TaxonName otherTypifiedName = typeDesignation.getTypifiedNames().iterator().next();
377 if(typifiedName.getId() != otherTypifiedName.getId()){
378 //TODO instead throw RegistrationValidationException()
379 problems.add("Multiple typifiedName in " + typeDesignation.toString());
380 }
381 }
382
383 }
384 if(!problems.isEmpty()){
385 // FIXME use the validation framework
386 throw new RegistrationValidationException("Inconsistent type designations", problems);
387 }
388
389 if(typifiedName != null){
390 // ON SUCCESS -------------------
391 this.typifiedName = typifiedName;
392 this.typifiedNameRef = new EntityReference(typifiedName.getId(), typifiedName.getTitleCache());
393
394 }
395 }
396
397
398 /**
399 * @return the title cache of the typifying name or <code>null</code>
400 */
401 public String getTypifiedNameCache() {
402 if(typifiedNameRef != null){
403 return typifiedNameRef.getLabel();
404 }
405 return null;
406 }
407
408 /**
409 * @return the title cache of the typifying name or <code>null</code>
410 */
411 public EntityReference getTypifiedNameRef() {
412
413 return typifiedNameRef;
414 }
415
416 /**
417 * @return
418 */
419 public Collection<TypeDesignationBase> getTypeDesignations() {
420 return typeDesignations;
421 }
422
423 /**
424 * @param ref
425 * @return
426 */
427 public TypeDesignationBase findTypeDesignation(EntityReference typeDesignationRef) {
428 for(TypeDesignationBase td : typeDesignations){
429 if(td.getId() == typeDesignationRef.getId()){
430 return td;
431 }
432 }
433 // TODO Auto-generated method stub
434 return null;
435 }
436
437
438 public LinkedHashMap<TypedEntityReference, TypeDesignationWorkingSet> getOrderdTypeDesignationWorkingSets() {
439 return orderedByTypesByBaseEntity;
440 }
441
442 /**
443 * @param td
444 * @return
445 */
446 private String stringify(TypeDesignationBase td) {
447
448 if(td instanceof NameTypeDesignation){
449 return stringify((NameTypeDesignation)td);
450 } else {
451 return stringify((SpecimenTypeDesignation)td, false);
452 }
453 }
454
455
456 /**
457 * @param td
458 * @return
459 */
460 protected String stringify(NameTypeDesignation td) {
461
462 StringBuffer sb = new StringBuffer();
463
464 if(td.getTypeName() != null){
465 sb.append(td.getTypeName().getTitleCache());
466 }
467 if(td.getCitation() != null){
468 sb.append(" ").append(td.getCitation().getTitleCache());
469 if(td.getCitationMicroReference() != null){
470 sb.append(":").append(td.getCitationMicroReference());
471 }
472 }
473 if(td.isNotDesignated()){
474 sb.append(" not designated");
475 }
476 if(td.isRejectedType()){
477 sb.append(" rejected");
478 }
479 if(td.isConservedType()){
480 sb.append(" conserved");
481 }
482 return sb.toString();
483 }
484
485 /**
486 * @param td
487 * @return
488 */
489 private String stringify(SpecimenTypeDesignation td, boolean useFullTitleCache) {
490 String result = "";
491
492 if(useFullTitleCache){
493 if(td.getTypeSpecimen() != null){
494 String nameTitleCache = td.getTypeSpecimen().getTitleCache();
495 if(getTypifiedNameCache() != null){
496 nameTitleCache = nameTitleCache.replace(getTypifiedNameCache(), "");
497 }
498 result += nameTitleCache;
499 }
500 } else {
501 if(td.getTypeSpecimen() != null){
502 DerivedUnit du = td.getTypeSpecimen();
503 if(du.isProtectedTitleCache()){
504 result += du.getTitleCache();
505 } else {
506 DerivedUnitFacadeCacheStrategy cacheStrategy = new DerivedUnitFacadeCacheStrategy();
507 result += cacheStrategy.getTitleCache(du, true);
508 }
509 }
510 }
511
512 if(isPrintCitation() && td.getCitation() != null){
513 if(td.getCitation().getAbbrevTitle() != null){
514 result += " " + td.getCitation().getAbbrevTitle();
515 } else {
516 result += " " + td.getCitation().getTitleCache();
517 }
518 if(td.getCitationMicroReference() != null){
519 result += " :" + td.getCitationMicroReference();
520 }
521 }
522 if(td.isNotDesignated()){
523 result += " not designated";
524 }
525
526 return result;
527 }
528
529 /**
530 * @param td
531 * @return
532 * @deprecated
533 */
534 @Deprecated
535 private FieldUnit findFieldUnit(SpecimenTypeDesignation td) {
536
537 DerivedUnit du = td.getTypeSpecimen();
538 return findFieldUnit(du);
539 }
540
541 private FieldUnit findFieldUnit(DerivedUnit du) {
542
543 if(du == null || du.getOriginals() == null){
544 return null;
545 }
546 @SuppressWarnings("rawtypes")
547 Set<SpecimenOrObservationBase> originals = du.getDerivedFrom().getOriginals();
548 @SuppressWarnings("rawtypes")
549 Optional<SpecimenOrObservationBase> fieldUnit = originals.stream()
550 .filter(original -> original instanceof FieldUnit).findFirst();
551 if (fieldUnit.isPresent()) {
552 return (FieldUnit) fieldUnit.get();
553 } else {
554 for (@SuppressWarnings("rawtypes")
555 SpecimenOrObservationBase sob : originals) {
556 if (sob instanceof DerivedUnit) {
557 FieldUnit fu = findFieldUnit((DerivedUnit) sob);
558 if (fu != null) {
559 return fu;
560 }
561 }
562 }
563 }
564
565 return null;
566 }
567
568 public String print() {
569 return finalString.trim();
570 }
571
572 /**
573 * @return the printCitation
574 */
575 public boolean isPrintCitation() {
576 return printCitation;
577 }
578
579 /**
580 * @param printCitation the printCitation to set
581 */
582 public void setPrintCitation(boolean printCitation) {
583 this.printCitation = printCitation;
584 }
585
586 /**
587 * @return the typifiedName
588 */
589 public TaxonName getTypifiedName() {
590 return typifiedName;
591 }
592
593 /**
594 * TypeDesignations which refer to the same FieldUnit (SpecimenTypeDesignation) or TaxonName
595 * (NameTypeDesignation) form a working set. The <code>TypeDesignationWorkingSet</code> internally
596 * works with EnityReferences to the actual TypeDesignations.
597 *
598 * The EntityReferences for TypeDesignations are grouped by the according TypeDesignationStatus.
599 * The TypeDesignationStatusBase keys can be ordered by the term order defined in the vocabulary.
600 *
601 * A workingset can be referenced by the <code>workingSetId</code>, this is a autoincrement
602 * value which is created during the process of determining the workingsets in a collection of
603 * TypeDesignations.
604 *
605 * TODO: consider using a concatenation of baseEntity.getClass() + baseEntity.getId() as workingset identifier
606 */
607 public class TypeDesignationWorkingSet extends LinkedHashMap<TypeDesignationStatusBase<?>, Collection<EntityReference>> {
608
609 private static final long serialVersionUID = -1329007606500890729L;
610
611 String workingSetRepresentation = null;
612
613 TypedEntityReference<IdentifiableEntity<?>> baseEntityReference;
614
615 IdentifiableEntity<?> baseEntity;
616
617 List<DerivedUnit> derivedUnits = null;
618
619 int workingSetId = workingSetIdAutoIncrement++;
620
621 /**
622 * @param baseEntityReference
623 */
624 public TypeDesignationWorkingSet(IdentifiableEntity<?> baseEntity, TypedEntityReference<IdentifiableEntity<?>> baseEntityReference) {
625 this.baseEntity = baseEntity;
626 this.baseEntityReference = baseEntityReference;
627 }
628
629 /**
630 * @return
631 */
632 public IdentifiableEntity<?> getBaseEntity() {
633 return baseEntity;
634 }
635
636 public List<EntityReference> getTypeDesignations() {
637 List<EntityReference> typeDesignations = new ArrayList<>();
638 this.values().forEach(typeDesignationReferences -> typeDesignationReferences.forEach(td -> typeDesignations.add(td)));
639 return typeDesignations;
640 }
641
642 /**
643 * @param status
644 * @param typeDesignationEntityReference
645 */
646 public void insert(TypeDesignationStatusBase<?> status, EntityReference typeDesignationEntityReference) {
647
648 if(status == null){
649 status = NULL_STATUS;
650 }
651 if(!containsKey(status)){
652 put(status, new ArrayList<EntityReference>());
653 }
654 get(status).add(typeDesignationEntityReference);
655 }
656
657 /**
658 * @return the workingSetId
659 */
660 public int getWorkingSetId() {
661 return workingSetId;
662 }
663
664 /**
665 * @param workingSetId the workingSetId to set
666 */
667 public void setWorkingSetId(int workingSetId) {
668 this.workingSetId = workingSetId;
669 }
670
671 public String getRepresentation() {
672 return workingSetRepresentation;
673 }
674
675 public void setRepresentation(String representation){
676 this.workingSetRepresentation = representation;
677 }
678
679 /**
680 * A reference to the entity which is the common base entity for all TypeDesignations in this workingset.
681 * For a {@link SpecimenTypeDesignation} this is usually the {@link FieldUnit} if it is present. Otherwise it can also be
682 * a {@link DerivedUnit} or something else depending on the specific use case.
683 *
684 * @return the baseEntityReference
685 */
686 public TypedEntityReference getBaseEntityReference() {
687 return baseEntityReference;
688 }
689
690 @Override
691 public String toString(){
692 if(workingSetRepresentation != null){
693 return workingSetRepresentation;
694 } else {
695 return super.toString();
696 }
697 }
698
699 /**
700 * @return
701 */
702 public boolean isSpecimenTypeDesigationWorkingSet() {
703 return SpecimenOrObservationBase.class.isAssignableFrom(baseEntityReference.getType());
704 }
705
706 public TypeDesignationWorkingSetType getWorkingsetType() {
707 return isSpecimenTypeDesigationWorkingSet() ? TypeDesignationWorkingSetType.SPECIMEN_TYPE_DESIGNATION_WORKINGSET : TypeDesignationWorkingSetType.NAME_TYPE_DESIGNATION_WORKINGSET;
708 }
709
710 }
711
712 public enum TypeDesignationWorkingSetType {
713 SPECIMEN_TYPE_DESIGNATION_WORKINGSET,
714 NAME_TYPE_DESIGNATION_WORKINGSET,
715 }
716
717 @SuppressWarnings({ "deprecation", "serial" })
718 class NullTypeDesignationStatus extends TypeDesignationStatusBase<NullTypeDesignationStatus>{
719
720 /**
721 * {@inheritDoc}
722 */
723 @Override
724 public void resetTerms() {
725 // empty
726
727 }
728
729 /**
730 * {@inheritDoc}
731 */
732 @Override
733 protected void setDefaultTerms(TermVocabulary<NullTypeDesignationStatus> termVocabulary) {
734 // empty
735 }
736
737 }
738
739 }