ref #9331 add NamedSource and NamedSourceBase and use it, SecundumSource inherits...
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / taxon / Classification.java
index a11ad2cfe9700ff607846f636a3b260be706d861..60249ea1d1c98b9569accd3934dbdcae28cebe68 100644 (file)
@@ -1,4 +1,3 @@
-// $Id$
 /**
 * Copyright (C) 2007 EDIT
 * European Distributed Institute of Taxonomy
@@ -7,7 +6,6 @@
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * See LICENSE.TXT at the top of this package for the full license terms.
 */
-
 package eu.etaxonomy.cdm.model.taxon;
 
 import java.util.ArrayList;
@@ -47,19 +45,21 @@ import org.hibernate.search.annotations.IndexedEmbedded;
 
 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
 import eu.etaxonomy.cdm.jaxb.MultilanguageTextAdapter;
-import eu.etaxonomy.cdm.model.common.IReferencedEntity;
 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
+import eu.etaxonomy.cdm.model.common.IdentifiableSource;
 import eu.etaxonomy.cdm.model.common.Language;
 import eu.etaxonomy.cdm.model.common.LanguageString;
 import eu.etaxonomy.cdm.model.common.MultilanguageText;
 import eu.etaxonomy.cdm.model.common.TimePeriod;
 import eu.etaxonomy.cdm.model.location.NamedArea;
+import eu.etaxonomy.cdm.model.reference.NamedSource;
 import eu.etaxonomy.cdm.model.reference.Reference;
 import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
+import eu.etaxonomy.cdm.strategy.cache.taxon.ClassificationDefaultCacheStrategy;
 
 /**
  * @author a.mueller
- * @created 31.03.2009
+ * @since 31.03.2009
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "Classification", propOrder = {
@@ -68,6 +68,7 @@ import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
     "rootNode",
     "reference",
     "microReference",
+    "source",
     "timeperiod",
     "geoScopes"
 })
@@ -75,7 +76,10 @@ import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
 @Entity
 @Audited
 @Indexed(index = "eu.etaxonomy.cdm.model.taxon.Classification")
-public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheStrategy<Classification>> implements IReferencedEntity, ITaxonTreeNode, Cloneable{
+public class Classification
+            extends IdentifiableEntity<IIdentifiableEntityCacheStrategy<Classification>>
+            implements ITaxonTreeNode{
+
     private static final long serialVersionUID = -753804821474209635L;
     private static final Logger logger = Logger.getLogger(Classification.class);
 
@@ -86,7 +90,6 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
     @IndexedEmbedded
     private LanguageString name;
 
-
     @XmlElement(name = "rootNode")
     @XmlIDREF
     @XmlSchemaType(name = "IDREF")
@@ -114,7 +117,7 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
     @ManyToMany(fetch = FetchType.LAZY)
     @JoinTable(name="Classification_GeoScope")
 //    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})  remove cascade #5755
-    private Set<NamedArea> geoScopes = new HashSet<NamedArea>();
+    private Set<NamedArea> geoScopes = new HashSet<>();
 
        @XmlElement(name = "Description")
        @XmlJavaTypeAdapter(MultilanguageTextAdapter.class)
@@ -126,6 +129,14 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
 //    @FieldBridge(impl=MultilanguageTextFieldBridge.class)
     private Map<Language,LanguageString> description = new HashMap<>();
 
+       //TODO remove, due to #9211
+       //the source for this single classification
+    @XmlElement(name = "source")
+    @XmlIDREF
+    @XmlSchemaType(name = "IDREF")
+    @OneToOne(fetch = FetchType.LAZY, orphanRemoval=true)
+    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE, CascadeType.DELETE})
+    private IdentifiableSource source;
 
 
 //     /**
@@ -168,7 +179,13 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
         rootNode.setClassification(this);
     }
 
+    @Override
+    protected void initDefaultCacheStrategy() {
+        this.cacheStrategy = ClassificationDefaultCacheStrategy.NewInstance();
+    }
+
 //********************** xxxxxxxxxxxxx ******************************************/
