1 |
9479da48
|
Andreas Müller
|
/**
|
2 |
|
|
* Copyright (C) 2007 EDIT
|
3 |
ad190552
|
Andreas Kohlbecker
|
* European Distributed Institute of Taxonomy
|
4 |
9479da48
|
Andreas Müller
|
* http://www.e-taxonomy.eu
|
5 |
ad190552
|
Andreas Kohlbecker
|
*
|
6 |
9479da48
|
Andreas Müller
|
* 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 |
533cbb43
|
Andreas Müller
|
import java.lang.reflect.Constructor;
|
13 |
f7f4a80d
|
Andreas Müller
|
import java.net.URI;
|
14 |
ee91bcd9
|
ben.clark
|
import java.util.HashSet;
|
15 |
|
|
import java.util.List;
|
16 |
|
|
import java.util.Map;
|
17 |
|
|
import java.util.Set;
|
18 |
|
|
import java.util.UUID;
|
19 |
9479da48
|
Andreas Müller
|
|
20 |
974e7f9a
|
Andreas Müller
|
import javax.persistence.Column;
|
21 |
ee91bcd9
|
ben.clark
|
import javax.persistence.Entity;
|
22 |
|
|
import javax.persistence.FetchType;
|
23 |
|
|
import javax.persistence.Inheritance;
|
24 |
|
|
import javax.persistence.InheritanceType;
|
25 |
0a6f2f53
|
Andreas Müller
|
import javax.persistence.ManyToMany;
|
26 |
ee91bcd9
|
ben.clark
|
import javax.persistence.ManyToOne;
|
27 |
|
|
import javax.persistence.OneToMany;
|
28 |
b70a7f94
|
Andreas Kohlbecker
|
import javax.persistence.Transient;
|
29 |
70440a7d
|
a.babadshanjan
|
import javax.xml.bind.annotation.XmlAccessType;
|
30 |
|
|
import javax.xml.bind.annotation.XmlAccessorType;
|
31 |
|
|
import javax.xml.bind.annotation.XmlElement;
|
32 |
|
|
import javax.xml.bind.annotation.XmlElementWrapper;
|
33 |
c4c118de
|
a.babadshanjan
|
import javax.xml.bind.annotation.XmlIDREF;
|
34 |
70440a7d
|
a.babadshanjan
|
import javax.xml.bind.annotation.XmlRootElement;
|
35 |
c4c118de
|
a.babadshanjan
|
import javax.xml.bind.annotation.XmlSchemaType;
|
36 |
c9866164
|
ben.clark
|
import javax.xml.bind.annotation.XmlSeeAlso;
|
37 |
|
|
import javax.xml.bind.annotation.XmlTransient;
|
38 |
70440a7d
|
a.babadshanjan
|
import javax.xml.bind.annotation.XmlType;
|
39 |
9479da48
|
Andreas Müller
|
|
40 |
ee91bcd9
|
ben.clark
|
import org.apache.log4j.Logger;
|
41 |
1631c353
|
Andreas Müller
|
import org.codehaus.plexus.util.StringUtils;
|
42 |
ee91bcd9
|
ben.clark
|
import org.hibernate.annotations.Cascade;
|
43 |
|
|
import org.hibernate.annotations.CascadeType;
|
44 |
|
|
import org.hibernate.envers.Audited;
|
45 |
c7f65649
|
Andreas Kohlbecker
|
import org.hibernate.proxy.HibernateProxy;
|
46 |
|
|
import org.hibernate.proxy.LazyInitializer;
|
47 |
ad190552
|
Andreas Kohlbecker
|
import org.hibernate.search.annotations.ClassBridge;
|
48 |
ee91bcd9
|
ben.clark
|
|
49 |
|
|
import au.com.bytecode.opencsv.CSVWriter;
|
50 |
ad190552
|
Andreas Kohlbecker
|
import eu.etaxonomy.cdm.hibernate.search.DefinedTermBaseClassBridge;
|
51 |
933e5ac3
|
Cherian Mathew
|
import eu.etaxonomy.cdm.model.ICdmUuidCacher;
|
52 |
c9866164
|
ben.clark
|
import eu.etaxonomy.cdm.model.description.Feature;
|
53 |
|
|
import eu.etaxonomy.cdm.model.description.MeasurementUnit;
|
54 |
|
|
import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
|
55 |
|
|
import eu.etaxonomy.cdm.model.description.TextFormat;
|
56 |
|
|
import eu.etaxonomy.cdm.model.location.NamedAreaType;
|
57 |
|
|
import eu.etaxonomy.cdm.model.location.ReferenceSystem;
|
58 |
ee91bcd9
|
ben.clark
|
import eu.etaxonomy.cdm.model.media.Media;
|
59 |
ff3882c8
|
Andreas Müller
|
import eu.etaxonomy.cdm.model.media.RightsType;
|
60 |
c9866164
|
ben.clark
|
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
|
61 |
|
|
import eu.etaxonomy.cdm.model.occurrence.DerivationEventType;
|
62 |
|
|
import eu.etaxonomy.cdm.model.occurrence.PreservationMethod;
|
63 |
ee91bcd9
|
ben.clark
|
|
64 |
fbd23d1d
|
Andreas Müller
|
|
65 |
9479da48
|
Andreas Müller
|
/**
|
66 |
02dc229b
|
Andreas Kohlbecker
|
* workaround for enumerations, base type according to TDWG. For linear ordering
|
67 |
9479da48
|
Andreas Müller
|
* use partOf relation and BreadthFirst. Default iterator order should therefore
|
68 |
|
|
* be BreadthFirst (not DepthFirst)
|
69 |
|
|
* @author m.doering
|
70 |
|
|
* @created 08-Nov-2007 13:06:19
|
71 |
|
|
*/
|
72 |
70440a7d
|
a.babadshanjan
|
@XmlAccessorType(XmlAccessType.FIELD)
|
73 |
|
|
@XmlType(name = "DefinedTermBase", propOrder = {
|
74 |
|
|
"media",
|
75 |
efa9828a
|
Andreas Müller
|
"vocabulary",
|
76 |
73b20217
|
Andreas Müller
|
"idInVocabulary",
|
77 |
|
|
"symbol"
|
78 |
70440a7d
|
a.babadshanjan
|
})
|
79 |
|
|
@XmlRootElement(name = "DefinedTermBase")
|
80 |
c9866164
|
ben.clark
|
@XmlSeeAlso({
|
81 |
ad190552
|
Andreas Kohlbecker
|
AnnotationType.class,
|
82 |
|
|
DerivationEventType.class,
|
83 |
533cbb43
|
Andreas Müller
|
DefinedTerm.class,
|
84 |
ad190552
|
Andreas Kohlbecker
|
ExtensionType.class,
|
85 |
c9866164
|
ben.clark
|
Feature.class,
|
86 |
|
|
Language.class,
|
87 |
|
|
MarkerType.class,
|
88 |
|
|
MeasurementUnit.class,
|
89 |
|
|
NamedAreaType.class,
|
90 |
|
|
NomenclaturalCode.class,
|
91 |
|
|
PreservationMethod.class,
|
92 |
|
|
ReferenceSystem.class,
|
93 |
ff3882c8
|
Andreas Müller
|
RightsType.class,
|
94 |
c9866164
|
ben.clark
|
StatisticalMeasure.class,
|
95 |
828f8b96
|
a.babadshanjan
|
TextFormat.class
|
96 |
c9866164
|
ben.clark
|
})
|
97 |
9479da48
|
Andreas Müller
|
@Entity
|
98 |
ee91bcd9
|
ben.clark
|
@Audited
|
99 |
9479da48
|
Andreas Müller
|
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
|
100 |
ad190552
|
Andreas Kohlbecker
|
@ClassBridge(impl=DefinedTermBaseClassBridge.class)
|
101 |
589ecf52
|
Andreas Müller
|
//TODO Comparable implemented only for fixing failing JAXB import, may be removed when this is fixed
|
102 |
|
|
public abstract class DefinedTermBase<T extends DefinedTermBase> extends TermBase implements ILoadableTerm<T>, IDefinedTerm<T>, Comparable<T> {
|
103 |
ad190552
|
Andreas Kohlbecker
|
private static final long serialVersionUID = 2931811562248571531L;
|
104 |
|
|
private static final Logger logger = Logger.getLogger(DefinedTermBase.class);
|
105 |
|
|
|
106 |
c9866164
|
ben.clark
|
// @XmlElement(name = "KindOf")
|
107 |
|
|
// @XmlIDREF
|
108 |
|
|
// @XmlSchemaType(name = "IDREF")
|
109 |
ad190552
|
Andreas Kohlbecker
|
@XmlTransient
|
110 |
ee91bcd9
|
ben.clark
|
@ManyToOne(fetch = FetchType.LAZY, targetEntity = DefinedTermBase.class)
|
111 |
903cecc9
|
Cherian Mathew
|
@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
|
112 |
ad190552
|
Andreas Kohlbecker
|
private T kindOf;
|
113 |
|
|
/**
|
114 |
ee91b8fd
|
Andreas Kohlbecker
|
* FIXME - Hibernate returns this as a collection of CGLibProxy$$DefinedTermBase objects
|
115 |
ad190552
|
Andreas Kohlbecker
|
* which can't be cast to instances of T - can we explicitly initialize these terms using
|
116 |
|
|
* Hibernate.initialize(), does this imply a distinct load, and find methods in the dao?
|
117 |
|
|
*/
|
118 |
c9866164
|
ben.clark
|
// @XmlElementWrapper(name = "Generalizations")
|
119 |
|
|
// @XmlElement(name = "GeneralizationOf")
|
120 |
|
|
// @XmlIDREF
|
121 |
|
|
// @XmlSchemaType(name = "IDREF")
|
122 |
ad190552
|
Andreas Kohlbecker
|
@XmlTransient
|
123 |
ee91bcd9
|
ben.clark
|
@OneToMany(fetch=FetchType.LAZY, mappedBy = "kindOf", targetEntity = DefinedTermBase.class)
|
124 |
903cecc9
|
Cherian Mathew
|
@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
|
125 |
ad190552
|
Andreas Kohlbecker
|
private Set<T> generalizationOf = new HashSet<T>();
|
126 |
|
|
|
127 |
c9866164
|
ben.clark
|
// @XmlElement(name = "PartOf")
|
128 |
|
|
// @XmlIDREF
|
129 |
|
|
// @XmlSchemaType(name = "IDREF")
|
130 |
ad190552
|
Andreas Kohlbecker
|
@XmlTransient
|
131 |
|
|
@ManyToOne(fetch = FetchType.LAZY, targetEntity = DefinedTermBase.class)
|
132 |
903cecc9
|
Cherian Mathew
|
@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
|
133 |
ad190552
|
Andreas Kohlbecker
|
protected T partOf;
|
134 |
|
|
|
135 |
|
|
/**
|
136 |
|
|
* FIXME - Hibernate retuns this as a collection of CGLibProxy$$DefinedTermBase objects
|
137 |
|
|
* which can't be cast to instances of T - can we explicitly initialize these terms using
|
138 |
|
|
* Hibernate.initialize(), does this imply a distinct load, and find methods in the dao?
|
139 |
|
|
*/
|
140 |
c9866164
|
ben.clark
|
// @XmlElementWrapper(name = "Includes")
|
141 |
|
|
// @XmlElement(name = "Include")
|
142 |
|
|
// @XmlIDREF
|
143 |
|
|
// @XmlSchemaType(name = "IDREF")
|
144 |
ad190552
|
Andreas Kohlbecker
|
@XmlTransient
|
145 |
|
|
@OneToMany(fetch=FetchType.LAZY, mappedBy = "partOf", targetEntity = DefinedTermBase.class)
|
146 |
903cecc9
|
Cherian Mathew
|
@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
|
147 |
ad190552
|
Andreas Kohlbecker
|
private Set<T> includes = new HashSet<T>();
|
148 |
|
|
|
149 |
|
|
@XmlElementWrapper(name = "Media")
|
150 |
|
|
@XmlElement(name = "Medium")
|
151 |
0ae18eec
|
a.babadshanjan
|
@XmlIDREF
|
152 |
|
|
@XmlSchemaType(name = "IDREF")
|
153 |
0a6f2f53
|
Andreas Müller
|
@ManyToMany(fetch = FetchType.LAZY)
|
154 |
903cecc9
|
Cherian Mathew
|
@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
|
155 |
ad190552
|
Andreas Kohlbecker
|
private Set<Media> media = new HashSet<Media>();
|
156 |
|
|
|
157 |
|
|
@XmlElement(name = "TermVocabulary")
|
158 |
|
|
@XmlIDREF
|
159 |
|
|
@XmlSchemaType(name = "IDREF")
|
160 |
|
|
@ManyToOne(fetch=FetchType.LAZY)
|
161 |
c53e35a3
|
Andreas Müller
|
// @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE}) remove cascading #5754
|
162 |
ad190552
|
Andreas Kohlbecker
|
protected TermVocabulary<T> vocabulary;
|
163 |
ee91b8fd
|
Andreas Kohlbecker
|
|
164 |
c53e35a3
|
Andreas Müller
|
//the unique iedentifier/name this term uses in its given vocabulary #3479
|
165 |
efa9828a
|
Andreas Müller
|
@XmlElement(name = "idInVocabulary")
|
166 |
974e7f9a
|
Andreas Müller
|
@Column(length=255)
|
167 |
d6fcdafc
|
Andreas M��ller
|
//TODO Val #3379, #4245
|
168 |
|
|
// @NullOrNotEmpty
|
169 |
ed0e00d0
|
Andreas Müller
|
private String idInVocabulary; //the unique identifier/name this term uses in its given vocabulary #3479
|
170 |
903cecc9
|
Cherian Mathew
|
|
171 |
73b20217
|
Andreas Müller
|
@XmlElement(name = "symbol")
|
172 |
47e005aa
|
Andreas Müller
|
@Column(length=30)
|
173 |
73b20217
|
Andreas Müller
|
//the symbol to be used in String representations for this term #5734
|
174 |
|
|
//this term can be changed by the database instance even if the term is not managed by this instance as it is only for representation and has no semantic or identifying character
|
175 |
|
|
//empty string is explicitly allowed and should be distinguished from NULL!
|
176 |
|
|
private String symbol;
|
177 |
ad190552
|
Andreas Kohlbecker
|
|
178 |
|
|
//***************************** CONSTRUCTOR *******************************************/
|
179 |
|
|
|
180 |
d0b0c36b
|
Andreas Müller
|
//for javassit only
|
181 |
9e3239f6
|
Andreas Müller
|
@Deprecated
|
182 |
|
|
protected DefinedTermBase(){};
|
183 |
ee91b8fd
|
Andreas Kohlbecker
|
|
184 |
9e3239f6
|
Andreas Müller
|
protected DefinedTermBase(TermType type) {
|
185 |
|
|
super(type);
|
186 |
ad190552
|
Andreas Kohlbecker
|
}
|
187 |
533cbb43
|
Andreas Müller
|
public DefinedTermBase(TermType type, String description, String label, String labelAbbrev) {
|
188 |
|
|
super(type, description, label, labelAbbrev);
|
189 |
ad190552
|
Andreas Kohlbecker
|
}
|
190 |
9479da48
|
Andreas Müller
|
|
191 |
ad190552
|
Andreas Kohlbecker
|
|
192 |
ee91b8fd
|
Andreas Kohlbecker
|
//********************** GETTER /SETTER *************************************
|
193 |
|
|
|
194 |
|
|
@Override
|
195 |
|
|
public String getIdInVocabulary() {
|
196 |
|
|
return idInVocabulary;
|
197 |
|
|
}
|
198 |
|
|
|
199 |
|
|
@Override
|
200 |
|
|
public void setIdInVocabulary(String idInVocabulary) {
|
201 |
d6fcdafc
|
Andreas M��ller
|
|
202 |
85147fc2
|
Katja Luther
|
this.idInVocabulary = StringUtils.isBlank(idInVocabulary)? null : idInVocabulary;
|
203 |
ee91b8fd
|
Andreas Kohlbecker
|
}
|
204 |
|
|
|
205 |
|
|
@Override
|
206 |
221619fa
|
Andreas Müller
|
public T getKindOf(){
|
207 |
c7f65649
|
Andreas Kohlbecker
|
|
208 |
|
|
if (this instanceof HibernateProxy) {
|
209 |
|
|
HibernateProxy proxy = (HibernateProxy) this;
|
210 |
|
|
LazyInitializer li = proxy.getHibernateLazyInitializer();
|
211 |
|
|
return (T) ((T)li.getImplementation()).getKindOf();
|
212 |
|
|
} else {
|
213 |
|
|
return (T)DefinedTermBase.deproxy(this.kindOf, this.getClass());
|
214 |
|
|
}
|
215 |
efa9828a
|
Andreas Müller
|
}
|
216 |
|
|
|
217 |
|
|
public void setKindOf(T kindOf){
|
218 |
|
|
this.kindOf = kindOf;
|
219 |
|
|
}
|
220 |
|
|
|
221 |
42414138
|
Andreas Müller
|
|
222 |
|
|
@Override
|
223 |
efa9828a
|
Andreas Müller
|
public Set<T> getGeneralizationOf(){
|
224 |
|
|
return this.generalizationOf;
|
225 |
|
|
}
|
226 |
|
|
|
227 |
|
|
protected void setGeneralizationOf(Set<T> value) {
|
228 |
|
|
this.generalizationOf = value;
|
229 |
|
|
}
|
230 |
|
|
|
231 |
|
|
public void addGeneralizationOf(T generalization) {
|
232 |
|
|
generalization.setKindOf(this);
|
233 |
|
|
this.generalizationOf.add(generalization);
|
234 |
|
|
}
|
235 |
|
|
|
236 |
221619fa
|
Andreas Müller
|
|
237 |
efa9828a
|
Andreas Müller
|
public void removeGeneralization(T generalization) {
|
238 |
|
|
if(generalizationOf.contains(generalization)){
|
239 |
|
|
generalization.setKindOf(null);
|
240 |
|
|
this.generalizationOf.remove(generalization);
|
241 |
|
|
}
|
242 |
|
|
}
|
243 |
|
|
|
244 |
42414138
|
Andreas Müller
|
@Override
|
245 |
efa9828a
|
Andreas Müller
|
public T getPartOf(){
|
246 |
c7f65649
|
Andreas Kohlbecker
|
if (this instanceof HibernateProxy) {
|
247 |
|
|
HibernateProxy proxy = (HibernateProxy) this;
|
248 |
|
|
LazyInitializer li = proxy.getHibernateLazyInitializer();
|
249 |
|
|
return (T) ((T)li.getImplementation()).getPartOf();
|
250 |
|
|
} else {
|
251 |
|
|
return (T)DefinedTermBase.deproxy(this.partOf, this.getClass());
|
252 |
|
|
}
|
253 |
efa9828a
|
Andreas Müller
|
}
|
254 |
|
|
|
255 |
42414138
|
Andreas Müller
|
/**
|
256 |
|
|
* @see #getPartOf()
|
257 |
|
|
*/
|
258 |
efa9828a
|
Andreas Müller
|
public void setPartOf(T partOf){
|
259 |
|
|
this.partOf = partOf;
|
260 |
|
|
}
|
261 |
903cecc9
|
Cherian Mathew
|
|
262 |
|
|
|
263 |
589ecf52
|
Andreas Müller
|
//TODO Comparable implemented only for fixing failing JAXB imports, may be removed when this is fixed
|
264 |
|
|
@Override
|
265 |
|
|
@Deprecated //for inner use only
|
266 |
|
|
public int compareTo(T other) {
|
267 |
|
|
return ((Integer)this.getId()).compareTo(other.getId());
|
268 |
|
|
}
|
269 |
|
|
|
270 |
|
|
@Override
|
271 |
efa9828a
|
Andreas Müller
|
public Set<T> getIncludes(){
|
272 |
|
|
return this.includes;
|
273 |
|
|
}
|
274 |
|
|
|
275 |
42414138
|
Andreas Müller
|
/**
|
276 |
|
|
* @see #getIncludes()
|
277 |
|
|
*/
|
278 |
efa9828a
|
Andreas Müller
|
protected void setIncludes(Set<T> includes) {
|
279 |
|
|
this.includes = includes;
|
280 |
|
|
}
|
281 |
|
|
|
282 |
42414138
|
Andreas Müller
|
/**
|
283 |
|
|
* @see #getIncludes()
|
284 |
efa9828a
|
Andreas Müller
|
*/
|
285 |
|
|
public void addIncludes(T includes) {
|
286 |
|
|
includes.setPartOf(this);
|
287 |
|
|
this.includes.add(includes);
|
288 |
|
|
}
|
289 |
ee91b8fd
|
Andreas Kohlbecker
|
|
290 |
42414138
|
Andreas Müller
|
/**
|
291 |
|
|
* @see #getIncludes()
|
292 |
efa9828a
|
Andreas Müller
|
*/
|
293 |
|
|
public void removeIncludes(T includes) {
|
294 |
|
|
if(this.includes.contains(includes)) {
|
295 |
|
|
includes.setPartOf(null);
|
296 |
|
|
this.includes.remove(includes);
|
297 |
|
|
}
|
298 |
|
|
}
|
299 |
|
|
|
300 |
42414138
|
Andreas Müller
|
@Override
|
301 |
efa9828a
|
Andreas Müller
|
public Set<Media> getMedia(){
|
302 |
|
|
return this.media;
|
303 |
|
|
}
|
304 |
|
|
|
305 |
|
|
public void addMedia(Media media) {
|
306 |
|
|
this.media.add(media);
|
307 |
|
|
}
|
308 |
|
|
public void removeMedia(Media media) {
|
309 |
|
|
this.media.remove(media);
|
310 |
|
|
}
|
311 |
|
|
|
312 |
|
|
/**
|
313 |
|
|
* @return
|
314 |
|
|
*/
|
315 |
|
|
public TermVocabulary<T> getVocabulary() {
|
316 |
|
|
return this.vocabulary;
|
317 |
|
|
}
|
318 |
|
|
|
319 |
|
|
//for bedirectional use only, use vocabulary.addTerm instead
|
320 |
|
|
/**
|
321 |
|
|
* @param newVocabulary
|
322 |
|
|
*/
|
323 |
|
|
protected void setVocabulary(TermVocabulary<T> newVocabulary) {
|
324 |
|
|
this.vocabulary = newVocabulary;
|
325 |
42414138
|
Andreas Müller
|
}
|
326 |
efa9828a
|
Andreas Müller
|
|
327 |
d0b0c36b
|
Andreas Müller
|
|
328 |
|
|
public String getSymbol() {
|
329 |
|
|
return symbol;
|
330 |
|
|
}
|
331 |
|
|
public void setSymbol(String symbol) {
|
332 |
|
|
this.symbol = symbol;
|
333 |
|
|
}
|
334 |
|
|
|
335 |
efa9828a
|
Andreas Müller
|
//******************************* METHODS ******************************************************/
|
336 |
ee91b8fd
|
Andreas Kohlbecker
|
|
337 |
|
|
|
338 |
|
|
@Override
|
339 |
|
|
public boolean isKindOf(T ancestor) {
|
340 |
|
|
if (kindOf == null || ancestor == null){
|
341 |
|
|
return false;
|
342 |
|
|
}else if (kindOf.equals(ancestor)){
|
343 |
|
|
return true;
|
344 |
|
|
}else{
|
345 |
|
|
return kindOf.isKindOf(ancestor);
|
346 |
|
|
}
|
347 |
|
|
}
|
348 |
|
|
|
349 |
|
|
@Override
|
350 |
|
|
public Set<T> getGeneralizationOf(boolean recursive) {
|
351 |
|
|
Set<T> result = new HashSet<T>();
|
352 |
|
|
result.addAll(this.generalizationOf);
|
353 |
|
|
if (recursive){
|
354 |
|
|
for (T child : this.generalizationOf){
|
355 |
|
|
result.addAll(child.getGeneralizationOf());
|
356 |
|
|
}
|
357 |
|
|
}
|
358 |
|
|
return result;
|
359 |
|
|
}
|
360 |
|
|
|
361 |
|
|
|
362 |
|
|
|
363 |
ad190552
|
Andreas Kohlbecker
|
public abstract void resetTerms();
|
364 |
|
|
|
365 |
|
|
protected abstract void setDefaultTerms(TermVocabulary<T> termVocabulary);
|
366 |
|
|
|
367 |
|
|
|
368 |
9e3239f6
|
Andreas Müller
|
@Override
|
369 |
|
|
public T readCsvLine(Class<T> termClass, List<String> csvLine, Map<UUID,DefinedTermBase> terms, boolean abbrevAsId) {
|
370 |
ad190552
|
Andreas Kohlbecker
|
try {
|
371 |
533cbb43
|
Andreas Müller
|
T newInstance = getInstance(termClass);
|
372 |
14149f73
|
Andreas Müller
|
readCsvLine(newInstance, csvLine, Language.CSV_LANGUAGE(), abbrevAsId);
|
373 |
|
|
readIsPartOf(newInstance, csvLine, terms);
|
374 |
|
|
return newInstance;
|
375 |
ad190552
|
Andreas Kohlbecker
|
} catch (Exception e) {
|
376 |
|
|
logger.error(e);
|
377 |
|
|
for(StackTraceElement ste : e.getStackTrace()) {
|
378 |
|
|
logger.error(ste);
|
379 |
|
|
}
|
380 |
14149f73
|
Andreas Müller
|
throw new RuntimeException(e);
|
381 |
ad190552
|
Andreas Kohlbecker
|
}
|
382 |
|
|
}
|
383 |
ee91b8fd
|
Andreas Kohlbecker
|
|
384 |
|
|
protected static <TERM extends DefinedTermBase> TERM readCsvLine(TERM newInstance, List<String> csvLine, Language lang, boolean abbrevAsId) {
|
385 |
54ccc2d6
|
Andreas Müller
|
newInstance.setUuid(UUID.fromString(csvLine.get(0)));
|
386 |
|
|
newInstance.setUri( URI.create(csvLine.get(1)));
|
387 |
|
|
String label = csvLine.get(2).trim();
|
388 |
|
|
String description = csvLine.get(3);
|
389 |
|
|
String abbreviatedLabel = csvLine.get(4);
|
390 |
|
|
if (StringUtils.isBlank(abbreviatedLabel)){
|
391 |
ee91b8fd
|
Andreas Kohlbecker
|
abbreviatedLabel = null;
|
392 |
54ccc2d6
|
Andreas Müller
|
}
|
393 |
|
|
if (abbrevAsId){
|
394 |
ee91b8fd
|
Andreas Kohlbecker
|
newInstance.setIdInVocabulary(abbreviatedLabel); //new in 3.3
|
395 |
54ccc2d6
|
Andreas Müller
|
}
|
396 |
|
|
newInstance.addRepresentation(Representation.NewInstance(description, label, abbreviatedLabel, lang) );
|
397 |
ee91b8fd
|
Andreas Kohlbecker
|
|
398 |
54ccc2d6
|
Andreas Müller
|
return newInstance;
|
399 |
|
|
}
|
400 |
ee91b8fd
|
Andreas Kohlbecker
|
|
401 |
14149f73
|
Andreas Müller
|
protected void readIsPartOf(T newInstance, List<String> csvLine, Map<UUID, DefinedTermBase> terms){
|
402 |
|
|
int index = partOfCsvLineIndex();
|
403 |
ee91b8fd
|
Andreas Kohlbecker
|
if (index != -1){
|
404 |
|
|
String partOfString = csvLine.get(index);
|
405 |
|
|
if(StringUtils.isNotBlank(partOfString)) {
|
406 |
|
|
UUID partOfUuid = UUID.fromString(partOfString);
|
407 |
|
|
DefinedTermBase partOf = terms.get(partOfUuid);
|
408 |
|
|
partOf.addIncludes(newInstance);
|
409 |
|
|
}
|
410 |
|
|
}
|
411 |
|
|
|
412 |
|
|
}
|
413 |
|
|
|
414 |
|
|
/**
|
415 |
|
|
* Get the
|
416 |
|
|
* @return
|
417 |
|
|
*/
|
418 |
|
|
protected int partOfCsvLineIndex() {
|
419 |
|
|
return -1;
|
420 |
|
|
}
|
421 |
|
|
|
422 |
|
|
|
423 |
|
|
private <T extends DefinedTermBase> T getInstance(Class<? extends DefinedTermBase> termClass) {
|
424 |
|
|
try {
|
425 |
|
|
Constructor<T> c = ((Class<T>)termClass).getDeclaredConstructor();
|
426 |
|
|
c.setAccessible(true);
|
427 |
|
|
T termInstance = c.newInstance();
|
428 |
|
|
return termInstance;
|
429 |
|
|
} catch (Exception e) {
|
430 |
|
|
throw new RuntimeException(e);
|
431 |
|
|
}
|
432 |
14149f73
|
Andreas Müller
|
}
|
433 |
|
|
|
434 |
639679e0
|
Andreas Müller
|
@Override
|
435 |
ad190552
|
Andreas Kohlbecker
|
public void writeCsvLine(CSVWriter writer, T term) {
|
436 |
|
|
String [] line = new String[4];
|
437 |
|
|
line[0] = term.getUuid().toString();
|
438 |
|
|
line[1] = term.getUri().toString();
|
439 |
|
|
line[2] = term.getLabel();
|
440 |
|
|
line[3] = term.getDescription();
|
441 |
|
|
writer.writeNext(line);
|
442 |
|
|
}
|
443 |
|
|
|
444 |
|
|
@Transient
|
445 |
|
|
public T getByUuid(UUID uuid){
|
446 |
|
|
return this.vocabulary.findTermByUuid(uuid);
|
447 |
|
|
}
|
448 |
|
|
|
449 |
|
|
|
450 |
2e8b8e21
|
Katja Luther
|
//*********************** CLONE ********************************************************/
|
451 |
ad190552
|
Andreas Kohlbecker
|
|
452 |
|
|
/**
|
453 |
|
|
* Clones <i>this</i> DefinedTermBase. This is a shortcut that enables to create
|
454 |
|
|
* a new instance that differs only slightly from <i>this</i> defined term base by
|
455 |
|
|
* modifying only some of the attributes.
|
456 |
|
|
*
|
457 |
|
|
* @see eu.etaxonomy.cdm.model.common.TermBase#clone()
|
458 |
|
|
* @see java.lang.Object#clone()
|
459 |
|
|
*/
|
460 |
|
|
@Override
|
461 |
|
|
public Object clone() {
|
462 |
|
|
DefinedTermBase result;
|
463 |
|
|
try {
|
464 |
|
|
result = (DefinedTermBase) super.clone();
|
465 |
|
|
}catch (CloneNotSupportedException e) {
|
466 |
|
|
logger.warn("Object does not implement cloneable");
|
467 |
|
|
e.printStackTrace();
|
468 |
|
|
return null;
|
469 |
|
|
}
|
470 |
|
|
|
471 |
|
|
result.generalizationOf = new HashSet<DefinedTermBase>();
|
472 |
|
|
for (DefinedTermBase generalizationOf : this.generalizationOf){
|
473 |
ee91b8fd
|
Andreas Kohlbecker
|
result.generalizationOf.add(generalizationOf.clone());
|
474 |
ad190552
|
Andreas Kohlbecker
|
}
|
475 |
|
|
|
476 |
|
|
result.includes = new HashSet<DefinedTermBase>();
|
477 |
|
|
|
478 |
|
|
for (DefinedTermBase include: this.includes){
|
479 |
ee91b8fd
|
Andreas Kohlbecker
|
result.includes.add(include.clone());
|
480 |
ad190552
|
Andreas Kohlbecker
|
}
|
481 |
|
|
|
482 |
|
|
result.media = new HashSet<Media>();
|
483 |
|
|
|
484 |
|
|
for (Media media: this.media){
|
485 |
|
|
result.addMedia(media);
|
486 |
|
|
}
|
487 |
|
|
|
488 |
|
|
return result;
|
489 |
|
|
}
|
490 |
efa9828a
|
Andreas Müller
|
|
491 |
93f50b5e
|
Cherian Mathew
|
// Currently the CDM Caching mechanism is only used for caching terms
|
492 |
933e5ac3
|
Cherian Mathew
|
private static ICdmUuidCacher cacher;
|
493 |
903cecc9
|
Cherian Mathew
|
|
494 |
d6fcdafc
|
Andreas M��ller
|
|
495 |
93f50b5e
|
Cherian Mathew
|
/**
|
496 |
|
|
* Gets the CDM cacher object
|
497 |
903cecc9
|
Cherian Mathew
|
*
|
498 |
93f50b5e
|
Cherian Mathew
|
* @return the CDM cacher object
|
499 |
|
|
*/
|
500 |
933e5ac3
|
Cherian Mathew
|
public static ICdmUuidCacher getCacher() {
|
501 |
93f50b5e
|
Cherian Mathew
|
return cacher;
|
502 |
|
|
}
|
503 |
|
|
|
504 |
|
|
/**
|
505 |
|
|
* Sets the CDM cacher object
|
506 |
903cecc9
|
Cherian Mathew
|
*
|
507 |
93f50b5e
|
Cherian Mathew
|
* @param cacher the CDM cacher object
|
508 |
|
|
*/
|
509 |
933e5ac3
|
Cherian Mathew
|
public static void setCacher(ICdmUuidCacher cacher) {
|
510 |
93f50b5e
|
Cherian Mathew
|
DefinedTermBase.cacher = cacher;
|
511 |
|
|
}
|
512 |
933e5ac3
|
Cherian Mathew
|
|
513 |
|
|
public static <T extends DefinedTermBase> T getTermByClassAndUUID(Class<T> clazz, UUID uuid) {
|
514 |
|
|
if(cacher != null) {
|
515 |
|
|
Object obj = getCacher().load(uuid);
|
516 |
|
|
if(obj != null && obj.getClass().equals(clazz)) {
|
517 |
|
|
return (T)obj;
|
518 |
|
|
}
|
519 |
|
|
}
|
520 |
|
|
return null;
|
521 |
|
|
}
|
522 |
9479da48
|
Andreas Müller
|
}
|