improving loadRankSpecificRootNodes
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / taxon / TaxonomicTree.java
index 684c66e984568310741ab6340feb6f20c679276f..6fbe47eb4c444190619e9f4e92910abf4e7370c2 100644 (file)
@@ -17,6 +17,7 @@ import java.util.Set;
 \r
 import javax.persistence.Entity;\r
 import javax.persistence.FetchType;\r
+import javax.persistence.JoinColumn;\r
 import javax.persistence.ManyToOne;\r
 import javax.persistence.OneToMany;\r
 import javax.persistence.OneToOne;\r
@@ -34,6 +35,7 @@ import org.apache.log4j.Logger;
 import org.hibernate.annotations.Cascade;\r
 import org.hibernate.annotations.CascadeType;\r
 import org.hibernate.envers.Audited;\r
+import org.hibernate.search.annotations.IndexedEmbedded;\r
 \r
 import eu.etaxonomy.cdm.model.common.IReferencedEntity;\r
 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;\r
@@ -61,11 +63,11 @@ public class TaxonomicTree extends IdentifiableEntity implements IReferencedEnti
        private static final long serialVersionUID = -753804821474209635L;\r
        private static final Logger logger = Logger.getLogger(TaxonomicTree.class);\r
        \r
-       @XmlElement(name = "name")\r
-       @XmlIDREF\r
-       @XmlSchemaType(name = "IDREF")\r
+       @XmlElement(name = "Name")\r
        @OneToOne(fetch = FetchType.LAZY)\r
        @Cascade({CascadeType.SAVE_UPDATE})\r
+       @JoinColumn(name = "name_id", referencedColumnName = "id")\r
+       @IndexedEmbedded\r
        private LanguageString name;\r
        \r
 //     @XmlElementWrapper(name = "allNodes")\r
@@ -136,12 +138,14 @@ public class TaxonomicTree extends IdentifiableEntity implements IReferencedEnti
         */\r
        public TaxonNode addChildNode(TaxonNode childNode, ReferenceBase citation,\r
                        String microCitation, Synonym synonymToBeUsed) {\r
+               \r
                rootNodes.add(childNode);\r
                childNode.setParent(null);\r
-               childNode.setTaxonomicView(this);\r
-               childNode.setReferenceForParentChildRelation(citation);\r
-               childNode.setMicroReferenceForParentChildRelation(microCitation);\r
+               childNode.setTaxonomicTree(this);\r
+               childNode.setReference(citation);\r
+               childNode.setMicroReference(microCitation);\r
                childNode.setSynonymToBeUsed(synonymToBeUsed);\r
+               \r
                return childNode;\r
        }\r
 \r
@@ -160,12 +164,11 @@ public class TaxonomicTree extends IdentifiableEntity implements IReferencedEnti
         * @return\r
         * @deprecated use addChildNode() or addChildTaxon() instead\r
         */\r
