d90fab85d41ec5a3eec61b99a5638a6103783d04
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / taxon / TaxonRelationship.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9
10 package eu.etaxonomy.cdm.model.taxon;
11
12 import javax.persistence.Entity;
13 import javax.persistence.FetchType;
14 import javax.persistence.ManyToOne;
15 import javax.persistence.Transient;
16 import javax.xml.bind.annotation.XmlAccessType;
17 import javax.xml.bind.annotation.XmlAccessorType;
18 import javax.xml.bind.annotation.XmlElement;
19 import javax.xml.bind.annotation.XmlIDREF;
20 import javax.xml.bind.annotation.XmlRootElement;
21 import javax.xml.bind.annotation.XmlSchemaType;
22 import javax.xml.bind.annotation.XmlType;
23
24 import org.apache.log4j.Logger;
25 import org.hibernate.annotations.Cascade;
26 import org.hibernate.annotations.CascadeType;
27 import org.hibernate.envers.Audited;
28
29 import eu.etaxonomy.cdm.model.common.RelationshipBase;
30 import eu.etaxonomy.cdm.model.reference.Reference;
31 import eu.etaxonomy.cdm.validation.Level3;
32 import eu.etaxonomy.cdm.validation.annotation.ChildTaxaMustBeLowerRankThanParent;
33 import eu.etaxonomy.cdm.validation.annotation.ChildTaxaMustDeriveNameFromParent;
34 import eu.etaxonomy.cdm.validation.annotation.ChildTaxaMustNotSkipRanks;
35
36 /**
37 * The class representing a relationship between two {@link Taxon ("accepted/correct") taxa}.
38 * This includes a {@link TaxonRelationshipType taxon relationship type} (for instance "congruent to" or
39 * "misapplied name for").
40 * <P>
41 * This class corresponds in part to: <ul>
42 * <li> Relationship according to the TDWG ontology
43 * <li> TaxonRelationship according to the TCS
44 * </ul>
45 *
46 * @author m.doering
47 * @version 1.0
48 * @created 08-Nov-2007 13:06:58
49 */
50 @XmlAccessorType(XmlAccessType.FIELD)
51 @XmlType(name = "TaxonRelationship", propOrder = {
52 "relatedFrom",
53 "relatedTo",
54 "type"
55 })
56 @XmlRootElement(name = "TaxonRelationship")
57 @Entity
58 @Audited
59 @ChildTaxaMustBeLowerRankThanParent(groups = Level3.class)
60 @ChildTaxaMustNotSkipRanks(groups = Level3.class)
61 @ChildTaxaMustDeriveNameFromParent(groups = Level3.class)
62 public class TaxonRelationship extends RelationshipBase<Taxon, Taxon, TaxonRelationshipType> {
63 private static final long serialVersionUID = 1378437971941534653L;
64 static private final Logger logger = Logger.getLogger(TaxonRelationship.class);
65
66 @XmlElement(name = "RelatedFrom")
67 @XmlIDREF
68 @XmlSchemaType(name = "IDREF")
69 @ManyToOne(fetch=FetchType.EAGER)
70 @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE})
71 private Taxon relatedFrom;
72
73 @XmlElement(name = "RelatedTo")
74 @XmlIDREF
75 @XmlSchemaType(name = "IDREF")
76 @ManyToOne(fetch=FetchType.EAGER)
77 @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE})
78 private Taxon relatedTo;
79
80 @XmlElement(name = "Type")
81 @XmlIDREF
82 @XmlSchemaType(name = "IDREF")
83 @ManyToOne(fetch=FetchType.EAGER)
84 private TaxonRelationshipType type;
85
86 /**
87 * @deprecated for hibernate only, don't use
88 */
89 @Deprecated
90 private TaxonRelationship(){
91 }
92
93 /**
94 * Class constructor: creates a new taxon relationship instance (with the
95 * given "accepted/correct" {@link Taxon taxa}, the given {@link SynonymRelationshipType synonym relationship type}
96 * and with the {@link eu.etaxonomy.cdm.model.reference.Reference reference source} on which the relationship
97 * assertion is based). Moreover the new taxon relationship will be added to
98 * the respective sets of taxon relationships assigned to both taxa.
99 *
100 * @param from the taxon instance to be involved as a source in the new taxon relationship
101 * @param to the taxon instance to be involved as a target in the new taxon relationship
102 * @param type the taxon relationship type of the new taxon relationship
103 * @param citation the reference source for the new taxon relationship
104 * @param citationMicroReference the string with the details describing the exact localisation within the reference
105 * @see eu.etaxonomy.cdm.model.common.RelationshipBase
106 */
107 protected TaxonRelationship(Taxon from, Taxon to, TaxonRelationshipType type, Reference citation, String citationMicroReference) {
108 super(from, to, type, citation, citationMicroReference);
109 }
110
111 /**
112 * Returns the {@link Taxon taxon} involved as a source in <i>this</i>
113 * taxon relationship.
114 *
115 * @see #getToTaxon()
116 * @see Taxon#getRelationsFromThisTaxon()
117 * @see eu.etaxonomy.cdm.model.common.RelationshipBase#getRelatedFrom()
118 * @see eu.etaxonomy.cdm.model.common.RelationshipBase#getType()
119 */
120 @Transient
121 public Taxon getFromTaxon(){
122 return getRelatedFrom();
123 }
124 /**
125 * Sets the given {@link Taxon taxon} as a source in <i>this</i> taxon relationship.
126 * Therefore <i>this</i> taxon relationship will be added to the corresponding
127 * set of taxon relationships assigned to the given taxon. Furthermore if
128 * the given taxon replaces an "old" one <i>this</i> taxon relationship will
129 * be removed from the set of taxon relationships assigned to the "old"
130 * source taxon.
131 *
132 * @param fromTaxon the taxon instance to be set as a source in <i>this</i> synonym relationship
133 * @see #getFromTaxon()
134 */
135 public void setFromTaxon(Taxon fromTaxon){
136 setRelatedFrom(fromTaxon);
137 }
138
139 /**
140 * Returns the {@link Taxon taxon} involved as a target in <i>this</i>
141 * taxon relationship.
142 *
143 * @see #getFromTaxon()
144 * @see Taxon#getRelationsToThisTaxon()
145 * @see eu.etaxonomy.cdm.model.common.RelationshipBase#getRelatedTo()
146 * @see eu.etaxonomy.cdm.model.common.RelationshipBase#getType()
147 */
148 @Transient
149 public Taxon getToTaxon(){
150 return getRelatedTo();
151 }
152
153 /**
154 * Sets the given {@link Taxon taxon} as a target in <i>this</i> taxon relationship.
155 * Therefore <i>this</i> taxon relationship will be added to the corresponding
156 * set of taxon relationships assigned to the given taxon. Furthermore if
157 * the given taxon replaces an "old" one <i>this</i> taxon relationship will
158 * be removed from the set of taxon relationships assigned to the "old"
159 * target taxon.
160 *
161 * @param toTaxon the taxon instance to be set as a target in <i>this</i> synonym relationship
162 * @see #getToTaxon()
163 */
164 public void setToTaxon(Taxon toTaxon){
165 setRelatedTo(toTaxon);
166 }
167
168 // for extra-package access to relatedFrom use getFromTaxon instead
169 protected Taxon getRelatedFrom() {
170 return relatedFrom;
171 }
172
173 // for extra-package access to relatedFrom use getToTaxon instead
174 protected Taxon getRelatedTo() {
175 return relatedTo;
176 }
177
178 public TaxonRelationshipType getType() {
179 return type;
180 }
181
182 protected void setRelatedFrom(Taxon relatedFrom) {
183 if (relatedFrom == null){
184 this.deletedObjects.add(this.relatedFrom);
185 }
186 this.relatedFrom = relatedFrom;
187 }
188
189 protected void setRelatedTo(Taxon relatedTo) {
190 if (relatedTo == null){
191 this.deletedObjects.add(this.relatedTo);
192 }
193 this.relatedTo = relatedTo;
194 }
195
196 public void setType(TaxonRelationshipType type) {
197 this.type = type;
198 }
199
200 //*********************************** CLONE *****************************************/
201
202 /**
203 * Clones <i>this</i> TaxonRelationship. This is a shortcut that enables to create
204 * a new instance that differs only slightly from <i>this</i> TaxonRelationship by
205 * modifying only some of the attributes.
206 *
207 * @see eu.etaxonomy.cdm.model.common.RelationshipBase#clone()
208 * @see java.lang.Object#clone()
209 */
210 @Override
211 public Object clone() {
212 TaxonRelationship result;
213
214 try{
215 result = (TaxonRelationship) super.clone();
216 //no changes to relatedFrom, relatedTo, type
217
218 return result;
219 } catch (CloneNotSupportedException e) {
220 logger.warn("Object does not implement cloneable");
221 e.printStackTrace();
222 return null;
223 }
224 }
225 }