Project

General

Profile

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

    
77
    private static final long serialVersionUID = 8065879180505546803L;
78
    @SuppressWarnings("unused")
79
    private static final Logger logger = Logger.getLogger(TaxonDescription.class);
80

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

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

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

    
106

    
107

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

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

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

    
146
//******************** CONSTRUCTOR *************************************************/
147

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

    
156
//************************** METHODS **********************************************/
157

    
158

    
159
    public Taxon getTaxon() {
160
        return taxon;
161
    }
162

    
163

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

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

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

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

    
200

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

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

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

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

    
253

    
254
//*********************** CLONE ********************************************************/
255

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

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

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

    
281
        //no changes to: taxon
282
        return result;
283
    }
284
}
(31-31/37)