Project

General

Profile

Download (11.8 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.HashMap;
14
import java.util.HashSet;
15
import java.util.Map;
16
import java.util.Set;
17

    
18
import javax.persistence.Entity;
19
import javax.persistence.FetchType;
20
import javax.persistence.ManyToMany;
21
import javax.persistence.ManyToOne;
22
import javax.persistence.MapKeyJoinColumn;
23
import javax.persistence.OneToMany;
24
import javax.xml.bind.annotation.XmlAccessType;
25
import javax.xml.bind.annotation.XmlAccessorType;
26
import javax.xml.bind.annotation.XmlElement;
27
import javax.xml.bind.annotation.XmlElementWrapper;
28
import javax.xml.bind.annotation.XmlIDREF;
29
import javax.xml.bind.annotation.XmlRootElement;
30
import javax.xml.bind.annotation.XmlSchemaType;
31
import javax.xml.bind.annotation.XmlType;
32
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
33

    
34
import org.apache.log4j.Logger;
35
import org.hibernate.annotations.Cascade;
36
import org.hibernate.annotations.CascadeType;
37
import org.hibernate.envers.Audited;
38
import org.hibernate.search.annotations.Field;
39
import org.hibernate.search.annotations.FieldBridge;
40
import org.hibernate.search.annotations.IndexedEmbedded;
41

    
42
import eu.etaxonomy.cdm.hibernate.search.MultilanguageTextFieldBridge;
43
import eu.etaxonomy.cdm.jaxb.MultilanguageTextAdapter;
44
import eu.etaxonomy.cdm.model.common.DefinedTerm;
45
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
46
import eu.etaxonomy.cdm.model.common.IMultiLanguageTextHolder;
47
import eu.etaxonomy.cdm.model.common.Language;
48
import eu.etaxonomy.cdm.model.common.LanguageString;
49
import eu.etaxonomy.cdm.model.common.MultilanguageText;
50
import eu.etaxonomy.cdm.model.common.TermVocabulary;
51
import eu.etaxonomy.cdm.model.common.VersionableEntity;
52

    
53
/**
54
 * This class represents the assignment of values ({@link State state terms}) to {@link Feature features}
55
 * corresponding to {@link CategoricalData categorical data}. A state data instance
56
 * constitutes an atomized part of an information piece (categorical data) so
57
 * that several state data instances may belong to one categorical data
58
 * instance.
59
 * <P>
60
 * This class corresponds to CharacterStateDataType according to the SDD schema.
61
 *
62
 * @author m.doering
63
 * @version 1.0
64
 * @created 08-Nov-2007 13:06:53
65
 */
66
@XmlAccessorType(XmlAccessType.FIELD)
67
@XmlType(name = "StateData", propOrder = {
68
    "state",
69
    "categoricalData",
70
    "modifiers",
71
    "modifyingText"
72
})
73
@XmlRootElement(name = "StateData")
74
@Entity
75
@Audited
76
public class StateData extends VersionableEntity implements IModifiable, IMultiLanguageTextHolder, Cloneable{
77
    private static final long serialVersionUID = -4380314126624505415L;
78
    private static final Logger logger = Logger.getLogger(StateData.class);
79

    
80
    @XmlElement(name = "State")
81
    @XmlIDREF
82
    @XmlSchemaType(name = "IDREF")
83
    @ManyToOne(fetch = FetchType.LAZY)
84
    @IndexedEmbedded(depth=1)
85
    private State state;
86

    
87
    @XmlElement(name = "CategoricalData")
88
    @XmlIDREF
89
    @XmlSchemaType(name = "IDREF")
90
    @ManyToOne(fetch = FetchType.LAZY )
91
    @IndexedEmbedded(depth=1)
92
    private CategoricalData categoricalData;
93

    
94
    @XmlElementWrapper(name = "Modifiers")
95
    @XmlElement(name = "Modifier")
96
    @ManyToMany(fetch = FetchType.LAZY)
97
//    @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE})   remove cascade #5755
98
    @IndexedEmbedded(depth=1)
99
//	@NotNull // avoids creating a UNIQUE key for this field -> not needed for ManyToMany
100
    private Set<DefinedTerm> modifiers = new HashSet<DefinedTerm>();
101

    
102
    @XmlElement(name = "ModifyingText")
103
    @XmlJavaTypeAdapter(MultilanguageTextAdapter.class)
104
    @OneToMany(fetch = FetchType.LAZY)
105
    @MapKeyJoinColumn(name="modifyingtext_mapkey_id")
106
    @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE})
