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
.IPublishable
;
41 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
42 import eu
.etaxonomy
.cdm
.model
.name
.HomotypicalGroup
;
43 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
44 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
45 import eu
.etaxonomy
.cdm
.strategy
.cache
.common
.IIdentifiableEntityCacheStrategy
;
46 import eu
.etaxonomy
.cdm
.validation
.Level2
;
47 import eu
.etaxonomy
.cdm
.validation
.Level3
;
48 import eu
.etaxonomy
.cdm
.validation
.annotation
.TaxonNameCannotBeAcceptedAndSynonym
;
51 * 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}
52 * or within a taxonomic view/treatment either as a {@link Taxon taxon}
53 * ("accepted" respectively "correct" name) or as a (junior) {@link Synonym synonym}.
54 * Within a taxonomic view/treatment or a reference a taxon name can be used
55 * only in one of both described meanings. The reference using the taxon name
56 * is generally cited with "sec." (secundum, sensu). For instance:
57 * "<i>Juncus longirostris</i> Kuvaev sec. Kirschner, J. et al. 2002".
59 * This class corresponds to: <ul>
60 * <li> TaxonConcept according to the TDWG ontology
61 * <li> TaxonConcept according to the TCS
65 * @created 08-Nov-2007 13:06:56
67 @XmlAccessorType(XmlAccessType
.FIELD
)
68 @XmlType(name
= "TaxonBase", propOrder
= {
78 //@PreFilter("hasPermission(filterObject, 'edit')")
79 @Table(appliesTo
="TaxonBase", indexes
= { @Index(name
= "taxonBaseTitleCacheIndex", columnNames
= { "titleCache" }) })
80 @TaxonNameCannotBeAcceptedAndSynonym(groups
= Level3
.class)
82 @ClassBridge(name
="classInfo",
83 index
= org
.hibernate
.search
.annotations
.Index
.YES
,
85 impl
= ClassInfoBridge
.class),
86 @ClassBridge(name
="accTaxon", // TODO rename to acceptedTaxon, since we are usually not using abbreviations for field names
87 index
= org
.hibernate
.search
.annotations
.Index
.YES
,
89 impl
= AcceptedTaxonBridge
.class),
90 @ClassBridge(impl
= eu
.etaxonomy
.cdm
.hibernate
.search
.NomenclaturalSortOrderBrigde
.class)
92 public abstract class TaxonBase
<S
extends IIdentifiableEntityCacheStrategy
> extends IdentifiableEntity
<S
> implements IPublishable
, Cloneable
{
93 private static final long serialVersionUID
= -3589185949928938529L;
94 private static final Logger logger
= Logger
.getLogger(TaxonBase
.class);
96 private static Method methodTaxonNameAddTaxonBase
;
100 methodTaxonNameAddTaxonBase
= TaxonNameBase
.class.getDeclaredMethod("addTaxonBase", TaxonBase
.class);
101 methodTaxonNameAddTaxonBase
.setAccessible(true);
102 } catch (Exception e
) {
104 for(StackTraceElement ste
: e
.getStackTrace()) {
110 //The assignment to the Taxon or to the Synonym class is not definitive
111 @XmlAttribute(name
= "isDoubtful")
112 private boolean doubtful
;
115 @XmlElement(name
= "Name", required
= true)
117 @XmlSchemaType(name
= "IDREF")
118 @ManyToOne(fetch
= FetchType
.LAZY
)
120 @Cascade(CascadeType
.SAVE_UPDATE
)
121 @NotNull(groups
= Level2
.class)
122 private TaxonNameBase
<?
,?
> name
;
124 // The concept reference
125 @XmlElement(name
= "Sec")
127 @XmlSchemaType(name
= "IDREF")
128 @ManyToOne(fetch
= FetchType
.LAZY
)
129 @Cascade(CascadeType
.SAVE_UPDATE
)
130 @NotNull(groups
= Level2
.class)
132 private Reference
<?
> sec
;
135 @XmlElement(name
= "AppendedPhrase")
136 private String appendedPhrase
;
138 @XmlAttribute(name
= "UseNameCache")
139 private boolean useNameCache
= false;
141 @XmlAttribute(name
= "publish")
142 private boolean publish
= true;
145 // ************* CONSTRUCTORS *************/
147 * Class constructor: creates a new empty (abstract) taxon.
149 * @see #TaxonBase(TaxonNameBase, Reference)
151 protected TaxonBase(){
156 * Class constructor: creates a new (abstract) taxon with the
157 * {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used and the {@link eu.etaxonomy.cdm.model.reference.Reference reference}
160 * @param taxonNameBase the taxon name used
161 * @param sec the reference using the taxon name
164 protected TaxonBase(TaxonNameBase taxonNameBase
, Reference sec
){
166 if (taxonNameBase
!= null){
167 this.invokeSetMethod(methodTaxonNameAddTaxonBase
, taxonNameBase
);
172 //********* METHODS **************************************/
175 * Generates and returns the string with the full scientific name (including
176 * authorship) of the {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used in <i>this</i>
177 * (abstract) taxon as well as the title of the {@link eu.etaxonomy.cdm.model.reference.Reference reference} using
178 * this taxon name. This string may be stored in the inherited
179 * {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache() titleCache} attribute.
180 * This method overrides the generic and inherited generateTitle() method
181 * from {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity IdentifiableEntity}.
183 * @return the string with the full scientific name of the taxon name
184 * and with the title of the reference involved in <i>this</i> (abstract) taxon
185 * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle()
186 * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache()
189 // public String generateTitle() {
191 // if (name != null && name.getTitleCache() != null){
192 // title = name.getTitleCache() + " sec. ";
194 // title += sec.getTitleCache();
199 // title = this.toString();
205 * Returns the {@link TaxonNameBase taxon name} used in <i>this</i> (abstract) taxon.
207 public TaxonNameBase
getName(){
214 public void setName(TaxonNameBase name
) {
215 if (this.name
!= null){
216 this.name
.getTaxonBases().remove(this);
219 name
.getTaxonBases().add(this);
225 * Returns the {@link eu.etaxonomy.cdm.model.name.HomotypicalGroup homotypical group} of the
226 * {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used in <i>this</i> (abstract) taxon.
229 public HomotypicalGroup
getHomotypicGroup(){
230 if (this.getName() == null){
233 return this.getName().getHomotypicalGroup();
238 * Returns the boolean value indicating whether the assignment of <i>this</i>
239 * (abstract) taxon to the {@link Taxon Taxon} or to the {@link Synonym Synonym} class
240 * is definitive (false) or not (true). If this flag is set the use of <i>this</i> (abstract)
241 * taxon as an "accepted/correct" name or as a (junior) "synonym" might
242 * still change in the course of taxonomical working process.
244 public boolean isDoubtful(){
245 return this.doubtful
;
250 public void setDoubtful(boolean doubtful
){
251 this.doubtful
= doubtful
;
256 * Returns the boolean value indicating if this taxon should be withheld (<code>publish=false</code>) or not
257 * (<code>publish=true</code>) during any publication process to the general public.
258 * This publish flag implementation is preliminary and may be replaced by a more general
259 * implementation of READ rights in future.<BR>
260 * The default value is <code>true</code>.
263 public boolean isPublish() {
268 public void setPublish(boolean publish
) {
269 this.publish
= publish
;
273 * Returns the {@link eu.etaxonomy.cdm.model.reference.Reference reference} of <i>this</i> (abstract) taxon.
274 * This is the reference or the treatment using the {@link TaxonNameBase taxon name}
275 * in <i>this</i> (abstract) taxon.
277 public Reference
getSec() {
284 public void setSec(Reference sec
) {
291 * An appended phrase is a phrase that is added to the {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name}
292 * 's title cache to be used just in this taxon. E.g. the phrase "sensu latu" may be added
293 * to the name to describe this taxon more precisely.
294 * If {@link #isUseNameCache()}
295 * @return the appendedPhrase
297 public String
getAppendedPhrase() {
298 return appendedPhrase
;
302 * @param appendedPhrase the appendedPhrase to set
304 public void setAppendedPhrase(String appendedPhrase
) {
305 this.appendedPhrase
= appendedPhrase
;
309 * @return the useNameCache
311 public boolean isUseNameCache() {
316 * @param useNameCache the useNameCache to set
318 public void setUseNameCache(boolean useNameCache
) {
319 this.useNameCache
= useNameCache
;
323 public abstract boolean isOrphaned();
324 //*********************** CLONE ********************************************************/
327 * Clones <i>this</i> taxon. This is a shortcut that enables to create
328 * a new instance with empty taxon name and sec reference.
330 * @see eu.etaxonomy.cdm.model.media.IdentifiableEntity#clone()
331 * @see java.lang.Object#clone()
334 public Object
clone() {
337 result
= (TaxonBase
)super.clone();
341 } catch (CloneNotSupportedException e
) {
342 logger
.warn("Object does not implement cloneable");