+
     /**
      * Returns the topmost {@link TaxonNode taxon node} (root node) of <i>this</i>
      * classification. The root node does not have any parent and no taxon. Since taxon nodes
@@ -193,8 +210,8 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
 
         childNode.setParentTreeNode(this.rootNode, index);
 
-        childNode.setReference(citation);
-        childNode.setMicroReference(microCitation);
+        childNode.setCitation(citation);
+        childNode.setCitationMicroReference(microCitation);
 //             childNode.setSynonymToBeUsed(synonymToBeUsed);
 
         return childNode;
@@ -207,7 +224,25 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
 
     @Override
     public TaxonNode addChildTaxon(Taxon taxon, int index, Reference citation, String microCitation) {
-        return addChildNode(new TaxonNode(taxon), index, citation, microCitation);
+        return addChildNode(new TaxonNode(taxon), index, NamedSource.NewPrimarySourceInstance(citation, microCitation));
+    }
+
+    @Override
+    public TaxonNode addChildTaxon(Taxon taxon, NamedSource source) {
+        return addChildTaxon(taxon, rootNode.getCountChildren(), source);
+    }
+
+    @Override
+    public TaxonNode addChildTaxon(Taxon taxon, int index, NamedSource source) {
+        return addChildNode(new TaxonNode(taxon), index, source);
+    }
+
+    @Override
+    public TaxonNode addChildNode(TaxonNode childNode, int index, NamedSource source) {
+        childNode.setParentTreeNode(this.rootNode, index);
+        childNode.setSource(source);
+
+        return childNode;
     }
 
     @Override
@@ -219,7 +254,7 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
             node.setTaxon(null);
         }
 
-        ArrayList<TaxonNode> childNodes = new ArrayList<TaxonNode>(node.getChildNodes());
+        ArrayList<TaxonNode> childNodes = new ArrayList<>(node.getChildNodes());
         for (TaxonNode childNode : childNodes){
             if (childNode != null){
                 node.deleteChildNode(childNode);
@@ -230,9 +265,11 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
 
     public boolean deleteChildNode(TaxonNode node, boolean deleteChildren) {
         boolean result = removeChildNode(node);
+        if (node.hasTaxon()){
+            node.getTaxon().removeTaxonNode(node);
+            node.setTaxon(null);
+        }
 
-        node.getTaxon().removeTaxonNode(node);
-        //node.setTaxon(null);
         if (deleteChildren){
             ArrayList<TaxonNode> childNodes = new ArrayList<TaxonNode>(node.getChildNodes());
             for (TaxonNode childNode : childNodes){
@@ -242,17 +279,13 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
         return result;
     }
 
-    /**
-     *
-     * @param node
-     * @return
-     */
     protected boolean removeChildNode(TaxonNode node){
         boolean result = false;
+        rootNode = HibernateProxyHelper.deproxy(rootNode, TaxonNode.class);
         if(!rootNode.getChildNodes().contains(node)){
             throw new IllegalArgumentException("TaxonNode is a not a root node of this classification");
         }
-
+//        rootNode = HibernateProxyHelper.deproxy(rootNode, TaxonNode.class);
         result = rootNode.removeChildNode(node);
 
         node.setParent(null);
@@ -271,7 +304,6 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
             result = true;
         }
         return result;
-
     }
 
     /**
@@ -300,7 +332,6 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
         otherNode.addChildNode(topmostNode, ref, microReference);
     }
 
-
     /**
      * Checks if the given taxon is part of <b>this</b> tree.
      * @param taxon
@@ -313,7 +344,7 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
 
     /**
      * Checks if the given taxon is part of <b>this</b> tree. If so the according TaxonNode is returned.
-     * Otherwise null is returned.
+     * Otherwise <code>null</code> is returned.
      * @param taxon
      * @return
      */
@@ -323,7 +354,7 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
         }
 
         for (TaxonNode taxonNode: taxon.getTaxonNodes()){
-               Classification classification = HibernateProxyHelper.deproxy(taxonNode.getClassification(), Classification.class);
+               Classification classification = deproxy(taxonNode.getClassification());
             if (classification.equals(this)){
                 return taxonNode;
             }
@@ -340,10 +371,9 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
         return (getTopmostNode(taxon) != null);
     }
 
-
     /**
-     * Checks if the taxon is a direct child of <b>this</b> tree and returns the according node if true.
-     * Returns null otherwise.
+     * Checks if the taxon is a direct child of the root of <b>this</b> tree and returns the according node if true.
+     * Returns <code>null</code> otherwise.
      * @param taxon
      * @return
      */