107
    @Field(name="modifyingText")
108
    @FieldBridge(impl=MultilanguageTextFieldBridge.class)
109
    private Map<Language,LanguageString> modifyingText = new HashMap<>();
110

    
111
//********************* FACTORY METHODS ************************\
112

    
113
    /**
114
     * Creates a new empty state data instance.
115
     */
116
    public static StateData NewInstance(){
117
        return new StateData();
118
    }
119

    
120

    
121
    /**
122
     * Creates a new empty state data instance.
123
     *
124
     * <b>NOTE:</b> {@link State}  is a sub class of {@link DefinedTermBase}.
125
     * If the state passed as parameter has been created newly it <b>has to be persisted before</b> it is possible to save the StateData.
126
     */
127
    public static StateData NewInstance(State state){
128
        StateData stateData = new StateData();
129
        stateData.setState(state);
130
        return stateData;
131
    }
132

    
133
//*************************** CONSTRUCTOR ************************\
134

    
135
    /**
136
     * Class constructor: creates a new empty state data instance.
137
     */
138
    public StateData() {
139
        super();
140
    }
141

    
142
//************************** GETTER /SETTER *************************\
143

    
144
    /**
145
     * Returns the {@link State state term} used in <i>this</i> state data.
146
     */
147
    public State getState(){
148
        return this.state;
149
    }
150
    /**
151
     * @see	#getState()
152
     */
153
    public void setState(State state){
154
        this.state = state;
155
    }
156

    
157
    /**
158
     * Returns the {@link CategoricalData state term} <i>this</i> state data
159
     * belongs to.
160
     */
161
    public CategoricalData getCategoricalData(){
162
        return this.categoricalData;
163
    }
164
    //for bidirectional use only
165
    @Deprecated
166
    protected void setCategoricalData(CategoricalData categoricalData) {
167
        this.categoricalData = categoricalData;
168
    }
169

    
170

    
171
    /**
172
     * Returns the set of {@link Modifier modifiers} used to qualify the validity
173
     * of <i>this</i> state data. This is only metainformation.
174
     */
175
    @Override
176
    public Set<DefinedTerm> getModifiers(){
177
        return this.modifiers;
178
    }
179

    
180
    /**
181
     * Adds a {@link Modifier modifier} to the set of {@link #getModifiers() modifiers}
182
     * used to qualify the validity of <i>this</i> state data.
183
     *
184
     * @param modifier	the modifier to be added to <i>this</i> state data
185
     * @see    	   		#getModifiers()
186
     */
187
    @Override
188
    public void addModifier(DefinedTerm modifier){
189
        this.modifiers.add(modifier);
190
    }
191
    /**
192
     * Removes one element from the set of {@link #getModifiers() modifiers}
193
     * used to qualify the validity of <i>this</i> state data.
194
     *
195
     * @param  modifier	the modifier which should be removed
196
     * @see     		#getModifiers()
197
     * @see     		#addModifier(Modifier)
198
     */
199
    @Override
200
    public void removeModifier(DefinedTerm modifier){
201
        this.modifiers.remove(modifier);
202
    }
203

    
204

    
205
    /**
206
     * Returns the {@link MultilanguageText multilanguage text} used to qualify the validity
207
     * of <i>this</i> state data.  The different {@link LanguageString language strings}
208
     * contained in the multilanguage text should all have the same meaning.<BR>
209
     * A multilanguage text does not belong to a controlled {@link TermVocabulary term vocabulary}
210
     * as a {@link Modifier modifier} does.
211
     * <P>
212
     * NOTE: the actual content of <i>this</i> state data is NOT
213
     * stored in the modifying text. This is only metainformation
214
     * (like "Some experts express doubt about this assertion").
215
     */
216
    public Map<Language,LanguageString> getModifyingText(){
217
        return this.modifyingText;
218
    }
