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
.description
;
12 import java
.util
.ArrayList
;
13 import java
.util
.HashSet
;
16 import javax
.persistence
.Entity
;
17 import javax
.persistence
.FetchType
;
18 import javax
.persistence
.ManyToOne
;
19 import javax
.persistence
.OneToMany
;
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
;
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
.Indexed
;
35 import org
.hibernate
.validator
.constraints
.NotEmpty
;
37 import eu
.etaxonomy
.cdm
.validation
.Level2
;
40 * This class represents information pieces expressed in numerical data
41 * (in opposition to {@link CategoricalData categorical data} on one side and to literal data on
42 * the other side). Only {@link TaxonDescription taxon descriptions} and
43 * {@link SpecimenDescription specimen descriptions} may contain quantitative data.<BR>
44 * The "length of leaves" {@link Feature feature} for instance can be measured in inches.
45 * If the length of leaves of a particular tree is described as
46 * "typically between 3 and 5 inches" and "at the utmost 8 inches" then three
47 * {@link StatisticalMeasurementValue statistical measurement value} instances
48 * must be assigned to an instance of the present class
49 * (with the {@link MeasurementUnit measurement unit} set to "inch"):<ul>
50 * <li> the first one with the value "3" and the {@link StatisticalMeasure statistical measure}
51 * "typical lower boundary",
52 * <li> the second one with the value "5" and the statistical measure
53 * "typical upper boundary"
54 * <li> the third one with the value "8" and the statistical measure "maximum"
57 * This class corresponds partially to CodedDescriptionType according to
62 * @created 08-Nov-2007 13:06:46
64 @XmlAccessorType(XmlAccessType
.FIELD
)
65 @XmlType(name
= "QuantitativeData", propOrder
= {
69 @XmlRootElement(name
= "QuantitativeData")
71 @Indexed(index
= "eu.etaxonomy.cdm.model.description.DescriptionElementBase")
73 public class QuantitativeData
extends DescriptionElementBase
implements Cloneable
{
74 private static final long serialVersionUID
= -2755806455420051488L;
75 @SuppressWarnings("unused")
76 private static final Logger logger
= Logger
.getLogger(QuantitativeData
.class);
78 @XmlElement(name
= "MeasurementUnit")
80 @XmlSchemaType(name
= "IDREF")
81 @ManyToOne(fetch
= FetchType
.LAZY
)
82 private MeasurementUnit unit
;
84 @XmlElementWrapper(name
= "StatisticalValues")
85 @XmlElement(name
= "StatisticalValue")
86 @OneToMany(fetch
= FetchType
.LAZY
)
87 @Cascade({ CascadeType
.SAVE_UPDATE
, CascadeType
.MERGE
, CascadeType
.DELETE
,CascadeType
.DELETE_ORPHAN
})
88 @NotEmpty(groups
= Level2
.class)
89 private Set
<StatisticalMeasurementValue
> statisticalValues
= new HashSet
<StatisticalMeasurementValue
>();
91 // ******************************** FACTORY METHOD *******************************/
94 * Creates a new empty quantitative data instance.
96 public static QuantitativeData
NewInstance(){
97 return new QuantitativeData();
100 // ******************************** FACTORY METHOD *******************************/
103 * Creates a new empty quantitative data instance.
105 public static QuantitativeData
NewInstance(Feature feature
){
106 return new QuantitativeData(feature
);
110 // ******************************** CONSTRUCTOR *******************************/
113 * Class constructor: creates a new empty quantitative data instance.
115 protected QuantitativeData(){
120 * Class constructor: creates a new empty quantitative data instance.
122 protected QuantitativeData(Feature feature
){
127 // ******************************** GETTER /SETTER *******************************/
131 * Returns the set of {@link StatisticalMeasurementValue statistical measurement values} describing
132 * the {@link Feature feature} corresponding to <i>this</i> quantitative data.
134 public Set
<StatisticalMeasurementValue
> getStatisticalValues() {
135 return statisticalValues
;
138 protected void setStatisticalValues(Set
<StatisticalMeasurementValue
> statisticalValues
) {
139 this.statisticalValues
= statisticalValues
;
142 * Adds a {@link StatisticalMeasurementValue statistical measurement value} to the set of
143 * {@link #getStatisticalValues() statistical measurement values} describing
144 * the {@link Feature feature} corresponding to <i>this</i> quantitative data.
146 * @param statisticalValue the statistical measurement value to be added to
147 * <i>this</i> quantitative data
148 * @see #getStatisticalValues()
150 public void addStatisticalValue(StatisticalMeasurementValue statisticalValue
) {
151 this.statisticalValues
.add(statisticalValue
);
154 * Removes one element from the set of {@link #getStatisticalValues() statistical measurement values}
155 * describing the {@link Feature feature} corresponding to <i>this</i> quantitative data.
157 * @param statisticalValue the statistical measurement value which should be removed
158 * @see #getStatisticalValues()
159 * @see #addStatisticalValue(StatisticalMeasurementValue)
161 public void removeStatisticalValue(StatisticalMeasurementValue statisticalValue
) {
162 this.statisticalValues
.remove(statisticalValue
);
167 * Returns the {@link MeasurementUnit measurement unit} used in <i>this</i>
170 public MeasurementUnit
getUnit(){
176 public void setUnit(MeasurementUnit unit
){
180 // ******************************** TRANSIENT METHODS *******************************/
184 * Returns the numerical value of the one {@link StatisticalMeasurementValue statistical measurement value}
185 * with the corresponding {@link StatisticalMeasure statistical measure} "minimum" and
186 * belonging to <i>this</i> quantitative data. Returns <code>null</code> if no such
187 * statistical measurement value instance exists.
190 public Float
getMin(){
191 return getSpecificStatisticalValue(StatisticalMeasure
.MIN());
195 * Returns the numerical value of the one {@link StatisticalMeasurementValue statistical measurement value}
196 * with the corresponding {@link StatisticalMeasure statistical measure} "maximum" and
197 * belonging to <i>this</i> quantitative data. Returns <code>null</code> if no such
198 * statistical measurement value instance exists.
201 public Float
getMax(){
202 return getSpecificStatisticalValue(StatisticalMeasure
.MAX());
206 * Returns the numerical value of the one {@link StatisticalMeasurementValue statistical measurement value}
207 * with the corresponding {@link StatisticalMeasure statistical measure}
208 * "typical lower boundary" and belonging to <i>this</i> quantitative data.
209 * Returns <code>null</code> if no such statistical measurement value instance exists.
212 public Float
getTypicalLowerBoundary(){
213 return getSpecificStatisticalValue(StatisticalMeasure
.TYPICAL_LOWER_BOUNDARY());
217 * Returns the numerical value of the one {@link StatisticalMeasurementValue statistical measurement value}
218 * with the corresponding {@link StatisticalMeasure statistical measure}
219 * "typical upper boundary" and belonging to <i>this</i> quantitative data.
220 * Returns <code>null</code> if no such statistical measurement value instance exists.
223 public Float
getTypicalUpperBoundary(){
224 return getSpecificStatisticalValue(StatisticalMeasure
.TYPICAL_UPPER_BOUNDARY());
228 * Returns the statistical value of type <code>type</code>.
229 * If no such value exists <code>null</code> is returned. If multiple such
230 * values exist an arbitrary one is returned.
234 public Float
getSpecificStatisticalValue(StatisticalMeasure type
){
236 for (StatisticalMeasurementValue value
: statisticalValues
){
237 if (type
.equals(value
.getType())){
238 result
= value
.getValue();
246 //*********************************** CLONE *****************************************/
249 * Clones <i>this</i> quantitative data. This is a shortcut that enables to create
250 * a new instance that differs only slightly from <i>this</i> quantitative data by
251 * modifying only some of the attributes.
253 * @see eu.etaxonomy.cdm.model.description.DescriptionElementBase#clone()
254 * @see java.lang.Object#clone()
257 public Object
clone() {
260 QuantitativeData result
= (QuantitativeData
)super.clone();
263 result
.statisticalValues
= new HashSet
<StatisticalMeasurementValue
>();
264 for (StatisticalMeasurementValue data
: getStatisticalValues()){
265 //TODO do we need to clone here?
266 StatisticalMeasurementValue newData
= (StatisticalMeasurementValue
)data
.clone();
267 result
.statisticalValues
.add(newData
);
271 //no changes to: unit
272 } catch (CloneNotSupportedException e
) {
273 logger
.warn("Object does not implement cloneable");