fix #6687 per view implementation of the 'session-per-conversation' pattern
[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.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 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 TypeDesignationSetManager 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 TypeDesignationSetManager {
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 TypeDesignationSetManager(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 TypeDesignationSetManager 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 public TypeDesignationWorkingSetType getWorkingsetType() {
639 return isSpecimenTypeDesigationWorkingSet() ? TypeDesignationWorkingSetType.SPECIMEN_TYPE_DESIGNATION_WORKINGSET : TypeDesignationWorkingSetType.NAME_TYPE_DESIGNATION_WORKINGSET;
640 }
641
642 }
643
644 public enum TypeDesignationWorkingSetType {
645 SPECIMEN_TYPE_DESIGNATION_WORKINGSET,
646 NAME_TYPE_DESIGNATION_WORKINGSET,
647 }
648
649 @SuppressWarnings({ "deprecation", "serial" })
650 class NullTypeDesignationStatus extends TypeDesignationStatusBase<NullTypeDesignationStatus>{
651
652 /**
653 * {@inheritDoc}
654 */
655 @Override
656 public void resetTerms() {
657 // empty
658
659 }
660
661 /**
662 * {@inheritDoc}
663 */
664 @Override
665 protected void setDefaultTerms(TermVocabulary<NullTypeDesignationStatus> termVocabulary) {
666 // empty
667 }
668
669 }
670
671 }