Project

General

Profile

Download (11.7 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

    
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;
26

    
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;
37

    
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;
49

    
50
/**
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".
58
 * <P>
59
 * This class corresponds to: <ul>
60
 * <li> TaxonConcept according to the TDWG ontology
61
 * <li> TaxonConcept according to the TCS
62
 * </ul>
63
 *
64
 * @author m.doering
65
 * @created 08-Nov-2007 13:06:56
66
 */
67
@XmlAccessorType(XmlAccessType.FIELD)
68
@XmlType(name = "TaxonBase", propOrder = {
69
    "name",
70
    "sec",
71
    "doubtful",
72
    "appendedPhrase",
73
    "useNameCache",
74
    "publish"
75
})
76
@Entity
77
@Audited
78
//@PreFilter("hasPermission(filterObject, 'edit')")
79
@Table(appliesTo="TaxonBase", indexes = { @Index(name = "taxonBaseTitleCacheIndex", columnNames = { "titleCache" }) })
80
@TaxonNameCannotBeAcceptedAndSynonym(groups = Level3.class)
81
@ClassBridges({
82
    @ClassBridge(name="classInfo",
83
            index = org.hibernate.search.annotations.Index.YES,
84
            store = Store.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,
88
            store = Store.YES,
89
            impl = AcceptedTaxonBridge.class),
90
    @ClassBridge(impl = eu.etaxonomy.cdm.hibernate.search.NomenclaturalSortOrderBrigde.class)
91
})
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);
95

    
96
    private static Method methodTaxonNameAddTaxonBase;
97

    
98
    static {
99
        try {
100
            methodTaxonNameAddTaxonBase = TaxonNameBase.class.getDeclaredMethod("addTaxonBase", TaxonBase.class);
101
            methodTaxonNameAddTaxonBase.setAccessible(true);
102
        } catch (Exception e) {
103
            logger.error(e);
104
            for(StackTraceElement ste : e.getStackTrace()) {
105
                logger.error(ste);
106
            }
107
        }
108
    }
109

    
110
    //The assignment to the Taxon or to the Synonym class is not definitive
111
    @XmlAttribute(name = "isDoubtful")
112
    private boolean doubtful;
113

    
114

    
115
    @XmlElement(name = "Name", required = true)
116
    @XmlIDREF
117
    @XmlSchemaType(name = "IDREF")
118
    @ManyToOne(fetch = FetchType.LAZY)
119
    @IndexedEmbedded
120
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
121
    @NotNull(groups = Level2.class)
122
    private TaxonNameBase<?,?> name;
123

    
124
    // The concept reference
125
    @XmlElement(name = "Sec")
126
    @XmlIDREF
127
    @XmlSchemaType(name = "IDREF")
128
    @ManyToOne(fetch = FetchType.LAZY)
129
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
130
    @NotNull(groups = Level2.class)
131
    @IndexedEmbedded
132
    private Reference<?> sec;
133

    
134

    
135
    @XmlElement(name = "AppendedPhrase")
136
    private String appendedPhrase;
137

    
138
    @XmlAttribute(name= "UseNameCache")
139
    private boolean useNameCache = false;
140
    
141
    @XmlAttribute(name = "publish")
142
    private boolean publish = true;
143

    
144

    
145
// ************* CONSTRUCTORS *************/
146
    /**
147
     * Class constructor: creates a new empty (abstract) taxon.
148
     *
149
     * @see 	#TaxonBase(TaxonNameBase, Reference)
150
     */
151
    protected TaxonBase(){
152
        super();
153
    }
154

    
155
    /**
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}
158
     * using it.
159
     *
160
     * @param  taxonNameBase	the taxon name used
161
     * @param  sec				the reference using the taxon name
162
     * @see    #TaxonBase()
163
     */
