Project

General

Profile

Download (7.38 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.common;
11

    
12

    
13
import java.net.URI;
14
import java.util.HashSet;
15
import java.util.Iterator;
16
import java.util.List;
17
import java.util.Set;
18
import java.util.SortedSet;
19
import java.util.TreeSet;
20
import java.util.UUID;
21

    
22
import javax.persistence.Entity;
23
import javax.persistence.FetchType;
24
import javax.persistence.Inheritance;
25
import javax.persistence.InheritanceType;
26
import javax.persistence.OneToMany;
27
import javax.persistence.Transient;
28
import javax.xml.bind.annotation.XmlAccessType;
29
import javax.xml.bind.annotation.XmlAccessorType;
30
import javax.xml.bind.annotation.XmlElement;
31
import javax.xml.bind.annotation.XmlElementWrapper;
32
import javax.xml.bind.annotation.XmlIDREF;
33
import javax.xml.bind.annotation.XmlRootElement;
34
import javax.xml.bind.annotation.XmlSchemaType;
35
import javax.xml.bind.annotation.XmlType;
36

    
37
import org.apache.log4j.Logger;
38
import org.hibernate.annotations.Cascade;
39
import org.hibernate.annotations.CascadeType;
40
import org.hibernate.annotations.Type;
41
import org.hibernate.envers.Audited;
42
import org.hibernate.search.annotations.Analyze;
43
import org.hibernate.search.annotations.Field;
44
import org.hibernate.search.annotations.IndexedEmbedded;
45

    
46
import eu.etaxonomy.cdm.common.CdmUtils;
47

    
48

    
49
/**
50
 * A single enumeration must only contain DefinedTerm instances of one kind
51
 * (this means a subclass of DefinedTerm).
52
 * @author m.doering
53
 * @created 08-Nov-2007 13:06:23
54
 */
55
@XmlAccessorType(XmlAccessType.FIELD)
56
@XmlType(name = "TermVocabulary", propOrder = {
57
    "termSourceUri",
58
    "terms"
59
})
60
@XmlRootElement(name = "TermVocabulary")
61
@Entity
62
//@Indexed disabled to reduce clutter in indexes, since this type is not used by any search
63
//@Indexed(index = "eu.etaxonomy.cdm.model.common.TermVocabulary")
64
@Audited
65
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
66
public class TermVocabulary<T extends DefinedTermBase> extends TermBase implements Iterable<T> {
67
	private static final long serialVersionUID = 1925052321596648672L;
68
	private static final Logger logger = Logger.getLogger(TermVocabulary.class);
69

    
70
	//The vocabulary source (e.g. ontology) defining the terms to be loaded when a database 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

    
79
	//TODO Changed
80
	@XmlElementWrapper(name = "Terms")
81
	@XmlElement(name = "Term")
82
    @XmlIDREF
83
    @XmlSchemaType(name = "IDREF")
84
    @OneToMany(mappedBy="vocabulary", fetch=FetchType.LAZY, targetEntity = DefinedTermBase.class)
85
	@Type(type="DefinedTermBase")
86
	@Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE})
87
	@IndexedEmbedded(depth = 2)
88
	protected Set<T> terms = getNewTermSet();
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
	public static TermVocabulary NewInstance(TermType type, String description, String label, String abbrev, URI termSourceUri){
102
		return new TermVocabulary(type, description, label, abbrev, termSourceUri);
103
	}
104

    
105
// ************************* CONSTRUCTOR *************************************************
106

    
107
	//for hibernate use only
108
	@Deprecated
109
	protected TermVocabulary() {
110
		super(TermType.Unknown);
111
	}
112

    
113
	protected TermVocabulary(TermType type) {
114
		super(type);
115
	}
116

    
117
	protected TermVocabulary(TermType type, String term, String label, String labelAbbrev, URI termSourceUri) {
118
		super(type, term, label, labelAbbrev);
119
		setTermSourceUri(termSourceUri);
120
	}
121

    
122

    
123
// ******************* METHODS *************************************************/
124

    
125
	public T findTermByUuid(UUID uuid){
126
		for(T t : terms) {
127
			if(t.getUuid().equals(uuid)) {
128
				return t;
129
			}
130
		}
131
		return null;
132
	}
