sync trunk
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / description / KeyStatement.java
1 /**
2 *
3 */
4 package eu.etaxonomy.cdm.model.description;
5
6 import java.util.HashMap;
7 import java.util.Iterator;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.Map.Entry;
11
12 import javax.persistence.Entity;
13 import javax.persistence.FetchType;
14 import javax.persistence.OneToMany;
15 import javax.xml.bind.annotation.XmlAccessType;
16 import javax.xml.bind.annotation.XmlAccessorType;
17 import javax.xml.bind.annotation.XmlElement;
18 import javax.xml.bind.annotation.XmlRootElement;
19 import javax.xml.bind.annotation.XmlType;
20 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
21
22 import org.apache.log4j.Logger;
23 import org.hibernate.annotations.Cascade;
24 import org.hibernate.annotations.CascadeType;
25 import org.hibernate.envers.Audited;
26
27 import eu.etaxonomy.cdm.jaxb.MultilanguageTextAdapter;
28 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
29 import eu.etaxonomy.cdm.model.common.IMultiLanguageTextHolder;
30 import eu.etaxonomy.cdm.model.common.Language;
31 import eu.etaxonomy.cdm.model.common.LanguageString;
32 import eu.etaxonomy.cdm.model.common.MultilanguageTextHelper;
33 import eu.etaxonomy.cdm.model.common.TermBase;
34 import eu.etaxonomy.cdm.model.common.VersionableEntity;
35
36 /**
37 * This class represents a statement or a question within a (polytomous) key.
38 * Compare with SDD SimpleRepresentation.
39 *
40 * @author a.mueller
41 *
42 */
43 @XmlAccessorType(XmlAccessType.FIELD)
44 @XmlType(name = "KeyStatement", propOrder = {
45 "label"
46 // ,"mediaObject"
47 })
48 @XmlRootElement(name = "KeyStatement")
49 @Entity
50 @Audited
51 public class KeyStatement extends VersionableEntity implements IMultiLanguageTextHolder{
52 private static final long serialVersionUID = 3771323100914695139L;
53 @SuppressWarnings("unused")
54 private static final Logger logger = Logger.getLogger(KeyStatement.class);
55
56
57 @XmlElement(name = "MultiLanguageText")
58 @XmlJavaTypeAdapter(MultilanguageTextAdapter.class)
59 @OneToMany (fetch= FetchType.LAZY)
60 @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE, CascadeType.DELETE, CascadeType.DELETE_ORPHAN })
61 // @IndexedEmbedded
62 private Map<Language, LanguageString> label = new HashMap<Language, LanguageString>();
63
64 //private mediaObjects needs to be discussed (how to implement the role of the media)
65
66
67
68 public static KeyStatement NewInstance(){
69 KeyStatement result = new KeyStatement();
70 return result;
71 }
72
73
74 public static KeyStatement NewInstance(String defaultLabel){
75 KeyStatement result = new KeyStatement();
76 result.putLabel(Language.DEFAULT(), defaultLabel);
77 return result;
78 }
79
80 /**
81 *
82 */
83 public KeyStatement() {
84 }
85
86 // ********************************* METHODS ***************************/
87
88 /**
89 * Returns the label with the content of <i>this</i> key statement.
90 * The different {@link LanguageString language strings} (texts) contained in the
91 * label should all have the same meaning.
92 *
93 * @see #getText(Language)
94 */
95 public Map<Language, LanguageString> getLabel() {
96 return label;
97 }
98
99 /**
100 * Returns the label with the content of <i>this</i> key statement for
101 * a specific language.
102 *
103 * @param language the language in which the label is formulated
104 * @return
105 */
106 public LanguageString getLabel(Language language){
107 return label.get(language);
108 }
109
110 public void setLabel(Map<Language,LanguageString> label) {
111 this.label = label;
112 }
113
114 /**
115 * Returns the text string in the given {@link Language language} with the content
116 * of <i>this</i> key statement.
117 *
118 * @param language the language in which the label is formulated
119 * @see #getLabel(Language)
120 */
121 public String getLabelText(Language language) {
122 LanguageString languageString = label.get(language);
123 if (languageString == null){
124 return null;
125 }else{
126 return languageString.getText();
127 }
128 }
129
130 /**
131 * Returns the LanguageString in the preferred language. Preferred languages
132 * are specified by the parameter languages, which receives a list of
133 * Language instances in the order of preference. If no representation in
134 * any preferred languages is found the method falls back to return the
135 * Representation in Language.DEFAULT() and if necessary further falls back
136 * to return the first element found if any.
137 *
138 * TODO think about this fall-back strategy &
139 * see also {@link TermBase#getPreferredRepresentation(List)}
140 *
141 * @param languages
142 * @return
143 */
144 public LanguageString getPreferredLanguageString(List<Language> languages) {
145 return MultilanguageTextHelper.getPreferredLanguageString(label, languages);
146 }
147
148 /**
149 * Creates a {@link LanguageString language string} based on the given text string
150 * and the given {@link Language language}, returns it and adds it to the multilanguage
151 * text representing the content of <i>this</i> text data.
152 *
153 * @param text the string representing the content of the text data
154 * in a particular language
155 * @param language the language in which the text string is formulated
156 * @return the language string
157 * @see #getMultilanguageText()
158 * @see #putText(LanguageString)
159 * @deprecated should follow the put semantic of maps, this method will be removed in v4.0
160 * Use the {@link #putLabel(Language, String) putLabel} method
161 */
162 public LanguageString putLabel(String label, Language language) {
163 return putLabel(language, label);
164 }
165
166 /**
167 * Creates a {@link LanguageString language string} based on the given text string
168 * and the given {@link Language language}, returns it and adds it to the multilanguage
169 * text representing the content of <i>this</i> text data.
170 *
171 * @param language the language in which the text string is formulated
172 * @param text the string representing the content of the text data
173 * in a particular language
174 *
175 * @return the language string
176 * @see #getLabel()
177 * @see #putLabel(LanguageString)
178 *
179 */
180 public LanguageString putLabel(Language language, String label) {
181 LanguageString result = this.label.put(language , LanguageString.NewInstance(label, language));
182 return (result == null ? null : result);
183 }
184 /**
185 * Adds a translated {@link LanguageString text in a particular language}
186 * to the label.
187 * The given language string will be returned.
188 *
189 * @param languageString the language string representing the content of
190 * the text data in a particular language
191 * @return the language string
192 * @see #getLabel()
193 * @see #putLabel(String, Language)
194 */
195 public LanguageString putLabel(LanguageString languageString) {
196 if (languageString == null){
197 return null;
198 }else{
199 Language language = languageString.getLanguage();
200 return this.label.put(language, languageString);
201 }
202 }
203
204 /**
205 * Adds a translated {@link LanguageString text in a particular language}
206 * to the label.
207 * The given language string will be returned.
208 *
209 * @param languageString the language string representing the content of
210 * the text data in a particular language
211 * @return the language string
212 * @see #getLabel()
213 * @see #putLabel(String, Language)
214 * @deprecated This method will be removed in v4.0
215 * Use the {@link #putLabel(LanguageString) putLabel} method instead
216 */
217 public LanguageString putText(LanguageString languageString) {
218 return putLabel(languageString);
219 }
220
221 /**
222 * Removes from label the one {@link LanguageString language string}
223 * with the given {@link Language language}. Returns the removed
224 * language string.
225 *
226 * @param language the language in which the language string to be removed
227 * has been formulated
228 * @return the language string associated with the given language
229 * @see #getLabelText()
230 * @deprecated This method will be removed in v4.0
231 * Use the {@link #removeLabel(Language)} method instead
232 */
233 public LanguageString removeText(Language language) {
234 return removeLabel(language);
235 }
236
237 /**
238 * Removes from label the one {@link LanguageString language string}
239 * with the given {@link Language language}. Returns the removed
240 * language string.
241 *
242 * @param language the language in which the language string to be removed
243 * has been formulated
244 * @return the language string associated with the given language
245 * @see #getLabelText()
246 */
247 public LanguageString removeLabel(Language language) {
248 return this.label.remove(language);
249 }
250
251
252 /**
253 * Returns the number of {@link Language languages} in which the label
254 * of <i>this</i> key statement has been formulated.
255 *
256 * @see #getMultilanguageText()
257 */
258 public int countLanguages(){
259 return label.size();
260 }
261
262 //*********************** CLONE ********************************************************/
263
264 /**
265 * Clones <i>this</i> KeyStatement. This is a shortcut that enables to create
266 * a new instance that differs only slightly from <i>this</i> KeyStatement by
267 * modifying only some of the attributes.
268 *
269 * @see eu.etaxonomy.cdm.model.common.VersionableEntitity#clone()
270 * @see java.lang.Object#clone()
271 */
272 @Override
273 public Object clone() {
274 KeyStatement result;
275 try {
276 result = (KeyStatement) super.clone();
277
278 result.label = new HashMap<Language, LanguageString>();
279
280
281 for (Entry<Language,LanguageString> entry: this.label.entrySet()){
282
283 result.label.put(entry.getKey(), entry.getValue());
284 }
285
286 return result;
287 }catch (CloneNotSupportedException e) {
288 logger.warn("Object does not implement cloneable");
289 e.printStackTrace();
290 return null;
291 }
292 }
293
294 }