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