@OneToMany for Media becomes @ManyToMany
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / common / DefinedTermBase.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 import org.apache.log4j.Logger;
13 import org.hibernate.annotations.Cascade;
14 import org.hibernate.annotations.CascadeType;
15 import org.hibernate.collection.AbstractPersistentCollection;
16 import org.hibernate.search.annotations.Indexed;
17
18 import au.com.bytecode.opencsv.CSVWriter;
19 import eu.etaxonomy.cdm.model.common.init.ITermInitializer;
20 import eu.etaxonomy.cdm.model.media.Media;
21 import java.lang.reflect.Field;
22 import java.util.*;
23
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;
34
35
36 /**
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)
40 * @author m.doering
41 * @version 1.0
42 * @created 08-Nov-2007 13:06:19
43 */
44 @XmlAccessorType(XmlAccessType.FIELD)
45 @XmlType(name = "DefinedTermBase", propOrder = {
46 "kindOf",
47 "generalizationOf",
48 "partOf",
49 "includes",
50 "media",
51 "vocabulary"
52 })
53 @XmlRootElement(name = "DefinedTermBase")
54 @Entity
55 //@Audited
56 @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
57 @Indexed
58 public abstract class DefinedTermBase<T extends DefinedTermBase> extends TermBase implements ILoadableTerm<T> {
59 private static final long serialVersionUID = 2931811562248571531L;
60 @SuppressWarnings("unused")
61 private static final Logger logger = Logger.getLogger(DefinedTermBase.class);
62
63 @XmlElement(name = "KindOf")
64 @XmlIDREF
65 @XmlSchemaType(name = "IDREF")
66 private T kindOf;
67 /**
68 * FIXME - Hibernate retuns this as a collection of CGLibProxy$$DefinedTermBase objects
69 * which can't be cast to instances of T - can we explicitly initialize these terms using
70 * Hibernate.initialize(), does this imply a distinct load, and find methods in the dao?
71 */
72 @XmlElement(name = "GeneralizationOf")
73 @XmlIDREF
74 @XmlSchemaType(name = "IDREF")
75 private Set<T> generalizationOf = new HashSet<T>();
76
77 @XmlElement(name = "PartOf")
78 @XmlIDREF
79 @XmlSchemaType(name = "IDREF")
80 private T partOf;
81
82 /**
83 * FIXME - Hibernate retuns this as a collection of CGLibProxy$$DefinedTermBase objects
84 * which can't be cast to instances of T - can we explicitly initialize these terms using
85 * Hibernate.initialize(), does this imply a distinct load, and find methods in the dao?
86 */
87 @XmlElementWrapper(name = "Includes")
88 @XmlElement(name = "Include")
89 private Set<T> includes = new HashSet<T>();
90
91 @XmlElementWrapper(name = "Media")
92 @XmlElement(name = "Medium")
93 @XmlIDREF
94 @XmlSchemaType(name = "IDREF")
95 private Set<Media> media = new HashSet<Media>();
96
97 @XmlElement(name = "TermVocabulary")
98 @XmlIDREF
99 @XmlSchemaType(name = "IDREF")
100 protected TermVocabulary<T> vocabulary;
101
102 public DefinedTermBase() {
103 super();
104 }
105 public DefinedTermBase(String term, String label, String labelAbbrev) {
106 super(term, label, labelAbbrev);
107 }
108
109 protected abstract void setDefaultTerms(TermVocabulary<T> termVocabulary);
110
111 /* (non-Javadoc)
112 * @see eu.etaxonomy.cdm.model.common.ILoadableTerm#readCsvLine(java.util.List)
113 */
114 public T readCsvLine(Class<T> termClass, List<String> csvLine, Map<UUID,DefinedTermBase> terms) {
115 try {
116 T newInstance = termClass.newInstance();
117 return readCsvLine(newInstance, csvLine, Language.ENGLISH());
118 } catch (Exception e) {
119 logger.error(e);
120 for(StackTraceElement ste : e.getStackTrace()) {
121 logger.error(ste);
122 }
123 }
124
125 return null;
126 }
127
128 protected static <TERM extends DefinedTermBase> TERM readCsvLine(TERM newInstance, List<String> csvLine, Language lang) {
129 newInstance.setUuid(UUID.fromString(csvLine.get(0)));
130 newInstance.setUri(csvLine.get(1));
131 String label = csvLine.get(2).trim();
132 String text = csvLine.get(3);
133 String abbreviatedLabel = csvLine.get(4);
134 newInstance.addRepresentation(Representation.NewInstance(text, label, abbreviatedLabel, lang) );
135 return newInstance;
136 }
137
138 /* (non-Javadoc)
139 * @see eu.etaxonomy.cdm.model.common.ILoadableTerm#writeCsvLine(au.com.bytecode.opencsv.CSVWriter)
140 */
141 public void writeCsvLine(CSVWriter writer, T term) {
142 String [] line = new String[4];
143 line[0] = term.getUuid().toString();
144 line[1] = term.getUri();
145 line[2] = term.getLabel();
146 line[3] = term.getDescription();
147 writer.writeNext(line);
148 }
149
150 @Transient
151 public T getByUuid(UUID uuid){
152 return this.vocabulary.findTermByUuid(uuid);
153 }
154
155
156 @ManyToOne(fetch = FetchType.LAZY, targetEntity = DefinedTermBase.class)
157 @Cascade({CascadeType.SAVE_UPDATE})
158 public T getKindOf(){
159 return this.kindOf;
160 }
161
162 public void setKindOf(T kindOf){
163 this.kindOf = kindOf;
164 }
165
166 @OneToMany(fetch=FetchType.LAZY, mappedBy = "kindOf", targetEntity = DefinedTermBase.class)
167 @Cascade({CascadeType.SAVE_UPDATE})
168 public Set<T> getGeneralizationOf(){
169 return this.generalizationOf;
170 }
171
172 public void setGeneralizationOf(Set<T> generalizationOf) {
173 this.generalizationOf = generalizationOf;
174 }
175
176 public void addGeneralizationOf(T generalization) {
177 generalization.setKindOf(this);
178 this.generalizationOf.add(generalization);
179 }
180
181 public void removeGeneralization(T generalization) {
182 if(generalizationOf.contains(generalization)){
183 generalization.setKindOf(null);
184 this.generalizationOf.remove(generalization);
185 }
186 }
187
188
189 @ManyToOne(fetch = FetchType.LAZY, targetEntity = DefinedTermBase.class)
190 @Cascade({CascadeType.SAVE_UPDATE})
191 public T getPartOf(){
192 return this.partOf;
193 }
194 public void setPartOf(T partOf){
195 this.partOf = partOf;
196 }
197
198
199 @OneToMany(fetch=FetchType.LAZY, mappedBy = "partOf", targetEntity = DefinedTermBase.class)
200 @Cascade({CascadeType.SAVE_UPDATE})
201 public Set<T> getIncludes(){
202 return this.includes;
203 }
204 public void setIncludes(Set<T> includes) {
205 this.includes = includes;
206 }
207 public void addIncludes(T includes) {
208 includes.setPartOf(this);
209 this.includes.add(includes);
210 }
211 public void removeIncludes(T includes) {
212 if(this.includes.contains(includes)) {
213 includes.setPartOf(null);
214 this.includes.remove(includes);
215 }
216 }
217
218
219 @ManyToMany(fetch = FetchType.LAZY)
220 @Cascade({CascadeType.SAVE_UPDATE})
221 public Set<Media> getMedia(){
222 return this.media;
223 }
224 public void setMedia(Set<Media> media) {
225 this.media = media;
226 }
227 public void addMedia(Media media) {
228 this.media.add(media);
229 }
230 public void removeMedia(Media media) {
231 this.media.remove(media);
232 }
233
234 /* (non-Javadoc)
235 * @see eu.etaxonomy.cdm.model.common.IDefTerm#getVocabulary()
236 */
237 @XmlTransient
238 @ManyToOne(fetch=FetchType.LAZY)
239 @Cascade( { CascadeType.SAVE_UPDATE })
240 public TermVocabulary<T> getVocabulary() {
241 return this.vocabulary;
242 }
243 /* (non-Javadoc)
244 * @see eu.etaxonomy.cdm.model.common.IDefTerm#setVocabulary(eu.etaxonomy.cdm.model.common.TermVocabulary)
245 */
246 public void setVocabulary(TermVocabulary<T> newVocabulary) {
247 this.vocabulary = newVocabulary;
248 }
249 }