Project

General

Profile

Download (8.1 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 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.List;
15
import java.util.Set;
16
import java.util.SortedSet;
17
import java.util.TreeSet;
18
import java.util.UUID;
19

    
20
import javax.persistence.Entity;
21
import javax.persistence.FetchType;
22
import javax.persistence.OneToMany;
23
import javax.xml.bind.annotation.XmlAccessType;
24
import javax.xml.bind.annotation.XmlAccessorType;
25
import javax.xml.bind.annotation.XmlElement;
26
import javax.xml.bind.annotation.XmlElementWrapper;
27
import javax.xml.bind.annotation.XmlIDREF;
28
import javax.xml.bind.annotation.XmlRootElement;
29
import javax.xml.bind.annotation.XmlSchemaType;
30
import javax.xml.bind.annotation.XmlType;
31

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

    
41
import eu.etaxonomy.cdm.common.CdmUtils;
42
import eu.etaxonomy.cdm.model.common.ExternallyManaged;
43
import eu.etaxonomy.cdm.model.common.Language;
44

    
45

    
46
/**
47
 * A single enumeration must only contain DefinedTerm instances of one kind
48
 * (this means a subclass of DefinedTerm).
49
 * @author m.doering
50
 * @since 08-Nov-2007 13:06:23
51
 */
52
@XmlAccessorType(XmlAccessType.FIELD)
53
@XmlType(name = "TermVocabulary", propOrder = {
54
    "termSourceUri",
55
    "terms",
56
    "externallyManaged"
57
})
58
@XmlRootElement(name = "TermVocabulary")
59
@Entity
60
//@Indexed disabled to reduce clutter in indexes, since this type is not used by any search
61
//@Indexed(index = "eu.etaxonomy.cdm.model.term.TermVocabulary")
62
@Audited
63
public class TermVocabulary<T extends DefinedTermBase>
64
        extends TermCollection<T,TermNode> {
65

    
66
    private static final long serialVersionUID = 1925052321596648672L;
67
	private static final Logger logger = Logger.getLogger(TermVocabulary.class);
68

    
69
	//The vocabulary source (e.g. ontology) defining the terms to be loaded when a database
70
	//is created for the first time.
71
	// Software can go and grap these terms incl. labels and description.
72
	// UUID needed? Further vocs can be setup through our own ontology.
73
	@XmlElement(name = "TermSourceURI")
74
	@Type(type="uriUserType")
75
	@Field(analyze = Analyze.NO)
76
	private URI termSourceUri;
77

    
78
	@XmlElementWrapper(name = "Terms")
79
	@XmlElement(name = "Term")
80
    @XmlIDREF
81
    @XmlSchemaType(name = "IDREF")
82
    @OneToMany(mappedBy="vocabulary", fetch=FetchType.LAZY, targetEntity = DefinedTermBase.class)
83
	@Type(type="DefinedTermBase")
84
	@Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE})
85
	@IndexedEmbedded(depth = 2)
86
	protected Set<T> terms = newTermSet();
87

    
88
    private ExternallyManaged externallyManaged;
89

    
90
// ********************************* FACTORY METHODS *****************************************/
91

    
92

    
93
	public static TermVocabulary NewInstance(TermType type){
94
		return new TermVocabulary(type);
95
	}
96

    
97
	public static <T extends DefinedTermBase<T>> TermVocabulary<T> NewInstance(TermType type, Class<T> clazz){
98
		return new TermVocabulary<T>(type);
99
	}
100

    
101
	/**
102
	 * @deprecated use {@link #NewInstance(TermType, Class, String, String, String, URI)} instead
103
	 */
104
	@Deprecated
105
	public static TermVocabulary NewInstance(TermType type, String description, String label, String abbrev, URI termSourceUri){
106
		return new TermVocabulary(type, description, label, abbrev, termSourceUri);
107
	}
108

    
109
    public static <T extends DefinedTermBase<T>> TermVocabulary<T> NewInstance(TermType type, Class<T> clazz, String description, String label, String abbrev, URI termSourceUri){
110
        return new TermVocabulary<T>(type, description, label, abbrev, termSourceUri);
111
    }
112

    
113
// ************************* CONSTRUCTOR *************************************************
114

    
115
	//for hibernate use only
116
	@Deprecated
117
	protected TermVocabulary() {
118
		super(TermType.Unknown);
119
	}
120

    
121
	protected TermVocabulary(TermType type) {
122
		super(type);
123
	}
124

    
125
	protected TermVocabulary(TermType type, String term, String label, String labelAbbrev, URI termSourceUri) {
126
		super(type, term, label, labelAbbrev);
127
		setTermSourceUri(termSourceUri);
128
	}
129

    
130

    
131
	protected Set<T> newTermSet(){
132
	    return new HashSet<>();
133
	}
