Project

General

Profile

Download (9.24 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.FieldBridge;
36
import org.springframework.beans.factory.annotation.Configurable;
37

    
38
import eu.etaxonomy.cdm.hibernate.search.NotNullAwareIdBridge;
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
import javafx.stage.Stage;
46

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

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

    
87
    @XmlElementWrapper( name = "GeoScopes")
88
    @XmlElement( name = "GeoScope")
89
    @XmlIDREF
90
    @XmlSchemaType(name="IDREF")
91
    @ManyToMany(fetch = FetchType.LAZY)
92
    @JoinTable(name="DescriptionBase_GeoScope")
93
//    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})  remove cascade #5755
94
    private Set<NamedArea> geoScopes = new HashSet<NamedArea>();
95

    
96
    @XmlElement( name = "Taxon")
97
    @ManyToOne(fetch = FetchType.LAZY)
98
    @XmlIDREF
99
    @XmlSchemaType(name="IDREF")
100
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
101
    @FieldBridge(impl=NotNullAwareIdBridge.class)
102
    private Taxon taxon;
103

    
104

    
105

    
106
    /**
107
     * Creates a new empty taxon description instance.
108
     *
109
     * @see	#NewInstance(Taxon)
110
     */
111
    public static TaxonDescription NewInstance(){
112
        return new TaxonDescription();
113
    }
114

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

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

    
144
//******************** CONSTRUCTOR *************************************************/
145

    
146
    /**
147
     * Class constructor: creates a new empty taxon description instance.
148
     */
149
    public TaxonDescription(){
150
        super();
151
        this.cacheStrategy = new TaxonDescriptionDefaultCacheStrategy();
152
        }
153

    
154
//************************** METHODS **********************************************/
155

    
156

    
157
    public Taxon getTaxon() {
158
        return taxon;
159
    }
160

    
161

    
162
    protected void setTaxon(Taxon taxon) {
163
    	//TODO needs correct bidirectional handling before making it public
164
    	this.taxon = taxon;
165
    }
166

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

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

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

    
198

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

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

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

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

    
251

    
252
//*********************** CLONE ********************************************************/
253

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

    
267
        //scopes
268
        result.scopes = new HashSet<DefinedTerm>();
269
        for (DefinedTerm scope : getScopes()){
270
            result.scopes.add(scope);
271
        }
272

    
273
        //geo-scopes
274
        result.geoScopes = new HashSet<NamedArea>();
275
        for (NamedArea namedArea : getGeoScopes()){
276
            result.geoScopes.add(namedArea);
277
        }
278

    
279
        //no changes to: taxon
280
        return result;
281
    }
282

    
283

    
284
}
(30-30/37)