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.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
 * @created 08-Nov-2007 13:06:53
64
 */
65
@XmlAccessorType(XmlAccessType.FIELD)
66
@XmlType(name = "StateData", propOrder = {
67
    "state",
68
    "categoricalData",
69
    "modifiers",
70
    "modifyingText"
71
})
72
@XmlRootElement(name = "StateData")
73
@Entity
74
@Audited
75
public class StateData extends VersionableEntity implements IModifiable, IMultiLanguageTextHolder, Cloneable{
76
    private static final long serialVersionUID = -4380314126624505415L;
77
    private static final Logger logger = Logger.getLogger(StateData.class);
78

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

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

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

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

    
110
//********************* FACTORY METHODS ************************\
111

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

    
119

    
120
    /**
121
     * Creates a new empty state data instance.
122
     *
123
     * <b>NOTE:</b> {@link State}  is a sub class of {@link DefinedTermBase}.
124
     * 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.
125
     */
126
    public static StateData NewInstance(State state){
127
        StateData stateData = new StateData();
128
        stateData.setState(state);
129
        return stateData;
130
    }
131

    
132
//*************************** CONSTRUCTOR ************************\
133

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

    
141
//************************** GETTER /SETTER *************************\
142

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

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

    
169

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

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

    
203

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

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

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

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

    
297
//*********************************** CLONE *****************************************/
298

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

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

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

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

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