-       @Deprecated\r
        public TaxonNode addRoot(Taxon taxon, Synonym synonymUsed, ReferenceBase reference){\r
                TaxonNode newRoot = new TaxonNode(taxon, this);\r
                rootNodes.add(newRoot);\r
                newRoot.setParent(null);\r
-               newRoot.setTaxonomicView(this);\r
+               newRoot.setTaxonomicTree(this);\r
                newRoot.setTaxon(taxon);\r
                newRoot.setReferenceForParentChildRelation(reference);\r
                newRoot.setSynonymToBeUsed(synonymUsed);\r
@@ -176,25 +179,47 @@ public class TaxonomicTree extends IdentifiableEntity implements IReferencedEnti
        /* (non-Javadoc)\r
         * @see eu.etaxonomy.cdm.model.taxon.ITreeNode#removeChildNode(eu.etaxonomy.cdm.model.taxon.TaxonNode)\r
         */\r
-       public boolean removeChildNode(TaxonNode node) {\r
+       public boolean deleteChildNode(TaxonNode node) {\r
+               boolean result = removeChildNode(node);\r
+               \r
+               node.getTaxon().removeTaxonNode(node);\r
+               node.setTaxon(null);    \r
+               \r
+               ArrayList<TaxonNode> childNodes = new ArrayList<TaxonNode>(node.getChildNodes()); \r
+               for (TaxonNode childNode : childNodes){\r
+                       node.deleteChildNode(childNode);\r
+               }\r
+               return result;\r
+       }\r
+       \r
+       /**\r
+        * \r
+        * @param node\r
+        * @return\r
+        */\r
+       protected boolean removeChildNode(TaxonNode node){\r
                boolean result = false;\r
-               if(node.isRootNode()){\r
-\r
-                       for (TaxonNode childNode : node.getChildNodes()){\r
-                               node.removeChildNode(childNode);\r
-                       }\r
-                       result = rootNodes.remove(node);\r
-\r
-                       node.getTaxon().removeTaxonNode(node);\r
-                       node.setParent(null);\r
-                       node.setTaxonomicView(null);\r
-                       node.setTaxon(null);                    \r
+               \r
+               if(!rootNodes.contains(node)){\r
+                       throw new IllegalArgumentException("TaxonNode is a not a root node of this taxonomic tree");\r
                }\r
+               \r
+               result = rootNodes.remove(node);\r
+\r
+               node.setParent(null);\r
+               node.setTaxonomicTree(null);\r
+               \r
                return result;\r
        }\r
        \r
+       /**\r
+        * \r
+        * @param node\r
+        * @return\r
+        * @deprecated use removeChildNode() instead\r
+        */\r
        public boolean removeRoot(TaxonNode node){\r
-               return removeChildNode(node);\r
+               return deleteChildNode(node);\r
        }\r
        \r
        /**\r
@@ -221,7 +246,7 @@ public class TaxonomicTree extends IdentifiableEntity implements IReferencedEnti
                        throw new IllegalArgumentException("root node and other node must not be the same");\r
                }\r
                otherNode.addChildNode(root, ref, microReference, null);\r
-               getRootNodes().remove(root);\r
+               //getRootNodes().remove(root);\r
        }\r
        \r
 //     public void makeThisNodePartOfOtherView(TaxonNode oldRoot, TaxonNode replacedNodeInOtherView, ReferenceBase reference, String microReference){\r
@@ -313,6 +338,13 @@ public class TaxonomicTree extends IdentifiableEntity implements IReferencedEnti
         * one parent. <Br>\r
         * If the parent-child relationship between these two taxa already exists nothing is changed. Only \r
         * citation and microcitation are overwritten by the new values if these values are not null.\r
+        * \r
+        * TODO this looks like very specialized functionality. Upon examination, it turned out that it is used\r
+        * solely in imports and it also looks like it is very tightly coupled with the way the imports are implemented.\r
+        * As an advocat for a clean API, I would very much recommend not having this in the library itself as I can \r
+        * not really see who else will be needing this.\r
+        * - n.hoffmann\r
+        * \r
         * @param parent\r
         * @param child\r
         * @param citation\r
@@ -330,8 +362,8 @@ public class TaxonomicTree extends IdentifiableEntity implements IReferencedEnti
                        //no multiple parents are allowed in the tree\r
                        if (childNode != null && childNode.getParent() != null){\r
                                //...different to the parent taxon  throw exception\r
-                               if (! childNode.getParent().getTaxon().equals(parent) ){\r
-                                       throw new IllegalStateException("The child taxon is already part of the tree but has an other parent taxon than the one than the parent to be added. Child: " + child.toString() + ", new parent:" + parent.toString() + ", old parent: " + childNode.getParent().getTaxon().toString()) ;\r
+                               if ((childNode.getParent() instanceof TaxonNode) && !((TaxonNode)childNode.getParent()).getTaxon().equals(parent) ){\r
+                                       throw new IllegalStateException("The child taxon is already part of the tree but has an other parent taxon than the one than the parent to be added. Child: " + child.toString() + ", new parent:" + parent.toString() + ", old parent: " + ((TaxonNode) childNode.getParent()).getTaxon().toString()) ;\r
                                //... same as the parent taxon do nothing but overwriting citation and microCitation\r
                                }else{\r
                                        handleCitationOverwrite(childNode, citation, microCitation);\r
@@ -386,7 +418,6 @@ public class TaxonomicTree extends IdentifiableEntity implements IReferencedEnti
         * @return\r
         */\r
        @Transient\r
-       @Deprecated\r
        public Set<TaxonNode> getAllNodes() {\r
                Set<TaxonNode> allNodes = new HashSet<TaxonNode>();\r
                \r
@@ -448,7 +479,9 @@ public class TaxonomicTree extends IdentifiableEntity implements IReferencedEnti
         * \r
         * @param rank may be null\r
         * @return\r
+        * @deprecated use {@link ITaxonTreeService.loadRankSpecificRootNode} or {@link ITaxonomicTreeDao.loadRankSpecificRootNode} instead\r
         */\r
+       @Deprecated\r
        public List<TaxonNode> getRankSpecificRootNodes(Rank rank) {\r
                List<TaxonNode> baseNodes = new ArrayList<TaxonNode>();\r
                if(rank != null){\r
@@ -484,4 +517,11 @@ public class TaxonomicTree extends IdentifiableEntity implements IReferencedEnti
                }\r
                return rootNodes;\r
        }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.model.taxon.ITreeNode#hasChildNodes()\r
+        */\r
+       public boolean hasChildNodes() {\r
+               return getRootNodes().size() > 0;\r
+       }\r
 }\r