219

    
220
    /**
221
     * Creates a {@link LanguageString language string} based on the given text string
222
     * and the given {@link Language language} and adds it to the {@link MultilanguageText multilanguage text}
223
     * used to qualify the validity of <i>this</i> state data.
224
     *
225
     *
226
     * @param text		the string describing the validity
227
     * 					in a particular language
228
     * @param language	the language in which the text string is formulated
229
     *
230
     * @see    	   		#getModifyingText()
231
     * @see    	   		#putModifyingText(LanguageString)
232
     * @deprecated 		should follow the put semantic of maps, this method will be removed in v4.0
233
     * 					Use the {@link #putModifyingText(Language, String) putModifyingText} method instead
234
     */
235
    @Deprecated
236
    public LanguageString addModifyingText(String text, Language language){
237
        return this.putModifyingText(language, text);
238
    }
239

    
240
    /**
241
     * Creates a {@link LanguageString language string} based on the given text string
242
     * and the given {@link Language language} and adds it to the {@link MultilanguageText multilanguage text}
243
     * used to qualify the validity of <i>this</i> state data.
244
     *
245
     * @param language	the language in which the text string is formulated
246
     * @param text		the string describing the validity
247
     * 					in a particular language
248
     *
249
     * @see    	   		#getModifyingText()
250
     * @see    	   		#addModifyingText(LanguageString)
251
     */
252
    public LanguageString putModifyingText(Language language, String text){
253
        return this.modifyingText.put(language, LanguageString.NewInstance(text, language));
254
    }
255
    /**
256
     * Adds a translated {@link LanguageString text in a particular language}
257
     * to the {@link MultilanguageText multilanguage text} used to qualify the validity
258
     * of <i>this</i> state data.
259
     *
260
     * @param text	the language string describing the validity
261
     * 				in a particular language
262
     * @see    	   	#getModifyingText()
263
     * @see    	   	#putModifyingText(Language, String)
264
     * @deprecated	should follow the put semantic of maps, this method will be removed in v4.0
265
     * 				Use the {@link #putModifyingText(LanguagString) putModifyingText} method instead
266
     */
267
    @Deprecated
268
    public LanguageString addModifyingText(LanguageString text){
269
        return this.putModifyingText(text);
270
    }
271

    
272
    /**
273
     * Adds a translated {@link LanguageString text in a particular language}
274
     * to the {@link MultilanguageText multilanguage text} used to qualify the validity
275
     * of <i>this</i> state data.
276
     *
277
     * @param text	the language string describing the validity
278
     * 				in a particular language
279
     * @see    	   	#getModifyingText()
280
     * @see    	   	#putModifyingText(Language, String)
281
     */
282
    public LanguageString putModifyingText(LanguageString text){
283
        return this.modifyingText.put(text.getLanguage(),text);
284
    }
285
    /**
286
     * Removes from the {@link MultilanguageText multilanguage text} used to qualify the validity
287
     * of <i>this</i> state data the one {@link LanguageString language string}
288
     * with the given {@link Language language}.
289
     *
290
     * @param  lang	the language in which the language string to be removed
291
     * 				has been formulated
292
     * @see     	#getModifyingText()
293
     */
294
    public LanguageString removeModifyingText(Language lang){
295
        return this.modifyingText.remove(lang);
296
    }
297

    
298
//*********************************** CLONE *****************************************/
299

    
300
    /**
301
     * Clones <i>this</i> state data. This is a shortcut that enables to create
302
     * a new instance that differs only slightly from <i>this</i> state data by
303
     * modifying only some of the attributes.
304
     *
305
     * @see eu.etaxonomy.cdm.model.common.VersionableEntity#clone()
306
     * @see java.lang.Object#clone()
307
     */
308
    @Override
309
    public Object clone() {
310

    
311
        try {
312
            StateData result = (StateData)super.clone();
313

    
314
            //modifiers
315
            result.modifiers = new HashSet<DefinedTerm>();
316
            for (DefinedTerm modifier : getModifiers()){
317
                result.modifiers.add(modifier);
318
            }
319

    
320
            //modifying text
321
            result.modifyingText = cloneLanguageString(this.modifyingText);
322

    
323
            return result;
324
            //no changes to: state
325
        } catch (CloneNotSupportedException e) {
326
            logger.warn("Object does not implement cloneable");
327
            e.printStackTrace();
328
            return null;
329
        }
330
    }
331
}
(27-27/37)