2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.model
.description
;
13 import java
.util
.HashMap
;
14 import java
.util
.HashSet
;
18 import javax
.persistence
.Entity
;
19 import javax
.persistence
.FetchType
;
20 import javax
.persistence
.ManyToMany
;
21 import javax
.persistence
.ManyToOne
;
22 import javax
.persistence
.OneToMany
;
23 import javax
.validation
.constraints
.NotNull
;
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
;
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
;
42 import eu
.etaxonomy
.cdm
.hibernate
.search
.DefinedTermBaseClassBridge
;
43 import eu
.etaxonomy
.cdm
.hibernate
.search
.MultilanguageTextFieldBridge
;
44 import eu
.etaxonomy
.cdm
.jaxb
.MultilanguageTextAdapter
;
45 import eu
.etaxonomy
.cdm
.model
.common
.IMultiLanguageTextHolder
;
46 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
47 import eu
.etaxonomy
.cdm
.model
.common
.LanguageString
;
48 import eu
.etaxonomy
.cdm
.model
.common
.MultilanguageText
;
49 import eu
.etaxonomy
.cdm
.model
.common
.TermVocabulary
;
50 import eu
.etaxonomy
.cdm
.model
.common
.VersionableEntity
;
53 * This class represents the assignment of values ({@link State state terms}) to {@link Feature features}
54 * corresponding to {@link CategoricalData categorical data}. A state data instance
55 * constitutes an atomized part of an information piece (categorical data) so
56 * that several state data instances may belong to one categorical data
59 * This class corresponds to CharacterStateDataType according to the SDD schema.
63 * @created 08-Nov-2007 13:06:53
65 @XmlAccessorType(XmlAccessType
.FIELD
)
66 @XmlType(name
= "StateData", propOrder
= {
71 @XmlRootElement(name
= "StateData")
74 public class StateData
extends VersionableEntity
implements IModifiable
, IMultiLanguageTextHolder
, Cloneable
{
75 private static final long serialVersionUID
= -4380314126624505415L;
76 private static final Logger logger
= Logger
.getLogger(StateData
.class);
78 @XmlElement(name
= "State")
80 @XmlSchemaType(name
= "IDREF")
81 @ManyToOne(fetch
= FetchType
.LAZY
)
85 @XmlElementWrapper(name
= "Modifiers")
86 @XmlElement(name
= "Modifier")
87 @ManyToMany(fetch
= FetchType
.LAZY
)
88 @Cascade({CascadeType
.SAVE_UPDATE
, CascadeType
.MERGE
})
90 // @NotNull // avoids creating a UNIQUE key for this field -> not needed for ManyToMany
91 private Set
<Modifier
> modifiers
= new HashSet
<Modifier
>();
93 @XmlElement(name
= "ModifyingText")
94 @XmlJavaTypeAdapter(MultilanguageTextAdapter
.class)
95 @OneToMany(fetch
= FetchType
.LAZY
)
96 @Cascade({CascadeType
.SAVE_UPDATE
, CascadeType
.MERGE
})
97 @Field(name
="modifyingText")
98 @FieldBridge(impl
=MultilanguageTextFieldBridge
.class)
99 private Map
<Language
,LanguageString
> modifyingText
= new HashMap
<Language
,LanguageString
>();
101 //********************* FACTORY METHODS ************************\
104 * Creates a new empty state data instance.
106 public static StateData
NewInstance(){
107 return new StateData();
112 * Creates a new empty state data instance.
114 * <b>NOTE:</b> {@link State} is a sub class of {@link DefinedTermBase}.
115 * 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.
117 public static StateData
NewInstance(State state
){
118 StateData stateData
= new StateData();
119 stateData
.setState(state
);
123 //*************************** CONSTRUCTOR ************************\
126 * Class constructor: creates a new empty state data instance.
132 //************************** GETTER /SETTER *************************\
135 * Returns the {@link State state term} used in <i>this</i> state data.
137 public State
getState(){
143 public void setState(State state
){
149 * Returns the set of {@link Modifier modifiers} used to qualify the validity
150 * of <i>this</i> state data. This is only metainformation.
152 public Set
<Modifier
> getModifiers(){
153 return this.modifiers
;
157 * Adds a {@link Modifier modifier} to the set of {@link #getModifiers() modifiers}
158 * used to qualify the validity of <i>this</i> state data.
160 * @param modifier the modifier to be added to <i>this</i> state data
161 * @see #getModifiers()
163 public void addModifier(Modifier modifier
){
164 this.modifiers
.add(modifier
);
167 * Removes one element from the set of {@link #getModifiers() modifiers}
168 * used to qualify the validity of <i>this</i> state data.
170 * @param modifier the modifier which should be removed
171 * @see #getModifiers()
172 * @see #addModifier(Modifier)
174 public void removeModifier(Modifier modifier
){
175 this.modifiers
.remove(modifier
);
180 * Returns the {@link MultilanguageText multilanguage text} used to qualify the validity
181 * of <i>this</i> state data. The different {@link LanguageString language strings}
182 * contained in the multilanguage text should all have the same meaning.<BR>
183 * A multilanguage text does not belong to a controlled {@link TermVocabulary term vocabulary}
184 * as a {@link Modifier modifier} does.
186 * NOTE: the actual content of <i>this</i> state data is NOT
187 * stored in the modifying text. This is only metainformation
188 * (like "Some experts express doubt about this assertion").
190 public Map
<Language
,LanguageString
> getModifyingText(){
191 return this.modifyingText
;
195 * Creates a {@link LanguageString language string} based on the given text string
196 * and the given {@link Language language} and adds it to the {@link MultilanguageText multilanguage text}
197 * used to qualify the validity of <i>this</i> state data.
200 * @param text the string describing the validity
201 * in a particular language
202 * @param language the language in which the text string is formulated
204 * @see #getModifyingText()
205 * @see #putModifyingText(LanguageString)
206 * @deprecated should follow the put semantic of maps, this method will be removed in v4.0
207 * Use the {@link #putModifyingText(Language, String) putModifyingText} method instead
210 public LanguageString
addModifyingText(String text
, Language language
){
211 return this.putModifyingText(language
, text
);
215 * Creates a {@link LanguageString language string} based on the given text string
216 * and the given {@link Language language} and adds it to the {@link MultilanguageText multilanguage text}
217 * used to qualify the validity of <i>this</i> state data.
219 * @param language the language in which the text string is formulated
220 * @param text the string describing the validity
221 * in a particular language
223 * @see #getModifyingText()
224 * @see #addModifyingText(LanguageString)
226 public LanguageString
putModifyingText(Language language
, String text
){
227 return this.modifyingText
.put(language
, LanguageString
.NewInstance(text
, language
));
230 * Adds a translated {@link LanguageString text in a particular language}
231 * to the {@link MultilanguageText multilanguage text} used to qualify the validity
232 * of <i>this</i> state data.
234 * @param text the language string describing the validity
235 * in a particular language
236 * @see #getModifyingText()
237 * @see #putModifyingText(Language, String)
238 * @deprecated should follow the put semantic of maps, this method will be removed in v4.0
239 * Use the {@link #putModifyingText(LanguagString) putModifyingText} method instead
242 public LanguageString
addModifyingText(LanguageString text
){
243 return this.putModifyingText(text
);
247 * Adds a translated {@link LanguageString text in a particular language}
248 * to the {@link MultilanguageText multilanguage text} used to qualify the validity
249 * of <i>this</i> state data.
251 * @param text the language string describing the validity
252 * in a particular language
253 * @see #getModifyingText()
254 * @see #putModifyingText(Language, String)
256 public LanguageString
putModifyingText(LanguageString text
){
257 return this.modifyingText
.put(text
.getLanguage(),text
);
260 * Removes from the {@link MultilanguageText multilanguage text} used to qualify the validity
261 * of <i>this</i> state data the one {@link LanguageString language string}
262 * with the given {@link Language language}.
264 * @param lang the language in which the language string to be removed
265 * has been formulated
266 * @see #getModifyingText()
268 public LanguageString
removeModifyingText(Language lang
){
269 return this.modifyingText
.remove(lang
);
272 //*********************************** CLONE *****************************************/
275 * Clones <i>this</i> state data. This is a shortcut that enables to create
276 * a new instance that differs only slightly from <i>this</i> state data by
277 * modifying only some of the attributes.
279 * @see eu.etaxonomy.cdm.model.common.VersionableEntity#clone()
280 * @see java.lang.Object#clone()
283 public Object
clone() {
286 StateData result
= (StateData
)super.clone();
289 result
.modifiers
= new HashSet
<Modifier
>();
290 for (Modifier modifier
: getModifiers()){
291 result
.modifiers
.add(modifier
);
295 result
.modifyingText
= new HashMap
<Language
, LanguageString
>();
296 for (Language language
: getModifyingText().keySet()){
297 //TODO clone needed? See also IndividualsAssociation
298 LanguageString newLanguageString
= (LanguageString
)getModifyingText().get(language
).clone();
299 result
.modifyingText
.put(language
, newLanguageString
);
303 //no changes to: state
304 } catch (CloneNotSupportedException e
) {
305 logger
.warn("Object does not implement cloneable");