fix #9229 using NomenclaturalStatusDTO in the TaxonNameEditor
[cdm-vaadin.git] / src / main / java / eu / etaxonomy / cdm / vaadin / model / name / TaxonNameDTO.java
index 8c6a12e08100b838ff1cf9371eed1a51ed12096e..a15930f2565ede75abecf27c5f299b11208b2c53 100644 (file)
@@ -8,9 +8,11 @@
 */
 package eu.etaxonomy.cdm.vaadin.model.name;
 
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import org.joda.time.DateTime;
 
@@ -20,32 +22,35 @@ import eu.etaxonomy.cdm.model.common.Credit;
 import eu.etaxonomy.cdm.model.common.Extension;
 import eu.etaxonomy.cdm.model.common.Identifier;
 import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
-import eu.etaxonomy.cdm.model.common.User;
 import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
+import eu.etaxonomy.cdm.model.name.NameRelationship;
 import eu.etaxonomy.cdm.model.name.NameRelationshipType;
 import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
+import eu.etaxonomy.cdm.model.name.NomenclaturalSource;
 import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
 import eu.etaxonomy.cdm.model.name.Rank;
 import eu.etaxonomy.cdm.model.name.TaxonName;
+import eu.etaxonomy.cdm.model.permission.User;
 import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
-import eu.etaxonomy.cdm.vaadin.model.CdmEntityDecoraterDTO;
+import eu.etaxonomy.cdm.model.reference.Reference;
+import eu.etaxonomy.cdm.vaadin.model.CdmEntityAdapterDTO;
 
 /**
  * @author a.kohlbecker
  * @since Apr 23, 2018
  *
  */
