(no commit message)
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / name / NameRelationship.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 import eu.etaxonomy.cdm.validation.Level3;
31 import eu.etaxonomy.cdm.validation.annotation.NamesWithHomotypicRelationshipsMustBelongToSameGroup;
32
33 /**
34 * The class representing a relationship between two {@link TaxonNameBase taxon names} according
35 * to the {@link NomenclaturalCode nomenclatural code} which governs both of them.
36 * This includes a {@link NameRelationshipType name relationship type} (for instance "later homonym" or
37 * "orthographic variant") and the article of the corresponding nomenclatural
38 * code on which the assignation of the relationship type is based.
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:37
48 */
49 @XmlAccessorType(XmlAccessType.FIELD)
50 @XmlType(name = "NameRelationship", propOrder = {
51 "relatedFrom",
52 "relatedTo",
53 "type",
54 "ruleConsidered"
55 })
56 @Entity
57 @Audited
58 @NamesWithHomotypicRelationshipsMustBelongToSameGroup(groups = {Level3.class})
59 public class NameRelationship extends RelationshipBase<TaxonNameBase, TaxonNameBase, NameRelationshipType> implements Cloneable{
60
61 static Logger logger = Logger.getLogger(NameRelationship.class);
62
63 //The nomenclatural code rule considered. The article/note/recommendation in the code in question that is commented on in
64 //the note property.
65 @XmlElement(name = "RuleConsidered")
66 private String ruleConsidered;
67
68 @XmlElement(name = "RelatedFrom")
69 @XmlIDREF
70 @XmlSchemaType(name = "IDREF")
71 @ManyToOne(fetch=FetchType.LAZY)
72 @Cascade({CascadeType.SAVE_UPDATE})
73 private TaxonNameBase relatedFrom;
74
75 @XmlElement(name = "RelatedTo")
76 @XmlIDREF
77 @XmlSchemaType(name = "IDREF")
78 @ManyToOne(fetch=FetchType.LAZY)
79 @Cascade(CascadeType.SAVE_UPDATE)
80 private TaxonNameBase relatedTo;
81
82 @XmlElement(name = "Type")
83 @XmlIDREF
84 @XmlSchemaType(name = "IDREF")
85 @ManyToOne(fetch = FetchType.LAZY)
86 private NameRelationshipType type;
87
88 /**
89 * @deprecated for hibernate use only, don't use
90 */
91 @Deprecated
92 private NameRelationship(){
93 super();
94 }
95
96
97 // ************* CONSTRUCTORS *************/
98 /**
99 * Class constructor: creates a new name relationship instance with no
100 * reference and adds it to the respective
101 * {@link TaxonNameBase#getNameRelations() taxon name relation sets} of both involved names.
102 *
103 * @param toName the taxon name to be set as target for the new name relationship
104 * @param fromName the taxon name to be set as source for the new name relationship
105 * @param type the relationship type to be assigned to the new name relationship
106 * @param ruleConsidered the string indicating the article of the nomenclatural code for the new name relationship
107 * @see #NameRelationship(TaxonNameBase, TaxonNameBase, NameRelationshipType, Reference, String, String)
108 * @see TaxonNameBase#addNameRelationship(NameRelationship)
109 * @see TaxonNameBase#addRelationshipFromName(TaxonNameBase, NameRelationshipType, String)
110 * @see TaxonNameBase#addRelationshipToName(TaxonNameBase, NameRelationshipType, String)
111 */
112 protected NameRelationship(TaxonNameBase toName, TaxonNameBase fromName, NameRelationshipType type, String ruleConsidered) {
113 this(toName, fromName, type, null, null, ruleConsidered);
114 }
115
116 /**
117 * Class constructor: creates a new name relationship instance including
118 * its {@link eu.etaxonomy.cdm.model.reference.Reference reference source} and adds it to the respective
119 *{@link TaxonNameBase#getNameRelations() taxon name relation sets} of both involved names.
120 *
121 * @param toName the taxon name to be set as target for the new name relationship
122 * @param fromName the taxon name to be set as source for the new name relationship
123 * @param type the relationship type to be assigned to the new name relationship
124 * @param citation the reference source for the new name relationship
125 * @param citationMicroReference the string with the details describing the exact localisation within the reference
126 * @param ruleConsidered the string indicating the article of the nomenclatural code justifying the new name relationship
127 * @see #NameRelationship(TaxonNameBase, TaxonNameBase, NameRelationshipType, String)
128 * @see TaxonNameBase#addNameRelationship(NameRelationship)
129 * @see TaxonNameBase#addRelationshipFromName(TaxonNameBase, NameRelationshipType, String)
130 * @see TaxonNameBase#addRelationshipToName(TaxonNameBase, NameRelationshipType, String)
131 */
132 protected NameRelationship(TaxonNameBase toName, TaxonNameBase fromName, NameRelationshipType type, Reference citation, String citationMicroReference, String ruleConsidered) {
133 super(fromName, toName, type, citation, citationMicroReference);
134 this.setRuleConsidered(ruleConsidered);
135 }
136
137 //********* METHODS **************************************/
138
139 /**
140 * Returns the {@link TaxonNameBase taxon name} that plays the source role
141 * in <i>this</i> taxon name relationship.
142 *
143 * @see #getToName()
144 * @see eu.etaxonomy.cdm.model.common.RelationshipBase#getRelatedFrom()
145 */
146 @Transient
147 public TaxonNameBase getFromName(){
148 return this.getRelatedFrom();
149 }
150
151 /**
152 * @see #getFromName()
153 */
154 void setFromName(TaxonNameBase fromName){
155 this.setRelatedFrom(fromName);
156 }
157
158 /**
159 * Returns the {@link TaxonNameBase taxon name} that plays the target role
160 * in <i>this</i> taxon name relationship.
161 *
162 * @see #getFromName()
163 * @see eu.etaxonomy.cdm.model.common.RelationshipBase#getRelatedTo()
164 */
165 @Transient
166 public TaxonNameBase getToName(){
167 return this.getRelatedTo();
168 }
169
170 /**
171 * @see #getToName()
172 */
173 void setToName(TaxonNameBase toName){
174 this.setRelatedTo(toName);
175 }
176
177 /**
178 * Returns the nomenclatural code rule considered (that is the
179 * article/note/recommendation in the nomenclatural code ruling
180 * the taxon name(s) of this nomenclatural status).
181 * The considered rule gives the reason why the
182 * {@link NomenclaturalStatusType nomenclatural status type} has been
183 * assigned to the {@link TaxonNameBase taxon name(s)}.
184 */
185 public String getRuleConsidered(){
186 return this.ruleConsidered;
187 }
188
189 /**
190 * @see #getRuleConsidered()
191 */
192 public void setRuleConsidered(String ruleConsidered){
193 this.ruleConsidered = ruleConsidered;
194 }
195
196 protected TaxonNameBase getRelatedFrom() {
197 return relatedFrom;
198 }
199
200 protected TaxonNameBase getRelatedTo() {
201 return relatedTo;
202 }
203
204 public NameRelationshipType getType() {
205 return type;
206 }
207
208 protected void setRelatedFrom(TaxonNameBase relatedFrom) {
209 if (relatedFrom == null){
210 this.deletedObjects.add(this.relatedFrom);
211 }
212 this.relatedFrom = relatedFrom;
213 }
214
215 protected void setRelatedTo(TaxonNameBase relatedTo) {
216 if (relatedTo == null){
217 this.deletedObjects.add(this.relatedTo);
218 }
219 this.relatedTo = relatedTo;
220 }
221
222 public void setType(NameRelationshipType type) {
223 this.type = type;
224 }
225
226
227 //*********************** CLONE ********************************************************/
228
229 /**
230 * Clones <i>this</i> name relationship. This is a shortcut that enables to create
231 * a new instance that differs only slightly from <i>this</i> name relationship by
232 * modifying only some of the attributes.<BR>
233 * CAUTION: Cloning a relationship will not add the relationship to the according
234 * {@link #relatedFrom} and {@link #relatedTo} objects. The method is meant to be used
235 * mainly for internal purposes (e.g. used within {@link TaxonNameBase#clone()}
236 *
237 * @see eu.etaxonomy.cdm.model.common.RelationshipBase#clone()
238 * @see java.lang.Object#clone()
239 */
240 @Override
241 public Object clone() {
242 NameRelationship result;
243 try {
244 result = (NameRelationship)super.clone();
245 //no changes to: relatedFrom, relatedTo, type
246 return result;
247 } catch (CloneNotSupportedException e) {
248 logger.warn("Object does not implement cloneable");
249 e.printStackTrace();
250 return null;
251 }
252 }
253 }