improve to better fulfill the Comparator contract
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / name / TypeDesignationBase.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 java.util.HashSet;
13 import java.util.Set;
14
15 import javax.persistence.Entity;
16 import javax.persistence.FetchType;
17 import javax.persistence.Inheritance;
18 import javax.persistence.InheritanceType;
19 import javax.persistence.ManyToMany;
20 import javax.persistence.ManyToOne;
21 import javax.xml.bind.annotation.XmlElement;
22 import javax.xml.bind.annotation.XmlElementWrapper;
23 import javax.xml.bind.annotation.XmlIDREF;
24 import javax.xml.bind.annotation.XmlRootElement;
25 import javax.xml.bind.annotation.XmlSchemaType;
26 import javax.xml.bind.annotation.XmlSeeAlso;
27 import javax.xml.bind.annotation.XmlType;
28
29 import org.apache.log4j.Logger;
30 import org.hibernate.annotations.Cascade;
31 import org.hibernate.annotations.CascadeType;
32 import org.hibernate.envers.Audited;
33
34 import eu.etaxonomy.cdm.model.common.ReferencedEntityBase;
35 import eu.etaxonomy.cdm.model.reference.Reference;
36
37 /**
38 * The (abstract) class representing a typification of one or several {@link TaxonNameBase taxon names}.<BR>
39 * All taxon names which have a {@link Rank rank} "species aggregate" or lower
40 * can only be typified by specimens (a {@link SpecimenTypeDesignation specimen type designation}), but taxon
41 * names with a higher rank might be typified by an other taxon name with
42 * rank "species" or "genus" (a {@link NameTypeDesignation name type designation}).
43 *
44 * @see TaxonNameBase
45 * @see NameTypeDesignation
46 * @see SpecimenTypeDesignation
47 * @author a.mueller
48 * @created 07.08.2008
49 * @version 1.0
50 */
51 @XmlRootElement(name = "TypeDesignationBase")
52 @XmlType(name = "TypeDesignationBase", propOrder = {
53 "typifiedNames",
54 "notDesignated",
55 "typeStatus"
56 })
57 @XmlSeeAlso({
58 NameTypeDesignation.class,
59 SpecimenTypeDesignation.class
60 })
61 @Entity
62 @Audited
63 @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
64 public abstract class TypeDesignationBase<T extends TypeDesignationStatusBase> extends ReferencedEntityBase implements ITypeDesignation {
65 private static final long serialVersionUID = 8622351017235131355L;
66
67 @SuppressWarnings("unused")
68 private static final Logger logger = Logger.getLogger(TypeDesignationBase.class);
69
70 @XmlElement(name = "IsNotDesignated")
71 private boolean notDesignated;
72
73 @XmlElementWrapper(name = "TypifiedNames")
74 @XmlElement(name = "TypifiedName")
75 @XmlIDREF
76 @XmlSchemaType(name = "IDREF")
77 @ManyToMany(fetch = FetchType.LAZY , mappedBy="typeDesignations")
78 @Cascade({CascadeType.SAVE_UPDATE})
79 private Set<TaxonNameBase> typifiedNames = new HashSet<TaxonNameBase>();
80
81 // @XmlElement(name = "HomotypicalGroup")
82 // @XmlIDREF
83 // @XmlSchemaType(name = "IDREF")
84 // @ManyToOne(fetch = FetchType.LAZY)
85 // @Cascade(CascadeType.SAVE_UPDATE)
86 // private HomotypicalGroup homotypicalGroup;
87
88 @XmlElement(name = "TypeStatus")
89 @XmlIDREF
90 @XmlSchemaType(name = "IDREF")
91 @ManyToOne(fetch = FetchType.LAZY, targetEntity = TypeDesignationStatusBase.class)
92 private T typeStatus;
93
94 // **************** CONSTRUCTOR *************************************/
95
96 /**
97 * Class constructor: creates a new empty type designation.
98 *
99 * @see #TypeDesignationBase(Reference, String, String, Boolean)
100 */
101 protected TypeDesignationBase(){
102 super();
103 }
104
105 /**
106 * Class constructor: creates a new type designation
107 * (including its {@link Reference reference source} and eventually
108 * the taxon name string originally used by this reference when establishing
109 * the former designation).
110 *
111 * @param citation the reference source for the new designation
112 * @param citationMicroReference the string with the details describing the exact localisation within the reference
113 * @param originalNameString the taxon name string used originally in the reference source for the new designation
114 * @see #TypeDesignationBase()
115 * @see #isNotDesignated()
116 * @see TaxonNameBase#getTypeDesignations()
117 */
118 protected TypeDesignationBase(Reference citation, String citationMicroReference, String originalNameString) {
119 this(citation, citationMicroReference, originalNameString, false);
120 }
121
122 /**
123 * Class constructor: creates a new type designation
124 * (including its {@link Reference reference source} and eventually
125 * the taxon name string originally used by this reference when establishing
126 * the former designation).
127 *
128 * @param citation the reference source for the new designation
129 * @param citationMicroReference the string with the details describing the exact localisation within the reference
130 * @param originalNameString the taxon name string used originally in the reference source for the new designation
131 * @param isNotDesignated the boolean flag indicating whether there is no type at all for
132 * <i>this</i> type designation
133 * @see #TypeDesignationBase()
134 * @see #isNotDesignated()
135 * @see TaxonNameBase#getTypeDesignations()
136 */
137 protected TypeDesignationBase(Reference citation, String citationMicroReference, String originalNameString, boolean notDesignated){
138 super(citation, citationMicroReference, originalNameString);
139 this.notDesignated = notDesignated;
140 }
141
142
143 // **************** METHODS *************************************/
144
145
146 /**
147 * Returns the {@link TypeDesignationStatusBase type designation status} for <i>this</i> specimen type
148 * designation. This status describes which of the possible categories of
149 * types like "holotype", "neotype", "syntype" or "isotype" applies to <i>this</i>
150 * specimen type designation.
151 */
152 public T getTypeStatus(){
153 return this.typeStatus;
154 }
155 /**
156 * @see #getTypeStatus()
157 */
158 public void setTypeStatus(T typeStatus){
159 this.typeStatus = typeStatus;
160 }
161
162 // /* (non-Javadoc)
163 // * @see eu.etaxonomy.cdm.model.name.ITypeDesignation#getHomotypicalGroup()
164 // */
165 // /**
166 // * Returns the {@link HomotypicalGroup homotypical group} to which all (in <i>this</i>
167 // * type designation) typified {@link TaxonNameBase taxon names} belong.
168 // *
169 // * @see #getTypifiedNames()
170 // * @deprecated homotypical group can not be set and always seems to be <code>null</code>.
171 // * Probably it is a relict of an old version.
172 // * See also http://dev.e-taxonomy.eu/trac/ticket/2173
173 // */
174 // @Deprecated
175 // public HomotypicalGroup getHomotypicalGroup() {
176 // return homotypicalGroup;
177 // }
178
179 /* (non-Javadoc)
180 * @see eu.etaxonomy.cdm.model.name.ITypeDesignation#getTypifiedNames()
181 */
182 /**
183 * Returns the set of {@link TaxonNameBase taxon names} typified in <i>this</i>
184 * type designation. This is a subset of the taxon names belonging to the
185 * corresponding {@link #getHomotypicalGroup() homotypical group}.
186 */
187 public Set<TaxonNameBase> getTypifiedNames() {
188 return typifiedNames;
189 }
190
191 /**
192 * Returns the boolean value "true" if it is known that a type does not
193 * exist and therefore the {@link TaxonNameBase taxon name} to which <i>this</i>
194 * type designation is assigned must still be typified. Two
195 * cases must be differentiated: <BR><ul>
196 * <li> a) it is unknown whether a type exists and
197 * <li> b) it is known that no type exists
198 * </ul>
199 * If a) is true there should be no TypeDesignation instance at all
200 * assigned to the "typified" taxon name.<BR>
201 * If b) is true there should be a TypeDesignation instance with the
202 * flag isNotDesignated set. The typeName attribute, in case of a
203 * {@link NameTypeDesignation name type designation}, or the typeSpecimen attribute,
204 * in case of a {@link SpecimenTypeDesignation specimen type designation}, should then be "null".
205 */
206 public boolean isNotDesignated() {
207 return notDesignated;
208 }
209
210 /**
211 * @see #isNotDesignated()
212 */
213 public void setNotDesignated(boolean notDesignated) {
214 this.notDesignated = notDesignated;
215 }
216
217 /**
218 * @deprecated for bidirectional use only
219 */
220 @Deprecated
221 protected void addTypifiedName(TaxonNameBase taxonName){
222 this.typifiedNames.add(taxonName);
223 }
224
225 /**
226 * @deprecated for bidirectional use only
227 */
228 @Deprecated
229 protected void removeTypifiedName(TaxonNameBase taxonName){
230 this.typifiedNames.remove(taxonName);
231 if (taxonName.getTypeDesignations().contains(this)){
232 taxonName.removeTypeDesignation(this);
233 }
234 }
235
236 public abstract void removeType();
237
238 //*********************** CLONE ********************************************************/
239
240 /**
241 * Clones <i>this</i> type designation. This is a shortcut that enables to create
242 * a new instance that differs only slightly from <i>this</i> type designation by
243 * modifying only some of the attributes.<BR>
244 * CAUTION: the typifiedNames set is not cloned but empty after cloning as the typified
245 * names is considered to be the not owning part of a bidirectional relationship.
246 * This may be changed in future.
247 *
248 * @throws CloneNotSupportedException
249 *
250 * @see eu.etaxonomy.cdm.model.common.ReferencedEntityBase#clone()
251 * @see java.lang.Object#clone()
252 */
253 @Override
254 public Object clone() throws CloneNotSupportedException {
255 TypeDesignationBase result = (TypeDesignationBase)super.clone();
256
257 result.typifiedNames = new HashSet<TaxonNameBase>();
258 // for (TaxonNameBase taxonNameBase : getTypifiedNames()){
259 // result.typifiedNames.add(taxonNameBase);
260 // }
261
262
263 //no changes to: notDesignated, typeStatus, homotypicalGroup
264 return result;
265 }
266 }