Add missing @Audited annotations to mapped superclasses
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / common / TermBase.java
1 /**
2 * Copyright (C) 2009 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
10 package eu.etaxonomy.cdm.model.common;
11
12 import java.net.URI;
13 import java.util.HashSet;
14 import java.util.Iterator;
15 import java.util.List;
16 import java.util.Set;
17
18 import javax.persistence.FetchType;
19 import javax.persistence.MappedSuperclass;
20 import javax.persistence.OneToMany;
21 import javax.persistence.Transient;
22 import javax.xml.bind.annotation.XmlAccessType;
23 import javax.xml.bind.annotation.XmlAccessorType;
24 import javax.xml.bind.annotation.XmlElement;
25 import javax.xml.bind.annotation.XmlElementWrapper;
26 import javax.xml.bind.annotation.XmlSeeAlso;
27 import javax.xml.bind.annotation.XmlType;
28
29 import org.apache.log4j.Logger;
30 import org.hibernate.LazyInitializationException;
31 import org.hibernate.annotations.Cascade;
32 import org.hibernate.annotations.CascadeType;
33 import org.hibernate.annotations.Type;
34 import org.hibernate.envers.Audited;
35 import org.hibernate.search.annotations.Analyze;
36 import org.hibernate.search.annotations.Field;
37
38 import eu.etaxonomy.cdm.model.description.FeatureTree;
39 import eu.etaxonomy.cdm.model.description.TextData;
40 import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
41 import eu.etaxonomy.cdm.strategy.cache.common.TermDefaultCacheStrategy;
42
43 @XmlAccessorType(XmlAccessType.FIELD)
44 @XmlType(name = "TermBase", propOrder = {
45 "uri",
46 "representations"
47 })
48 @XmlSeeAlso({
49 DefinedTermBase.class,
50 TermVocabulary.class,
51 FeatureTree.class
52 })
53 @MappedSuperclass
54 @Audited
55 public abstract class TermBase extends IdentifiableEntity<IIdentifiableEntityCacheStrategy >{
56 private static final long serialVersionUID = 1471561531632115822L;
57 @SuppressWarnings("unused")
58 private static final Logger logger = Logger.getLogger(TermBase.class);
59
60 @XmlElement(name = "URI")
61 @Field(analyze = Analyze.NO)
62 @Type(type="uriUserType")
63 private URI uri;
64
65 @XmlElementWrapper(name = "Representations")
66 @XmlElement(name = "Representation")
67 @OneToMany(fetch=FetchType.EAGER, orphanRemoval=true)
68 @Cascade( { CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE})
69 // @IndexedEmbedded no need for embedding since we are using the DefinedTermBaseClassBridge
70 private Set<Representation> representations = new HashSet<Representation>();
71
72 public TermBase(){
73 super();
74 initCacheStrategy();
75
76 }
77 private void initCacheStrategy() {
78 this.cacheStrategy = new TermDefaultCacheStrategy<TermBase>();
79 }
80 public TermBase(String term, String label, String labelAbbrev) {
81 super();
82 initCacheStrategy();
83 this.addRepresentation(new Representation(term, label, labelAbbrev, Language.DEFAULT()) );
84 }
85
86 public Set<Representation> getRepresentations() {
87 return this.representations;
88 }
89
90 public void addRepresentation(Representation representation) {
91 this.representations.add(representation);
92 // this is just a preliminary solution (see ticket #3148)
93 if(representation.language!=null && representation.language.equals(Language.DEFAULT())){
94 this.regenerateTitleCache();
95 }
96 }
97
98 public void removeRepresentation(Representation representation) {
99 this.representations.remove(representation);
100 }
101
102 public Representation getRepresentation(Language lang) {
103 for (Representation repr : representations){
104 Language reprLanguage = repr.getLanguage();
105 if (reprLanguage != null && reprLanguage.equals(lang)){
106 return repr;
107 }
108 }
109 return null;
110 }
111
112 /**
113 * @see #getPreferredRepresentation(Language)
114 * @param language
115 * @return
116 */
117 public Representation getPreferredRepresentation(Language language) {
118 Representation repr = getRepresentation(language);
119 if(repr == null){
120 repr = getRepresentation(Language.DEFAULT());
121 }
122 if(repr == null){
123 repr = getRepresentations().iterator().next();
124 }
125 return repr;
126 }
127
128 /**
129 * Returns the Representation in the preferred language. Preferred languages
130 * are specified by the parameter languages, which receives a list of
131 * Language instances in the order of preference. If no representation in
132 * any preferred languages is found the method falls back to return the
133 * Representation in Language.DEFAULT() and if necessary further falls back
134 * to return the first element found if any.
135 *
136 * TODO think about this fall-back strategy &
137 * see also {@link TextData#getPreferredLanguageString(List)}
138 *
139 * @param languages
140 * @return
141 */
142 public Representation getPreferredRepresentation(List<Language> languages) {
143 Representation repr = null;
144 if(languages != null){
145 for(Language language : languages) {
146 repr = getRepresentation(language);
147 if(repr != null){
148 return repr;
149 }
150 }
151 }
152 if(repr == null){
153 repr = getRepresentation(Language.DEFAULT());
154 }
155 if(repr == null){
156 Iterator<Representation> it = getRepresentations().iterator();
157 if(it.hasNext()){
158 repr = getRepresentations().iterator().next();
159 }
160 }
161 return repr;
162 }
163
164 public URI getUri() {
165 return this.uri;
166 }
167
168 public void setUri(URI uri) {
169 this.uri = uri;
170 }
171
172 /* (non-Javadoc)
173 * @see eu.etaxonomy.cdm.model.common.ITerm#getLabel()
174 */
175 @Transient
176 public String getLabel() {
177 if(getLabel(Language.DEFAULT())!=null){
178 Representation repr = getRepresentation(Language.DEFAULT());
179 return (repr == null)? null :repr.getLabel();
180 }else{
181 for (Representation r : representations){
182 return r.getLabel();
183 }
184 }
185 return super.getUuid().toString();
186 }
187
188 /* (non-Javadoc)
189 * @see eu.etaxonomy.cdm.model.common.ITerm#getLabel(eu.etaxonomy.cdm.model.common.Language)
190 */
191 public String getLabel(Language lang) {
192 Representation repr = this.getRepresentation(lang);
193 return (repr == null) ? null : repr.getLabel();
194 }
195
196 public void setLabel(String label){
197 Language lang = Language.DEFAULT();
198 setLabel(label, lang);
199 }
200
201 public void setLabel(String label, Language language){
202 if (language != null){
203 Representation repr = getRepresentation(language);
204 if (repr != null){
205 repr.setLabel(label);
206 }else{
207 repr = Representation.NewInstance(null, label, null, language);
208 }
209 this.addRepresentation(repr);
210 }
211 }
212
213 /* (non-Javadoc)
214 * @see eu.etaxonomy.cdm.model.common.ITerm#getDescription()
215 */
216 @Transient
217 public String getDescription() {
218 return this.getDescription(Language.DEFAULT());
219 }
220
221 /* (non-Javadoc)
222 * @see eu.etaxonomy.cdm.model.common.ITerm#getDescription(eu.etaxonomy.cdm.model.common.Language)
223 */
224 public String getDescription(Language lang) {
225 Representation repr = this.getRepresentation(lang);
226 return (repr == null) ? null :repr.getDescription();
227 }
228
229 @Override
230 public boolean equals(Object obj) {
231 if (obj == null){
232 return false;
233 }
234 if (TermBase.class.isAssignableFrom(obj.getClass())){
235 TermBase dtb = (TermBase)obj;
236 if (dtb.getUuid().equals(this.getUuid())){
237 return true;
238 }
239 }
240 return false;
241 }
242
243 @Override
244 public String toString() {
245 //TODO eliminate nasty LazyInitializationException loggings
246 try {
247 return super.toString();
248 } catch (LazyInitializationException e) {
249 return super.toString()+" "+this.getUuid();
250 }
251 }
252
253 //*********************** CLONE ********************************************************/
254
255 /**
256 * Clones <i>this</i> TermBase. This is a shortcut that enables to create
257 * a new instance that differs only slightly from <i>this</i> TermBase by
258 * modifying only some of the attributes.
259 *
260 * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#clone()
261 * @see java.lang.Object#clone()
262 */
263 @Override
264 public Object clone()throws CloneNotSupportedException {
265
266 TermBase result = (TermBase) super.clone();
267
268 result.representations = new HashSet<Representation>();
269 for (Representation rep : this.representations){
270 result.representations.add((Representation)rep.clone());
271 }
272
273
274
275 return result;
276
277 }
278
279 }