2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.model
.taxon
;
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
;
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 import org
.hibernate
.search
.annotations
.ContainedIn
;
29 import org
.hibernate
.search
.annotations
.Indexed
;
30 import org
.springframework
.beans
.factory
.annotation
.Configurable
;
32 import eu
.etaxonomy
.cdm
.model
.name
.HomotypicalGroup
;
33 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
34 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
35 import eu
.etaxonomy
.cdm
.strategy
.cache
.taxon
.ITaxonCacheStrategy
;
36 import eu
.etaxonomy
.cdm
.strategy
.cache
.taxon
.TaxonBaseDefaultCacheStrategy
;
37 import eu
.etaxonomy
.cdm
.validation
.Level3
;
38 import eu
.etaxonomy
.cdm
.validation
.annotation
.HomotypicSynonymsShouldBelongToGroup
;
41 * The class for synonyms: these are {@link TaxonBase taxa} the {@link name.TaxonNameBase taxon names}
42 * of which are not used by the {@link TaxonBase#getSec() reference} to designate a real
43 * taxon but are mentioned as taxon names that were oder are used by some other
44 * unspecified references to designate (at least to some extent) the same
45 * particular real taxon. Synonyms that are {@link #getAcceptedTaxon() attached} to an accepted {@link Taxon taxon}
46 * are actually meaningless.<BR>
47 * Splitting taxa in "accepted/valid" and "synonyms"
48 * makes it easier to handle particular relationships between
49 * ("accepted/valid") {@link Taxon taxa} on the one hand and ("synonym") taxa
53 * @created 08-Nov-2007 13:06:55
55 @XmlAccessorType(XmlAccessType
.FIELD
)
56 @XmlType(name
= "Synonym", propOrder
= {
62 @XmlRootElement(name
= "Synonym")
64 @Indexed(index
= "eu.etaxonomy.cdm.model.taxon.TaxonBase")
67 @HomotypicSynonymsShouldBelongToGroup(groups
= Level3
.class)
68 public class Synonym
extends TaxonBase
<ITaxonCacheStrategy
<Synonym
>> {
69 private static final long serialVersionUID
= 6977221584815363620L;
72 @SuppressWarnings("unused")
73 private static final Logger logger
= Logger
.getLogger(Synonym
.class);
76 @XmlElement(name
= "acceptedTaxon")
78 @XmlSchemaType(name
= "IDREF")
79 @ManyToOne(fetch
= FetchType
.LAZY
)
80 @Cascade({CascadeType
.SAVE_UPDATE
, CascadeType
.MERGE
})
82 // @NotEmpty(groups = Level2.class,message="{eu.etaxonomy.cdm.model.taxon.Synonym.noOrphanedSynonyms.message}")
83 // @NotNull(groups = Level2.class)
84 private Taxon acceptedTaxon
;
87 @XmlElement(name
= "IsProParte")
88 private boolean proParte
= false;
90 @XmlElement(name
= "IsPartial")
91 private boolean partial
= false;
94 @XmlElement(name
= "Type")
96 @XmlSchemaType(name
= "IDREF")
97 @ManyToOne(fetch
=FetchType
.EAGER
)
98 private SynonymType type
;
100 //************************************* FACTORY ****************************/
103 * Creates a new synonym instance with
104 * the {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used and the {@link eu.etaxonomy.cdm.model.reference.Reference reference}
105 * using it as a synonym and not as an ("accepted/correct") {@link Taxon taxon}.
107 * @param taxonNameBase the taxon name used
108 * @param sec the reference using the taxon name
109 * @see #Synonym(TaxonNameBase, Reference)
111 public static Synonym
NewInstance(TaxonNameBase taxonName
, Reference sec
){
112 Synonym result
= new Synonym(taxonName
, sec
, null);
116 public static Synonym
NewInstance(TaxonNameBase taxonName
, Reference sec
, String secDetail
){
117 Synonym result
= new Synonym(taxonName
, sec
, secDetail
);
121 // ************* CONSTRUCTORS *************/
123 * Class constructor: creates a new empty synonym instance.
125 * @see #Synonym(TaxonNameBase, Reference)
127 //TODO should be private, but still produces Spring init errors
129 this.cacheStrategy
= new TaxonBaseDefaultCacheStrategy
<Synonym
>();
132 private Synonym(TaxonNameBase taxonNameBase
, Reference sec
, String secDetail
){
133 super(taxonNameBase
, sec
, secDetail
);
134 this.cacheStrategy
= new TaxonBaseDefaultCacheStrategy
<Synonym
>();
137 //********************** GETTER/SETTER ******************************/
140 * Returns the "accepted/valid" {@link Taxon taxon}
143 public Taxon
getAcceptedTaxon() {
144 return this.acceptedTaxon
;
149 * @param acceptedTaxon the acceptedTaxon to set
151 protected void setAcceptedTaxon(Taxon acceptedTaxon
) {
152 if (acceptedTaxon
== null){
153 Taxon oldTaxon
= this.acceptedTaxon
;
154 this.acceptedTaxon
= null;
155 oldTaxon
.removeSynonym(this);
157 if (this.acceptedTaxon
!= null){
158 this.acceptedTaxon
.removeSynonym(this, false);
160 this.acceptedTaxon
= acceptedTaxon
;
161 this.acceptedTaxon
.addSynonym(this);
167 * Returns "true" if the proParte flag is set.
168 * This indicates that the {@link name.TaxonNameBase taxon name} used as a
169 * {@link Synonym synonym} designated originally a real taxon which later has
170 * been split. In this case the synonym is therefore the synonym of at least
171 * two different ("accepted/valid") {@link Taxon taxa}.
173 public boolean isProParte() {
180 public void setProParte(boolean proParte
) {
181 this.proParte
= proParte
;
185 * Returns "true" if the ProParte flag is set.
186 * This indicates that the {@link name.TaxonNameBase taxon name} used as <code>this</code>
187 * {@link Synonym synonym} designated originally a real taxon which later has
188 * been lumped together with another one. In this case the
189 * ("accepted/valid") {@link Taxon taxon} has therefore at least
190 * two different synonyms (for the two lumped real taxa).
192 public boolean isPartial() {
199 public void setPartial(boolean partial
) {
200 this.partial
= partial
;
204 public SynonymType
getType() {
208 public void setType(SynonymType type
) {
214 //***************** METHODS **************************/
216 * Returns true if <i>this</i> is a synonym of the given taxon.
218 * @param taxon the taxon to check synonym for
219 * @return true if <i>this</i> is a synonm of the given taxon
221 * @see #getAcceptedTaxon()
224 public boolean isSynonymOf(Taxon taxon
){
225 return taxon
!= null && taxon
.equals(this.acceptedTaxon
);
230 public boolean isOrphaned() {
231 return this.acceptedTaxon
== null || this.acceptedTaxon
.isOrphaned();
235 * Checks if the synonym type is homotypic. If it is
236 * the name of <code>this</code> synonym is added to the {@link HomotypicalGroup
237 * homotypic group} of the {@link Taxon accepted taxon}.
239 private void checkHomotypic() {
240 if (type
!= null && type
.equals(SynonymType
.HOMOTYPIC_SYNONYM_OF())
241 && acceptedTaxon
!= null && acceptedTaxon
.getName() != null){
242 acceptedTaxon
.getName().getHomotypicalGroup().addTypifiedName(this.getName());
246 //*********************** CLONE ********************************************************/
249 public Object
clone() {
251 result
= (Synonym
)super.clone();
253 //no changes to accepted taxon, type, partial, proParte