133

    
134
	@Transient
135
	Set<T> getNewTermSet() {
136
		return new HashSet<T>();
137
	}
138

    
139
	public Set<T> getTerms() {
140
		return terms;
141
	}
142

    
143
	public void addTerm(T term) {
144
		term.setVocabulary(this);
145
		this.terms.add(term);
146
	}
147
	public void removeTerm(T term) {
148
		this.terms.remove(term);
149
		term.setVocabulary(null);
150
	}
151

    
152
	public URI getTermSourceUri() {
153
		return termSourceUri;
154
	}
155
	public void setTermSourceUri(URI vocabularyUri) {
156
		this.termSourceUri = vocabularyUri;
157
	}
158

    
159
    /**
160
     * Returns the first term found having the defined idInVocabulary.
161
     * If number of terms with given idInVoc > 1 the result is not deterministic.
162
     * @param idInVoc
163
     * @return the term with the given idInVoc
164
     */
165
    public T getTermByIdInvocabulary(String idInVoc) {
166
        for (T term : getTerms() ){
167
            if (CdmUtils.nullSafeEqual(idInVoc, term.getIdInVocabulary())){
168
                return term;
169
            }
170
        }
171
        return null;
172
    }
173

    
174
	@Override
175
    public Iterator<T> iterator() {
176
		return terms.iterator();  // OLD: new TermIterator<T>(this.terms);
177
	}
178

    
179
	public int size(){
180
		return terms.size();
181
	}
182

    
183

    
184
	/**
185
	 * Returns all terms of this vocabulary sorted by their representation defined by the given language.
186
	 * If such an representation does not exist, the representation of the default language is testing instead for ordering.
187
	 * @param language
188
	 * @return
189
	 */
190
	public SortedSet<T> getTermsOrderedByLabels(Language language){
191
		TermLanguageComparator<T> comp = new TermLanguageComparator<T>();
192
		comp.setCompareLanguage(language);
193

    
194
		SortedSet<T> result = new TreeSet<T>(comp);
195
		result.addAll(getTerms());
196
		return result;
197
	}
198

    
199

    
200
	/* (non-Javadoc)
201
	 * @see eu.etaxonomy.cdm.model.common.ILoadableTerm#readCsvLine(java.util.List)
202
	 */
203
	public TermVocabulary<T> readCsvLine(List<String> csvLine) {
204
		return readCsvLine(csvLine, Language.CSV_LANGUAGE());
205
	}
206

    
207
	public TermVocabulary<T> readCsvLine(List<String> csvLine, Language lang) {
208
		this.setUuid(UUID.fromString(csvLine.get(0)));
209
		this.setUri(URI.create(csvLine.get(1)));
210
		String label = csvLine.get(2).trim();
211
		String description = csvLine.get(3);
212

    
213
		//see  http://dev.e-taxonomy.eu/trac/ticket/3550
214
		this.addRepresentation(Representation.NewInstance(description, label, null, lang) );
215

    
216
		TermType termType = TermType.getByKey(csvLine.get(4));
217
		if (termType == null){
218
			throw new IllegalArgumentException("TermType can not be mapped: " + csvLine.get(4));
219
		}
220
		this.setTermType(termType);
221

    
222
		return this;
223
	}
224

    
225
//*********************** CLONE ********************************************************/
226

    
227
	/**
228
	 * Clones <i>this</i> TermVocabulary. This is a shortcut that enables to create
229
	 * a new instance that differs only slightly from <i>this</i> TermVocabulary.
230
	 * The terms of the original vocabulary are cloned
231
	 *
232
	 * @see eu.etaxonomy.cdm.model.common.TermBase#clone()
233
	 * @see java.lang.Object#clone()
234
	 */
235
	@Override
236
	public Object clone() {
237
		TermVocabulary<T> result;
238
		try {
239
			result = (TermVocabulary<T>) super.clone();
240

    
241
		}catch (CloneNotSupportedException e) {
242
			logger.warn("Object does not implement cloneable");
243
			e.printStackTrace();
244
			return null;
245
		}
246
		result.terms = new HashSet<T>();
247
		for (T term: this.terms){
248
			result.addTerm((T)term.clone());
249
		}
250

    
251
		return result;
252
	}
253
}
(65-65/72)