serial Version ID for HomGroup
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / name / HybridRelationship.java
index 65f94e1766dbb84a2743adcedf52ec4b22ca506a..c4cc412f051a9b427ed19bd47fe0b1e1c9e3531c 100644 (file)
@@ -9,15 +9,25 @@
 
 package eu.etaxonomy.cdm.model.name;
 
-import eu.etaxonomy.cdm.model.common.RelationshipBase;
-import eu.etaxonomy.cdm.model.reference.ReferenceBase;
-import org.apache.log4j.Logger;
-import javax.persistence.*;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.ManyToOne;
+import javax.persistence.Transient;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlIDREF;
+import javax.xml.bind.annotation.XmlSchemaType;
 import javax.xml.bind.annotation.XmlType;
 
+import org.apache.log4j.Logger;
+import org.hibernate.annotations.Cascade;
+import org.hibernate.annotations.CascadeType;
+import org.hibernate.envers.Audited;
+
+import eu.etaxonomy.cdm.model.common.RelationshipBase;
+import eu.etaxonomy.cdm.model.reference.Reference;
+
 /**
  * The class representing a hybrid relationship between one of the {@link BotanicalName parents}
  * of a hybrid taxon name and the hybrid taxon name itself. A hybrid taxon name
@@ -26,27 +36,57 @@ import javax.xml.bind.annotation.XmlType;
  * of the hybrid flags set. The hybrid relationship includes a {@link HybridRelationshipType hybrid relationship type}
  * (for instance "first parent" or "female parent") and the article of the ICBN
  * on which the hybrid taxon name relies.
+ * <P>
+ * This class corresponds partially to: <ul>
+ * <li> Relationship according to the TDWG ontology
+ * <li> TaxonRelationship according to the TCS
+ * </ul>
+ * 
  * @author m.doering
  * @version 1.0
  * @created 08-Nov-2007 13:06:26
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "HybridRelationship", propOrder = {
+       "relatedFrom",
+       "relatedTo",
+       "type",
     "ruleConsidered"
 })
 @Entity
-public class HybridRelationship extends RelationshipBase<BotanicalName, BotanicalName, HybridRelationshipType> {
-  
+@Audited
+public class HybridRelationship extends RelationshipBase<NonViralName, NonViralName, HybridRelationshipType>  implements Cloneable, Comparable<HybridRelationship>{
        private static final Logger logger = Logger.getLogger(HybridRelationship.class);
        
        //The nomenclatural code rule considered. The article/note/recommendation in the code in question that is commented on in
        //the note property.
        @XmlElement(name = "RuleConsidered")
        private String ruleConsidered;
+       
+       @XmlElement(name = "RelatedFrom")
+    @XmlIDREF
+    @XmlSchemaType(name = "IDREF")
+    @ManyToOne(fetch=FetchType.LAZY)
+    @Cascade(CascadeType.SAVE_UPDATE)
+       private NonViralName relatedFrom;
+
+       @XmlElement(name = "RelatedTo")
+    @XmlIDREF
+    @XmlSchemaType(name = "IDREF")
+    @ManyToOne(fetch=FetchType.LAZY)
+    @Cascade(CascadeType.SAVE_UPDATE)
+       private NonViralName relatedTo;
+       
+    @XmlElement(name = "Type")
+    @XmlIDREF
+    @XmlSchemaType(name = "IDREF")
+    @ManyToOne(fetch=FetchType.LAZY)
+       private HybridRelationshipType type;
 
-       //for hibernate use only, don't use
-       @Deprecated
+       /**
+        * @deprecated for hibernate use only, don't use
+        */
+       @Deprecated 
        private HybridRelationship(){
                super();
        }
@@ -62,16 +102,16 @@ public class HybridRelationship extends RelationshipBase<BotanicalName, Botanica
         * @param fromName                      the taxon name to be set as source for the new hybrid relationship
         * @param type                          the relationship type to be assigned to the new hybrid relationship
         * @param ruleConsidered        the string indicating the article of the ICBN for the hybrid taxon name
-        * @see                                         #HybridRelationship(BotanicalName, BotanicalName, HybridRelationshipType, ReferenceBase, String, String)
+        * @see                                         #HybridRelationship(BotanicalName, BotanicalName, HybridRelationshipType, Reference, String, String)
         * @see                                         BotanicalName#addHybridRelationship(HybridRelationship)
         */