134

    
135
// ******************* METHODS *************************************************/
136

    
137
	public T findTermByUuid(UUID uuid){
138
		for(T t : terms) {
139
			if(t.getUuid().equals(uuid)) {
140
				return t;
141
			}
142
		}
143
		return null;
144
	}
145

    
146

    
147
	public Set<T> getTerms() {
148
		return terms;
149
	}
150

    
151
	public void addTerm(T term) {
152
	    checkTermType(term);
153
		term.setVocabulary(this);
154
		this.terms.add(term);
155
	}
156
	public void removeTerm(T term) {
157
		this.terms.remove(term);
158
		term.setVocabulary(null);
159
	}
160

    
161
	public URI getTermSourceUri() {
162
		return termSourceUri;
163
	}
164
	public void setTermSourceUri(URI vocabularyUri) {
165
		this.termSourceUri = vocabularyUri;
166
	}
167

    
168
	@Deprecated //deprecated for now as only needed for property path handling; but may become generally public in future
169
    public Set<TermNode> getTermRelations() {
170
        return super.termRelations();
171
    }
172

    
173
    /**
174
     * Returns the first term found having the defined idInVocabulary.
175
     * If number of terms with given idInVoc > 1 the result is not deterministic.
176
     * @param idInVoc
177
     * @return the term with the given idInVoc
178
     */
179
    public T getTermByIdInvocabulary(String idInVoc) {
180
        for (T term : getTerms() ){
181
            if (CdmUtils.nullSafeEqual(idInVoc, term.getIdInVocabulary())){
182
                return term;
183
            }
184
        }
185
        return null;
186
    }
187

    
188
	public int size(){
189
		return terms.size();
190
	}
191

    
192
	/**
193
	 * Returns all terms of this vocabulary sorted by their representation defined by the given language.
194
	 * If such an representation does not exist, the representation of the default language is testing instead for ordering.
195
	 * @param language
196
	 * @return
197
	 */
198
	public SortedSet<T> getTermsOrderedByLabels(Language language){
199
		TermLanguageComparator<T> comp = new TermLanguageComparator<>();
200
		comp.setCompareLanguage(language);
201

    
202
		SortedSet<T> result = new TreeSet<>(comp);
203
		result.addAll(getTerms());
204
		return result;
205
	}
206

    
207

    
208
	public TermVocabulary<T> readCsvLine(List<String> csvLine) {
209
		return readCsvLine(csvLine, Language.CSV_LANGUAGE());
210
	}
211

    
212
	public TermVocabulary<T> readCsvLine(List<String> csvLine, Language lang) {
213
		this.setUuid(UUID.fromString(csvLine.get(0)));
214
        String uriStr = CdmUtils.Ne(csvLine.get(1));
215
        this.setUri(uriStr == null? null: URI.create(uriStr));
216
		String label = csvLine.get(2).trim();
217
		String description = csvLine.get(3);
218

    
219
		//see  https://dev.e-taxonomy.eu/redmine/issues/3550
220
		this.addRepresentation(Representation.NewInstance(description, label, null, lang) );
221

    
222
		TermType termType = TermType.getByKey(csvLine.get(4));
223
		if (termType == null){
224
			throw new IllegalArgumentException("TermType can not be mapped: " + csvLine.get(4));
225
		}
226
		this.setTermType(termType);
227

    
228
		return this;
229
	}
230

    
231
	/**
232
     * Throws {@link IllegalArgumentException} if the given
233
     * term has not the same term type as this term or if term type is null.
234
     * @param term
235
     */
236
    private void checkTermType(IHasTermType term) {
237
        IHasTermType.checkTermTypes(term, this);
238
    }
239

    
240
//*********************** CLONE ********************************************************/
241

    
242
	/**
243
	 * Clones <i>this</i> TermVocabulary. This is a shortcut that enables to create
244
	 * a new instance that differs only slightly from <i>this</i> TermVocabulary.
245
	 * The terms of the original vocabulary are cloned
246
	 *
247
	 * @see eu.etaxonomy.cdm.model.term.TermBase#clone()
248
	 * @see java.lang.Object#clone()
249
	 */
250
	@Override
251
	public TermVocabulary<T> clone() {
252
		TermVocabulary<T> result;
253
		try {
254
			result = (TermVocabulary<T>) super.clone();
255

    
256
		}catch (CloneNotSupportedException e) {
257
			logger.warn("Object does not implement cloneable");
258
			e.printStackTrace();
259
			return null;
260
		}
261
		result.terms = new HashSet<T>();
262
		for (T term: this.terms){
263
			result.addTerm((T)term.clone());
264
		}
265

    
266
		return result;
267
	}
268
}
(31-31/33)