ref #9228 , ref #4866 some fixes for subtree cloning
authorAndreas Müller <a.mueller@bgbm.org>
Wed, 2 Dec 2020 15:12:19 +0000 (16:12 +0100)
committerAndreas Müller <a.mueller@bgbm.org>
Wed, 2 Dec 2020 15:12:53 +0000 (16:12 +0100)
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/name/Registration.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/name/TaxonName.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/taxon/Taxon.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/taxon/TaxonRelationshipType.java
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/ClassificationServiceImpl.java
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/config/SubtreeCloneConfigurator.java

index ec1ffca5db6666423b94a0c1a63f425380e434de..a7b00d6404a1ea7ec898179f5b530306f8635520 100644 (file)
@@ -28,6 +28,7 @@ import javax.xml.bind.annotation.XmlSchemaType;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 
+import org.apache.log4j.Logger;
 import org.hibernate.annotations.Cascade;
 import org.hibernate.annotations.CascadeType;
 import org.hibernate.annotations.Type;
@@ -69,6 +70,7 @@ import eu.etaxonomy.cdm.validation.annotation.NullOrNotEmpty;
 public class Registration extends AnnotatableEntity {
 
     private static final long serialVersionUID = -5633923579539766801L;
+    private static final Logger logger = Logger.getLogger(Registration.class);
 
     @XmlElement(name = "Identifier")
     @NullOrNotEmpty
@@ -260,5 +262,31 @@ public class Registration extends AnnotatableEntity {
         }
     }
 
+    @Override
+    public Registration clone() {
+        try {
+            Registration result = (Registration)super.clone();
+
+            result.blockedBy = new HashSet<>();
+            for (Registration blockedByReg: this.blockedBy){
+                result.addBlockedBy(blockedByReg);
+            }
+
+            result.typeDesignations = new HashSet<>();
+            for (TypeDesignationBase<?> typeDesignation: this.typeDesignations){
+                result.addTypeDesignation(typeDesignation);
+            }
+
+
+            //no changes to: identifier, institution, registrationDate, specificIdentifier,
+            //status, submitter
+            return result;
+        } catch (CloneNotSupportedException e) {
+            logger.warn("Object does not implement cloneable");
+            e.printStackTrace();
+            return null;
+        }
+
+    }
 
 }
index 923568b9f7e0f0cdb750adf66a13706ed8b1c8db..a88f77b1a834489d15d72c64fcbda4b060e32484 100644 (file)
@@ -3702,6 +3702,12 @@ public class TaxonName
                 result.authorshipCache = null;
             }
 
+            //registrations
+            result.registrations = new HashSet<>();
+            for (Registration registration : getRegistrations()){
+                result.registrations.add(registration);
+            }
+
             //no changes to: appendedPharse, nomenclaturalReference,
             //nomenclaturalMicroReference, parsingProblem, problemEnds, problemStarts
             //protectedFullTitleCache, rank
index 9aa3facfd4a4af027a9e1d2cb9d0b1ca7c07fe45..c836943c392d52807c4d600518ef7a174e35dc01 100644 (file)
@@ -1711,17 +1711,25 @@ public class Taxon
         result.setRelationsFromThisTaxon(new HashSet<>());
         result.setRelationsToThisTaxon(new HashSet<>());
 
