| 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 | } |
|---|