Project

General

Profile

Download (9.59 KB) Statistics
| Branch: | Tag: | Revision:
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.Column;
19
import javax.persistence.FetchType;
20
import javax.persistence.MappedSuperclass;
21
import javax.persistence.OneToMany;
22
import javax.persistence.Transient;
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.XmlAttribute;
27
import javax.xml.bind.annotation.XmlElement;
28
import javax.xml.bind.annotation.XmlElementWrapper;
29
import javax.xml.bind.annotation.XmlSeeAlso;
30
import javax.xml.bind.annotation.XmlType;
31

    
32
import org.apache.log4j.Logger;
33
import org.hibernate.LazyInitializationException;
34
import org.hibernate.annotations.Cascade;
35
import org.hibernate.annotations.CascadeType;
36
import org.hibernate.annotations.Type;
37
import org.hibernate.envers.Audited;
38
import org.hibernate.search.annotations.Analyze;
39
import org.hibernate.search.annotations.Field;
40

    
41
import eu.etaxonomy.cdm.model.description.TextData;
42
import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
43
import eu.etaxonomy.cdm.strategy.cache.common.TermDefaultCacheStrategy;
44

    
45
@XmlAccessorType(XmlAccessType.FIELD)
46
@XmlType(name = "TermBase", propOrder = {
47
    "uri",
48
    "termType",
49
    "representations"
50
})
51
@XmlSeeAlso({
52
    DefinedTermBase.class,
53
    TermVocabulary.class
54
})
55
@MappedSuperclass
56
@Audited
57
public abstract class TermBase extends IdentifiableEntity<IIdentifiableEntityCacheStrategy<TermBase> >{
58
    private static final long serialVersionUID = 1471561531632115822L;
59
    @SuppressWarnings("unused")
60
    private static final Logger logger = Logger.getLogger(TermBase.class);
61

    
62
    @XmlElement(name = "URI")
63
    @Field(analyze = Analyze.NO)
64
    @Type(type="uriUserType")
65
    private URI uri;
66

    
67
	/**
68
	 * The {@link TermType type} of this term. Needs to be the same type in a {@link DefinedTermBase defined term}
69
	 * and in it's {@link TermVocabulary vocabulary}.
70
	 */
71
	@XmlAttribute(name ="TermType")
72
	@Column(name="termType")
73
	@NotNull
74
    @Type(type = "eu.etaxonomy.cdm.hibernate.EnumUserType",
75
        parameters = {@org.hibernate.annotations.Parameter(name  = "enumClass", value = "eu.etaxonomy.cdm.model.common.TermType")}
76
    )
77
	@Audited
78
	private TermType termType;
79

    
80
    @XmlElementWrapper(name = "Representations")
81
    @XmlElement(name = "Representation")
82
    @OneToMany(fetch=FetchType.EAGER, orphanRemoval=true)
83
    @Cascade( { CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE})
84
    // @IndexedEmbedded no need for embedding since we are using the DefinedTermBaseClassBridge
85
    private Set<Representation> representations = new HashSet<>();
86

    
87
//******************* CONSTRUCTOR *************************************/
88

    
89
    //for JAXB only, TODO needed?
90
    @Deprecated
91
    protected TermBase(){}
92

    
93
    protected TermBase(TermType type){
94
        super();
95
        if (type == null){
96
        	throw new IllegalArgumentException("TermType must not be null");
97
        }else{
98
        	this.termType = type;
99
        }
100
        initCacheStrategy();
101
    }
102

    
103
    protected TermBase(TermType type, String term, String label, String labelAbbrev) {
104
        this(type);
105
        this.addRepresentation(new Representation(term, label, labelAbbrev, Language.DEFAULT()) );
106
    }
107

    
108
    private void initCacheStrategy() {
109
        this.cacheStrategy = new TermDefaultCacheStrategy<TermBase>();
110
    }
111

    
112
//******************** GETTER /SETTER ********************************/
113

    
114
	public TermType getTermType() {
115
		return termType;
116
	}
117
	public void setTermType(TermType termType) {
118
		this.termType = termType;
119
	}
120

    
121

    
122
    public Set<Representation> getRepresentations() {
123
        return this.representations;
124
    }
125

    
126
    public void addRepresentation(Representation representation) {
127
//        this.representations.add(representation);
128
        this.addToSetWithChangeEvent(this.representations, representation, "representations");
129
    }
130

    
131
    public void removeRepresentation(Representation representation) {
132
//        this.representations.remove(representation);
133
        this.removeFromSetWithChangeEvent(this.representations, representation, "representations");
134
    }
135

    
136
    public Representation getRepresentation(Language lang) {
137
        for (Representation repr : representations){
138
            Language reprLanguage = repr.getLanguage();
139
            if (reprLanguage != null && reprLanguage.equals(lang)){
140
                return repr;
141
            }
142
        }
143
        return null;
144
    }
145

    
146
    /**
147
     * @see #getPreferredRepresentation(Language)
148
     * @param language
149
     * @return
150
     */
151
    public Representation getPreferredRepresentation(Language language) {
152
        Representation repr = getRepresentation(language);
153
        if(repr == null){
154
            repr = getRepresentation(Language.DEFAULT());
155
        }
156
        if(repr == null){
157
            repr = getRepresentations().isEmpty() ? null : getRepresentations().iterator().next();
158
        }
159
        return repr;
160
    }
161

    
162
    /**
163
     * Returns the Representation in the preferred language. Preferred languages
164
     * are specified by the parameter languages, which receives a list of
165
     * Language instances in the order of preference. If no representation in
166
     * any preferred languages is found the method falls back to return the
167
     * Representation in Language.DEFAULT() and if necessary further falls back
168
     * to return the first element found if any.
169
     *
170
     * TODO think about this fall-back strategy &
171
     * see also {@link TextData#getPreferredLanguageString(List)}
172
     *
173
     * @param languages
174
     * @return
175
     */
176
    public Representation getPreferredRepresentation(List<Language> languages) {
177
        Representation repr = null;
178
        if(languages != null){
179
            for(Language language : languages) {
180
                repr = getRepresentation(language);
181
                if(repr != null){
182
                    return repr;
183
                }
184
            }
185
        }
186
        if(repr == null){
187
            repr = getRepresentation(Language.DEFAULT());
188
        }
189
        if(repr == null){
190
            Iterator<Representation> it = getRepresentations().iterator();
191
            if(it.hasNext()){
192
                repr = getRepresentations().iterator().next();
193
            }
194
        }
195
        return repr;
196
    }
197

    
198
    public URI getUri() {
199
        return this.uri;
200
    }
201

    
202
    public void setUri(URI uri) {
203
        this.uri = uri;
204
    }
205

    
206
    @Transient
207
    public String getLabel() {
208
        if(getLabel(Language.DEFAULT())!=null){
209
            Representation repr = getRepresentation(Language.DEFAULT());
210
            return (repr == null)? null :repr.getLabel();
211
        }else{
212
            for (Representation r : representations){
213
                if (r.getLabel()!= null){
214
                    return r.getLabel();
215
                }
216
            }
217
            if (representations.size()>0){
218
                return null;
219
            }else{
220
                return super.getUuid().toString();
221
            }
222
        }
223
    }
224

    
225
    public String getLabel(Language lang) {
226
        Representation repr = this.getRepresentation(lang);
227
        return (repr == null) ? null : repr.getLabel();
228
    }
229

    
230
    public void setLabel(String label){
231
        Language lang = Language.DEFAULT();
232
        setLabel(label, lang);
233
    }
234

    
235
    public void setLabel(String label, Language language){
236
        if (language != null){
237
            Representation repr = getRepresentation(language);
238
            if (repr != null){
239
                repr.setLabel(label);
240
            }else{
241
                repr = Representation.NewInstance(null, label, null, language);
242
                this.addRepresentation(repr);
243
            }
244
            this.titleCache = null; //force titleCache refresh
245
        }
246
    }
247

    
248
    @Transient
249
    public String getDescription() {
250
        return this.getDescription(Language.DEFAULT());
251
    }
252

    
253
    public String getDescription(Language lang) {
254
        Representation repr = this.getRepresentation(lang);
255
        return (repr == null) ? null :repr.getDescription();
256
    }
257

    
258
    @Override
259
    public boolean equals(Object obj) {
260
        if (obj == null){
261
            return false;
262
        }
263
        if (TermBase.class.isAssignableFrom(obj.getClass())){
264
            TermBase dtb = (TermBase)obj;
265
            if (dtb.getUuid().equals(this.getUuid())){
266
                return true;
267
            }
268
        }
269
        return false;
270
    }
271

    
272
    @Override
273
    public String toString() {
274
        //TODO eliminate nasty LazyInitializationException loggings
275
        try {
276
            return super.toString();
277
        } catch (LazyInitializationException e) {
278
            return super.toString()+" "+this.getUuid();
279
        }
280
    }
281

    
282
//*********************** CLONE ********************************************************/
283

    
284
    /**
285
     * Clones <i>this</i> TermBase. This is a shortcut that enables to create
286
     * a new instance that differs only slightly from <i>this</i> TermBase by
287
     * modifying only some of the attributes.
288
     *
289
     * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#clone()
290
     * @see java.lang.Object#clone()
291
     */
292
    @Override
293
    public Object clone()throws CloneNotSupportedException {
294

    
295
        TermBase result = (TermBase) super.clone();
296

    
297
        result.representations = new HashSet<Representation>();
298
        for (Representation rep : this.representations){
299
            result.representations.add((Representation)rep.clone());
300
        }
301

    
302
        return result;
303
    }
304
}
(64-64/77)