-        if (withTaxonRelations){
+        if (withTaxonRelations || withSynonyms){
             for (TaxonRelationship fromRelationship : this.getRelationsFromThisTaxon()){
-                TaxonRelationship newRelationship = fromRelationship.clone();
-                newRelationship.setRelatedFrom(result);
-                result.relationsFromThisTaxon.add(newRelationship);
+                boolean isSynonymRelation = fromRelationship.getType() != null &&
+                        fromRelationship.getType().isAnySynonymOrMisappliedName();
+                if (isSynonymRelation && withSynonyms || !isSynonymRelation && withTaxonRelations){
+                    TaxonRelationship newRelationship = fromRelationship.clone();
+                    newRelationship.setRelatedFrom(result);
+                    result.relationsFromThisTaxon.add(newRelationship);
+                }
             }
 
             for (TaxonRelationship toRelationship : this.getRelationsToThisTaxon()){
-                TaxonRelationship newRelationship = toRelationship.clone();
-                newRelationship.setRelatedTo(result);
-                result.relationsToThisTaxon.add(newRelationship);
+                boolean isSynonymRelation = toRelationship.getType() != null &&
+                        toRelationship.getType().isAnySynonymOrMisappliedName();
+                if (isSynonymRelation && withSynonyms || !isSynonymRelation && withTaxonRelations){
+                    TaxonRelationship newRelationship = toRelationship.clone();
+                    newRelationship.setRelatedTo(result);
+                    result.relationsToThisTaxon.add(newRelationship);
+                }
             }
         }
 
index b68befcecf6f9e9292f3e585ca2d2fd85d941e8b..21a6e56a48ef8b4962b41426b12f05e166e38433 100644 (file)
@@ -188,6 +188,15 @@ public class TaxonRelationshipType extends RelationshipTermBase<TaxonRelationshi
         return (allMisappliedNameTypes().contains(this));
     }
 
+    /**
+     * <code>true</code> if this relationship type is any
+     * of the {@link #isAnyMisappliedName() misapplied name relationships} or
+     * any of the {@link #isAnySynonym() (pro parte) synonym relationships}
+     */
+    public boolean isAnySynonymOrMisappliedName(){
+        return (allMisappliedNameTypes().contains(this) || allSynonymTypes().contains(this));
+    }
+
 
     /**
      * <code>true</code> if this relationship type is any
index 5007810aa126e6ca60933d21e4d4702d09641869..878aa4ec3af9086dcc6df8532a9f5e27a9f1bbcc 100644 (file)
@@ -200,8 +200,15 @@ public class ClassificationServiceImpl
             if (config.isReuseTaxa()){
                 childNodeClone = parentNodeClone.addChildTaxon(originalTaxon, config.getParentChildReference(), microReference);
             }else{
-                Taxon cloneTaxon = originalTaxon.clone(config.isCloneSynonyms(), config.isCloneTaxonRelationships(),
-                        config.isCloneDescriptiveData(), config.isCloneMedia());
+                Taxon cloneTaxon = originalTaxon.clone(config.isIncludeSynonymsIncludingManAndProParte(),
+                        config.isIncludeTaxonRelationshipsExcludingManAndProParte(),
+                        config.isIncludeDescriptiveData(), config.isIncludeMedia());
+
+                //name
+                if (!config.isReuseNames()){
+                    cloneTaxon.setName(cloneTaxon.getName().clone());
+                }
+
 //                xxx KonzeptClone MAN, ppSyns;
                 if (!config.isReuseTaxonSecundum()){
                     cloneTaxon.setSec(config.getTaxonSecundum());
@@ -216,7 +223,7 @@ public class ClassificationServiceImpl
                 childNodeClone = parentNodeClone.addChildTaxon(cloneTaxon, config.getParentChildReference(), microReference);
             }
 
-            //TODO necessary?
+            //probably necessary as taxon nodes do not cascade
             taxonNodeDao.saveOrUpdate(childNodeClone);
             //add children
             List<TaxonNode> originalChildNodes = originalParentNode.getChildNodes();
index e7e348775aec33583eec2a02372f405f94bc6df4..33fd754c35a8d738d3869a589c6a09c62f651152 100644 (file)
@@ -37,13 +37,13 @@ public class SubtreeCloneConfigurator implements Serializable {
 
     private boolean reuseTaxa = false;
      //used only if reuseTaxa == false
-     private boolean cloneSynonyms = true;
+     private boolean includeSynonymsIncludingManAndProParte = true;
      //used only if reuseTaxa == false
-     private boolean cloneDescriptiveData = true;
+     private boolean includeDescriptiveData = true;
      //used only if reuseTaxa == false
-     private boolean cloneMedia = true;
+     private boolean includeMedia = true;
      //used only if reuseTaxa == false
-     private boolean cloneTaxonRelationships = false;
+     private boolean includeTaxonRelationshipsExcludingManAndProParte = false;
      //used only if reuseTaxa == false
      private boolean reuseNames = true;
      //used only if reuseTaxa == false
@@ -274,52 +274,55 @@ public class SubtreeCloneConfigurator implements Serializable {
         this.relationshipReference = relationshipReference;
     }
 
-    public boolean isCloneSynonyms() {
-        return cloneSynonyms;
+    public boolean isIncludeSynonymsIncludingManAndProParte() {
+        return this.includeSynonymsIncludingManAndProParte;
     }
     /**
      * If <code>true</code> the synonyms relationships of this taxon are cloned and attached to the new taxon.
      * <BR>
      * This parameter is used only if <code>{@link #isReuseTaxa() reuseTaxa} == false</code>
      */
