Project

General

Profile

Download (9.49 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.term;
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.common.IdentifiableEntity;
42
import eu.etaxonomy.cdm.model.common.Language;
43
import eu.etaxonomy.cdm.model.description.TextData;
44
import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
45
import eu.etaxonomy.cdm.strategy.cache.common.TermDefaultCacheStrategy;
46

    
47
@XmlAccessorType(XmlAccessType.FIELD)
48
@XmlType(name = "TermBase", propOrder = {
49
    "uri",
50
    "termType",
51
    "representations"
52
})
53
@XmlSeeAlso({
54
    DefinedTermBase.class,
55
    TermVocabulary.class
56
})
57
@MappedSuperclass
58
@Audited
59
public abstract class TermBase
60
            extends IdentifiableEntity<IIdentifiableEntityCacheStrategy<TermBase>>
61
            implements IHasTermType {
62

    
63
    private static final long serialVersionUID = 1471561531632115822L;
64
    @SuppressWarnings("unused")
65
    private static final Logger logger = Logger.getLogger(TermBase.class);
66

    
67
    @XmlElement(name = "URI")
68
    @Field(analyze = Analyze.NO)
69
    @Type(type="uriUserType")
70
    private URI uri;
71

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

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

    
92
//******************* CONSTRUCTOR *************************************/
93

    
94
    //for JAXB only, TODO needed?
95
    @Deprecated
96
    protected TermBase(){}
97

    
98
    protected TermBase(TermType type){
99
        super();
100
        if (type == null){
101
        	throw new IllegalArgumentException("TermType must not be null");
102
        }else{
103
        	this.termType = type;
104
        }
105
        initCacheStrategy();
106
    }
107

    
108
    protected TermBase(TermType type, String term, String label, String labelAbbrev) {
109
        this(type);
110
        this.addRepresentation(new Representation(term, label, labelAbbrev, Language.DEFAULT()) );
111
    }
112

    
113
    private void initCacheStrategy() {
114
        this.cacheStrategy = new TermDefaultCacheStrategy<TermBase>();
115
    }
116

    
117
//******************** GETTER /SETTER ********************************/
118

    
119
	@Override
120
    public TermType getTermType() {
121
		return termType;
122
	}
123
	@Deprecated //the term type should never be changed, might be removed in future
124
	public void setTermType(TermType termType) {
125
		this.termType = termType;
126
	}
127

    
128

    
129
    public Set<Representation> getRepresentations() {
130
        return this.representations;
131
    }
132

    
133
    public void addRepresentation(Representation representation) {
134
//        this.representations.add(representation);
135
        this.addToSetWithChangeEvent(this.representations, representation, "representations");
136
    }
137

    
138
    public void removeRepresentation(Representation representation) {
139
//        this.representations.remove(representation);
140
        this.removeFromSetWithChangeEvent(this.representations, representation, "representations");
141
    }
142

    
143
    public Representation getRepresentation(Language lang) {
144
        for (Representation repr : representations){
145
            Language reprLanguage = repr.getLanguage();
146
            if (reprLanguage != null && reprLanguage.equals(lang)){
147
                return repr;
148
            }
149
        }
150
        return null;
151
    }
152

    
153
    /**
154
     * @see #getPreferredRepresentation(Language)
155
     * @param language
156
     * @return
157
     */
158
    public Representation getPreferredRepresentation(Language language) {
159
        Representation repr = getRepresentation(language);
160
        if(repr == null){
161
            repr = getRepresentation(Language.DEFAULT());
162
        }
163
        if(repr == null){
164
            repr = getRepresentations().isEmpty() ? null : getRepresentations().iterator().next();
165
        }
166
        return repr;
167
    }
168

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

    
205
    public URI getUri() {
206
        return this.uri;
207
    }
208

    
209
    public void setUri(URI uri) {
210
        this.uri = uri;
211
    }
212

    
213
    @Transient
214
    public String getLabel() {
215
        if(getLabel(Language.DEFAULT())!=null){
216
            Representation repr = getRepresentation(Language.DEFAULT());
217
            return (repr == null)? null :repr.getLabel();
218
        }else{
219
            for (Representation r : representations){
220
                if (r.getLabel()!= null){
221
                    return r.getLabel();
222
                }
223
            }
224
            if (representations.size()>0){
225
                return null;
226
            }else{
227
                return super.getUuid().toString();
228
            }
229
        }
230
    }
231

    
232
    public String getLabel(Language lang) {
233
        Representation repr = this.getRepresentation(lang);
234
        return (repr == null) ? null : repr.getLabel();
235
    }
236

    
237
    public void setLabel(String label){
238
        Language lang = Language.DEFAULT();
239
        setLabel(label, lang);
240
    }
241

    
242
    public void setLabel(String label, Language language){
243
        if (language != null){
244
            Representation repr = getRepresentation(language);
245
            if (repr != null){
246
                repr.setLabel(label);
247
            }else{
248
                repr = Representation.NewInstance(null, label, null, language);
249
                this.addRepresentation(repr);
250
            }
251
            this.titleCache = null; //force titleCache refresh
252
        }
253
    }
254

    
255
    @Transient
256
    public String getDescription() {
257
        return this.getDescription(Language.DEFAULT());
258
    }
259

    
260
    public String getDescription(Language lang) {
261
        Representation repr = this.getRepresentation(lang);
262
        return (repr == null) ? null :repr.getDescription();
263
    }
264

    
265

    
266
    @Override
267
    public String toString() {
268
        //TODO eliminate nasty LazyInitializationException logging
269
        try {
270
            return super.toString();
271
        } catch (LazyInitializationException e) {
272
            return super.toString()+" "+this.getUuid();
273
        }
274
    }
275

    
276
//*********************** CLONE ********************************************************/
277

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

    
289
        TermBase result = (TermBase) super.clone();
290

    
291
        result.representations = new HashSet<Representation>();
292
        for (Representation rep : this.representations){
293
            result.representations.add((Representation)rep.clone());
294
        }
295

    
296
        return result;
297
    }
298
}
(17-17/23)