Project

General

Profile

Download (10.8 KB) Statistics
| Branch: | Tag: | Revision:
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.occurrence;
11

    
12
import java.util.HashSet;
13
import java.util.Set;
14

    
15
import javax.persistence.Entity;
16
import javax.persistence.FetchType;
17
import javax.persistence.ManyToOne;
18
import javax.persistence.OneToMany;
19
import javax.persistence.Transient;
20
import javax.validation.constraints.Size;
21
import javax.xml.bind.annotation.XmlAccessType;
22
import javax.xml.bind.annotation.XmlAccessorType;
23
import javax.xml.bind.annotation.XmlElement;
24
import javax.xml.bind.annotation.XmlElementWrapper;
25
import javax.xml.bind.annotation.XmlIDREF;
26
import javax.xml.bind.annotation.XmlRootElement;
27
import javax.xml.bind.annotation.XmlSchemaType;
28
import javax.xml.bind.annotation.XmlType;
29

    
30
import org.apache.log4j.Logger;
31
import org.hibernate.annotations.Cascade;
32
import org.hibernate.annotations.CascadeType;
33
import org.hibernate.envers.Audited;
34
import org.hibernate.search.annotations.Analyze;
35
import org.hibernate.search.annotations.Field;
36
import org.hibernate.search.annotations.Indexed;
37
import org.hibernate.search.annotations.IndexedEmbedded;
38
import org.hibernate.validator.constraints.Length;
39

    
40
import eu.etaxonomy.cdm.model.molecular.DnaSample;
41
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
42
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
43
import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
44

    
45
/**
46
 * A derived unit is regarded as derived from a field unit,
47
 * so locality and gathering related information is captured as a separate FieldUnit object
48
 * related to a specimen via a derivation event
49
 * 
50
 * http://www.bgbm.org/biodivinf/docs/CollectionModel/ReprintTNR.pdf
51
 * http://www.bgbm.org/biodivinf/docs/CollectionModel/
52
 * <BR>
53
 * Type figures are derived units with at least a figure object in media
54
 *
55
 * @author m.doering
56
 * @created 08-Nov-2007 13:06:52
57
 *
58
 */
