Project

General

Profile

Download (9.58 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
package eu.etaxonomy.cdm.model.term;
10

    
11
import java.util.HashSet;
12
import java.util.Iterator;
13
import java.util.List;
14
import java.util.Set;
15

    
16
import javax.persistence.Column;
17
import javax.persistence.FetchType;
18
import javax.persistence.MappedSuperclass;
19
import javax.persistence.OneToMany;
20
import javax.persistence.Transient;
21
import javax.validation.constraints.NotNull;
22
import javax.xml.bind.annotation.XmlAccessType;
23
import javax.xml.bind.annotation.XmlAccessorType;
24
import javax.xml.bind.annotation.XmlAttribute;
25
import javax.xml.bind.annotation.XmlElement;
26
import javax.xml.bind.annotation.XmlElementWrapper;
27
import javax.xml.bind.annotation.XmlSeeAlso;
28
import javax.xml.bind.annotation.XmlType;
29

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

    
40
import eu.etaxonomy.cdm.common.URI;
41
import eu.etaxonomy.cdm.hibernate.search.UriBridge;
42
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
43
import eu.etaxonomy.cdm.model.common.Language;
44
import eu.etaxonomy.cdm.model.description.TextData;
45
import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
46
import eu.etaxonomy.cdm.strategy.cache.term.TermDefaultCacheStrategy;
47

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

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

    
68
    @XmlElement(name = "URI")
69
    @Field(analyze = Analyze.NO)
70
    @FieldBridge(impl = UriBridge.class)
71
    @Type(type="uriUserType")
72
    private URI uri;
73

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

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

    
94
//******************* CONSTRUCTOR *************************************/
95

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

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

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

    
115
    private void initCacheStrategy() {
116
        this.cacheStrategy = new TermDefaultCacheStrategy<>();
117
    }
118

    
119
//******************** GETTER /SETTER ********************************/
120

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

    
130

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

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

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

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

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

    
171
    /**
172
     * Returns the Representation in the preferred language. Preferred languages
173
     * are specified by the parameter languages, which receives a list of
174
     * Language instances in the order of preference. If no representation in
175
     * any preferred languages is found the method falls back to return the
176
     * Representation in Language.DEFAULT() and if necessary further falls back
177
     * to return the first element found if any.
178
     *
179
     * TODO think about this fall-back strategy &
180
     * see also {@link TextData#getPreferredLanguageString(List)}
181
     *
182
     * @param languages
183
     * @return
184
     */
185
    public Representation getPreferredRepresentation(List<Language> languages) {
186
        Representation repr = null;
187
        if(languages != null){
188
            for(Language language : languages) {
189
                repr = getRepresentation(language);
190
                if(repr != null){
191
                    return repr;
192
                }
193
            }
194
        }
195
        repr = getRepresentation(Language.DEFAULT());
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 TermBase 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(rep.clone());
294
        }
295

    
296
        return result;
297
    }
298
}
(19-19/33)