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")
69 @XmlSchemaType(name
= "IDREF")
72 * FIXME - Hibernate retuns this as a collection of CGLibProxy$$DefinedTermBase objects
73 * which can't be cast to instances of T - can we explicitly initialize these terms using
74 * Hibernate.initialize(), does this imply a distinct load, and find methods in the dao?
76 @XmlElement(name
= "GeneralizationOf")
78 @XmlSchemaType(name
= "IDREF")
79 private Set
<T
> generalizationOf
= new HashSet
<T
>();
81 @XmlElement(name
= "PartOf")
83 @XmlSchemaType(name
= "IDREF")
87 * FIXME - Hibernate retuns this as a collection of CGLibProxy$$DefinedTermBase objects
88 * which can't be cast to instances of T - can we explicitly initialize these terms using
89 * Hibernate.initialize(), does this imply a distinct load, and find methods in the dao?
91 @XmlElementWrapper(name
= "Includes")
92 @XmlElement(name
= "Include")
94 @XmlSchemaType(name
= "IDREF")
95 private Set
<T
> includes
= new HashSet
<T
>();
97 @XmlElementWrapper(name
= "Media")
98 @XmlElement(name
= "Medium")
100 @XmlSchemaType(name
= "IDREF")
101 private Set
<Media
> media
= new HashSet
<Media
>();
103 @XmlElement(name
= "TermVocabulary")
105 @XmlSchemaType(name
= "IDREF")
106 protected TermVocabulary
<T
> vocabulary
;
109 public static DefinedTermBase
findByUuid(UUID uuid
){
110 return vocabularyStore
.getTermByUuid(uuid
);
113 public DefinedTermBase() {
116 public DefinedTermBase(String term
, String label
, String labelAbbrev
) {
117 super(term
, label
, labelAbbrev
);
122 * @see eu.etaxonomy.cdm.model.common.ILoadableTerm#readCsvLine(java.util.List)
124 public ILoadableTerm
readCsvLine(List
<String
> csvLine
) {
125 return readCsvLine(csvLine
, Language
.ENGLISH());
128 public ILoadableTerm
readCsvLine(List
<String
> csvLine
, Language lang
) {
129 this.setUuid(UUID
.fromString(csvLine
.get(0)));
130 this.setUri(csvLine
.get(1));
131 String label
= csvLine
.get(2).trim();
132 String text
= csvLine
.get(3);
133 String abbreviatedLabel
= null;
134 this.addRepresentation(Representation
.NewInstance(text
, label
, abbreviatedLabel
, lang
) );
139 * @see eu.etaxonomy.cdm.model.common.ILoadableTerm#writeCsvLine(au.com.bytecode.opencsv.CSVWriter)
141 public void writeCsvLine(CSVWriter writer
) {
142 String
[] line
= new String
[4];
143 line
[0] = getUuid().toString();
145 line
[2] = getLabel();
146 line
[3] = getDescription();
147 writer
.writeNext(line
);
151 @ManyToOne(fetch
= FetchType
.LAZY
, targetEntity
= DefinedTermBase
.class)
152 @Cascade({CascadeType
.SAVE_UPDATE
})
153 public T
getKindOf(){
157 public void setKindOf(T kindOf
){
158 this.kindOf
= kindOf
;
161 @OneToMany(fetch
=FetchType
.LAZY
, mappedBy
= "kindOf", targetEntity
= DefinedTermBase
.class)
162 @Cascade({CascadeType
.SAVE_UPDATE
})
163 public Set
<T
> getGeneralizationOf(){
164 return this.generalizationOf
;
167 public void setGeneralizationOf(Set
<T
> generalizationOf
) {
168 this.generalizationOf
= generalizationOf
;
171 public void addGeneralizationOf(T generalization
) {
172 generalization
.setKindOf(this);
173 this.generalizationOf
.add(generalization
);
176 public void removeGeneralization(T generalization
) {
177 if(generalizationOf
.contains(generalization
)){
178 generalization
.setKindOf(null);
179 this.generalizationOf
.remove(generalization
);
184 @ManyToOne(fetch
= FetchType
.LAZY
, targetEntity
= DefinedTermBase
.class)
185 @Cascade({CascadeType
.SAVE_UPDATE
})
186 public T
getPartOf(){
189 public void setPartOf(T partOf
){
190 this.partOf
= partOf
;
194 @OneToMany(fetch
=FetchType
.LAZY
, mappedBy
= "partOf", targetEntity
= DefinedTermBase
.class)
195 @Cascade({CascadeType
.SAVE_UPDATE
})
196 public Set
<T
> getIncludes(){
197 return this.includes
;
199 public void setIncludes(Set
<T
> includes
) {
200 this.includes
= includes
;
202 public void addIncludes(T includes
) {
203 includes
.setPartOf(this);
204 this.includes
.add(includes
);
206 public void removeIncludes(T includes
) {
207 if(this.includes
.contains(includes
)) {
208 includes
.setPartOf(null);
209 this.includes
.remove(includes
);
215 @Cascade({CascadeType
.SAVE_UPDATE
})
216 public Set
<Media
> getMedia(){
219 public void setMedia(Set
<Media
> media
) {
222 public void addMedia(Media media
) {
223 this.media
.add(media
);
225 public void removeMedia(Media media
) {
226 this.media
.remove(media
);
230 * @see eu.etaxonomy.cdm.model.common.IDefTerm#getVocabulary()
234 public TermVocabulary
<T
> getVocabulary() {
235 return this.vocabulary
;
238 * @see eu.etaxonomy.cdm.model.common.IDefTerm#setVocabulary(eu.etaxonomy.cdm.model.common.TermVocabulary)
240 public void setVocabulary(TermVocabulary
<T
> newVocabulary
) {
241 // Hibernate bidirectional cascade hack:
242 // http://opensource.atlassian.com/projects/hibernate/browse/HHH-1054
243 if(this.vocabulary
== newVocabulary
){ return;}
244 if (this.vocabulary
!= null) {
245 this.vocabulary
.terms
.remove(this);
247 if (newVocabulary
!= null) {
248 newVocabulary
.terms
.add((T
)this);
250 this.vocabulary
= newVocabulary
;
255 * @see eu.etaxonomy.cdm.model.common.IDefTerm#getVocabulary()
257 @ManyToOne(fetch
=FetchType
.LAZY
)
258 @Cascade( { CascadeType
.SAVE_UPDATE
})
259 protected TermVocabulary
<T
> getPersistentVocabulary() {
260 return this.vocabulary
;
263 * @see eu.etaxonomy.cdm.model.common.IDefTerm#setVocabulary(eu.etaxonomy.cdm.model.common.TermVocabulary)
265 protected void setPersistentVocabulary(TermVocabulary newVocabulary
) {
266 // Hibernate bidirectional cascade hack:
267 // http://opensource.atlassian.com/projects/hibernate/browse/HHH-1054
268 if(this.vocabulary
== newVocabulary
){ return;}
269 if (this.vocabulary
!= null) {
270 this.vocabulary
.terms
.remove(this);
272 if (newVocabulary
!= null) {
274 Field fieldInitializing
= AbstractPersistentCollection
.class.getDeclaredField("initializing");
275 fieldInitializing
.setAccessible(true);
276 if (AbstractPersistentCollection
.class.isAssignableFrom(newVocabulary
.terms
.getClass())){
277 boolean initValue
= fieldInitializing
.getBoolean(newVocabulary
.terms
);
278 if (initValue
== false){
279 newVocabulary
.terms
.add(this);
284 newVocabulary
.terms
.add(this);
286 } catch (SecurityException e
) {
288 } catch (IllegalArgumentException e
) {
290 } catch (NoSuchFieldException e
) {
292 } catch (IllegalAccessException e
) {
296 this.vocabulary
= newVocabulary
;