59
@XmlAccessorType(XmlAccessType.FIELD)
60
@XmlType(name = "DerivedUnit", propOrder = {
61
    "collection",
62
    "catalogNumber",
63
    "storedUnder",
64
    "derivedFrom",
65
    "accessionNumber",
66
    "collectorsNumber",
67
    "barcode",
68
	"preservation",
69
	"exsiccatum",
70
    "specimenTypeDesignations"
71
})
72
@XmlRootElement(name = "DerivedUnit")
73
@Entity
74
@Audited
75
// even if hibernate complains "Abstract classes can never insert index documents. Remove @Indexed."
76
// this is needed, otherwise the fields of the also abstract super class are missed during indexing
77
@Indexed(index = "eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase")
78
public class DerivedUnit extends SpecimenOrObservationBase<IIdentifiableEntityCacheStrategy> implements Cloneable{
79
	private static final long serialVersionUID = -3525746216270843517L;
80

    
81
	private static final Logger logger = Logger.getLogger(DnaSample.class);
82
	
83
	@XmlElement(name = "Collection")
84
	@XmlIDREF
85
	@XmlSchemaType(name = "IDREF")
86
	@ManyToOne(fetch = FetchType.LAZY)
87
	@Cascade(CascadeType.SAVE_UPDATE)
88
	@IndexedEmbedded
89
	private Collection collection;
90

    
91
	@XmlElement(name = "CatalogNumber")
92
	@Field(analyze = Analyze.NO)
93
    //TODO Val #3379
94
//	@NullOrNotEmpty
95
	@Length(max = 255)
96
	private String catalogNumber;
97

    
98
	@XmlElement(name = "AccessionNumber")
99
	@Field(analyze = Analyze.NO)
100
    //TODO Val #3379
101
//	@NullOrNotEmpty
102
	@Length(max = 255)
103
	private String accessionNumber;
104

    
105
	@XmlElement(name = "CollectorsNumber")
106
	@Field(analyze = Analyze.NO)
107
    //TODO Val #3379
108
//	@NullOrNotEmpty
109
	@Length(max = 255)
110
	private String collectorsNumber;
111

    
112
	@XmlElement(name = "Barcode")
113
	@Field(analyze = Analyze.NO)
114
    //TODO Val #3379
115
//	@NullOrNotEmpty
116
	@Length(max = 255)
117
	private String barcode;
118

    
119
	@XmlElement(name = "StoredUnder")
120
	@XmlIDREF
121
	@XmlSchemaType(name = "IDREF")
122
	@ManyToOne(fetch = FetchType.LAZY)
123
	@Cascade(CascadeType.SAVE_UPDATE)
124
	@IndexedEmbedded
125
	private TaxonNameBase storedUnder;
126

    
127
	@XmlElement(name = "DerivedFrom")
128
	@XmlIDREF
129
	@XmlSchemaType(name = "IDREF")
130
	@ManyToOne(fetch = FetchType.LAZY)
131
	@Cascade(CascadeType.SAVE_UPDATE)
132
	@IndexedEmbedded(depth = 4)
133
	private DerivationEvent derivedFrom;
134

    
135
	@XmlElementWrapper(name = "SpecimenTypeDesignations")
136
	@XmlElement(name = "SpecimenTypeDesignation")
137
	@OneToMany(fetch = FetchType.LAZY, mappedBy = "typeSpecimen")
138
	@Cascade({ CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE })
139
	private final Set<SpecimenTypeDesignation> specimenTypeDesignations = new HashSet<SpecimenTypeDesignation>();
140

    
141
	
142
//*** attributes valid only for preserved specimen (PreservedSpecimen, Fossil, DnaSample)
143
	
144
	@XmlElement(name = "Preservation")
145
	@XmlIDREF
146
	@XmlSchemaType(name = "IDREF")
147
	@ManyToOne(fetch = FetchType.LAZY)
148
	private PreservationMethod preservation;
149

    
150

    
151
	@XmlElement(name = "Exsiccatum")
152
    //TODO Val #3379
153
//	@NullOrNotEmpty
154
	@Field
155
	@Size(max = 255)
156
    private String exsiccatum;
157
	
158
// ******************** FACTORY METHOD **********************************/
159

    
160

    
161
	public static DerivedUnit NewInstance(SpecimenOrObservationType type) {
162
		return new DerivedUnit(type);
163
	}
164
	
165
	/**
166
	 * Factory method
167
	 * @return
168
	 */
169
	public static DerivedUnit NewPreservedSpecimenInstance(){
170
		DerivedUnit result = new DerivedUnit(SpecimenOrObservationType.PreservedSpecimen);
171
		return result;
172
	}
173
	
174
//************************** CONSTRUCTOR *********************************/	
175
	
176
	//Constructor: For hibernate use only
177
	protected DerivedUnit() {super();}
178
	
179
	
180
	/**
181
	 * Constructor
182
	 * @param recordBasis
183
	 */
184
	protected DerivedUnit(SpecimenOrObservationType recordBasis) {
185
		super(recordBasis);
186
	}
187
	
188
	
189
	/**
190
	 * Create new unit derived from an existing field unit
191
	 * @param fieldUnit existing field unit from where this unit is derived
192
	 */
193
	protected DerivedUnit(SpecimenOrObservationType recordBasis, FieldUnit fieldUnit) {
194
		super(recordBasis);
195
		DerivationEvent derivedFrom = new DerivationEvent();
196
		// TODO: should be done in a more controlled way. Probably by making derivation event implement a general relationship interface (for bidirectional add/remove etc)
197
		fieldUnit.addDerivationEvent(derivedFrom);
198
		derivedFrom.getOriginals().add(fieldUnit);
199
		derivedFrom.getDerivatives().add(this);
200
		this.setDerivedFrom(derivedFrom);
201
	}
202
	
203
	/**
204
	 * create new unit derived from an existing gathering event,
205
	 * thereby creating a new empty field unit
206
	 * @param gatheringEvent the gathering event this unit was collected at
207
	 */
208
	protected DerivedUnit(SpecimenOrObservationType recordBasis, GatheringEvent gatheringEvent) {
209
		this(recordBasis, new FieldUnit());
210
		FieldUnit field = (FieldUnit)this.getOriginalUnit();
211
		field.setGatheringEvent(gatheringEvent);
212
	}
213

    
214
// ******************** GETTER / SETTER *************************************/
215
	
216
	public DerivationEvent getDerivedFrom() {
217
		return derivedFrom;
218
	}
219

    
220
	public void setDerivedFrom(DerivationEvent derivedFrom){
221
		if (getDerivedFrom() != null){
222
			getDerivedFrom().getDerivatives().remove(derivedFrom);
223
		}
224
		this.derivedFrom = derivedFrom;
225
		if (derivedFrom != null){
226
			derivedFrom.addDerivative(this);
227
		}
228
	}
229

    
230
	@Transient
231
	public Set<SpecimenOrObservationBase> getOriginals(){
232
		if(getDerivedFrom() != null){
233
			return getDerivedFrom().getOriginals();
234
		}
235
		return null;
236
	}
237

    
238
	public Collection getCollection(){
239
		return this.collection;
240
	}
241

    
242
	public void setCollection(Collection collection){
243
		this.collection = collection;
244
	}
245

    
246

    
247
	public String getCatalogNumber() {
248
		return catalogNumber;
249
	}
250

    
251
	public void setCatalogNumber(String catalogNumber) {
252
		this.catalogNumber = catalogNumber;
253
	}
254

    
255
	public void setBarcode(String barcode) {
256
		this.barcode = barcode;
257
	}
258
	public String getBarcode() {
259
		return barcode;
260
	}
261

    
262
	public void setStoredUnder(TaxonNameBase storedUnder) {
263
		this.storedUnder = storedUnder;
264
	}
265

    
266
	public String getAccessionNumber() {
267
		return accessionNumber;
268
	}
269

    
270

    
271
	public void setAccessionNumber(String accessionNumber) {
272
		this.accessionNumber = accessionNumber;
273
	}
274

    
275
	/**
276
	 * Will be removed in future versions as semantics is not clear.
277
	 * For accessing the collecting number use
278
	 * {@link FieldUnit#getFieldNumber()} instead.
279
	 * @return
280
	 */
281
	@Deprecated
282
	public String getCollectorsNumber() {
283
		return collectorsNumber;
284
	}
285

    
286
	/**
287
	 * Will be removed in future versions as semantics is not clear.
288
	 * For editing the collecting number use
289
	 * {@link FieldUnit#getFieldNumber()} instead.
290
	 * @return
291
	 */
292
	@Deprecated
293
	public void setCollectorsNumber(String collectorsNumber) {
294
		this.collectorsNumber = collectorsNumber;
295
	}
296

    
297
	public TaxonNameBase getStoredUnder() {
298
		return storedUnder;
299
	}
300

    
301
	public void addSpecimenTypeDesignation(SpecimenTypeDesignation specimenTypeDesignation){
302
		if (specimenTypeDesignation.getTypeSpecimen() == this){
303
			return ;
304
		}else if (specimenTypeDesignation.getTypeSpecimen() != null){
305
			specimenTypeDesignation.getTypeSpecimen().removeSpecimenTypeDesignation(specimenTypeDesignation);
306

    
307
		}
308
		specimenTypeDesignations.add(specimenTypeDesignation);
309
		specimenTypeDesignation.setTypeSpecimen(this);
310
	}
311

    
312
	public void removeSpecimenTypeDesignation(SpecimenTypeDesignation specimenTypeDesignation){
313
		if (specimenTypeDesignation == null){
314
			return;
315
		}
316
		if (specimenTypeDesignations.contains(specimenTypeDesignation)){
317
			specimenTypeDesignations.remove(specimenTypeDesignation);
318
			specimenTypeDesignation.setTypeSpecimen(null);
319
		}
320
	}
321

    
322
// ******* GETTER / SETTER for preserved specimen only ******************/
323
	
324
	public Set<SpecimenTypeDesignation> getSpecimenTypeDesignations(){
325
		return specimenTypeDesignations;
326
	}
327
	
328
	public PreservationMethod getPreservation(){
329
		return this.preservation;
330
	}
331

    
332
	public void setPreservation(PreservationMethod preservation){
333
		this.preservation = preservation;
334
	}
335

    
336

    
337
	public void setExsiccatum(String exsiccatum) {
338
		this.exsiccatum = exsiccatum;
339
	}
340

    
341
	public String getExsiccatum() {
342
		return exsiccatum;
343
	}
344

    
345
//*********** CLONE **********************************/
346

    
347
	/**
348
	 * Clones <i>this</i> derivedUnit. This is a shortcut that enables to
349
	 * create a new instance that differs only slightly from <i>this</i> specimen
350
	 * by modifying only some of the attributes.<BR>
351
	 * This method overrides the clone method from {@link SpecimenOrObservationBase SpecimenOrObservationBase}.
352
	 *
353
	 * @see SpecimenOrObservationBase#clone()
354
	 * @see eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity#clone()
355
	 * @see java.lang.Object#clone()
356
	 */
357
	@Override
358
	public Object clone() {
359
		try{
360
			DerivedUnit result = (DerivedUnit)super.clone();
361
			//collection
362
			result.setCollection(this.collection);
363
			//derivedFrom
364
			result.setDerivedFrom(this.derivedFrom);
365
			//storedUnder
366
			result.setStoredUnder(this.storedUnder);
367
			//preservation
368
			result.setPreservation(this.preservation);
369
			//no changes to: accessionNumber, catalogNumber, collectorsNumber
370
			return result;
371
		} catch (CloneNotSupportedException e) {
372
			logger.warn("Object does not implement cloneable");
373
			e.printStackTrace();
374
			return null;
375
		}
376
	}
377

    
378

    
379
}
(4-4/13)