Major changes to the cdmlib default term loading and initialization, plus indexing...
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / occurrence / GatheringEvent.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.occurrence;
11
12 import java.util.Calendar;
13 import java.util.HashSet;
14 import java.util.Set;
15
16 import javax.persistence.Entity;
17 import javax.persistence.FetchType;
18 import javax.persistence.ManyToMany;
19 import javax.persistence.ManyToOne;
20 import javax.persistence.Transient;
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.joda.time.Partial;
34
35 import eu.etaxonomy.cdm.model.agent.Agent;
36 import eu.etaxonomy.cdm.model.common.EventBase;
37 import eu.etaxonomy.cdm.model.common.LanguageString;
38 import eu.etaxonomy.cdm.model.common.TimePeriod;
39 import eu.etaxonomy.cdm.model.location.NamedArea;
40 import eu.etaxonomy.cdm.model.location.Point;
41
42 /**
43 * The event when gathering a specimen or recording a field observation only
44 * @author m.doering
45 *
46 */
47 @XmlAccessorType(XmlAccessType.FIELD)
48 @XmlType(name = "GatheringEvent", propOrder = {
49 "locality",
50 "exactLocation",
51 "collectingAreas",
52 "collectingMethod",
53 "absoluteElevation",
54 "absoluteElevationError",
55 "distanceToGround",
56 "distanceToWaterSurface"
57 })
58 @XmlRootElement(name = "GatheringEvent")
59 @Entity
60 //@Audited
61 public class GatheringEvent extends EventBase implements Cloneable{
62
63 static Logger logger = Logger.getLogger(GatheringEvent.class);
64
65 //Locality name (as free text) where this occurrence happened
66 @XmlElement(name = "Locality")
67 private LanguageString locality;
68
69 @XmlElement(name = "ExactLocation")
70 private Point exactLocation;
71
72 @XmlElementWrapper(name = "CollectingAreas")
73 @XmlElement(name = "CollectingArea")
74 @XmlIDREF
75 @XmlSchemaType(name = "IDREF")
76 private Set<NamedArea> collectingAreas = getNewNamedAreaSet();
77
78 @XmlElement(name = "CollectingMethod")
79 private String collectingMethod;
80
81 // meter above/below sea level of the surface
82 @XmlElement(name = "AbsoluteElevation")
83 private Integer absoluteElevation;
84
85 @XmlElement(name = "AbsoluteElevationError")
86 private Integer absoluteElevationError;
87
88 // 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
89 @XmlElement(name = "DistanceToGround")
90 private Integer distanceToGround;
91
92 // distance in meters to lake or sea surface. Similar to distanceToGround use negative integers for distance *below* the surface, ie under water
93 @XmlElement(name = "DistanceToWaterSurface")
94 private Integer distanceToWaterSurface;
95
96
97 /**
98 * Factory method
99 * @return
100 */
101 public static GatheringEvent NewInstance(){
102 return new GatheringEvent();
103 }
104
105 /**
106 * Constructor
107 */
108 protected GatheringEvent() {
109 super();
110 }
111
112 public Point getExactLocation(){
113 return this.exactLocation;
114 }
115 public void setExactLocation(Point exactLocation){
116 this.exactLocation = exactLocation;
117 }
118
119 @ManyToMany(fetch = FetchType.LAZY)
120 public Set<NamedArea> getCollectingAreas(){
121 return this.collectingAreas;
122 }
123 public void setCollectingAreas(Set<NamedArea> area){
124 if (area == null){
125 getNewNamedAreaSet();
126 }
127 this.collectingAreas = area;
128 }
129 public void addCollectingArea(NamedArea area){
130 if (this.collectingAreas == null)
131 this.collectingAreas = getNewNamedAreaSet();
132 this.collectingAreas.add(area);
133 }
134 public void removeCollectingArea(NamedArea area){
135 //TODO to be implemented?
136 logger.warn("not yet fully implemented?");
137 this.collectingAreas.remove(area);
138 }
139
140 @ManyToOne(fetch = FetchType.LAZY)
141 @Cascade({CascadeType.SAVE_UPDATE})
142 public LanguageString getLocality(){
143 return this.locality;
144 }
145 public void setLocality(LanguageString locality){
146 this.locality = locality;
147 }
148
149 /**
150 * EventBase managed attributes
151 * @return
152 */
153 @Transient
154 public Partial getGatheringDate(){
155 return this.getTimeperiod().getStart();
156 }
157 public void setGatheringDate(Partial gatheringDate){
158 this.setTimeperiod(TimePeriod.NewInstance(gatheringDate));
159 }
160 @Transient
161 public void setGatheringDate(Calendar gatheringDate){
162 this.setTimeperiod(TimePeriod.NewInstance(gatheringDate));
163 }
164
165 @Transient
166 public Agent getCollector(){
167 return this.getActor();
168 }
169 public void setCollector(Agent collector){
170 this.setActor(collector);
171 }
172
173
174 public String getCollectingMethod() {
175 return collectingMethod;
176 }
177 public void setCollectingMethod(String collectingMethod) {
178 this.collectingMethod = collectingMethod;
179 }
180
181
182 public Integer getAbsoluteElevation() {
183 return absoluteElevation;
184 }
185
186 public void setAbsoluteElevation(Integer absoluteElevation) {
187 this.absoluteElevation = absoluteElevation;
188 }
189
190
191 public Integer getAbsoluteElevationError() {
192 return absoluteElevationError;
193 }
194 public void setAbsoluteElevationError(Integer absoluteElevationError) {
195 this.absoluteElevationError = absoluteElevationError;
196 }
197 public Integer getDistanceToGround() {
198 return distanceToGround;
199 }
200 public void setDistanceToGround(Integer distanceToGround) {
201 this.distanceToGround = distanceToGround;
202 }
203 public Integer getDistanceToWaterSurface() {
204 return distanceToWaterSurface;
205 }
206 public void setDistanceToWaterSurface(Integer distanceToWaterSurface) {
207 this.distanceToWaterSurface = distanceToWaterSurface;
208 }
209
210
211 //*********** CLONE **********************************/
212
213 /**
214 * Clones <i>this</i> gathering event. This is a shortcut that enables to
215 * create a new instance that differs only slightly from <i>this</i> gathering event
216 * by modifying only some of the attributes.<BR>
217 * This method overrides the clone method from {@link DerivedUnitBase DerivedUnitBase}.
218 *
219 * @see DerivedUnitBase#clone()
220 * @see eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity#clone()
221 * @see java.lang.Object#clone()
222 */
223 @Override
224 public GatheringEvent clone(){
225 try{
226 GatheringEvent result = (GatheringEvent)super.clone();
227 //locality
228 LanguageString langString = LanguageString.NewInstance(this.locality.getText(), this.locality.getLanguage());
229 result.setLocality(langString);
230 //exact location
231 result.setExactLocation(this.exactLocation.clone());
232 //namedAreas
233 Set<NamedArea> namedAreas = getNewNamedAreaSet();
234 namedAreas.addAll(this.collectingAreas);
235 result.setCollectingAreas(namedAreas);
236
237 //no changes to: distanceToWaterSurface, distanceToGround, collectingMethod, absoluteElevationError, absoluteElevation
238 return result;
239 } catch (CloneNotSupportedException e) {
240 logger.warn("Object does not implement cloneable");
241 e.printStackTrace();
242 return null;
243 }
244 }
245
246 private static Set<NamedArea> getNewNamedAreaSet(){
247 return new HashSet<NamedArea>();
248 }
249 }