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
= {
77 //@PreFilter("hasPermission(filterObject, 'edit')")
78 @Table(appliesTo
="TaxonBase", indexes
= { @Index(name
= "taxonBaseTitleCacheIndex", columnNames
= { "titleCache" }) })
79 @TaxonNameCannotBeAcceptedAndSynonym(groups
= Level3
.class)
81 @ClassBridge(name
="classInfo",
82 index
= org
.hibernate
.search
.annotations
.Index
.YES
,
84 impl
= ClassInfoBridge
.class),
85 @ClassBridge(name
="accTaxon", // TODO rename to acceptedTaxon, since we are usually not using abbreviations for field names
86 index
= org
.hibernate
.search
.annotations
.Index
.YES
,
88 impl
= AcceptedTaxonBridge
.class),
89 @ClassBridge(impl
= eu
.etaxonomy
.cdm
.hibernate
.search
.NomenclaturalSortOrderBrigde
.class)
91 public abstract class TaxonBase
<S
extends IIdentifiableEntityCacheStrategy
> extends IdentifiableEntity
<S
> implements Cloneable
{
92 private static final long serialVersionUID
= -3589185949928938529L;
93 private static final Logger logger
= Logger
.getLogger(TaxonBase
.class);
95 private static Method methodTaxonNameAddTaxonBase
;
99 methodTaxonNameAddTaxonBase
= TaxonNameBase
.class.getDeclaredMethod("addTaxonBase", TaxonBase
.class);
100 methodTaxonNameAddTaxonBase
.setAccessible(true);
101 } catch (Exception e
) {
103 for(StackTraceElement ste
: e
.getStackTrace()) {
109 //The assignment to the Taxon or to the Synonym class is not definitive
110 @XmlAttribute(name
= "isDoubtful")
111 private boolean doubtful
;
113 @XmlAttribute(name
= "publish")
114 private boolean publish
= true;
116 @XmlElement(name
= "Name", required
= true)
118 @XmlSchemaType(name
= "IDREF")
119 @ManyToOne(fetch
= FetchType
.LAZY
)
121 @Cascade(CascadeType
.SAVE_UPDATE
)
122 @NotNull(groups
= Level2
.class)
123 private TaxonNameBase
<?
,?
> name
;
125 // The concept reference
126 @XmlElement(name
= "Sec")
128 @XmlSchemaType(name
= "IDREF")
129 @ManyToOne(fetch
= FetchType
.LAZY
)
130 @Cascade(CascadeType
.SAVE_UPDATE
)
131 @NotNull(groups
= Level2
.class)
133 private Reference
<?
> sec
;
136 @XmlElement(name
= "AppendedPhrase")
137 private String appendedPhrase
;
139 @XmlAttribute(name
= "UseNameCache")
140 private boolean useNameCache
= false;
143 // ************* CONSTRUCTORS *************/
145 * Class constructor: creates a new empty (abstract) taxon.
147 * @see #TaxonBase(TaxonNameBase, Reference)
149 protected TaxonBase(){
154 * Class constructor: creates a new (abstract) taxon with the
155 * {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used and the {@link eu.etaxonomy.cdm.model.reference.Reference reference}
158 * @param taxonNameBase the taxon name used
159 * @param sec the reference using the taxon name
162 protected TaxonBase(TaxonNameBase taxonNameBase
, Reference sec
){
164 if (taxonNameBase
!= null){
165 this.invokeSetMethod(methodTaxonNameAddTaxonBase
, taxonNameBase
);
170 //********* METHODS **************************************/
173 * Generates and returns the string with the full scientific name (including
174 * authorship) of the {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used in <i>this</i>
175 * (abstract) taxon as well as the title of the {@link eu.etaxonomy.cdm.model.reference.Reference reference} using
176 * this taxon name. This string may be stored in the inherited
177 * {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache() titleCache} attribute.
178 * This method overrides the generic and inherited generateTitle() method
179 * from {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity IdentifiableEntity}.
181 * @return the string with the full scientific name of the taxon name
182 * and with the title of the reference involved in <i>this</i> (abstract) taxon
183 * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle()
184 * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache()
187 // public String generateTitle() {
189 // if (name != null && name.getTitleCache() != null){
190 // title = name.getTitleCache() + " sec. ";
192 // title += sec.getTitleCache();
197 // title = this.toString();
203 * Returns the {@link TaxonNameBase taxon name} used in <i>this</i> (abstract) taxon.
205 public TaxonNameBase
getName(){
212 public void setName(TaxonNameBase name
) {
213 if (this.name
!= null){
214 this.name
.getTaxonBases().remove(this);
217 name
.getTaxonBases().add(this);
223 * Returns the {@link eu.etaxonomy.cdm.model.name.HomotypicalGroup homotypical group} of the
224 * {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used in <i>this</i> (abstract) taxon.
227 public HomotypicalGroup
getHomotypicGroup(){
228 if (this.getName() == null){
231 return this.getName().getHomotypicalGroup();
236 * Returns the boolean value indicating whether the assignment of <i>this</i>
237 * (abstract) taxon to the {@link Taxon Taxon} or to the {@link Synonym Synonym} class
238 * is definitive (false) or not (true). If this flag is set the use of <i>this</i> (abstract)
239 * taxon as an "accepted/correct" name or as a (junior) "synonym" might
240 * still change in the course of taxonomical working process.
242 public boolean isDoubtful(){
243 return this.doubtful
;
248 public void setDoubtful(boolean doubtful
){
249 this.doubtful
= doubtful
;
254 * Returns the boolean value indicating if this taxon should be withheld (<code>publish=false</code>) or not
255 * (<code>publish=true</code>) during any publication process to the general public.
256 * This publish flag implementation is preliminary and may be replaced by a more general
257 * implementation of READ rights in future.<BR>
258 * The default value is <code>true</code>.
260 public boolean isPublish() {
264 public void setPublish(boolean publish
) {
265 this.publish
= publish
;
269 * Returns the {@link eu.etaxonomy.cdm.model.reference.Reference reference} of <i>this</i> (abstract) taxon.
270 * This is the reference or the treatment using the {@link TaxonNameBase taxon name}
271 * in <i>this</i> (abstract) taxon.
273 public Reference
getSec() {
280 public void setSec(Reference sec
) {
287 * An appended phrase is a phrase that is added to the {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name}
288 * 's title cache to be used just in this taxon. E.g. the phrase "sensu latu" may be added
289 * to the name to describe this taxon more precisely.
290 * If {@link #isUseNameCache()}
291 * @return the appendedPhrase
293 public String
getAppendedPhrase() {
294 return appendedPhrase
;
298 * @param appendedPhrase the appendedPhrase to set
300 public void setAppendedPhrase(String appendedPhrase
) {
301 this.appendedPhrase
= appendedPhrase
;
305 * @return the useNameCache
307 public boolean isUseNameCache() {
312 * @param useNameCache the useNameCache to set
314 public void setUseNameCache(boolean useNameCache
) {
315 this.useNameCache
= useNameCache
;
319 public abstract boolean isOrphaned();
320 //*********************** CLONE ********************************************************/
323 * Clones <i>this</i> taxon. This is a shortcut that enables to create
324 * a new instance with empty taxon name and sec reference.
326 * @see eu.etaxonomy.cdm.model.media.IdentifiableEntity#clone()
327 * @see java.lang.Object#clone()
330 public Object
clone() {
333 result
= (TaxonBase
)super.clone();
337 } catch (CloneNotSupportedException e
) {
338 logger
.warn("Object does not implement cloneable");