commit 45c2e0b4c88e3622d1a1db88a0f1b269d30bae02
Author: Andreas Müller <a.mueller@bgbm.org>
Date:   Sat Jan 9 16:17:01 2021 +0100

    ref #1447 latest changes to PesiCommandLineMerge and PesiMergeObject

diff --git a/cdm-pesi/src/main/java/eu/etaxonomy/cdm/app/pesi/merging/PesiCommandLineMerge.java b/cdm-pesi/src/main/java/eu/etaxonomy/cdm/app/pesi/merging/PesiCommandLineMerge.java
index 0766d7b5..7bb0719c 100644
--- a/cdm-pesi/src/main/java/eu/etaxonomy/cdm/app/pesi/merging/PesiCommandLineMerge.java
+++ b/cdm-pesi/src/main/java/eu/etaxonomy/cdm/app/pesi/merging/PesiCommandLineMerge.java
@@ -111,7 +111,7 @@ public class PesiCommandLineMerge extends PesiMergeBase {
         }
         if (commit){
             app.commitTransaction(tx);
-            if (taxonInformation.taxonToUse == 1 && taxonInformation.nameToUse == 1){
+            if (isAutomatedAnswer(taxonInformation)){
                 removeTaxon(taxonInformation.taxon2);
             }else if (booleanAnswer("Information moved. Delete old taxon")){
                 removeTaxon(taxonInformation.taxonToUse == 2 ? taxonInformation.taxon1 : taxonInformation.taxon2);
@@ -122,6 +122,10 @@ public class PesiCommandLineMerge extends PesiMergeBase {
         return commit;
     }
 
+    private boolean isAutomatedAnswer(TaxonInformation taxonInformation) {
+        return taxonInformation.taxonToUse == 2 && taxonInformation.nameToUse == 2 && false;
+    }
+
     private class TaxonInformation{
         TaxonBase<?> taxon1;
         TaxonBase<?> taxon2;
@@ -206,6 +210,10 @@ public class PesiCommandLineMerge extends PesiMergeBase {
     private boolean compareTaxa(TaxonInformation taxonInformation) {
         TaxonBase<?> removeTaxon = taxonInformation.taxon2;
         TaxonBase<?> stayTaxon = taxonInformation.taxon1;
+        if(removeTaxon.getId() == stayTaxon.getId()){
+            logger.warn("Same taxon: "+  removeTaxon.getTitleCache());
+            return false;
+        }
         String nc1 = removeTaxon.getName().getNameCache();
         String nc2 = stayTaxon.getName().getNameCache();
 
@@ -213,7 +221,7 @@ public class PesiCommandLineMerge extends PesiMergeBase {
         String ft2 = stayTaxon.getName().getFullTitleCache();
         System.out.println("Remove " + getStatusStr(removeTaxon) + ft1);
         System.out.println("Stay   " + getStatusStr(stayTaxon) + ft2);
-        boolean isStandard = taxonInformation.taxonToUse == 1 && taxonInformation.nameToUse == 1;
+        boolean isStandard = isAutomatedAnswer(taxonInformation);
         if (!nc1.equals(nc2)){
             return booleanAnswer("Name Cache differs!!! Do you really want to merge???");
         }else if (!ft1.equals(ft2)){
@@ -307,7 +315,7 @@ public class PesiCommandLineMerge extends PesiMergeBase {
             mergeHybridRelationships(removeName, stayName);
             mergeNameDescriptions(removeName, stayName);
 
-            if(taxonInformation.taxonToUse == 1 && taxonInformation.nameToUse == 1){
+            if(isAutomatedAnswer(taxonInformation)){
                 return true;
             }else{
                 return booleanAnswer("Commit moved information");
@@ -393,6 +401,11 @@ public class PesiCommandLineMerge extends PesiMergeBase {
             }
         }
         TaxonNode removeNode = removeTaxon.getTaxonNodes().iterator().next();
+        if(removeNode.getChildNodes().isEmpty()){
+            return true;
+        }
+
+        stayTaxon = reallyAccTaxon(stayTaxon);
         TaxonNode stayNode = stayTaxon.getTaxonNodes().iterator().next();
         Set<UUID> removeNodeChildrenUuids = removeNode.getChildNodes()
                 .stream().map(tn->tn.getUuid()).collect(Collectors.toSet());
@@ -405,6 +418,17 @@ public class PesiCommandLineMerge extends PesiMergeBase {
         return true;
     }
 
+    private Taxon reallyAccTaxon(Taxon stayTaxon) {
+        if (isTaxonSynonym(stayTaxon)){
+            for (TaxonRelationship rel: stayTaxon.getRelationsFromThisTaxon()){
+                boolean isPseudo = TaxonRelationshipType.pseudoTaxonUuids().contains(rel.getType().getUuid());
+                if (isPseudo){
+                    return rel.getToTaxon();
+                }
+            }
+        }
+        return stayTaxon;
+    }
     private boolean mergeSynonyms(Taxon removeTaxon, Taxon stayTaxon, boolean isTaxonSynonym) {
         if (isTaxonSynonym){
             if (!removeTaxon.getSynonyms().isEmpty()){
@@ -467,7 +491,7 @@ public class PesiCommandLineMerge extends PesiMergeBase {
         }
     }
 
-    private IdentifiableEntity<?> selectStay(IdentifiableEntity<?> removeEntity, IdentifiableEntity<?> stayEntity, String type) {
+    private <T extends IdentifiableEntity<?>> T selectStay(T removeEntity, T stayEntity, String type) {
         if(removeEntity.isInstanceOf(Taxon.class) && stayEntity.isInstanceOf(Synonym.class)){
             String answer = "";
             while(!(answer.matches("[sSaAcC]"))){
@@ -476,7 +500,7 @@ public class PesiCommandLineMerge extends PesiMergeBase {
             if (answer.equalsIgnoreCase("c")){
                 return null;
             }else if (answer.equalsIgnoreCase("a")){
-               return accTaxon(CdmBase.deproxy(stayEntity, Synonym.class));
+               return (T)accTaxon(CdmBase.deproxy(stayEntity, Synonym.class));
             }else{
                 return stayEntity;
             }
@@ -525,7 +549,7 @@ public class PesiCommandLineMerge extends PesiMergeBase {
             IdentifiableEntity<?> stayEntity) throws CloneNotSupportedException {
         String className = removeEntity.getClass().getSimpleName();
         for (IdentifiableSource source: removeEntity.getSources()){
-            System.out.println("Move "+className+" source: " + source.getType().getMessage() + ": " + source.getCitation().getTitleCache() + "; " + source.getIdInSource() + "/" + source.getIdNamespace());
+            System.out.println("Move "+className+" source: " + source.getType().getLabel() + ": " + source.getCitation().getTitleCache() + "; " + source.getIdInSource() + "/" + source.getIdNamespace());
             stayEntity.addSource((IdentifiableSource)source.clone());
         }
     }
diff --git a/cdm-pesi/src/main/java/eu/etaxonomy/cdm/app/pesi/merging/PesiMergeObject.java b/cdm-pesi/src/main/java/eu/etaxonomy/cdm/app/pesi/merging/PesiMergeObject.java
index 6a48acc7..bec850a8 100644
--- a/cdm-pesi/src/main/java/eu/etaxonomy/cdm/app/pesi/merging/PesiMergeObject.java
+++ b/cdm-pesi/src/main/java/eu/etaxonomy/cdm/app/pesi/merging/PesiMergeObject.java
@@ -1,5 +1,8 @@
 package eu.etaxonomy.cdm.app.pesi.merging;
 
+import java.util.List;
+
+import eu.etaxonomy.cdm.common.CdmUtils;
 import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
 
 public class PesiMergeObject {
@@ -12,8 +15,6 @@ public class PesiMergeObject {
 
 	private String idTaxon;
 
-	private String uuidTaxonNode;
-
 	private String idInSource;
 
 	private String nameCache;
@@ -30,7 +31,13 @@ public class PesiMergeObject {
 
 	private TaxonNodeDto kingdom;
 
-	private TaxonNodeDto family;
+	private TaxonNodeDto tclass;
+
+	private TaxonNodeDto order;
+
+    private TaxonNodeDto family;
+
+	private List<TaxonNodeDto> higherClassification;
 
 	private String parentString;
 
@@ -127,6 +134,29 @@ public class PesiMergeObject {
         this.phylum = phylum;
     }
 
+    //class and getClass are part of java core therefore use other name
+    public TaxonNodeDto getTClass() {
+        return tclass;
+    }
+    public String getClassCache() {
+        return tclass == null? null : tclass.getNameCache();
+    }
+    public void setTClass(TaxonNodeDto tclass) {
+        this.tclass = tclass;
+    }
+
+    //order
+    public TaxonNodeDto getOrder() {
+        return order;
+    }
+    public String getOrderCache() {
+        return order == null? null : order.getNameCache();
+    }
+    public void setOrder(TaxonNodeDto order) {
+        this.order = order;
+    }
+
+    //family
     public TaxonNodeDto getFamily() {
         return family;
     }
@@ -137,30 +167,50 @@ public class PesiMergeObject {
         this.family = family;
     }
 
+    //classification
+    public List<TaxonNodeDto> getHigherClassification() {
+        return higherClassification;
+    }
+    public String getClassificationCache() {
+        return higherClassification == null? null : classificationCache();
+    }
+    public void setHigherClassification(List<TaxonNodeDto> higherClassification) {
+        this.higherClassification = higherClassification;
+    }
+
+    private String classificationCache() {
+        String result = "";
+        for (TaxonNodeDto dto : this.higherClassification){
+            result = CdmUtils.concat("-", result, dto.getNameCache());
+        }
+        return result;
+    }
+
+    //taxon uuid
     public String getUuidTaxon() {
         return uuidTaxon;
     }
-
     public void setUuidTaxon(String uuidTaxon) {
         this.uuidTaxon = uuidTaxon;
     }
 
+    //taxon id
     public String getIdTaxon() {
         return idTaxon;
     }
-
     public void setIdTaxon(String idTaxon) {
         this.idTaxon = idTaxon;
     }
 
+    //source uuid
     public String getUuidSource() {
         return uuidSource;
     }
-
     public void setUuidSource(String uuidSource) {
         this.uuidSource = uuidSource;
     }
 
+    //nom.ref.
     public String getNomenclaturalReference() {
         return nomenclaturalReference;
     }