-    public void setCloneSynonyms(boolean cloneSynonyms) {
-        this.cloneSynonyms = cloneSynonyms;
+    public void setIncludeSynonymsIncludingManAndProParte(boolean includeSynonyms) {
+        this.includeSynonymsIncludingManAndProParte = includeSynonyms;
     }
 
-    public boolean isCloneDescriptiveData() {
-        return cloneDescriptiveData;
+    public boolean isIncludeDescriptiveData() {
+        return includeDescriptiveData;
     }
-
     /**
-     * If <code>true</code> the descriptive data attached to this taxon are also cloned and attached to the new taxon.
+     * If <code>true</code> the descriptive data attached to this taxon are included in the copy
+     * and attached to the new taxon.
      * <BR>
      * This parameter is used only if <code>{@link #isReuseTaxa() reuseTaxa} == false</code>
      */
-    public void setCloneDescriptiveData(boolean cloneDescriptiveData) {
-        this.cloneDescriptiveData = cloneDescriptiveData;
+    public void setIncludeDescriptiveData(boolean includeDescriptiveData) {
+        this.includeDescriptiveData = includeDescriptiveData;
     }
 
-    public boolean isCloneMedia() {
-        return cloneMedia;
+    public boolean isIncludeMedia() {
+        return includeMedia;
     }
     /**
      * If <code>true</code> the media attached to this taxon are also attached to the new taxon.
-     * Media itself are always reused.<BR>
+     * Media itself are always reused.
+     * <BR>
      * This parameter is used only if <code>{@link #isReuseTaxa() reuseTaxa} == false</code>
      */
-    public void setCloneMedia(boolean cloneMedia) {
-        this.cloneMedia = cloneMedia;
+    public void setIncludeMedia(boolean includeMedia) {
+        this.includeMedia = includeMedia;
     }
 
-    public boolean isCloneTaxonRelationships() {
-        return cloneTaxonRelationships;
+    public boolean isIncludeTaxonRelationshipsExcludingManAndProParte() {
+        return includeTaxonRelationshipsExcludingManAndProParte;
     }
     /**
      * If <code>true</code> the taxon (concept) relationships to and from this taxon are also cloned.
+     * This includes all taxon relationships except those for {@link TaxonRelationshipType#isAnyMisappliedName() any misapplied names}
+     * and {@link TaxonRelationshipType#isAnySynonym() any (pro parte synonyms)}.
      * <BR>
      * This parameter is used only if <code>{@link #isReuseTaxa() reuseTaxa} == false</code>
      */
-    public void setCloneTaxonRelationships(boolean cloneTaxonRelationships) {
-        this.cloneTaxonRelationships = cloneTaxonRelationships;
+    public void setIncludeTaxonRelationshipsExcludingManAndProParte(boolean includeTaxonRelationshipsExcludingManAndProParte) {
+        this.includeTaxonRelationshipsExcludingManAndProParte = includeTaxonRelationshipsExcludingManAndProParte;
     }
 }