reintroducing transient getters where required for cdm-remote; removing cast from...
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / common / TermVocabulary.java
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.util.HashSet;
14 import java.util.Iterator;
15 import java.util.List;
16 import java.util.Set;
17 import java.util.SortedSet;
18 import java.util.TreeSet;
19 import java.util.UUID;
20
21 import javax.persistence.Entity;
22 import javax.persistence.FetchType;
23 import javax.persistence.Inheritance;
24 import javax.persistence.InheritanceType;
25 import javax.persistence.OneToMany;
26 import javax.persistence.Transient;
27 import javax.xml.bind.annotation.XmlAccessType;
28 import javax.xml.bind.annotation.XmlAccessorType;
29 import javax.xml.bind.annotation.XmlElement;
30 import javax.xml.bind.annotation.XmlElementWrapper;
31 import javax.xml.bind.annotation.XmlIDREF;
32 import javax.xml.bind.annotation.XmlRootElement;
33 import javax.xml.bind.annotation.XmlSchemaType;
34 import javax.xml.bind.annotation.XmlType;
35
36 import org.apache.log4j.Logger;
37 import org.hibernate.annotations.Cascade;
38 import org.hibernate.annotations.CascadeType;
39 import org.hibernate.annotations.Type;
40 import org.hibernate.envers.Audited;
41
42
43 /**
44 * A single enumeration must only contain DefinedTerm instances of one kind
45 * (this means a subclass of DefinedTerm).
46 * @author m.doering
47 * @version 1.0
48 * @created 08-Nov-2007 13:06:23
49 */
50 @XmlAccessorType(XmlAccessType.FIELD)
51 @XmlType(name = "TermVocabulary", propOrder = {
52 "termSourceUri",
53 "terms"
54 })
55 @XmlRootElement(name = "TermVocabulary")
56 @Entity
57 @Audited
58 @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
59 public class TermVocabulary<T extends DefinedTermBase> extends TermBase implements Iterable<T> {
60 private static final long serialVersionUID = 1925052321596648672L;
61 @SuppressWarnings("unused")
62 private static final Logger logger = Logger.getLogger(TermVocabulary.class);
63
64 //The vocabulary source (e.g. ontology) defining the terms to be loaded when a database is created for the first time.
65 // Software can go and grap these terms incl labels and description.
66 // UUID needed? Further vocs can be setup through our own ontology.
67 @XmlElement(name = "TermSourceURI")
68 private String termSourceUri;
69
70
71 //TODO Changed
72 @XmlElementWrapper(name = "Terms")
73 @XmlElement(name = "Term")
74 @XmlIDREF
75 @XmlSchemaType(name = "IDREF")
76 @OneToMany(mappedBy="vocabulary", fetch=FetchType.LAZY, targetEntity = DefinedTermBase.class)
77 @Type(type="DefinedTermBase")
78 @Cascade({CascadeType.SAVE_UPDATE})
79 protected Set<T> terms = getNewTermSet();
80
81 public T findTermByUuid(UUID uuid){
82 for(T t : terms) {
83 if(t.getUuid().equals(uuid)) {
84 return t;
85 }
86 }
87 return null;
88 }
89
90 public TermVocabulary(String term, String label, String labelAbbrev, String termSourceUri) {
91 super(term, label, labelAbbrev);
92 setTermSourceUri(termSourceUri);
93 }
94
95 public TermVocabulary() {
96 // TODO Auto-generated constructor stub
97 }
98
99 @Transient
100 Set<T> getNewTermSet() {
101 return new HashSet<T>();
102 }
103
104 public Set<T> getTerms() {
105 return terms;
106 }
107
108 public void addTerm(T term) {
109 term.setVocabulary(this);
110 this.terms.add(term);
111 }
112 public void removeTerm(T term) {
113 term.setVocabulary(null);
114 this.terms.remove(term);
115 }
116
117 public String getTermSourceUri() {
118 return termSourceUri;
119 }
120 public void setTermSourceUri(String vocabularyUri) {
121 this.termSourceUri = vocabularyUri;
122 }
123
124
125 // // inner iterator class for the iterable interface
126 // private class TermIterator<T> implements Iterator<T> {
127 // // FIXME: using a list here is probably not safe. Sth passed by value, an array, would be better
128 // // but arrays cause generics problems: http://forum.java.sun.com/thread.jspa?threadID=651276&messageID=3832182
129 // // hack for now ;(
130 // private Set<T> array;
131 // private int i= 0;
132 // // ctor
133 // public TermIterator(Set<T> array) {
134 // // check for null being passed in etc.
135 // this.array= array;
136 // }
137 // // interface implementation
138 // public boolean hasNext() { return i < array.size(); }
139 // public T next() { return array.get(i++); }
140 // public void remove() { throw new UnsupportedOperationException(); }
141 // }
142
143 public Iterator<T> iterator() {
144 return terms.iterator(); // OLD: new TermIterator<T>(this.terms);
145 }
146
147 public int size(){
148 return terms.size();
149 }
150
151
152 /**
153 * Returns all terms of this vocabulary sorted by their representation defined by the given language.
154 * If such an representation does not exist, the representation of the default language is testing instead for ordering.
155 * @param language
156 * @return
157 */
158 public SortedSet<T> getTermsOrderedByLabels(Language language){
159 TermLanguageComparator<T> comp = new TermLanguageComparator<T>();
160 comp.setCompareLanguage(language);
161
162 SortedSet<T> result = new TreeSet<T>(comp);
163 result.addAll(getTerms());
164 return result;
165 }
166
167
168 /* (non-Javadoc)
169 * @see eu.etaxonomy.cdm.model.common.ILoadableTerm#readCsvLine(java.util.List)
170 */
171 public TermVocabulary<T> readCsvLine(List<String> csvLine) {
172 return readCsvLine(csvLine, Language.ENGLISH());
173 }
174
175 public TermVocabulary<T> readCsvLine(List<String> csvLine, Language lang) {
176 this.setUuid(UUID.fromString(csvLine.get(0)));
177 this.setUri(csvLine.get(1));
178 //this.addRepresentation(Representation.NewInstance(csvLine.get(3), csvLine.get(2).trim(), lang) );
179 return this;
180 }
181
182 }