root/trunk/cdmlib/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/taxon/TaxonBase.java

Revision 13029, 9.5 kB (checked in by a.mueller, 8 months ago)

fix bidirectionality of taxon.name

  • Property svn:keywords set to Id
Line 
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
10package eu.etaxonomy.cdm.model.taxon;
11
12import java.lang.reflect.Method;
13
14import javax.persistence.Entity;
15import javax.persistence.FetchType;
16import javax.persistence.ManyToOne;
17import javax.persistence.Transient;
18import javax.validation.constraints.NotNull;
19import javax.xml.bind.annotation.XmlAccessType;
20import javax.xml.bind.annotation.XmlAccessorType;
21import javax.xml.bind.annotation.XmlAttribute;
22import javax.xml.bind.annotation.XmlElement;
23import javax.xml.bind.annotation.XmlIDREF;
24import javax.xml.bind.annotation.XmlSchemaType;
25import javax.xml.bind.annotation.XmlType;
26
27import org.apache.log4j.Logger;
28import org.hibernate.annotations.Cascade;
29import org.hibernate.annotations.CascadeType;
30import org.hibernate.annotations.Index;
31import org.hibernate.annotations.Table;
32import org.hibernate.envers.Audited;
33import org.hibernate.search.annotations.IndexedEmbedded;
34
35import org.springframework.security.access.prepost.PreFilter;
36
37import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
38import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
39import eu.etaxonomy.cdm.model.name.TaxonNameBase;
40import eu.etaxonomy.cdm.model.reference.Reference;
41import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
42import eu.etaxonomy.cdm.validation.Level2;
43import eu.etaxonomy.cdm.validation.Level3;
44import eu.etaxonomy.cdm.validation.annotation.TaxonNameCannotBeAcceptedAndSynonym;
45
46/**
47 * 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}
48 * or within a taxonomic view/treatment either as a {@link Taxon taxon}
49 * ("accepted" respectively "correct" name) or as a (junior) {@link Synonym synonym}.
50 * Within a taxonomic view/treatment or a reference a taxon name can be used
51 * only in one of both described meanings. The reference using the taxon name
52 * is generally cited with "sec." (secundum, sensu). For instance:
53 * "<i>Juncus longirostris</i> Kuvaev sec. Kirschner, J. et al. 2002".
54 * <P>
55 * This class corresponds to: <ul>
56 * <li> TaxonConcept according to the TDWG ontology
57 * <li> TaxonConcept according to the TCS
58 * </ul>
59 *
60 * @author m.doering
61 * @version 1.0
62 * @created 08-Nov-2007 13:06:56
63 */
64@XmlAccessorType(XmlAccessType.FIELD)
65@XmlType(name = "TaxonBase", propOrder = {
66    "name",
67    "sec",
68    "doubtful",
69    "appendedPhrase",
70    "useNameCache"
71})
72@Entity
73@Audited
74//@PreFilter("hasPermission(filterObject, 'edit')")
75@Table(appliesTo="TaxonBase", indexes = { @Index(name = "taxonBaseTitleCacheIndex", columnNames = { "titleCache" }) })
76@TaxonNameCannotBeAcceptedAndSynonym(groups = Level3.class)
77public abstract class TaxonBase<S extends IIdentifiableEntityCacheStrategy> extends IdentifiableEntity<S> implements Cloneable {
78        private static final long serialVersionUID = -3589185949928938529L;
79        private static final Logger logger = Logger.getLogger(TaxonBase.class);
80       
81        private static Method methodTaxonNameAddTaxonBase;
82       
83        static {
84                try {
85                        methodTaxonNameAddTaxonBase = TaxonNameBase.class.getDeclaredMethod("addTaxonBase", TaxonBase.class);
86                        methodTaxonNameAddTaxonBase.setAccessible(true);
87                } catch (Exception e) {
88                        logger.error(e);
89                        for(StackTraceElement ste : e.getStackTrace()) {
90                                logger.error(ste);
91                        }
92                }
93        }
94       
95        //The assignment to the Taxon or to the Synonym class is not definitive
96    @XmlAttribute(name = "isDoubtful")
97        private boolean doubtful;
98       
99    @XmlElement(name = "Name", required = true)
100    @XmlIDREF
101    @XmlSchemaType(name = "IDREF")
102    @ManyToOne(fetch = FetchType.LAZY)
103//      @JoinColumn(name="name_id")
104        @IndexedEmbedded
105        @Cascade(CascadeType.SAVE_UPDATE)
106        @NotNull(groups = Level2.class)
107        private TaxonNameBase name;
108       
109        // The concept reference
110    @XmlElement(name = "Sec")
111    @XmlIDREF
112    @XmlSchemaType(name = "IDREF")
113    @ManyToOne(fetch = FetchType.LAZY)
114    @IndexedEmbedded
115    @Cascade(CascadeType.SAVE_UPDATE)
116    @NotNull(groups = Level2.class)
117        private Reference sec;
118
119       
120        @XmlElement(name = "AppendedPhrase")
121        private String appendedPhrase;
122
123        @XmlAttribute(name= "UseNameCache")
124        private boolean useNameCache = false;
125   
126       
127// ************* CONSTRUCTORS *************/   
128        /**
129         * Class constructor: creates a new empty (abstract) taxon.
130         *
131         * @see         #TaxonBase(TaxonNameBase, Reference)
132         */
133        protected TaxonBase(){
134                super();
135        }
136       
137        /**
138         * Class constructor: creates a new (abstract) taxon with the
139         * {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used and the {@link eu.etaxonomy.cdm.model.reference.Reference reference}
140         * using it.
141         *
142         * @param  taxonNameBase        the taxon name used
143         * @param  sec                          the reference using the taxon name
144         * @see    #TaxonBase()
145         */
146        protected TaxonBase(TaxonNameBase taxonNameBase, Reference sec){
147                super();
148                if (taxonNameBase != null){
149                        this.invokeSetMethod(methodTaxonNameAddTaxonBase, taxonNameBase); 
150                }
151                this.setSec(sec);
152        }
153
154//********* METHODS **************************************/
155
156        /**
157         * Generates and returns the string with the full scientific name (including
158         * authorship) of the {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used in <i>this</i>
159         * (abstract) taxon as well as the title of the {@link eu.etaxonomy.cdm.model.reference.Reference reference} using
160         * this taxon name. This string may be stored in the inherited
161         * {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache() titleCache} attribute.
162         * This method overrides the generic and inherited generateTitle() method
163         * from {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity IdentifiableEntity}.
164         *
165         * @return  the string with the full scientific name of the taxon name
166         *                      and with the title of the reference involved in <i>this</i> (abstract) taxon
167         * @see         eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle()
168         * @see         eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache()
169         */
170//      @Override
171//      public String generateTitle() {
172//              String title;
173//              if (name != null && name.getTitleCache() != null){
174//                      title = name.getTitleCache() + " sec. ";
175//                      if (sec != null){
176//                              title += sec.getTitleCache();
177//                      }else{
178//                              title += "???";
179//                      }
180//              }else{
181//                      title = this.toString();
182//              }
183//              return title;
184//      }
185       
186        /**
187         * Returns the {@link TaxonNameBase taxon name} used in <i>this</i> (abstract) taxon.
188         */
189        public TaxonNameBase getName(){
190                return this.name;
191        }
192       
193        /*
194         * @see #getName
195         */
196        public void setName(TaxonNameBase name) {
197                if (this.name != null){
198                        this.name.getTaxonBases().remove(this);
199                }
200                if(name != null) {
201                        name.getTaxonBases().add(this);
202                }
203                this.name = name;
204        }
205       
206        /**
207         * Returns the {@link eu.etaxonomy.cdm.model.name.HomotypicalGroup homotypical group} of the
208         * {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used in <i>this</i> (abstract) taxon.
209         */
210        @Transient
211        public HomotypicalGroup getHomotypicGroup(){
212                if (this.getName() == null){
213                        return null;
214                }else{
215                        return this.getName().getHomotypicalGroup();
216                }
217        }
218
219        /**
220         * Returns the boolean value indicating whether the assignment of <i>this</i>
221         * (abstract) taxon to the {@link Taxon Taxon} or to the {@link Synonym Synonym} class is definitive
222         * (false) or not (true). If this flag is set the use of <i>this</i> (abstract)
223         * taxon as an "accepted/correct" name or as a (junior) "synonym" might
224         * still change in the course of taxonomical working process.
225         */
226        public boolean isDoubtful(){
227                return this.doubtful;
228        }
229        /**
230         * @see  #isDoubtful()
231         */
232        public void setDoubtful(boolean doubtful){
233                this.doubtful = doubtful;
234        }
235
236        /**
237         * Returns the {@link eu.etaxonomy.cdm.model.reference.Reference reference} of <i>this</i> (abstract) taxon.
238         * This is the reference or the treatment using the {@link TaxonNameBase taxon name}
239         * in <i>this</i> (abstract) taxon.
240         */
241        public Reference getSec() {
242                return sec;
243        }
244
245        /**
246         * @see  #getSec()
247         */
248        public void setSec(Reference sec) {
249                this.sec = sec;
250        }
251       
252       
253       
254        /**
255         * An appended phrase is a phrase that is added to the {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name}
256         * 's title cache to be used just in this taxon. E.g. the phrase "sensu latu" may be added
257         * to the name to describe this taxon more precisely.
258         * If {@link #isUseNameCache()}
259         * @return the appendedPhrase
260         */
261        public String getAppendedPhrase() {
262                return appendedPhrase;
263        }
264
265        /**
266         * @param appendedPhrase the appendedPhrase to set
267         */
268        public void setAppendedPhrase(String appendedPhrase) {
269                this.appendedPhrase = appendedPhrase;
270        }
271
272        /**
273         * @return the useNameCache
274         */
275        public boolean isUseNameCache() {
276                return useNameCache;
277        }
278
279        /**
280         * @param useNameCache the useNameCache to set
281         */
282        public void setUseNameCache(boolean useNameCache) {
283                this.useNameCache = useNameCache;
284        }
285//*********************** CLONE ********************************************************/
286       
287        /**
288         * Clones <i>this</i> taxon. This is a shortcut that enables to create
289         * a new instance with empty taxon name and sec reference.
290         * 
291         * @see eu.etaxonomy.cdm.model.media.IdentifiableEntity#clone()
292         * @see java.lang.Object#clone()
293         */
294        @Override
295        public Object clone() {
296                TaxonBase result;
297                try {
298                        result = (TaxonBase)super.clone();
299                        result.setSec(null);
300                       
301                        return result;
302                } catch (CloneNotSupportedException e) {
303                        logger.warn("Object does not implement cloneable");
304                        e.printStackTrace();
305                        return null;
306                }
307               
308               
309        }
310
311}
Note: See TracBrowser for help on using the browser.