remove imports
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / name / HybridRelationship.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.name;
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.XmlSchemaType;
21 import javax.xml.bind.annotation.XmlType;
22
23 import org.apache.log4j.Logger;
24 import org.hibernate.annotations.Cascade;
25 import org.hibernate.annotations.CascadeType;
26 import org.hibernate.envers.Audited;
27
28 import eu.etaxonomy.cdm.model.common.RelationshipBase;
29 import eu.etaxonomy.cdm.model.reference.Reference;
30
31 /**
32 * The class representing a hybrid relationship between one of the {@link BotanicalName parents}
33 * of a hybrid taxon name and the hybrid taxon name itself. A hybrid taxon name
34 * is a {@link BotanicalName botanical taxon name} assigned to a hybrid plant following
35 * the {@link NomenclaturalCode#ICBN() ICBN} (Appendix I). A hybrid taxon name must have one
36 * of the hybrid flags set. The hybrid relationship includes a {@link HybridRelationshipType hybrid relationship type}
37 * (for instance "first parent" or "female parent") and the article of the ICBN
38 * on which the hybrid taxon name relies.
39 * <P>
40 * This class corresponds partially to: <ul>
41 * <li> Relationship according to the TDWG ontology
42 * <li> TaxonRelationship according to the TCS
43 * </ul>
44 *
45 * @author m.doering
46 * @version 1.0
47 * @created 08-Nov-2007 13:06:26
48 */
49 @XmlAccessorType(XmlAccessType.FIELD)
50 @XmlType(name = "HybridRelationship", propOrder = {
51 "relatedFrom",
52 "relatedTo",
53 "type",
54 "ruleConsidered"
55 })
56 @Entity
57 @Audited
58 public class HybridRelationship extends RelationshipBase<NonViralName, NonViralName, HybridRelationshipType> implements Cloneable, Comparable<HybridRelationship>{
59 private static final Logger logger = Logger.getLogger(HybridRelationship.class);
60
61 //The nomenclatural code rule considered. The article/note/recommendation in the code in question that is commented on in
62 //the note property.
63 @XmlElement(name = "RuleConsidered")
64 private String ruleConsidered;
65
66 @XmlElement(name = "RelatedFrom")
67 @XmlIDREF
68 @XmlSchemaType(name = "IDREF")
69 @ManyToOne(fetch=FetchType.LAZY)
70 @Cascade(CascadeType.SAVE_UPDATE)
71 private NonViralName relatedFrom;
72
73 @XmlElement(name = "RelatedTo")
74 @XmlIDREF
75 @XmlSchemaType(name = "IDREF")
76 @ManyToOne(fetch=FetchType.LAZY)
77 @Cascade(CascadeType.SAVE_UPDATE)
78 private NonViralName relatedTo;
79
80 @XmlElement(name = "Type")
81 @XmlIDREF
82 @XmlSchemaType(name = "IDREF")
83 @ManyToOne(fetch=FetchType.LAZY)
84 private HybridRelationshipType type;
85
86 /**
87 * @deprecated for hibernate use only, don't use
88 */
89 @Deprecated
90 private HybridRelationship(){
91 super();
92 }
93
94
95 // ************* CONSTRUCTORS *************/
96 /**
97 * Class constructor: creates a new hybrid relationship instance with no
98 * reference and adds it to the respective
99 * {@link BotanicalName#getHybridRelationships() botanical taxon name relation sets} of both involved names.
100 *
101 * @param toName the taxon name to be set as target for the new hybrid relationship
102 * @param fromName the taxon name to be set as source for the new hybrid relationship
103 * @param type the relationship type to be assigned to the new hybrid relationship
104 * @param ruleConsidered the string indicating the article of the ICBN for the hybrid taxon name
105 * @see #HybridRelationship(BotanicalName, BotanicalName, HybridRelationshipType, Reference, String, String)
106 * @see BotanicalName#addHybridRelationship(HybridRelationship)
107 */
108 protected HybridRelationship(NonViralName hybridName, NonViralName parentName, HybridRelationshipType type, String ruleConsidered) {
109 this(hybridName, parentName, type, null, null, ruleConsidered);
110 }
111
112 /**
113 * Class constructor: creates a new hybrid relationship instance including
114 * its {@link eu.etaxonomy.cdm.model.reference.Reference reference source} and adds it to the respective
115 *{@link BotanicalName#getHybridRelationships() botanical taxon name relation sets} of both involved names.
116 *
117 * @param toName the taxon name to be set as target for the new hybrid relationship
118 * @param fromName the taxon name to be set as source for the new hybrid relationship
119 * @param type the relationship type to be assigned to the new hybrid relationship
120 * @param citation the reference source for the new hybrid relationship
121 * @param citationMicroReference the string with the details describing the exact localisation within the reference
122 * @param ruleConsidered the string indicating the article of the ICBN for the hybrid taxon name
123 * @see #HybridRelationship(BotanicalName, BotanicalName, HybridRelationshipType, String)
124 * @see BotanicalName#addHybridRelationship(HybridRelationship)
125 */
126 protected HybridRelationship(NonViralName hybridName, NonViralName parentName, HybridRelationshipType type, Reference citation, String citationMicroReference, String ruleConsidered) {
127 super(parentName, hybridName, type, citation, citationMicroReference);
128 this.setRuleConsidered(ruleConsidered);
129 }
130
131 //********* METHODS **************************************/
132
133 /**
134 * Returns the {@link BotanicalName botanical taxon name} that plays the parent role
135 * in <i>this</i> hybrid relationship.
136 *
137 * @see #getHybridName()
138 * @see eu.etaxonomy.cdm.model.common.RelationshipBase#getRelatedFrom()
139 */
140 @Transient
141 public NonViralName getParentName(){
142 return this.getRelatedFrom();
143 }
144 /**
145 * @see #getParentName()
146 */
147 public void setParentName(NonViralName parentName){
148 this.setRelatedFrom(parentName);
149 }
150
151 /**
152 * Returns the {@link BotanicalName botanical taxon name} that plays the child role
153 * (the child is actually the hybrid taxon name) in <i>this</i> hybrid relationship.
154 *
155 * @see #getParentName()
156 * @see eu.etaxonomy.cdm.model.common.RelationshipBase#getRelatedTo()
157 */
158 @Transient
159 public NonViralName getHybridName(){
160 return this.getRelatedTo();
161 }
162 /**
163 * @see #getHybridName()
164 */
165 public void setHybridName(NonViralName hybridName){
166 this.setRelatedTo(hybridName);
167 }
168
169 /**
170 * Returns the ICBN rule considered (that is the
171 * article/note/recommendation in the nomenclatural code) for building
172 * the string representing the (child) hybrid {@link BotanicalName taxon name}
173 * within <i>this</i> hybrid relationship.
174 */
175 public String getRuleConsidered(){
176 return this.ruleConsidered;
177 }
178 /**
179 * @see #getRuleConsidered()
180 */
181 public void setRuleConsidered(String ruleConsidered){
182 this.ruleConsidered = ruleConsidered;
183 }
184
185 protected NonViralName getRelatedFrom() {
186 return relatedFrom;
187 }
188
189 protected NonViralName getRelatedTo() {
190 return relatedTo;
191 }
192
193 public HybridRelationshipType getType() {
194 return type;
195 }
196
197 protected void setRelatedFrom(NonViralName relatedFrom) {
198 if (relatedFrom == null){
199 this.deletedObjects.add(this.relatedFrom);
200 }
201 this.relatedFrom = relatedFrom;
202 }
203
204 protected void setRelatedTo(NonViralName relatedTo) {
205 if (relatedTo == null){
206 this.deletedObjects.add(this.relatedTo);
207 }
208 this.relatedTo = relatedTo;
209 }
210
211 public void setType(HybridRelationshipType type) {
212 this.type = type;
213 }
214
215 // ************************ compareTo *************************************************
216 /* (non-Javadoc)
217 * @see java.lang.Comparable#compareTo(java.lang.Object)
218 */
219 // @Override //leads to compile errors in some environments
220 public int compareTo(HybridRelationship rel2) {
221 HybridRelationshipType type1 = this.getType();
222 HybridRelationshipType type2 = rel2.getType();
223 int compareType = type1.compareTo(type2);
224 if (compareType != 0){
225 return compareType;
226 }else{
227 NonViralName related1 = this.getRelatedFrom();
228 NonViralName<?> related2 = rel2.getRelatedFrom();
229 if (related1 != related2){
230 related1 = this.getRelatedTo();
231 related2 = rel2.getRelatedTo();
232 }
233 String title1 = related1.getTitleCache();
234 String title2 = related2.getTitleCache();
235 return title1.compareTo(title2);
236 }
237 }
238
239
240 //*********************** CLONE ********************************************************/
241
242 /**
243 * Clones <i>this</i> hybrid relationship. This is a shortcut that enables to create
244 * a new instance that differs only slightly from <i>this</i> hybrid relationship by
245 * modifying only some of the attributes.<BR>
246 * CAUTION: Cloning a relationship will not add the relationship to the according
247 * {@link #relatedFrom} and {@link #relatedTo} objects. The method is meant to be used
248 * mainly for internal purposes (e.g. used within {@link TaxonNameBase#clone()}
249 *
250 * @see eu.etaxonomy.cdm.model.common.RelationshipBase#clone()
251 * @see java.lang.Object#clone()
252 */
253 @Override
254 public Object clone() {
255 HybridRelationship result;
256 try {
257 result = (HybridRelationship)super.clone();
258 //no changes to: relatedFrom, relatedTo, type
259 return result;
260 } catch (CloneNotSupportedException e) {
261 logger.warn("Object does not implement cloneable");
262 e.printStackTrace();
263 return null;
264 }
265 }
266
267 }