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
.occurrence
;
12 import java
.util
.Calendar
;
13 import java
.util
.HashSet
;
16 import javax
.persistence
.Entity
;
17 import javax
.persistence
.FetchType
;
18 import javax
.persistence
.ManyToMany
;
19 import javax
.persistence
.ManyToOne
;
20 import javax
.persistence
.OneToOne
;
21 import javax
.persistence
.Transient
;
22 import javax
.validation
.constraints
.NotNull
;
23 import javax
.validation
.constraints
.Size
;
24 import javax
.xml
.bind
.annotation
.XmlAccessType
;
25 import javax
.xml
.bind
.annotation
.XmlAccessorType
;
26 import javax
.xml
.bind
.annotation
.XmlElement
;
27 import javax
.xml
.bind
.annotation
.XmlElementWrapper
;
28 import javax
.xml
.bind
.annotation
.XmlIDREF
;
29 import javax
.xml
.bind
.annotation
.XmlRootElement
;
30 import javax
.xml
.bind
.annotation
.XmlSchemaType
;
31 import javax
.xml
.bind
.annotation
.XmlType
;
33 import org
.apache
.log4j
.Logger
;
34 import org
.hibernate
.annotations
.Cascade
;
35 import org
.hibernate
.annotations
.CascadeType
;
36 import org
.hibernate
.envers
.Audited
;
37 import org
.hibernate
.search
.annotations
.Analyze
;
38 import org
.hibernate
.search
.annotations
.Field
;
39 import org
.hibernate
.search
.annotations
.Indexed
;
40 import org
.hibernate
.search
.annotations
.IndexedEmbedded
;
41 import org
.hibernate
.search
.annotations
.NumericField
;
42 import org
.hibernate
.validator
.constraints
.Length
;
43 import org
.joda
.time
.Partial
;
45 import eu
.etaxonomy
.cdm
.model
.agent
.AgentBase
;
46 import eu
.etaxonomy
.cdm
.model
.common
.EventBase
;
47 import eu
.etaxonomy
.cdm
.model
.common
.LanguageString
;
48 import eu
.etaxonomy
.cdm
.model
.common
.TimePeriod
;
49 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
50 import eu
.etaxonomy
.cdm
.model
.location
.Point
;
53 * The event when gathering a specimen or recording a field observation only
57 @XmlAccessorType(XmlAccessType
.FIELD
)
58 @XmlType(name
= "GatheringEvent", propOrder
= {
65 "absoluteElevationMax",
66 "absoluteElevationText",
68 "distanceToGroundMax",
69 "distanceToWaterSurface",
70 "distanceToWaterSurfaceMax"
72 @XmlRootElement(name
= "GatheringEvent")
76 public class GatheringEvent
extends EventBase
implements Cloneable
{
77 private static final long serialVersionUID
= 7980806082366532180L;
78 private static final Logger logger
= Logger
.getLogger(GatheringEvent
.class);
80 @XmlElement(name
= "Locality")
81 @OneToOne(fetch
= FetchType
.LAZY
, orphanRemoval
=true)
82 @Cascade({CascadeType
.ALL
})
84 private LanguageString locality
;
86 @XmlElement(name
= "ExactLocation")
88 private Point exactLocation
;
91 @XmlElement(name
= "Country")
93 @XmlSchemaType(name
= "IDREF")
94 @ManyToOne(fetch
= FetchType
.LAZY
)
95 @Cascade({CascadeType
.SAVE_UPDATE
})
97 private NamedArea country
;
99 @XmlElementWrapper(name
= "CollectingAreas")
100 @XmlElement(name
= "CollectingArea")
102 @XmlSchemaType(name
= "IDREF")
103 @ManyToMany(fetch
= FetchType
.LAZY
)
105 // further collecting areas. Should not include country
106 private Set
<NamedArea
> collectingAreas
= new HashSet
<NamedArea
>();
108 @XmlElement(name
= "CollectingMethod")
113 private String collectingMethod
;
116 * meter above/below sea level of the surface
117 * if absoluteElevationMax is defined this is the minimum value
120 @XmlElement(name
= "AbsoluteElevation")
123 private Integer absoluteElevation
;
125 // meter above/below sea level of the surface, maximum value
126 @XmlElement(name
= "AbsoluteElevationMax")
129 private Integer absoluteElevationMax
;
133 * Maximum value of meter above/below sea level of the surface as text.
134 * If min/max value exists together with absoluteElevationText
135 * the later will be preferred for formatting where as the former
136 * will be used for computations. If the absoluteElevation
137 * does not require any additional information such as
138 * "ca." it is suggested to use min/max value instead.
140 @XmlElement(name
= "AbsoluteElevationText")
143 private String absoluteElevationText
;
145 // @XmlElement(name = "AbsoluteElevationError")
146 // @Field(analyze = Analyze.NO)
148 // private Integer absoluteElevationError;
150 // distance in meter from the ground surface when collecting. E.g. 10m below the ground or 10m above the ground/bottom of a lake or 20m up in the canope
151 @XmlElement(name
= "DistanceToGround")
152 @Field(analyze
= Analyze
.NO
)
154 private Double distanceToGround
;
156 // distance in meter from the ground surface when collecting. E.g. 10m below the ground or 10m above the ground/bottom of a lake or 20m up in the canope
157 @XmlElement(name
= "distanceToGroundMax")
158 @Field(analyze
= Analyze
.NO
)
160 private Double distanceToGroundMax
;
162 // distance in meters to lake or sea surface. Similar to distanceToGround use negative integers for distance *below* the surface, ie under water
163 @XmlElement(name
= "DistanceToWaterSurface")
164 @Field(analyze
= Analyze
.NO
)
166 private Double distanceToWaterSurface
;
168 // distance in meters to lake or sea surface. Similar to distanceToGround use negative integers for distance *below* the surface, ie under water
169 @XmlElement(name
= "DistanceToWaterSurface")
170 @Field(analyze
= Analyze
.NO
)
172 private Double distanceToWaterSurfaceMax
;
178 public static GatheringEvent
NewInstance(){
179 return new GatheringEvent();
185 protected GatheringEvent() {
189 public Point
getExactLocation(){
190 return this.exactLocation
;
192 public void setExactLocation(Point exactLocation
){
193 this.exactLocation
= exactLocation
;
198 public NamedArea
getCountry() {
202 public void setCountry(NamedArea country
) {
203 this.country
= country
;
207 * Further collecting areas. Should not include #getCountry()
210 public Set
<NamedArea
> getCollectingAreas(){
211 if(collectingAreas
== null) {
212 this.collectingAreas
= new HashSet
<NamedArea
>();
214 return this.collectingAreas
;
219 * Further collecting areas. Should not include #getCountry()
222 public void addCollectingArea(NamedArea area
){
223 if (this.collectingAreas
== null) {
224 this.collectingAreas
= getNewNamedAreaSet();
226 this.collectingAreas
.add(area
);
229 public void removeCollectingArea(NamedArea area
){
230 //TODO to be implemented?
231 logger
.warn("not yet fully implemented?");
232 this.collectingAreas
.remove(area
);
235 public LanguageString
getLocality(){
236 return this.locality
;
239 public void setLocality(LanguageString locality
){
240 this.locality
= locality
;
244 * EventBase managed attributes
249 public Partial
getGatheringDate(){
250 return this.getTimeperiod().getStart();
253 public void setGatheringDate(Partial gatheringDate
){
254 this.setTimeperiod(TimePeriod
.NewInstance(gatheringDate
));
257 public void setGatheringDate(Calendar gatheringDate
){
258 this.setTimeperiod(TimePeriod
.NewInstance(gatheringDate
));
262 public AgentBase
getCollector(){
263 return this.getActor();
266 public void setCollector(AgentBase collector
){
267 this.setActor(collector
);
270 public String
getCollectingMethod() {
271 return collectingMethod
;
274 public void setCollectingMethod(String collectingMethod
) {
275 this.collectingMethod
= collectingMethod
;
278 public Integer
getAbsoluteElevation() {
279 return absoluteElevation
;
282 public void setAbsoluteElevation(Integer absoluteElevation
) {
283 this.absoluteElevation
= absoluteElevation
;
287 public Integer
getAbsoluteElevationMax() {
288 return absoluteElevationMax
;
291 public void setAbsoluteElevationMax(Integer absoluteElevationMax
) {
292 this.absoluteElevationMax
= absoluteElevationMax
;
296 public String
getAbsoluteElevationText() {
297 return absoluteElevationText
;
300 public void setAbsoluteElevationText(String absoluteElevationText
) {
301 this.absoluteElevationText
= absoluteElevationText
;
304 // public Integer getAbsoluteElevationError() {
305 // return absoluteElevationError;
308 // public void setAbsoluteElevationError(Integer absoluteElevationError) {
309 // this.absoluteElevationError = absoluteElevationError;
312 public Double
getDistanceToGround() {
313 return distanceToGround
;
316 public void setDistanceToGround(Double distanceToGround
) {
317 this.distanceToGround
= distanceToGround
;
320 public Double
getDistanceToWaterSurface() {
321 return distanceToWaterSurface
;
324 public void setDistanceToWaterSurface(Double distanceToWaterSurface
) {
325 this.distanceToWaterSurface
= distanceToWaterSurface
;
328 //*********** CLONE **********************************/
331 * Clones <i>this</i> gathering event. This is a shortcut that enables to
332 * create a new instance that differs only slightly from <i>this</i> gathering event
333 * by modifying only some of the attributes.<BR>
334 * This method overrides the clone method from {@link DerivedUnitBase DerivedUnitBase}.
336 * @see DerivedUnitBase#clone()
337 * @see eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity#clone()
338 * @see java.lang.Object#clone()
341 public GatheringEvent
clone(){
343 GatheringEvent result
= (GatheringEvent
)super.clone();
345 LanguageString langString
= LanguageString
.NewInstance(this.locality
.getText(), this.locality
.getLanguage());
346 result
.setLocality(langString
);
348 result
.setExactLocation(this.exactLocation
.clone());
350 result
.collectingAreas
= new HashSet
<NamedArea
>();
351 for(NamedArea collectingArea
: this.collectingAreas
) {
352 result
.addCollectingArea(collectingArea
);
355 //no changes to: distanceToWaterSurface, distanceToGround, collectingMethod, absoluteElevationError, absoluteElevation
357 } catch (CloneNotSupportedException e
) {
358 logger
.warn("Object does not implement cloneable");
364 private static Set
<NamedArea
> getNewNamedAreaSet(){
365 return new HashSet
<NamedArea
>();