Project

General

Profile

Download (9 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.description;
11

    
12

    
13
import java.util.HashSet;
14
import java.util.Set;
15

    
16
import javax.persistence.Entity;
17
import javax.persistence.FetchType;
18
import javax.persistence.JoinTable;
19
import javax.persistence.ManyToMany;
20
import javax.persistence.ManyToOne;
21
import javax.persistence.Transient;
22
import javax.xml.bind.annotation.XmlAccessType;
23
import javax.xml.bind.annotation.XmlAccessorType;
24
import javax.xml.bind.annotation.XmlElement;
25
import javax.xml.bind.annotation.XmlElementWrapper;
26
import javax.xml.bind.annotation.XmlIDREF;
27
import javax.xml.bind.annotation.XmlRootElement;
28
import javax.xml.bind.annotation.XmlSchemaType;
29
import javax.xml.bind.annotation.XmlType;
30

    
31
import org.apache.log4j.Logger;
32
import org.hibernate.annotations.Cascade;
33
import org.hibernate.annotations.CascadeType;
34
import org.hibernate.envers.Audited;
35
import org.hibernate.search.annotations.Indexed;
36
import org.hibernate.search.annotations.IndexedEmbedded;
37
import org.springframework.beans.factory.annotation.Configurable;
38

    
39
import eu.etaxonomy.cdm.model.common.CdmBase;
40
import eu.etaxonomy.cdm.model.common.DefinedTerm;
41
import eu.etaxonomy.cdm.model.location.NamedArea;
42
import eu.etaxonomy.cdm.model.taxon.Taxon;
43
import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
44
import eu.etaxonomy.cdm.strategy.cache.description.TaxonDescriptionDefaultCacheStrategy;
45

    
46
/**
47
 * This class represents descriptions that delimit or circumscribe a real taxon.
48
 * <P>
49
 * This class corresponds to: <ul>
50
 * <li> DescriptionsBaseType with a "Class" element according to the the SDD schema
51
 * <li> SpeciesProfileModel according to the TDWG ontology
52
 * <li> CharacterCircumscription according to the TCS
53
 * </ul>
54
 *
55
 * @author m.doering
56
 * @version 1.0
57
 * @created 08-Nov-2007 13:06:20
58
 */
59
@XmlAccessorType(XmlAccessType.FIELD)
60
@XmlType(name = "TaxonDescription", propOrder = {
61
    "scopes",
62
    "geoScopes",
63
    "taxon"
64
})
65
@XmlRootElement(name = "TaxonDescription")
66
@Entity
67
@Indexed(index = "eu.etaxonomy.cdm.model.description.DescriptionBase")
68
@Audited
69
@Configurable
70
public class TaxonDescription extends DescriptionBase<IIdentifiableEntityCacheStrategy<TaxonDescription>> implements Cloneable{
71
    private static final long serialVersionUID = 8065879180505546803L;
72
    @SuppressWarnings("unused")
73
    private static final Logger logger = Logger.getLogger(TaxonDescription.class);
74

    
75
    @XmlElementWrapper(name = "Scopes")
76
    @XmlElement(name = "Scope")
77
    @XmlIDREF
78
    @XmlSchemaType(name="IDREF")
79
    @ManyToMany(fetch = FetchType.LAZY)
80
    @JoinTable(name="DescriptionBase_Scope")
81
    private Set<DefinedTerm> scopes = new HashSet<DefinedTerm>();
82

    
83
    @XmlElementWrapper( name = "GeoScopes")
84
    @XmlElement( name = "GeoScope")
85
    @XmlIDREF
86
    @XmlSchemaType(name="IDREF")
87
    @ManyToMany(fetch = FetchType.LAZY)
88
    @JoinTable(name="DescriptionBase_GeoScope")
89
    @Cascade({CascadeType.SAVE_UPDATE})
90
    private Set<NamedArea> geoScopes = new HashSet<NamedArea>();
91

    
92
    @XmlElement( name = "Taxon")
93
    @ManyToOne(fetch = FetchType.LAZY)
94
    @XmlIDREF
95
    @XmlSchemaType(name="IDREF")
96
    @Cascade(CascadeType.SAVE_UPDATE)
97
    @IndexedEmbedded
98
    private Taxon taxon;
99

    
100

    
101

    
102
    /**
103
     * Creates a new empty taxon description instance.
104
     *
105
     * @see	#NewInstance(Taxon)
106
     */
107
    public static TaxonDescription NewInstance(){
108
        return new TaxonDescription();
109
    }
110

    
111
    /**
112
     * Creates a new taxon description instance for the given {@link Taxon taxon}.
113
     * The new taxon description will be also added to the {@link Taxon#getDescriptions() set of descriptions}
114
     * assigned to the given taxon.
115
     *
116
     * @see	#NewInstance()
117
     */
118
    public static TaxonDescription NewInstance(Taxon taxon){
119
        TaxonDescription description = new TaxonDescription();
120
        if (taxon != null){
121
            taxon.addDescription(description);
122
        }
123
        return description;
124
    }
125

    
126
    /**
127
     * Creates a new taxon description instance for the given {@link Taxon taxon}.
128
     * The new taxon description will be also added to the {@link Taxon#getDescriptions() set of descriptions}
129
     * assigned to the given taxon.
130
     *
131
     * @see	#NewInstance()
132
     */
133
    public static TaxonDescription NewInstance(Taxon taxon, boolean isImageGallery){
134
        TaxonDescription description = new TaxonDescription();
135
        taxon.addDescription(description);
136
        description.setImageGallery(isImageGallery);
137
        return description;
138
    }
139

    
140
//******************** CONSTRUCTOR *************************************************/
141

    
142
    /**
143
     * Class constructor: creates a new empty taxon description instance.
144
     */
145
    public TaxonDescription(){
146
        super();
147
        this.cacheStrategy = new TaxonDescriptionDefaultCacheStrategy();
148
        }
149

    
150
//************************** METHODS **********************************************/
151

    
152

    
153
    public Taxon getTaxon() {
154
        return taxon;
155
    }
156

    
157

    
158
    protected void setTaxon(Taxon taxon) {
159
    	//TODO needs correct bidirectional handling before making it public
160
    	this.taxon = taxon;
161
    }
162

    
163
    /**
164
     * Returns the set of {@link NamedArea named areas} indicating the geospatial
165
     * data where <i>this</i> taxon description is valid.
166
     */
167
    public Set<NamedArea> getGeoScopes(){
168
        return this.geoScopes;
169
    }
170

    
171
    /**
172
     * Adds a {@link NamedArea named area} to the set of {@link #getGeoScopes() named areas}
173
     * delimiting the geospatial area where <i>this</i> taxon description is valid.
174
     *
175
     * @param geoScope	the named area to be additionally assigned to <i>this</i> taxon description
176
     * @see    	   		#getGeoScopes()
177
     */
178
    public void addGeoScope(NamedArea geoScope){
179
        this.geoScopes.add(geoScope);
180
    }
181

    
182
    /**
183
     * Removes one element from the set of {@link #getGeoScopes() named areas} delimiting
184
     * the geospatial area where <i>this</i> taxon description is valid.
185
     *
186
     * @param  geoScope   the named area which should be removed
187
     * @see     		  #getGeoScopes()
188
     * @see     		  #addGeoScope(NamedArea)
189
     */
190
    public void removeGeoScope(NamedArea geoScope){
191
        this.geoScopes.remove(geoScope);
192
    }
193

    
194

    
195
    /**
196
     * Returns the set of {@link Scope scopes} (this covers mostly {@link Stage life stage} or {@link Sex sex} or both)
197
     * restricting the validity of <i>this</i> taxon description. This set
198
     * of scopes should contain no more than one "sex" and one "life stage".
199
     */
200
    public Set<DefinedTerm> getScopes(){
201
        return this.scopes;
202
    }
203

    
204
    /**
205
     * Adds a {@link Scope scope} (mostly a {@link Stage life stage} or a {@link Sex sex})
206
     * to the set of {@link #getScopes() scopes} restricting the validity of
207
     * <i>this</i> taxon description.
208
     *
209
     * @param scope	the scope to be added to <i>this</i> taxon description
210
     * @see    	   	#getScopes()
211
     */
212
    public void addScope(DefinedTerm scope){
213
        this.scopes.add(scope);
214
    }
215

    
216
    /**
217
     * Removes one element from the set of {@link #getScopes() scopes}
218
     * restricting the validity of <i>this</i> taxon description.
219
     *
220
     * @param  scope	the scope which should be removed
221
     * @see     		#getScopes()
222
     * @see     		#addScope(Scope)
223
     */
224
    public void removeScope(DefinedTerm scope){
225
        this.scopes.remove(scope);
226
    }
227

    
228
    /**
229
     * Returns the first TextData element of feature type image. If no such element exists,
230
     * a new one is created.
231
     * @return
232
     */
233
    @Transient
234
    public TextData getOrCreateImageTextData(){
235
        for (DescriptionElementBase element : this.getElements()){
236
            if (element.getFeature().equals(Feature.IMAGE())){
237
                if (element.isInstanceOf(TextData.class)){
238
                    return CdmBase.deproxy(element, TextData.class);
239
                }
240
            }
241
        }
242
        TextData textData = TextData.NewInstance(Feature.IMAGE());
243
        addElement(textData);
244
        return textData;
245
    }
246

    
247

    
248
//*********************** CLONE ********************************************************/
249

    
250
    /**
251
     * Clones <i>this</i> taxon description. This is a shortcut that enables to create
252
     * a new instance that differs only slightly from <i>this</i> taxon description by
253
     * modifying only some of the attributes.
254
     *
255
     * @see eu.etaxonomy.cdm.model.description.DescriptionBase#clone()
256
     * @see java.lang.Object#clone()
257
     */
258
    @Override
259
    public Object clone() {
260
        TaxonDescription result;
261
        result = (TaxonDescription)super.clone();
262

    
263
        //scopes
264
        result.scopes = new HashSet<DefinedTerm>();
265
        for (DefinedTerm scope : getScopes()){
266
            result.scopes.add(scope);
267
        }
268

    
269
        //geo-scopes
270
        result.geoScopes = new HashSet<NamedArea>();
271
        for (NamedArea namedArea : getGeoScopes()){
272
            result.geoScopes.add(namedArea);
273
        }
274

    
275
        //no changes to: taxon
276
        return result;
277
    }
278

    
279

    
280
}
(29-29/36)