-       protected HybridRelationship(BotanicalName hybridName, BotanicalName parentName, HybridRelationshipType type, String ruleConsidered) {
+       protected HybridRelationship(NonViralName hybridName, NonViralName parentName, HybridRelationshipType type, String ruleConsidered) {
                this(hybridName, parentName, type, null, null, ruleConsidered);
        }
        
        /**
         * Class constructor: creates a new hybrid relationship instance including
-        * its {@link reference.ReferenceBase reference source} and adds it to the respective 
+        * its {@link eu.etaxonomy.cdm.model.reference.Reference reference source} and adds it to the respective 
         *{@link BotanicalName#getHybridRelationships() botanical taxon name relation sets} of both involved names.
         * 
         * @param toName                                the taxon name to be set as target for the new hybrid relationship
@@ -83,7 +123,7 @@ public class HybridRelationship extends RelationshipBase<BotanicalName, Botanica
         * @see                                                 #HybridRelationship(BotanicalName, BotanicalName, HybridRelationshipType, String)
         * @see                                                 BotanicalName#addHybridRelationship(HybridRelationship)
         */
-       protected HybridRelationship(BotanicalName  hybridName, BotanicalName parentName, HybridRelationshipType type, ReferenceBase citation, String citationMicroReference, String ruleConsidered) {
+       protected HybridRelationship(NonViralName  hybridName, NonViralName parentName, HybridRelationshipType type, Reference citation, String citationMicroReference, String ruleConsidered) {
                super(parentName, hybridName, type, citation, citationMicroReference);
                this.setRuleConsidered(ruleConsidered);
        }       
@@ -95,17 +135,17 @@ public class HybridRelationship extends RelationshipBase<BotanicalName, Botanica
         * in <i>this</i> hybrid relationship.
         *  
         * @see   #getHybridName()
-        * @see   common.RelationshipBase#getRelatedFrom()
+        * @see   eu.etaxonomy.cdm.model.common.RelationshipBase#getRelatedFrom()
         */
        @Transient
-       public BotanicalName getParentName(){
-               return super.getRelatedFrom();
+       public NonViralName getParentName(){
+               return this.getRelatedFrom();
        }
        /**
         * @see  #getParentName()
         */
-       public void setParentName(BotanicalName parentName){
-               super.setRelatedFrom(parentName);
+       public void setParentName(NonViralName parentName){
+               this.setRelatedFrom(parentName);
        }
 
        /** 
@@ -113,24 +153,24 @@ public class HybridRelationship extends RelationshipBase<BotanicalName, Botanica
         * (the child is actually the hybrid taxon name) in <i>this</i> hybrid relationship.
         *  
         * @see   #getParentName()
-        * @see   common.RelationshipBase#getRelatedTo()
+        * @see   eu.etaxonomy.cdm.model.common.RelationshipBase#getRelatedTo()
         */
        @Transient
-       public BotanicalName getHybridName(){
-               return super.getRelatedTo();
+       public NonViralName getHybridName(){
+               return this.getRelatedTo();
        }
        /**
         * @see  #getHybridName()
         */
-       public void setHybridName(BotanicalName hybridName){
-               super.setRelatedTo(hybridName);
+       public void setHybridName(NonViralName hybridName){
+               this.setRelatedTo(hybridName);
        }
 
        /** 
         * Returns the ICBN rule considered (that is the
         * article/note/recommendation in the nomenclatural code) for building
-        * the string representing the hybrid taxon name within <i>this</i> hybrid
-        * relationship.
+        * the string representing the (child) hybrid {@link BotanicalName taxon name}
+        * within <i>this</i> hybrid relationship.
         */
        public String getRuleConsidered(){
                return this.ruleConsidered;
@@ -142,4 +182,86 @@ public class HybridRelationship extends RelationshipBase<BotanicalName, Botanica
                this.ruleConsidered = ruleConsidered;
        }
 
+       protected NonViralName getRelatedFrom() {
+               return relatedFrom;
+       }
+
+       protected NonViralName getRelatedTo() {
+               return relatedTo;
+       }
+
+       public HybridRelationshipType getType() {
+               return type;
+       }
+
+       protected void setRelatedFrom(NonViralName relatedFrom) {
+               if (relatedFrom == null){
+                       this.deletedObjects.add(this.relatedFrom);
+               }
+               this.relatedFrom = relatedFrom;
+       }
+
+       protected void setRelatedTo(NonViralName relatedTo) {
+               if (relatedTo == null){
+                       this.deletedObjects.add(this.relatedTo);
+               }
+               this.relatedTo = relatedTo;
+       }
+
+       public void setType(HybridRelationshipType type) {
+               this.type = type;
+       }
+       
+// ************************ compareTo *************************************************
+       /* (non-Javadoc)
+        * @see java.lang.Comparable#compareTo(java.lang.Object)
+        */
+//     @Override  //leads to compile errors in some environments
+       public int compareTo(HybridRelationship rel2) {
+               HybridRelationshipType type1 = this.getType();
+               HybridRelationshipType type2 = rel2.getType();
+               int compareType = type1.compareTo(type2);
+               if (compareType != 0){
+                       return compareType;
+               }else{
+                       NonViralName related1 = this.getRelatedFrom();
+                       NonViralName<?> related2 = rel2.getRelatedFrom();
+                       if (related1 != related2){
+                               related1 = this.getRelatedTo();
+                               related2 = rel2.getRelatedTo();
+                       }
+                       String title1 = related1.getTitleCache();
+                       String title2 = related2.getTitleCache();
+                       return title1.compareTo(title2);
+               }
+       }
+       
+       
+//*********************** CLONE ********************************************************/
+       
+       /** 
+        * Clones <i>this</i> hybrid relationship. This is a shortcut that enables to create
+        * a new instance that differs only slightly from <i>this</i> hybrid relationship by
+        * modifying only some of the attributes.<BR>
+        * CAUTION: Cloning a relationship will not add the relationship to the according 
+        * {@link #relatedFrom} and {@link #relatedTo} objects. The method is meant to be used
+        * mainly for internal purposes (e.g. used within {@link TaxonNameBase#clone()}
+        * 
+        * @see eu.etaxonomy.cdm.model.common.RelationshipBase#clone()
+        * @see java.lang.Object#clone()
+        */
+       @Override
+       public Object clone() {
+               HybridRelationship result;
+               try {
+                       result = (HybridRelationship)super.clone();
+                       //no changes to: relatedFrom, relatedTo, type
+                       return result;
+               } catch (CloneNotSupportedException e) {
+                       logger.warn("Object does not implement cloneable");
+                       e.printStackTrace();
+                       return null;
+               }
+       }
+       
 }
\ No newline at end of file