root/trunk/cdmlib/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/description/StateData.java

Revision 13976, 10.4 kB (checked in by a.mueller, 3 months ago)

bugfix for stateData.modifyingText (#2760)

  • Property svn:keywords set to Id
Line 
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
10package eu.etaxonomy.cdm.model.description;
11
12
13import java.util.HashMap;
14import java.util.HashSet;
15import java.util.Map;
16import java.util.Set;
17
18import javax.persistence.Entity;
19import javax.persistence.FetchType;
20import javax.persistence.ManyToMany;
21import javax.persistence.ManyToOne;
22import javax.persistence.OneToMany;
23import javax.validation.constraints.NotNull;
24import javax.xml.bind.annotation.XmlAccessType;
25import javax.xml.bind.annotation.XmlAccessorType;
26import javax.xml.bind.annotation.XmlElement;
27import javax.xml.bind.annotation.XmlElementWrapper;
28import javax.xml.bind.annotation.XmlIDREF;
29import javax.xml.bind.annotation.XmlRootElement;
30import javax.xml.bind.annotation.XmlSchemaType;
31import javax.xml.bind.annotation.XmlType;
32import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
33
34import org.apache.log4j.Logger;
35import org.hibernate.annotations.Cascade;
36import org.hibernate.annotations.CascadeType;
37import org.hibernate.envers.Audited;
38
39import eu.etaxonomy.cdm.jaxb.MultilanguageTextAdapter;
40import eu.etaxonomy.cdm.model.common.IMultiLanguageTextHolder;
41import eu.etaxonomy.cdm.model.common.Language;
42import eu.etaxonomy.cdm.model.common.LanguageString;
43import eu.etaxonomy.cdm.model.common.MultilanguageText;
44import eu.etaxonomy.cdm.model.common.TermVocabulary;
45import eu.etaxonomy.cdm.model.common.VersionableEntity;
46
47/**
48 * This class represents the assignment of values ({@link State state terms}) to {@link Feature features}
49 * corresponding to {@link CategoricalData categorical data}. A state data instance
50 * constitutes an atomized part of an information piece (categorical data) so
51 * that several state data instances may belong to one categorical data
52 * instance.
53 * <P>
54 * This class corresponds to CharacterStateDataType according to the SDD schema.
55 *
56 * @author m.doering
57 * @version 1.0
58 * @created 08-Nov-2007 13:06:53
59 */
60@XmlAccessorType(XmlAccessType.FIELD)
61@XmlType(name = "StateData", propOrder = {
62    "state",
63    "modifiers",
64    "modifyingText"
65})
66@XmlRootElement(name = "StateData")
67@Entity
68@Audited
69public class StateData extends VersionableEntity implements IModifiable, IMultiLanguageTextHolder, Cloneable{
70        private static final long serialVersionUID = -4380314126624505415L;
71        private static final Logger logger = Logger.getLogger(StateData.class);
72       
73        @XmlElement(name = "State")
74    @XmlIDREF
75    @XmlSchemaType(name = "IDREF")
76    @ManyToOne(fetch = FetchType.LAZY)
77        private State state;
78       
79        @XmlElementWrapper(name = "Modifiers")
80        @XmlElement(name = "Modifier")
81        @ManyToMany(fetch = FetchType.LAZY)
82        @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE})
83//      @NotNull // avoids creating a UNIQUE key for this field -> not needed for ManyToMany
84        private Set<Modifier> modifiers = new HashSet<Modifier>();
85       
86        @XmlElement(name = "ModifyingText")
87        @XmlJavaTypeAdapter(MultilanguageTextAdapter.class)
88        @OneToMany(fetch = FetchType.LAZY)
89        @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE})
90        private Map<Language,LanguageString> modifyingText = new HashMap<Language,LanguageString>();
91
92//********************* FACTORY METHODS ************************\
93       
94        /**
95         * Creates a new empty state data instance.
96         */
97        public static StateData NewInstance(){
98                return new StateData();
99        }
100       
101       
102        /**
103         * Creates a new empty state data instance.
104         */
105        public static StateData NewInstance(State state){
106                return new StateData();
107        }
108       
109        /**
110         * Creates a new empty state data instance.
111         */
112        public static StateData NewInstance(String term, String label, String labelAbbrev){
113                State state = State.NewInstance(term, label, labelAbbrev);
114                return NewInstance(state);
115        }
116       
117//*************************** CONSTRUCTOR ************************\     
118       
119        /**
120         * Class constructor: creates a new empty state data instance.
121         */
122        public StateData() {
123                super();
124        }
125
126//************************** GETTER /SETTER *************************\
127       
128        /**
129         * Returns the {@link State state term} used in <i>this</i> state data.
130         */
131        public State getState(){
132                return this.state;
133        }
134        /**
135         * @see #getState()
136         */
137        public void setState(State state){
138                this.state = state;
139        }
140       
141
142        /**
143         * Returns the set of {@link Modifier modifiers} used to qualify the validity
144         * of <i>this</i> state data. This is only metainformation.
145         */
146        public Set<Modifier> getModifiers(){
147                return this.modifiers;
148        }
149       
150        /**
151         * Adds a {@link Modifier modifier} to the set of {@link #getModifiers() modifiers}
152         * used to qualify the validity of <i>this</i> state data.
153         *
154         * @param modifier      the modifier to be added to <i>this</i> state data
155         * @see                         #getModifiers()
156         */
157        public void addModifier(Modifier modifier){
158                this.modifiers.add(modifier);
159        }
160        /**
161         * Removes one element from the set of {@link #getModifiers() modifiers}
162         * used to qualify the validity of <i>this</i> state data.
163         *
164         * @param  modifier     the modifier which should be removed
165         * @see                 #getModifiers()
166         * @see                 #addModifier(Modifier)
167         */
168        public void removeModifier(Modifier modifier){
169                this.modifiers.remove(modifier);
170        }
171
172
173        /**
174         * Returns the {@link MultilanguageText multilanguage text} used to qualify the validity
175         * of <i>this</i> state data.  The different {@link LanguageString language strings}
176         * contained in the multilanguage text should all have the same meaning.<BR>
177         * A multilanguage text does not belong to a controlled {@link TermVocabulary term vocabulary}
178         * as a {@link Modifier modifier} does.
179         * <P>
180         * NOTE: the actual content of <i>this</i> state data is NOT
181         * stored in the modifying text. This is only metainformation
182         * (like "Some experts express doubt about this assertion").
183         */
184        public Map<Language,LanguageString> getModifyingText(){
185                return this.modifyingText;
186        }
187
188        /**
189         * Creates a {@link LanguageString language string} based on the given text string
190         * and the given {@link Language language} and adds it to the {@link MultilanguageText multilanguage text}
191         * used to qualify the validity of <i>this</i> state data.
192         *
193         *
194         * @param text          the string describing the validity
195         *                                      in a particular language
196         * @param language      the language in which the text string is formulated
197         *
198         * @see                         #getModifyingText()
199         * @see                         #putModifyingText(LanguageString)
200         * @deprecated          should follow the put semantic of maps, this method will be removed in v4.0
201         *                                      Use the {@link #putModifyingText(Language, String) putModifyingText} method instead
202         */
203        @Deprecated
204        public LanguageString addModifyingText(String text, Language language){
205                return this.putModifyingText(language, text);
206        }
207       
208        /**
209         * Creates a {@link LanguageString language string} based on the given text string
210         * and the given {@link Language language} and adds it to the {@link MultilanguageText multilanguage text}
211         * used to qualify the validity of <i>this</i> state data.
212         *
213         * @param language      the language in which the text string is formulated
214         * @param text          the string describing the validity
215         *                                      in a particular language
216         *
217         * @see                         #getModifyingText()
218         * @see                         #addModifyingText(LanguageString)
219         */
220        public LanguageString putModifyingText(Language language, String text){
221                return this.modifyingText.put(language, LanguageString.NewInstance(text, language));
222        }
223        /**
224         * Adds a translated {@link LanguageString text in a particular language}
225         * to the {@link MultilanguageText multilanguage text} used to qualify the validity
226         * of <i>this</i> state data.
227         *
228         * @param text  the language string describing the validity
229         *                              in a particular language
230         * @see                 #getModifyingText()
231         * @see                 #putModifyingText(Language, String)
232         * @deprecated  should follow the put semantic of maps, this method will be removed in v4.0
233         *                              Use the {@link #putModifyingText(LanguagString) putModifyingText} method instead
234         */
235        @Deprecated
236        public LanguageString addModifyingText(LanguageString text){
237                return this.putModifyingText(text);
238        }
239       
240        /**
241         * Adds a translated {@link LanguageString text in a particular language}
242         * to the {@link MultilanguageText multilanguage text} used to qualify the validity
243         * of <i>this</i> state data.
244         *
245         * @param text  the language string describing the validity
246         *                              in a particular language
247         * @see                 #getModifyingText()
248         * @see                 #putModifyingText(Language, String)
249         */
250        public LanguageString putModifyingText(LanguageString text){
251                return this.modifyingText.put(text.getLanguage(),text);
252        }
253        /**
254         * Removes from the {@link MultilanguageText multilanguage text} used to qualify the validity
255         * of <i>this</i> state data the one {@link LanguageString language string}
256         * with the given {@link Language language}.
257         *
258         * @param  lang the language in which the language string to be removed
259         *                              has been formulated
260         * @see         #getModifyingText()
261         */
262        public LanguageString removeModifyingText(Language lang){
263                return this.modifyingText.remove(lang);
264        }
265
266//*********************************** CLONE *****************************************/
267
268        /**
269         * Clones <i>this</i> state data. This is a shortcut that enables to create
270         * a new instance that differs only slightly from <i>this</i> state data by
271         * modifying only some of the attributes.
272         *
273         * @see eu.etaxonomy.cdm.model.common.VersionableEntity#clone()
274         * @see java.lang.Object#clone()
275         */
276        @Override
277        public Object clone() {
278
279                try {
280                        StateData result = (StateData)super.clone();
281                       
282                        //modifiers
283                        result.modifiers = new HashSet<Modifier>();
284                        for (Modifier modifier : getModifiers()){
285                                result.modifiers.add(modifier);
286                        }
287                       
288                        //modifying text
289                        result.modifyingText = new HashMap<Language, LanguageString>();
290                        for (Language language : getModifyingText().keySet()){
291                                //TODO clone needed? See also IndividualsAssociation
292                                LanguageString newLanguageString = (LanguageString)getModifyingText().get(language).clone();
293                                result.modifyingText.put(language, newLanguageString);
294                        }
295                       
296                        return result;
297                        //no changes to: state
298                } catch (CloneNotSupportedException e) {
299                        logger.warn("Object does not implement cloneable");
300                        e.printStackTrace();
301                        return null;
302                }
303        }
304}
Note: See TracBrowser for help on using the browser.