@@ -371,15 +401,15 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
     private boolean handleCitationOverwrite(TaxonNode childNode, Reference citation, String microCitation){
         if (citation != null){
             if (childNode.getReference() != null && ! childNode.getReference().equals(citation)){
-                logger.warn("ReferenceForParentChildRelation will be overwritten");
+                logger.warn("TaxonNode source will be overwritten");
             }
-            childNode.setReference(citation);
+            childNode.setCitation(citation);
         }
         if (microCitation != null){
             if (childNode.getMicroReference() != null && ! childNode.getMicroReference().equals(microCitation)){
-                logger.warn("MicroReferenceForParentChildRelation will be overwritten");
+                logger.warn("TaxonNode source detail will be overwritten");
             }
-            childNode.setMicroReference(microCitation);
+            childNode.setCitationMicroReference(microCitation);
         }
         return true;
     }
@@ -466,8 +496,6 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
         }
     }
 
-
-    @Override
     @Transient
     public Reference getCitation() {
         return reference;
@@ -476,7 +504,6 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
     public LanguageString getName() {
         return name;
     }
-
     public void setName(LanguageString name) {
         this.name = name;
     }
@@ -491,7 +518,7 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
      */
     @Transient
     public Set<TaxonNode> getAllNodes() {
-        Set<TaxonNode> allNodes = new HashSet<TaxonNode>();
+        Set<TaxonNode> allNodes = new HashSet<>();
 
         for(TaxonNode rootNode : getChildNodes()){
             allNodes.addAll(rootNode.getDescendants());
@@ -510,25 +537,18 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
     public Reference getReference() {
         return reference;
     }
-
     public void setReference(Reference reference) {
         this.reference = reference;
     }
 
-
     @Override
     public String getMicroReference() {
         return microReference;
     }
-
-    /**
-     * @param microReference the microReference to set
-     */
     public void setMicroReference(String microReference) {
         this.microReference = microReference;
     }
 
-
     /**
         * The point in time, the time period or the season for which this description element
         * is valid. A season may be expressed by not filling the year part(s) of the time period.
@@ -536,7 +556,6 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
        public TimePeriod getTimeperiod() {
                return timeperiod;
        }
-
        /**
         * @see #getTimeperiod()
         */
@@ -547,7 +566,6 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
                this.timeperiod = timeperiod;
        }
 
-
     /**
      * Returns the set of {@link NamedArea named areas} indicating the geospatial
      * data where <i>this</i> {@link Classification} is valid.
@@ -579,7 +597,6 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
         this.geoScopes.remove(geoScope);
     }
 
-
        /**
         * Returns the i18n description used to describe
         * <i>this</i> {@link Classification}. The different {@link LanguageString language strings}
@@ -630,43 +647,27 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
                this.description.remove(language);
        }
 
-
-    @Override
-    public String generateTitle() {
-        //TODO implement as cache strategy
-        if (protectedTitleCache){
-            return this.titleCache;
-        }else if (name != null){
-            return name.getText();
-        }else if (reference != null){
-            return this.reference.getTitleCache();
-        }else{
-            return this.toString();
-        }
-    }
-
     public int compareTo(Object o) {
         //TODO needs to be implemented
         return 0;
     }
 
-
     @Override
     public boolean hasChildNodes() {
         return getChildNodes().size() > 0;
     }
 
     //*********************** CLONE ********************************************************/
+
     /**
      * Clones <i>this</i> classification. This is a shortcut that enables to create
      * a new instance that differs only slightly from <i>this</i> classification by
      * modifying only some of the attributes.<BR><BR>
 
-     * @see eu.etaxonomy.cdm.model.media.IdentifiableEntity#clone()
      * @see java.lang.Object#clone()
      */
     @Override
-    public Object clone() {
+    public Classification clone() {
         Classification result;
         try{
             result = (Classification)super.clone();
@@ -674,7 +675,6 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
             List<TaxonNode> rootNodes = new ArrayList<>();
             TaxonNode rootNodeClone;
 
-
             rootNodes.addAll(rootNode.getChildNodes());
             TaxonNode rootNode;
             Iterator<TaxonNode> iterator = rootNodes.iterator();
@@ -702,7 +702,5 @@ public class Classification extends IdentifiableEntity<IIdentifiableEntityCacheS
             e.printStackTrace();
             return null;
         }
-
     }
-
 }