2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.model
.common
;
12 import org
.apache
.log4j
.Logger
;
13 import org
.hibernate
.annotations
.Cascade
;
14 import org
.hibernate
.annotations
.CascadeType
;
15 import org
.hibernate
.collection
.AbstractPersistentCollection
;
17 import au
.com
.bytecode
.opencsv
.CSVWriter
;
18 import eu
.etaxonomy
.cdm
.model
.common
.init
.DefaultVocabularyStore
;
19 import eu
.etaxonomy
.cdm
.model
.common
.init
.IVocabularyStore
;
20 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
21 import java
.lang
.reflect
.Field
;
24 import javax
.persistence
.*;
25 import javax
.xml
.bind
.annotation
.XmlAccessType
;
26 import javax
.xml
.bind
.annotation
.XmlAccessorType
;
27 import javax
.xml
.bind
.annotation
.XmlElement
;
28 import javax
.xml
.bind
.annotation
.XmlElementWrapper
;
29 import javax
.xml
.bind
.annotation
.XmlIDREF
;
30 import javax
.xml
.bind
.annotation
.XmlRootElement
;
31 import javax
.xml
.bind
.annotation
.XmlSchemaType
;
32 import javax
.xml
.bind
.annotation
.XmlTransient
;
33 import javax
.xml
.bind
.annotation
.XmlType
;
37 * walkaround for enumerations, base type according to TDWG. For linear ordering
38 * use partOf relation and BreadthFirst. Default iterator order should therefore
39 * be BreadthFirst (not DepthFirst)
42 * @created 08-Nov-2007 13:06:19
44 @XmlAccessorType(XmlAccessType
.FIELD
)
45 @XmlType(name
= "DefinedTermBase", propOrder
= {
53 @XmlRootElement(name
= "DefinedTermBase")
55 @Inheritance(strategy
=InheritanceType
.SINGLE_TABLE
)
56 public abstract class DefinedTermBase
<T
extends DefinedTermBase
> extends TermBase
implements ILoadableTerm
<T
> {
57 private static final long serialVersionUID
= 2931811562248571531L;
58 @SuppressWarnings("unused")
59 private static final Logger logger
= Logger
.getLogger(DefinedTermBase
.class);
61 static protected IVocabularyStore vocabularyStore
= new DefaultVocabularyStore();
63 public static void setVocabularyStore(IVocabularyStore vocabularyStore
){
64 DefinedTermBase
.vocabularyStore
= vocabularyStore
;
67 @XmlElement(name
= "KindOf")
68 private DefinedTermBase
<T
> kindOf
;
70 @XmlElement(name
= "GeneralizationOf")
71 private Set
<DefinedTermBase
<T
>> generalizationOf
= new HashSet
<DefinedTermBase
<T
>>();
73 @XmlElement(name
= "PartOf")
74 private DefinedTermBase
<T
> partOf
;
76 @XmlElementWrapper(name
= "Includes")
77 @XmlElement(name
= "Include")
78 private Set
<DefinedTermBase
<T
>> includes
= new HashSet
<DefinedTermBase
<T
>>();
80 @XmlElementWrapper(name
= "Media")
81 @XmlElement(name
= "Medium")
83 @XmlSchemaType(name
= "IDREF")
84 private Set
<Media
> media
= new HashSet
<Media
>();
86 @XmlElement(name
= "TermVocabulary")
88 @XmlSchemaType(name
= "IDREF")
89 protected TermVocabulary
<T
> vocabulary
;
92 public static DefinedTermBase
findByUuid(UUID uuid
){
93 return vocabularyStore
.getTermByUuid(uuid
);
96 public DefinedTermBase() {
99 public DefinedTermBase(String term
, String label
, String labelAbbrev
) {
100 super(term
, label
, labelAbbrev
);
105 * @see eu.etaxonomy.cdm.model.common.ILoadableTerm#readCsvLine(java.util.List)
107 public ILoadableTerm
readCsvLine(List
<String
> csvLine
) {
108 return readCsvLine(csvLine
, Language
.ENGLISH());
111 public ILoadableTerm
readCsvLine(List
<String
> csvLine
, Language lang
) {
112 this.setUuid(UUID
.fromString(csvLine
.get(0)));
113 this.setUri(csvLine
.get(1));
114 String label
= csvLine
.get(2).trim();
115 String text
= csvLine
.get(3);
116 String abbreviatedLabel
= null;
117 this.addRepresentation(Representation
.NewInstance(text
, label
, abbreviatedLabel
, lang
) );
122 * @see eu.etaxonomy.cdm.model.common.ILoadableTerm#writeCsvLine(au.com.bytecode.opencsv.CSVWriter)
124 public void writeCsvLine(CSVWriter writer
) {
125 String
[] line
= new String
[4];
126 line
[0] = getUuid().toString();
128 line
[2] = getLabel();
129 line
[3] = getDescription();
130 writer
.writeNext(line
);
134 @ManyToOne(fetch
= FetchType
.LAZY
)
135 @Cascade({CascadeType
.SAVE_UPDATE
})
136 public DefinedTermBase
<T
> getKindOf(){
139 public void setKindOf(DefinedTermBase
<T
> kindOf
){
140 this.kindOf
= kindOf
;
143 @OneToMany(fetch
=FetchType
.LAZY
, mappedBy
= "kindOf")
144 @Cascade({CascadeType
.SAVE_UPDATE
})
145 public Set
<DefinedTermBase
<T
>> getGeneralizationOf(){
146 return this.generalizationOf
;
149 public void setGeneralizationOf(Set
<DefinedTermBase
<T
>> generalizationOf
) {
150 this.generalizationOf
= generalizationOf
;
153 public void addGeneralizationOf(DefinedTermBase
<T
> generalization
) {
154 generalization
.setKindOf(this);
155 this.generalizationOf
.add(generalization
);
158 public void removeGeneralization(DefinedTermBase
<T
> generalization
) {
159 if(generalizationOf
.contains(generalization
)){
160 generalization
.setKindOf(null);
161 this.generalizationOf
.remove(generalization
);
167 @Cascade({CascadeType
.SAVE_UPDATE
})
168 public DefinedTermBase
<T
> getPartOf(){
171 public void setPartOf(DefinedTermBase
<T
> partOf
){
172 this.partOf
= partOf
;
176 @OneToMany(fetch
=FetchType
.LAZY
, mappedBy
= "partOf")
177 @Cascade({CascadeType
.SAVE_UPDATE
})
178 public Set
<DefinedTermBase
<T
>> getIncludes(){
179 return this.includes
;
181 public void setIncludes(Set
<DefinedTermBase
<T
>> includes
) {
182 this.includes
= includes
;
184 public void addIncludes(DefinedTermBase
<T
> includes
) {
185 includes
.setPartOf(this);
186 this.includes
.add(includes
);
188 public void removeIncludes(DefinedTermBase
<T
> includes
) {
189 if(this.includes
.contains(includes
)) {
190 includes
.setPartOf(null);
191 this.includes
.remove(includes
);
197 @Cascade({CascadeType
.SAVE_UPDATE
})
198 public Set
<Media
> getMedia(){
201 public void setMedia(Set
<Media
> media
) {
204 public void addMedia(Media media
) {
205 this.media
.add(media
);
207 public void removeMedia(Media media
) {
208 this.media
.remove(media
);
212 * @see eu.etaxonomy.cdm.model.common.IDefTerm#getVocabulary()
216 public TermVocabulary
getVocabulary() {
217 return this.vocabulary
;
220 * @see eu.etaxonomy.cdm.model.common.IDefTerm#setVocabulary(eu.etaxonomy.cdm.model.common.TermVocabulary)
222 public void setVocabulary(TermVocabulary newVocabulary
) {
223 // Hibernate bidirectional cascade hack:
224 // http://opensource.atlassian.com/projects/hibernate/browse/HHH-1054
225 if(this.vocabulary
== newVocabulary
){ return;}
226 if (this.vocabulary
!= null) {
227 this.vocabulary
.terms
.remove(this);
229 if (newVocabulary
!= null) {
230 newVocabulary
.terms
.add(this);
232 this.vocabulary
= newVocabulary
;
237 * @see eu.etaxonomy.cdm.model.common.IDefTerm#getVocabulary()
239 @ManyToOne(fetch
=FetchType
.LAZY
)
240 @Cascade( { CascadeType
.SAVE_UPDATE
})
241 protected TermVocabulary
getPersistentVocabulary() {
242 return this.vocabulary
;
245 * @see eu.etaxonomy.cdm.model.common.IDefTerm#setVocabulary(eu.etaxonomy.cdm.model.common.TermVocabulary)
247 protected void setPersistentVocabulary(TermVocabulary newVocabulary
) {
248 // Hibernate bidirectional cascade hack:
249 // http://opensource.atlassian.com/projects/hibernate/browse/HHH-1054
250 if(this.vocabulary
== newVocabulary
){ return;}
251 if (this.vocabulary
!= null) {
252 this.vocabulary
.terms
.remove(this);
254 if (newVocabulary
!= null) {
256 Field fieldInitializing
= AbstractPersistentCollection
.class.getDeclaredField("initializing");
257 fieldInitializing
.setAccessible(true);
258 if (AbstractPersistentCollection
.class.isAssignableFrom(newVocabulary
.terms
.getClass())){
259 boolean initValue
= fieldInitializing
.getBoolean(newVocabulary
.terms
);
260 if (initValue
== false){
261 newVocabulary
.terms
.add(this);
266 newVocabulary
.terms
.add(this);
268 } catch (SecurityException e
) {
270 } catch (IllegalArgumentException e
) {
272 } catch (NoSuchFieldException e
) {
274 } catch (IllegalAccessException e
) {
278 this.vocabulary
= newVocabulary
;