Project

General

Profile

Download (9.39 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
58
            extends IdentifiableEntity<IIdentifiableEntityCacheStrategy<TermBase>>
59
            implements IHasTermType {
60

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

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

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

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

    
90
//******************* CONSTRUCTOR *************************************/
91

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

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

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

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

    
115
//******************** GETTER /SETTER ********************************/
116

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

    
126

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

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

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

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

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

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

    
203
    public URI getUri() {
204
        return this.uri;
205
    }
206

    
207
    public void setUri(URI uri) {
208
        this.uri = uri;
209
    }
210

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

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

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

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

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

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

    
263

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

    
274
//*********************** CLONE ********************************************************/
275

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

    
287
        TermBase result = (TermBase) super.clone();
288

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

    
294
        return result;
295
    }
296
}
(68-68/82)