Project

General

Profile

Download (12.3 KB) Statistics
| Branch: | Tag: | Revision:
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

    
10
package eu.etaxonomy.cdm.model.taxon;
11

    
12
import java.lang.reflect.Method;
13
import java.util.List;
14

    
15
import javax.persistence.Column;
16
import javax.persistence.Entity;
17
import javax.persistence.FetchType;
18
import javax.persistence.ManyToOne;
19
import javax.persistence.Transient;
20
import javax.validation.constraints.NotNull;
21
import javax.xml.bind.annotation.XmlAccessType;
22
import javax.xml.bind.annotation.XmlAccessorType;
23
import javax.xml.bind.annotation.XmlAttribute;
24
import javax.xml.bind.annotation.XmlElement;
25
import javax.xml.bind.annotation.XmlIDREF;
26
import javax.xml.bind.annotation.XmlSchemaType;
27
import javax.xml.bind.annotation.XmlType;
28

    
29
import org.apache.log4j.Logger;
30
import org.hibernate.annotations.Cascade;
31
import org.hibernate.annotations.CascadeType;
32
import org.hibernate.annotations.Index;
33
import org.hibernate.annotations.Table;
34
import org.hibernate.envers.Audited;
35
import org.hibernate.search.annotations.ClassBridge;
36
import org.hibernate.search.annotations.ClassBridges;
37
import org.hibernate.search.annotations.IndexedEmbedded;
38
import org.hibernate.search.annotations.Store;
39

    
40
import eu.etaxonomy.cdm.hibernate.search.AcceptedTaxonBridge;
41
import eu.etaxonomy.cdm.hibernate.search.ClassInfoBridge;
42
import eu.etaxonomy.cdm.model.common.IPublishable;
43
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
44
import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
45
import eu.etaxonomy.cdm.model.name.Rank;
46
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
47
import eu.etaxonomy.cdm.model.reference.Reference;
48
import eu.etaxonomy.cdm.strategy.cache.TaggedText;
49
import eu.etaxonomy.cdm.strategy.cache.name.CacheUpdate;
50
import eu.etaxonomy.cdm.strategy.cache.taxon.ITaxonCacheStrategy;
51
import eu.etaxonomy.cdm.validation.Level2;
52
import eu.etaxonomy.cdm.validation.Level3;
53
import eu.etaxonomy.cdm.validation.annotation.NullOrNotEmpty;
54
import eu.etaxonomy.cdm.validation.annotation.TaxonNameCannotBeAcceptedAndSynonym;
55

    
56
/**
57
 * 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}
58
 * or within a taxonomic view/treatment either as a {@link Taxon taxon}
59
 * ("accepted" respectively "correct" name) or as a (junior) {@link Synonym synonym}.
60
 * Within a taxonomic view/treatment or a reference a taxon name can be used
61
 * only in one of both described meanings. The reference using the taxon name
62
 * is generally cited with "sec." (secundum, sensu). For instance:
63
 * "<i>Juncus longirostris</i> Kuvaev sec. Kirschner, J. et al. 2002".
64
 * <P>
65
 * This class corresponds to: <ul>
66
 * <li> TaxonConcept according to the TDWG ontology
67
 * <li> TaxonConcept according to the TCS
68
 * </ul>
69
 *
70
 * @author m.doering
71
 * @created 08-Nov-2007 13:06:56
72
 */