164
    protected TaxonBase(TaxonNameBase taxonNameBase, Reference sec){
165
        super();
166
        if (taxonNameBase != null){
167
            this.invokeSetMethod(methodTaxonNameAddTaxonBase, taxonNameBase);
168
        }
169
        this.setSec(sec);
170
    }
171

    
172
//********* METHODS **************************************/
173

    
174
    /**
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}.
182
     *
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()
187
     */
188
//	@Override
189
//	public String generateTitle() {
190
//		String title;
191
//		if (name != null && name.getTitleCache() != null){
192
//			title = name.getTitleCache() + " sec. ";
193
//			if (sec != null){
194
//				title += sec.getTitleCache();
195
//			}else{
196
//				title += "???";
197
//			}
198
//		}else{
199
//			title = this.toString();
200
//		}
201
//		return title;
202
//	}
203

    
204
    /**
205
     * Returns the {@link TaxonNameBase taxon name} used in <i>this</i> (abstract) taxon.
206
     */
207
    public TaxonNameBase getName(){
208
        return this.name;
209
    }
210

    
211
    /*
212
     * @see #getName
213
     */
214
    public void setName(TaxonNameBase name) {
215
        if (this.name != null){
216
            this.name.getTaxonBases().remove(this);
217
        }
218
        if(name != null) {
219
            name.getTaxonBases().add(this);
220
        }
221
        this.name = name;
222
    }
223

    
224
    /**
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.
227
     */
228
    @Transient
229
    public HomotypicalGroup getHomotypicGroup(){
230
        if (this.getName() == null){
231
            return null;
232
        }else{
233
            return this.getName().getHomotypicalGroup();
234
        }
235
    }
236

    
237
    /**
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.
243
     */
244
    public boolean isDoubtful(){
245
        return this.doubtful;
246
    }
247
    /**
248
     * @see  #isDoubtful()
249
     */
250
    public void setDoubtful(boolean doubtful){
251
        this.doubtful = doubtful;
252
    }
253
    
254

    
255
    /**
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>.
261
     */
262
    @Override
263
    public boolean isPublish() {
264
        return publish;
265
    }
266

    
267
    @Override
268
    public void setPublish(boolean publish) {
269
        this.publish = publish;
270
    }
271

    
272
    /**
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.
276
     */
277
    public Reference getSec() {
278
        return sec;
279
    }
280

    
281
    /**
282
     * @see  #getSec()
283
     */
284
    public void setSec(Reference sec) {
285
        this.sec = sec;
286
    }
287

    
288

    
289

    
290
    /**
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
296
     */
297
    public String getAppendedPhrase() {
298
        return appendedPhrase;
299
    }
300

    
301
    /**
302
     * @param appendedPhrase the appendedPhrase to set
303
     */
304
    public void setAppendedPhrase(String appendedPhrase) {
305
        this.appendedPhrase = appendedPhrase;
306
    }
307

    
308
    /**
309
     * @return the useNameCache
310
     */
311
    public boolean isUseNameCache() {
312
        return useNameCache;
313
    }
314

    
315
    /**
316
     * @param useNameCache the useNameCache to set
317
     */
318
    public void setUseNameCache(boolean useNameCache) {
319
        this.useNameCache = useNameCache;
320
    }
321

    
322
    @Transient
323
    public abstract boolean isOrphaned();
324
//*********************** CLONE ********************************************************/
325

    
326
    /**
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.
329
     *
330
     * @see eu.etaxonomy.cdm.model.media.IdentifiableEntity#clone()
331
     * @see java.lang.Object#clone()
332
     */
333
    @Override
334
    public Object clone() {
335
        TaxonBase result;
336
        try {
337
            result = (TaxonBase)super.clone();
338
            result.setSec(null);
339

    
340
            return result;
341
        } catch (CloneNotSupportedException e) {
342
            logger.warn("Object does not implement cloneable");
343
            e.printStackTrace();
344
            return null;
345
        }
346

    
347

    
348
    }
349

    
350

    
351
}
(10-10/18)