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 java
.lang
.reflect
.Method
;
14 import javax
.persistence
.Entity
;
15 import javax
.persistence
.FetchType
;
16 import javax
.persistence
.ManyToOne
;
17 import javax
.persistence
.Transient
;
18 import javax
.validation
.constraints
.NotNull
;
19 import javax
.xml
.bind
.annotation
.XmlAccessType
;
20 import javax
.xml
.bind
.annotation
.XmlAccessorType
;
21 import javax
.xml
.bind
.annotation
.XmlAttribute
;
22 import javax
.xml
.bind
.annotation
.XmlElement
;
23 import javax
.xml
.bind
.annotation
.XmlIDREF
;
24 import javax
.xml
.bind
.annotation
.XmlSchemaType
;
25 import javax
.xml
.bind
.annotation
.XmlType
;
27 import org
.apache
.log4j
.Logger
;
28 import org
.hibernate
.annotations
.Cascade
;
29 import org
.hibernate
.annotations
.CascadeType
;
30 import org
.hibernate
.annotations
.Index
;
31 import org
.hibernate
.annotations
.Table
;
32 import org
.hibernate
.envers
.Audited
;
33 import org
.hibernate
.search
.annotations
.ClassBridge
;
34 import org
.hibernate
.search
.annotations
.ClassBridges
;
35 import org
.hibernate
.search
.annotations
.IndexedEmbedded
;
36 import org
.hibernate
.search
.annotations
.Store
;
38 import eu
.etaxonomy
.cdm
.hibernate
.search
.AcceptedTaxonBridge
;
39 import eu
.etaxonomy
.cdm
.hibernate
.search
.ClassInfoBridge
;
40 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
41 import eu
.etaxonomy
.cdm
.model
.name
.HomotypicalGroup
;
42 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
43 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
44 import eu
.etaxonomy
.cdm
.strategy
.cache
.common
.IIdentifiableEntityCacheStrategy
;
45 import eu
.etaxonomy
.cdm
.validation
.Level2
;
46 import eu
.etaxonomy
.cdm
.validation
.Level3
;
47 import eu
.etaxonomy
.cdm
.validation
.annotation
.TaxonNameCannotBeAcceptedAndSynonym
;
50 * The upmost (abstract) class for the use of a {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} in a {@link eu.etaxonomy.cdm.model.reference.Reference reference}
51 * or within a taxonomic view/treatment either as a {@link Taxon taxon}
52 * ("accepted" respectively "correct" name) or as a (junior) {@link Synonym synonym}.
53 * Within a taxonomic view/treatment or a reference a taxon name can be used
54 * only in one of both described meanings. The reference using the taxon name
55 * is generally cited with "sec." (secundum, sensu). For instance:
56 * "<i>Juncus longirostris</i> Kuvaev sec. Kirschner, J. et al. 2002".
58 * This class corresponds to: <ul>
59 * <li> TaxonConcept according to the TDWG ontology
60 * <li> TaxonConcept according to the TCS
64 * @created 08-Nov-2007 13:06:56
66 @XmlAccessorType(XmlAccessType
.FIELD
)
67 @XmlType(name
= "TaxonBase", propOrder
= {
76 //@PreFilter("hasPermission(filterObject, 'edit')")
77 @Table(appliesTo
="TaxonBase", indexes
= { @Index(name
= "taxonBaseTitleCacheIndex", columnNames
= { "titleCache" }) })
78 @TaxonNameCannotBeAcceptedAndSynonym(groups
= Level3
.class)
80 @ClassBridge(name
="classInfo",
81 index
= org
.hibernate
.search
.annotations
.Index
.YES
,
83 impl
= ClassInfoBridge
.class),
84 @ClassBridge(name
="accTaxon", // TODO rename to acceptedTaxon, since we are usually not using abbreviations for field names
85 index
= org
.hibernate
.search
.annotations
.Index
.YES
,
87 impl
= AcceptedTaxonBridge
.class),
88 @ClassBridge(impl
= eu
.etaxonomy
.cdm
.hibernate
.search
.NomenclaturalSortOrderBrigde
.class)
90 public abstract class TaxonBase
<S
extends IIdentifiableEntityCacheStrategy
> extends IdentifiableEntity
<S
> implements Cloneable
{
91 private static final long serialVersionUID
= -3589185949928938529L;
92 private static final Logger logger
= Logger
.getLogger(TaxonBase
.class);
94 private static Method methodTaxonNameAddTaxonBase
;
98 methodTaxonNameAddTaxonBase
= TaxonNameBase
.class.getDeclaredMethod("addTaxonBase", TaxonBase
.class);
99 methodTaxonNameAddTaxonBase
.setAccessible(true);
100 } catch (Exception e
) {
102 for(StackTraceElement ste
: e
.getStackTrace()) {
108 //The assignment to the Taxon or to the Synonym class is not definitive
109 @XmlAttribute(name
= "isDoubtful")
110 private boolean doubtful
;
113 @XmlElement(name
= "Name", required
= true)
115 @XmlSchemaType(name
= "IDREF")
116 @ManyToOne(fetch
= FetchType
.LAZY
)
118 @Cascade(CascadeType
.SAVE_UPDATE
)
119 @NotNull(groups
= Level2
.class)
120 private TaxonNameBase
<?
,?
> name
;
122 // The concept reference
123 @XmlElement(name
= "Sec")
125 @XmlSchemaType(name
= "IDREF")
126 @ManyToOne(fetch
= FetchType
.LAZY
)
127 @Cascade(CascadeType
.SAVE_UPDATE
)
128 @NotNull(groups
= Level2
.class)
130 private Reference
<?
> sec
;
133 @XmlElement(name
= "AppendedPhrase")
134 private String appendedPhrase
;
136 @XmlAttribute(name
= "UseNameCache")
137 private boolean useNameCache
= false;
140 // ************* CONSTRUCTORS *************/
142 * Class constructor: creates a new empty (abstract) taxon.
144 * @see #TaxonBase(TaxonNameBase, Reference)
146 protected TaxonBase(){
151 * Class constructor: creates a new (abstract) taxon with the
152 * {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used and the {@link eu.etaxonomy.cdm.model.reference.Reference reference}
155 * @param taxonNameBase the taxon name used
156 * @param sec the reference using the taxon name
159 protected TaxonBase(TaxonNameBase taxonNameBase
, Reference sec
){
161 if (taxonNameBase
!= null){
162 this.invokeSetMethod(methodTaxonNameAddTaxonBase
, taxonNameBase
);
167 //********* METHODS **************************************/
170 * Generates and returns the string with the full scientific name (including
171 * authorship) of the {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used in <i>this</i>
172 * (abstract) taxon as well as the title of the {@link eu.etaxonomy.cdm.model.reference.Reference reference} using
173 * this taxon name. This string may be stored in the inherited
174 * {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache() titleCache} attribute.
175 * This method overrides the generic and inherited generateTitle() method
176 * from {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity IdentifiableEntity}.
178 * @return the string with the full scientific name of the taxon name
179 * and with the title of the reference involved in <i>this</i> (abstract) taxon
180 * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle()
181 * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache()
184 // public String generateTitle() {
186 // if (name != null && name.getTitleCache() != null){
187 // title = name.getTitleCache() + " sec. ";
189 // title += sec.getTitleCache();
194 // title = this.toString();
200 * Returns the {@link TaxonNameBase taxon name} used in <i>this</i> (abstract) taxon.
202 public TaxonNameBase
getName(){
209 public void setName(TaxonNameBase name
) {
210 if (this.name
!= null){
211 this.name
.getTaxonBases().remove(this);
214 name
.getTaxonBases().add(this);
220 * Returns the {@link eu.etaxonomy.cdm.model.name.HomotypicalGroup homotypical group} of the
221 * {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used in <i>this</i> (abstract) taxon.
224 public HomotypicalGroup
getHomotypicGroup(){
225 if (this.getName() == null){
228 return this.getName().getHomotypicalGroup();
233 * Returns the boolean value indicating whether the assignment of <i>this</i>
234 * (abstract) taxon to the {@link Taxon Taxon} or to the {@link Synonym Synonym} class
235 * is definitive (false) or not (true). If this flag is set the use of <i>this</i> (abstract)
236 * taxon as an "accepted/correct" name or as a (junior) "synonym" might
237 * still change in the course of taxonomical working process.
239 public boolean isDoubtful(){
240 return this.doubtful
;
245 public void setDoubtful(boolean doubtful
){
246 this.doubtful
= doubtful
;
250 * Returns the {@link eu.etaxonomy.cdm.model.reference.Reference reference} of <i>this</i> (abstract) taxon.
251 * This is the reference or the treatment using the {@link TaxonNameBase taxon name}
252 * in <i>this</i> (abstract) taxon.
254 public Reference
getSec() {
261 public void setSec(Reference sec
) {
268 * An appended phrase is a phrase that is added to the {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name}
269 * 's title cache to be used just in this taxon. E.g. the phrase "sensu latu" may be added
270 * to the name to describe this taxon more precisely.
271 * If {@link #isUseNameCache()}
272 * @return the appendedPhrase
274 public String
getAppendedPhrase() {
275 return appendedPhrase
;
279 * @param appendedPhrase the appendedPhrase to set
281 public void setAppendedPhrase(String appendedPhrase
) {
282 this.appendedPhrase
= appendedPhrase
;
286 * @return the useNameCache
288 public boolean isUseNameCache() {
293 * @param useNameCache the useNameCache to set
295 public void setUseNameCache(boolean useNameCache
) {
296 this.useNameCache
= useNameCache
;
300 public abstract boolean isOrphaned();
301 //*********************** CLONE ********************************************************/
304 * Clones <i>this</i> taxon. This is a shortcut that enables to create
305 * a new instance with empty taxon name and sec reference.
307 * @see eu.etaxonomy.cdm.model.media.IdentifiableEntity#clone()
308 * @see java.lang.Object#clone()
311 public Object
clone() {
314 result
= (TaxonBase
)super.clone();
318 } catch (CloneNotSupportedException e
) {
319 logger
.warn("Object does not implement cloneable");