73
@XmlAccessorType(XmlAccessType.FIELD)
74
@XmlType(name = "TaxonBase", propOrder = {
75
    "name",
76
    "sec",
77
    "doubtful",
78
    "appendedPhrase",
79
    "useNameCache",
80
    "publish"
81
})
82
@Entity
83
@Audited
84
//@PreFilter("hasPermission(filterObject, 'edit')")
85
@Table(appliesTo="TaxonBase", indexes = { @Index(name = "taxonBaseTitleCacheIndex", columnNames = { "titleCache" }) })
86
@TaxonNameCannotBeAcceptedAndSynonym(groups = Level3.class)
87
@ClassBridges({
88
    @ClassBridge(name="classInfo",
89
            index = org.hibernate.search.annotations.Index.YES,
90
            store = Store.YES,
91
            impl = ClassInfoBridge.class),
92
    @ClassBridge(name="accTaxon", // TODO rename to acceptedTaxon, since we are usually not using abbreviations for field names
93
            index = org.hibernate.search.annotations.Index.YES,
94
            store = Store.YES,
95
            impl = AcceptedTaxonBridge.class),
96
    @ClassBridge(impl = eu.etaxonomy.cdm.hibernate.search.NomenclaturalSortOrderBrigde.class)
97
})
98
public abstract class TaxonBase<S extends ITaxonCacheStrategy> extends IdentifiableEntity<S> implements  IPublishable, Cloneable {
99
    private static final long serialVersionUID = -3589185949928938529L;
100
    private static final Logger logger = Logger.getLogger(TaxonBase.class);
101

    
102
    private static Method methodTaxonNameAddTaxonBase;
103

    
104
    static {
105
        try {
106
            methodTaxonNameAddTaxonBase = TaxonNameBase.class.getDeclaredMethod("addTaxonBase", TaxonBase.class);
107
            methodTaxonNameAddTaxonBase.setAccessible(true);
108
        } catch (Exception e) {
109
            logger.error(e);
110
            for(StackTraceElement ste : e.getStackTrace()) {
111
                logger.error(ste);
112
            }
113
        }
114
    }
115

    
116
    //The assignment to the Taxon or to the Synonym class is not definitive
117
    @XmlAttribute(name = "isDoubtful")
118
    private boolean doubtful;
119

    
120

    
121
    @XmlElement(name = "Name", required = true)
122
    @XmlIDREF
123
    @XmlSchemaType(name = "IDREF")
124
    @ManyToOne(fetch = FetchType.LAZY)
125
    @IndexedEmbedded(includeEmbeddedObjectId=true)
126
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
127
    @NotNull(groups = Level2.class)
128
    private TaxonNameBase<?,?> name;
129

    
130
    // The concept reference
131
    @XmlElement(name = "Sec")
132
    @XmlIDREF
133
    @XmlSchemaType(name = "IDREF")
134
    @ManyToOne(fetch = FetchType.LAZY)
135
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
136
    @NotNull(groups = Level2.class)
137
    @IndexedEmbedded
138
    private Reference<?> sec;
139

    
140
    @XmlElement(name = "secMicroReference")
141
    @CacheUpdate(noUpdate ="titleCache")
142
    @NullOrNotEmpty
143
    @Column(length=255)
144
    private String secMicroReference;
145

    
146

    
147
    @XmlElement(name = "AppendedPhrase")
148
    private String appendedPhrase;
149

    
150
    @XmlAttribute(name= "UseNameCache")
151
    private boolean useNameCache = false;
152

    
153
    @XmlAttribute(name = "publish")
154
    private boolean publish = true;
155

    
156

    
157
// ************* CONSTRUCTORS *************/
158
    /**
159
     * Class constructor: creates a new empty (abstract) taxon.
160
     *
161
     * @see 	#TaxonBase(TaxonNameBase, Reference)
162
     */
163
    protected TaxonBase(){
164
        super();
165
    }
166

    
167
    /**
168
     * Class constructor: creates a new (abstract) taxon with the
169
     * {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used and the {@link eu.etaxonomy.cdm.model.reference.Reference reference}
170
     * using it.
171
     *
172
     * @param  taxonNameBase	the taxon name used
173
     * @param  sec				the reference using the taxon name
174
     * @see    #TaxonBase()
175
     */
176
    protected TaxonBase(TaxonNameBase taxonNameBase, Reference sec){
177
        super();
178
        if (taxonNameBase != null){
179
            this.invokeSetMethod(methodTaxonNameAddTaxonBase, taxonNameBase);
180
        }
181
        this.setSec(sec);
182
    }
183

    
184
//********* METHODS **************************************/
185

    
186
    /**
187
     * Generates and returns the string with the full scientific name (including
188
     * authorship) of the {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used in <i>this</i>
189
     * (abstract) taxon as well as the title of the {@link eu.etaxonomy.cdm.model.reference.Reference reference} using
190
     * this taxon name. This string may be stored in the inherited
191
     * {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache() titleCache} attribute.
192
     * This method overrides the generic and inherited generateTitle() method
193
     * from {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity IdentifiableEntity}.
194
     *
195
     * @return  the string with the full scientific name of the taxon name
196
     *			and with the title of the reference involved in <i>this</i> (abstract) taxon
197
     * @see  	eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle()
198
     * @see  	eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache()
199
     */
200
//	@Override
201
//	public String generateTitle() {
202
//		String title;
203
//		if (name != null && name.getTitleCache() != null){
204
//			title = name.getTitleCache() + " sec. ";
205
//			if (sec != null){
206
//				title += sec.getTitleCache();
207
//			}else{
208
//				title += "???";
209
//			}
210
//		}else{
211
//			title = this.toString();
212
//		}
213
//		return title;
214
//	}
215

    
216
    @Transient
217
    public List<TaggedText> getTaggedTitle(){
218
        return getCacheStrategy().getTaggedTitle(this);
219
    }
220

    
221

    
222

    
223
    /**
224
     * Returns the {@link TaxonNameBase taxon name} used in <i>this</i> (abstract) taxon.
225
     */
226
    public TaxonNameBase getName(){
227
        return this.name;
228
    }
229

    
230
    public void setName(TaxonNameBase name) {
231
        if (this.name != null){
232
            this.name.getTaxonBases().remove(this);
233
        }
234
        if(name != null) {
235
            name.getTaxonBases().add(this);
236
        }
237
        this.name = name;
238
    }
239

    
240
    /**
241
     * Returns the {@link eu.etaxonomy.cdm.model.name.HomotypicalGroup homotypical group} of the
242
     * {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used in <i>this</i> (abstract) taxon.
243
     */
244
    @Transient
245
    public HomotypicalGroup getHomotypicGroup(){
246
        if (this.getName() == null){
247
            return null;
248
        }else{
249
            return this.getName().getHomotypicalGroup();
250
        }
251
    }
252

    
253
    /**
254
     * Returns the boolean value indicating whether the assignment of <i>this</i>
255
     * (abstract) taxon to the {@link Taxon Taxon} or to the {@link Synonym Synonym} class
256
     * is definitive (false) or not (true). If this flag is set the use of <i>this</i> (abstract)
257
     * taxon as an "accepted/correct" name or as a (junior) "synonym" might
258
     * still change in the course of taxonomical working process.
259
     */
260
    public boolean isDoubtful(){
261
        return this.doubtful;
262
    }
263
    /**
264
     * @see  #isDoubtful()
265
     */
266
    public void setDoubtful(boolean doubtful){
267
        this.doubtful = doubtful;
268
    }
269

    
270

    
271
    /**
272
     * Returns the boolean value indicating if this taxon should be withheld (<code>publish=false</code>) or not
273
     * (<code>publish=true</code>) during any publication process to the general public.
274
     * This publish flag implementation is preliminary and may be replaced by a more general
275
     * implementation of READ rights in future.<BR>
276
     * The default value is <code>true</code>.
277
     */
278
    @Override
279
    public boolean isPublish() {
280
        return publish;
281
    }
282

    
283
    @Override
284
    public void setPublish(boolean publish) {
285
        this.publish = publish;
286
    }
287

    
288
    /**
289
     * Returns the {@link eu.etaxonomy.cdm.model.reference.Reference reference} of <i>this</i> (abstract) taxon.
290
     * This is the reference or the treatment using the {@link TaxonNameBase taxon name}
291
     * in <i>this</i> (abstract) taxon.
292
     */
293
    public Reference getSec() {
294
        return sec;
295
    }
296

    
297
    /**
298
     * @see  #getSec()
299
     */
300
    public void setSec(Reference sec) {
301
        this.sec = sec;
302
    }
303

    
304

    
305

    
306
    /**
307
     * An appended phrase is a phrase that is added to the {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name}
308
     * 's title cache to be used just in this taxon. E.g. the phrase "sensu latu" may be added
309
     * to the name to describe this taxon more precisely.
310
     * If {@link #isUseNameCache()}
311
     * @return the appendedPhrase
312
     */
313
    public String getAppendedPhrase() {
314
        return appendedPhrase;
315
    }
316

    
317
    /**
318
     * @param appendedPhrase the appendedPhrase to set
319
     */
320
    public void setAppendedPhrase(String appendedPhrase) {
321
        this.appendedPhrase = appendedPhrase;
322
    }
323

    
324
    /**
325
     * @return the useNameCache
326
     */
327
    public boolean isUseNameCache() {
328
        return useNameCache;
329
    }
330

    
331
    /**
332
     * @param useNameCache the useNameCache to set
333
     */
334
    public void setUseNameCache(boolean useNameCache) {
335
        this.useNameCache = useNameCache;
336
    }
337

    
338
    @Transient
339
    public abstract boolean isOrphaned();
340

    
341

    
342
    /**
343
     * @return
344
     */
345
    @Transient
346
    public Rank getNullSafeRank() {
347
        return name == null ? null : name.getRank();
348
    }
349

    
350
//*********************** CLONE ********************************************************/
351

    
352
    /**
353
     * Clones <i>this</i> taxon. This is a shortcut that enables to create
354
     * a new instance with empty taxon name and sec reference.
355
     *
356
     * @see eu.etaxonomy.cdm.model.media.IdentifiableEntity#clone()
357
     * @see java.lang.Object#clone()
358
     */
359
    @Override
360
    public Object clone() {
361
        TaxonBase result;
362
        try {
363
            result = (TaxonBase)super.clone();
364
            result.setSec(null);
365

    
366
            return result;
367
        } catch (CloneNotSupportedException e) {
368
            logger.warn("Object does not implement cloneable");
369
            e.printStackTrace();
370
            return null;
371
        }
372

    
373

    
374
    }
375

    
376

    
377
}
(11-11/21)