-public class TaxonNameDTO extends CdmEntityDecoraterDTO<TaxonName> {
-
-    class TN extends TaxonName {
-
-    }
+public class TaxonNameDTO extends CdmEntityAdapterDTO<TaxonName> {
 
     private static final long serialVersionUID = -8018109905949198530L;
 
     private TaxonName name;
 
-    private Set<TaxonName> persistedBasionyms;
+    private TaxonName persistedValidatedName;
+
+    private TaxonName persistedOrthographicVariant;
+
+    private Set<NomenclaturalStatusDTO> nomenclaturalStatusDTOs = new HashSet<>();
 
     /**
      * @param entity
@@ -53,6 +58,9 @@ public class TaxonNameDTO extends CdmEntityDecoraterDTO<TaxonName> {
     public TaxonNameDTO(TaxonName entity) {
         super(entity);
         name = entity;
+        for(NomenclaturalStatus status : name.getStatus()) {
+            nomenclaturalStatusDTOs.add(NomenclaturalStatusDTO.from(status));
+        }
     }
 
     public String getAcronym() {
@@ -63,6 +71,25 @@ public class TaxonNameDTO extends CdmEntityDecoraterDTO<TaxonName> {
         return name.getAnnotations();
     }
 
+    public void setAnnotations(Set<Annotation> annotations) {
+        List<Annotation> currentAnnotations = new ArrayList<>(name.getAnnotations());
+        List<Annotation> annotationsSeen = new ArrayList<>();
+        for(Annotation a : annotations){
+            if(a == null){
+                continue;
+            }
+            if(!currentAnnotations.contains(a)){
+                name.addAnnotation(a);
+            }
+            annotationsSeen.add(a);
+        }
+        for(Annotation a : currentAnnotations){
+            if(!annotationsSeen.contains(a)){
+                name.removeAnnotation(a);
+            }
+        }
+    }
+
     public String getAppendedPhrase() {
         return name.getAppendedPhrase();
     }
@@ -78,17 +105,132 @@ public class TaxonNameDTO extends CdmEntityDecoraterDTO<TaxonName> {
 
     public Set<TaxonName> getBasionyms() {
         Set<TaxonName> basionyms = name.getRelatedNames(Direction.relatedTo, NameRelationshipType.BASIONYM());
-        if(persistedBasionyms == null){
-            // remember the persisted state before starting to operate on the DTO
-            persistedBasionyms = basionyms;
-        }
         return basionyms;
     }
 
+    public Set<TaxonName> getReplacedSynonyms() {
+        Set<TaxonName> replacedSynonyms = name.getRelatedNames(Direction.relatedTo, NameRelationshipType.REPLACED_SYNONYM());
+        return replacedSynonyms;
+    }
+
+    public NameRelationshipDTO getValidationFor() {
+        NameRelationshipDTO nameRelDto  = null;
+        NameRelationship validatingRelationship = uniqueNameRelationship(NameRelationshipType.VALIDATED_BY_NAME(), Direction.relatedTo);
+        if(validatingRelationship != null){
+            nameRelDto = new NameRelationshipDTO(Direction.relatedTo, validatingRelationship);
+            if(persistedValidatedName == null){
+               persistedValidatedName = nameRelDto.getOtherName();
+            }
+        }
+        return nameRelDto;
+    }
+
+    public void setValidationFor(NameRelationshipDTO nameRelDto) {
+        setUniqeNameRelationDTO(nameRelDto, NameRelationshipType.VALIDATED_BY_NAME(), Direction.relatedTo, persistedValidatedName);
+    }
+
+
+    public NameRelationshipDTO getOrthographicVariant() {
+        NameRelationshipDTO nameRelDto  = null;
+        NameRelationship nameRelationship = uniqueNameRelationship(NameRelationshipType.ORTHOGRAPHIC_VARIANT(), Direction.relatedTo);
+        if(nameRelationship != null){
+            nameRelDto = new NameRelationshipDTO(Direction.relatedTo, nameRelationship);
+            if(persistedOrthographicVariant == null){
+               persistedOrthographicVariant = nameRelDto.getOtherName();
+            }
+        }
+        return nameRelDto;
+    }
+
+    public void setOrthographicVariant(NameRelationshipDTO nameRelDto) {
+        setUniqeNameRelationDTO(nameRelDto, NameRelationshipType.ORTHOGRAPHIC_VARIANT(), Direction.relatedTo, persistedOrthographicVariant);
+    }
+
+    /**
+     * @param nameRelDto
+     * @param nameRelationshipType
+     * @param direction
+     * @param persistedRelatedName
+     */
+    public void setUniqeNameRelationDTO(NameRelationshipDTO nameRelDto, NameRelationshipType nameRelationshipType,
+            Direction direction, TaxonName persistedRelatedName) {
+        if(nameRelDto != null && nameRelDto.getOtherName() == null){
+            // treat as if there is no related name
+            nameRelDto = null;
+        }
+
+        NameRelationship relationship = uniqueNameRelationship(nameRelationshipType, direction);
+
+        if(nameRelDto != null){
+            // add or update ...
+            boolean currentNameIsTarget = false;
+            if(relationship != null && persistedRelatedName != null){
+                if(direction == Direction.relatedTo){
+                    currentNameIsTarget = relationship.getFromName().equals(persistedRelatedName);
+                } else {
+                    currentNameIsTarget = relationship.getToName().equals(persistedRelatedName);
+                }
+            }
+            if(relationship != null && currentNameIsTarget){
+                // related name has not changed, so we can update the relation
+                relationship.setCitation(nameRelDto.getCitation());
+                relationship.setCitationMicroReference(nameRelDto.getCitationMicroReference());
+                relationship.setRuleConsidered(nameRelDto.getRuleConsidered());
+                relationship.setCodeEdition(nameRelDto.getCodeEdition());
+            } else {
+                // need to remove the old relationship and to create a new one.
+                // the actual removal will take place ....
+                if(direction == Direction.relatedTo){
+                    name.addRelationshipFromName(nameRelDto.getOtherName(), nameRelationshipType,
+                            nameRelDto.getCitation(), nameRelDto.getCitationMicroReference(), nameRelDto.getRuleConsidered(), nameRelDto.getCodeEdition());
+                } else {
+                    name.addRelationshipToName(nameRelDto.getOtherName(), nameRelationshipType,
+                            nameRelDto.getCitation(), nameRelDto.getCitationMicroReference(), nameRelDto.getRuleConsidered(), nameRelDto.getCodeEdition());
+                }
+                if(persistedRelatedName != null){
+                    name.removeRelationWithTaxonName(persistedRelatedName, direction, nameRelationshipType);
+                }
+            }
+        } else {
+            // remove ...
+            if(persistedRelatedName != null && relationship != null){
+                name.removeRelationWithTaxonName(persistedRelatedName, direction, nameRelationshipType);
+            }
+        }
+    }
+
     public void setBasionyms(Set<TaxonName> basionyms) {
         setRelatedNames(Direction.relatedTo, NameRelationshipType.BASIONYM(), basionyms);
     }
 
+    public void setReplacedSynonyms(Set<TaxonName> replacedSynonyms) {
+        setRelatedNames(Direction.relatedTo, NameRelationshipType.REPLACED_SYNONYM(), replacedSynonyms);
+    }
+
+    /**
+     * @return
+     */
+    protected NameRelationship uniqueNameRelationship(NameRelationshipType relationShipType, Direction direction) {
+
+        Set<NameRelationship> relations;
+
+        if(direction == Direction.relatedTo){
+            relations = name.getRelationsToThisName();
+        } else {
+            relations = name.getRelationsFromThisName();
+        }
+        Set<NameRelationship> nameRelations = relations.stream().filter(
+                    nr -> nr.getType().equals(relationShipType)
+                ).collect(Collectors.toSet());
+        if(nameRelations.size() > 1){
+            // TODO use non RuntimeException
+            throw new RuntimeException("More than one relationship of type " + relationShipType.getLabel() + " found.");
+        } else if(nameRelations.size() == 0) {
+            return null;
+        }
+        return nameRelations.iterator().next();
+    }
+
     /**
      * @param basionyms
      * @param relType
@@ -102,11 +244,14 @@ public class TaxonNameDTO extends CdmEntityDecoraterDTO<TaxonName> {
             currentRelatedNames.add(tn);
         }
         for(TaxonName tn : relatedNames){
+            if(tn == null){
+                continue;
+            }
             if(!currentRelatedNames.contains(tn)){
                 if(direction.equals(Direction.relatedTo)){
-                    tn.addRelationshipToName(name, relType, null);
+                    tn.addRelationshipToName(name, relType, null, null);
                 } else {
-                    tn.addRelationshipFromName(name, relType, null);
+                    tn.addRelationshipFromName(name, relType, null, null);
                 }
             }
             namesSeen.add(tn);
@@ -118,10 +263,6 @@ public class TaxonNameDTO extends CdmEntityDecoraterDTO<TaxonName> {
         }
     }
 
-    public Set<TaxonName> persistedBasionyms(){
-        return persistedBasionyms;
-    }
-
     public TeamOrPersonBase<?> getCombinationAuthorship() {
         return name.getCombinationAuthorship();
     }
@@ -190,8 +331,12 @@ public class TaxonNameDTO extends CdmEntityDecoraterDTO<TaxonName> {
         return name.getRank();
     }
 
-    public Set<NomenclaturalStatus> getStatus() {
-        return name.getStatus();
+    public Set<NomenclaturalStatusDTO> getStatus() {
+        return nomenclaturalStatusDTOs;
+    }
+
+    public void setStatus(Set<NomenclaturalStatusDTO> status) {
+        nomenclaturalStatusDTOs = status;
     }
 
     public boolean isProtectedAuthorshipCache() {
@@ -283,11 +428,19 @@ public class TaxonNameDTO extends CdmEntityDecoraterDTO<TaxonName> {
     }
 
     public void setNomenclaturalMicroReference(String nomenclaturalMicroReference) {
-        name.setNomenclaturalMicroReference(nomenclaturalMicroReference);
+        assureNomenclaturalSource().setCitationMicroReference(nomenclaturalMicroReference);
+    }
+
+    public void setNomenclaturalReference(Reference nomenclaturalReference) {
+        assureNomenclaturalSource().setCitation(nomenclaturalReference);
     }
 
-    public void setNomenclaturalReference(INomenclaturalReference nomenclaturalReference) {
-        name.setNomenclaturalReference(nomenclaturalReference);
+    protected NomenclaturalSource assureNomenclaturalSource() {
+        NomenclaturalSource nomSource = name.getNomenclaturalSource();
+        if(nomSource == null) {
+            nomSource = NomenclaturalSource.NewNomenclaturalInstance(name);
+        }
+        return nomSource;
     }
 
     public void setProtectedAuthorshipCache(boolean protectedAuthorshipCache) {