root/trunk/cdmlib/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/description/QuantitativeData.java

Revision 11844, 14.8 kB (checked in by a.mueller, 13 months ago)

bugfix for generic setter (missing type)

  • Property svn:keywords set to Id
Line 
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
10package eu.etaxonomy.cdm.model.description;
11
12import java.util.HashSet;
13import java.util.Set;
14
15import javax.persistence.Entity;
16import javax.persistence.FetchType;
17import javax.persistence.ManyToOne;
18import javax.persistence.OneToMany;
19import javax.persistence.Transient;
20import javax.xml.bind.annotation.XmlAccessType;
21import javax.xml.bind.annotation.XmlAccessorType;
22import javax.xml.bind.annotation.XmlElement;
23import javax.xml.bind.annotation.XmlElementWrapper;
24import javax.xml.bind.annotation.XmlIDREF;
25import javax.xml.bind.annotation.XmlRootElement;
26import javax.xml.bind.annotation.XmlSchemaType;
27import javax.xml.bind.annotation.XmlType;
28
29import org.apache.log4j.Logger;
30import org.hibernate.annotations.Cascade;
31import org.hibernate.annotations.CascadeType;
32import org.hibernate.envers.Audited;
33import org.hibernate.search.annotations.Indexed;
34import org.hibernate.validator.constraints.NotEmpty;
35
36import eu.etaxonomy.cdm.validation.Level2;
37
38/**
39 * This class represents information pieces expressed in numerical data
40 * (in opposition to {@link CategoricalData categorical data} on one side and to literal data on
41 * the other side). Only {@link TaxonDescription taxon descriptions} and
42 * {@link SpecimenDescription specimen descriptions} may contain quantitative data.<BR>
43 * The "length of leaves" {@link Feature feature} for instance can be measured in inches.
44 * If the length of leaves of a particular tree is described as
45 * "typically between 3 and 5 inches" and "at the utmost 8 inches" then three
46 * {@link StatisticalMeasurementValue statistical measurement value} instances
47 * must be assigned to an instance of the present class
48 * (with the {@link MeasurementUnit measurement unit} set to "inch"):<ul>
49 * <li> the first one with the value "3" and the {@link StatisticalMeasure statistical measure}
50 * "typical lower boundary",
51 * <li> the second one with the value "5" and the statistical measure
52 * "typical upper boundary"
53 * <li> the third one with the value "8" and the statistical measure "maximum"
54 * </ul>
55 * <P>
56 * This class corresponds partially to CodedDescriptionType according to
57 * the SDD schema.
58 *
59 * @author m.doering
60 * @version 1.0
61 * @created 08-Nov-2007 13:06:46
62 */
63@XmlAccessorType(XmlAccessType.FIELD)
64@XmlType(name = "QuantitativeData", propOrder = {
65    "unit",
66    "statisticalValues"
67})
68@XmlRootElement(name = "QuantitativeData")
69@Entity
70@Indexed(index = "eu.etaxonomy.cdm.model.description.DescriptionElementBase")
71@Audited
72public class QuantitativeData extends DescriptionElementBase implements Cloneable {
73        private static final long serialVersionUID = -2755806455420051488L;
74        @SuppressWarnings("unused")
75        private static final Logger logger = Logger.getLogger(QuantitativeData.class);
76       
77        @XmlElement(name = "MeasurementUnit")
78        @XmlIDREF
79        @XmlSchemaType(name = "IDREF")
80        @ManyToOne(fetch = FetchType.LAZY)
81        private MeasurementUnit unit;
82       
83        @XmlElementWrapper(name = "StatisticalValues")
84        @XmlElement(name = "StatisticalValue")
85        @OneToMany(fetch = FetchType.LAZY)
86        @Cascade({ CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE,CascadeType.DELETE_ORPHAN })
87        @NotEmpty(groups = Level2.class)
88        private Set<StatisticalMeasurementValue> statisticalValues = new HashSet<StatisticalMeasurementValue>();
89
90// ******************************** FACTORY METHOD *******************************/
91       
92        /**
93         * Creates a new empty quantitative data instance.
94         */
95        public static QuantitativeData NewInstance(){
96                return new QuantitativeData();
97        }
98
99// ******************************** FACTORY METHOD *******************************/
100       
101        /**
102         * Creates a new empty quantitative data instance.
103         */
104        public static QuantitativeData NewInstance(Feature feature){
105                return new QuantitativeData(feature);
106        }
107
108       
109// ******************************** CONSTRUCTOR *******************************/
110
111        /**
112         * Class constructor: creates a new empty quantitative data instance.
113         */
114        protected QuantitativeData(){
115                super(null);
116        }
117
118        /**
119         * Class constructor: creates a new empty quantitative data instance.
120         */
121        protected QuantitativeData(Feature feature){
122                super(feature);
123        }
124
125       
126// ******************************** GETTER /SETTER *******************************/
127       
128       
129        /**
130         * Returns the set of {@link StatisticalMeasurementValue statistical measurement values} describing
131         * the {@link Feature feature} corresponding to <i>this</i> quantitative data.
132         */
133        public Set<StatisticalMeasurementValue> getStatisticalValues() {
134                return statisticalValues;
135        }
136
137        protected void setStatisticalValues(Set<StatisticalMeasurementValue> statisticalValues) {
138                this.statisticalValues = statisticalValues;
139        }
140        /**
141         * Adds a {@link StatisticalMeasurementValue statistical measurement value} to the set of
142         * {@link #getStatisticalValues() statistical measurement values} describing
143         * the {@link Feature feature} corresponding to <i>this</i> quantitative data.
144         *
145         * @param statisticalValue      the statistical measurement value to be added to
146         *                                                      <i>this</i> quantitative data
147         * @see                                         #getStatisticalValues()
148         */
149        public void addStatisticalValue(StatisticalMeasurementValue statisticalValue) {
150                this.statisticalValues.add(statisticalValue);
151        }
152        /**
153         * Removes one element from the set of {@link #getStatisticalValues() statistical measurement values}
154         * describing the {@link Feature feature} corresponding to <i>this</i> quantitative data.
155         *
156         * @param  statisticalValue     the statistical measurement value which should be removed
157         * @see                                 #getStatisticalValues()
158         * @see                                 #addStatisticalValue(StatisticalMeasurementValue)
159         */
160        public void removeStatisticalValue(StatisticalMeasurementValue statisticalValue) {
161                this.statisticalValues.remove(statisticalValue);
162        }
163
164       
165        /**
166         * Returns the {@link MeasurementUnit measurement unit} used in <i>this</i>
167         * quantitative data.
168         */
169        public MeasurementUnit getUnit(){
170                return this.unit;
171        }
172        /**
173         * @see #getUnit()
174         */
175        public void setUnit(MeasurementUnit unit){
176                this.unit = unit;
177        }
178
179// ******************************** TRANSIENT METHODS *******************************/
180       
181       
182        /**
183         * Returns the numerical value of the one {@link StatisticalMeasurementValue statistical measurement value}
184         * with the corresponding {@link StatisticalMeasure statistical measure} "minimum" and
185         * belonging to <i>this</i> quantitative data. Returns <code>null</code> if no such
186         * statistical measurement value instance exists.
187         */
188        @Transient
189        public Float getMin(){
190                return getSpecificStatisticalValue(StatisticalMeasure.MIN());
191        }
192
193        /**
194         * Returns the numerical value of the one {@link StatisticalMeasurementValue statistical measurement value}
195         * with the corresponding {@link StatisticalMeasure statistical measure} "maximum" and
196         * belonging to <i>this</i> quantitative data. Returns <code>null</code> if no such
197         * statistical measurement value instance exists.
198         */
199        @Transient
200        public Float getMax(){
201                return getSpecificStatisticalValue(StatisticalMeasure.MAX());
202        }
203
204        /**
205         * Returns the numerical value of the one {@link StatisticalMeasurementValue statistical measurement value}
206         * with the corresponding {@link StatisticalMeasure statistical measure}
207         * "typical lower boundary" and belonging to <i>this</i> quantitative data.
208         * Returns <code>null</code> if no such statistical measurement value instance exists.
209         */
210        @Transient
211        public Float getTypicalLowerBoundary(){
212                return getSpecificStatisticalValue(StatisticalMeasure.TYPICAL_LOWER_BOUNDARY());
213        }
214       
215        /**
216         * Returns the numerical value of the one {@link StatisticalMeasurementValue statistical measurement value}
217         * with the corresponding {@link StatisticalMeasure statistical measure}
218         * "average" and belonging to <i>this</i> quantitative data.
219         * Returns <code>null</code> if no such statistical measurement value instance exists.
220         */
221        @Transient
222        public Float getAverage(){
223                return getSpecificStatisticalValue(StatisticalMeasure.AVERAGE());
224        }
225
226        /**
227         * Returns the numerical value of the one {@link StatisticalMeasurementValue statistical measurement value}
228         * with the corresponding {@link StatisticalMeasure statistical measure}
229         * "standard deviation" and belonging to <i>this</i> quantitative data.
230         * Returns <code>null</code> if no such statistical measurement value instance exists.
231         */
232        @Transient
233        public Float getStandardDeviation(){
234                return getSpecificStatisticalValue(StatisticalMeasure.STANDARD_DEVIATION());
235        }
236
237        /**
238         * Returns the numerical value of the one {@link StatisticalMeasurementValue statistical measurement value}
239         * with the corresponding {@link StatisticalMeasure statistical measure}
240         * "sample size" and belonging to <i>this</i> quantitative data.
241         * Returns <code>null</code> if no such statistical measurement value instance exists.
242         */
243        @Transient
244        public Float getSampleSize(){
245                return getSpecificStatisticalValue(StatisticalMeasure.SAMPLE_SIZE());
246        }
247       
248        /**
249         * Returns the numerical value of the one {@link StatisticalMeasurementValue statistical measurement value}
250         * with the corresponding {@link StatisticalMeasure statistical measure}
251         * "typical upper boundary" and belonging to <i>this</i> quantitative data.
252         * Returns <code>null</code> if no such statistical measurement value instance exists.
253         */
254        @Transient
255        public Float getTypicalUpperBoundary(){
256                return getSpecificStatisticalValue(StatisticalMeasure.TYPICAL_UPPER_BOUNDARY());
257        }
258
259        /**
260         * Returns the statistical value of type <code>type</code>.
261         * If no such value exists <code>null</code> is returned. If multiple such
262         * values exist an arbitrary one is returned.
263         * @param type
264         * @return the value
265         */
266        public Float getSpecificStatisticalValue(StatisticalMeasure type){
267                Float result = null;
268                for (StatisticalMeasurementValue value : statisticalValues){
269                        if (type.equals(value.getType())){
270                                result = value.getValue();
271                                break;
272                        }
273                }
274                return result;
275        }
276
277       
278        /**
279         * Sets the statistical value for the minimum.
280         * If such value exists the old value is replaced by the new value.
281         * The new value is returned.
282         * @param type
283         * @param value
284         * @return the newValue
285         */
286        @Transient
287        public StatisticalMeasurementValue setMinimum(Float value, Set<Modifier> modifiers){
288                return setSpecificStatisticalValue(value, modifiers, StatisticalMeasure.MIN());
289        }
290
291       
292        /**
293         * Sets the statistical value for the maximum.
294         * If such value exists the old value is replaced by the new value.
295         * The new value is returned.
296         * @param type
297         * @param value
298         * @return the newValue
299         */
300        @Transient
301        public StatisticalMeasurementValue setMaximum(Float value, Set<Modifier> modifiers){
302                return setSpecificStatisticalValue(value, modifiers, StatisticalMeasure.MAX());
303        }
304       
305       
306        /**
307         * Sets the statistical value for the average.
308         * If such value exists the old value is replaced by the new value.
309         * The new value is returned.
310         * @param type
311         * @param value
312         * @return the newValue
313         */
314        @Transient
315        public StatisticalMeasurementValue setAverage(Float value, Set<Modifier> modifiers){
316                return setSpecificStatisticalValue(value, modifiers, StatisticalMeasure.AVERAGE());
317        }
318
319       
320        /**
321         * Sets the statistical value for the standard deviation.
322         * If such value exists the old value is replaced by the new value.
323         * The new value is returned.
324         * @param type
325         * @param value
326         * @return the newValue
327         */
328        @Transient
329        public StatisticalMeasurementValue setStandardDeviation(Float value, Set<Modifier> modifiers){
330                return setSpecificStatisticalValue(value, modifiers, StatisticalMeasure.STANDARD_DEVIATION());
331        }
332
333        /**
334         * Sets the statistical value for the sample size.
335         * If such value exists the old value is replaced by the new value.
336         * The new value is returned.
337         * @param type
338         * @param value
339         * @return the newValue
340         */
341        @Transient
342        public StatisticalMeasurementValue setSampleSize(Float value, Set<Modifier> modifiers){
343                return setSpecificStatisticalValue(value, modifiers, StatisticalMeasure.SAMPLE_SIZE());
344        }
345
346       
347        /**
348         * Sets the statistical value for the typical lower boundary.
349         * If such value exists the old value is replaced by the new value.
350         * The new value is returned.
351         * @param type
352         * @param value
353         * @return the newValue
354         */
355        @Transient
356        public StatisticalMeasurementValue setTypicalLowerBoundary(Float value, Set<Modifier> modifiers){
357                return setSpecificStatisticalValue(value, modifiers, StatisticalMeasure.TYPICAL_LOWER_BOUNDARY());
358        }
359
360       
361        /**
362         * Sets the statistical value for the typical upper boundary.
363         * If such value exists the old value is replaced by the new value.
364         * The new value is returned.
365         * @param type
366         * @param value
367         * @return the newValue
368         */
369        @Transient
370        public StatisticalMeasurementValue setTypicalUpperBoundary(Float value, Set<Modifier> modifiers){
371                return setSpecificStatisticalValue(value, modifiers, StatisticalMeasure.TYPICAL_UPPER_BOUNDARY());
372        }
373       
374        /**
375         * Sets the statistical value of type <code>type</code>.
376         * If such value exists the old value is replaced by the new value.
377         * The new value is returned.
378         * @param type
379         * @param value
380         * @return the newValue
381         */
382        public StatisticalMeasurementValue setSpecificStatisticalValue(Float value, Set<Modifier> modifiers, StatisticalMeasure type){
383                StatisticalMeasurementValue result = null;
384                if (value != null){
385                        StatisticalMeasurementValue newValue = StatisticalMeasurementValue.NewInstance();
386                        newValue.setValue(value);
387                        if (modifiers != null){
388                                newValue.getModifiers().addAll(modifiers);
389                        }
390                        newValue.setType(type);
391                        result = newValue;
392                }
393                for (StatisticalMeasurementValue existingValue : statisticalValues){
394                        if (type.equals(existingValue.getType())){
395                                result = existingValue;
396                                statisticalValues.remove(existingValue);
397                                break;
398                        }
399                }
400                if (result != null){
401                        statisticalValues.add(result);
402                }
403                return result;
404        }
405       
406
407//*********************************** CLONE *****************************************/
408
409        /**
410         * Clones <i>this</i> quantitative data. This is a shortcut that enables to create
411         * a new instance that differs only slightly from <i>this</i> quantitative data by
412         * modifying only some of the attributes.
413         *
414         * @see eu.etaxonomy.cdm.model.description.DescriptionElementBase#clone()
415         * @see java.lang.Object#clone()
416         */
417        @Override
418        public Object clone() {
419
420                try {
421                        QuantitativeData result = (QuantitativeData)super.clone();
422                       
423                        //states
424                        result.statisticalValues = new HashSet<StatisticalMeasurementValue>();
425                        for (StatisticalMeasurementValue data : getStatisticalValues()){
426                                //TODO do we need to clone here?
427                                StatisticalMeasurementValue newData = (StatisticalMeasurementValue)data.clone();
428                                result.statisticalValues.add(newData);
429                        }
430                       
431                        return result;
432                        //no changes to: unit
433                } catch (CloneNotSupportedException e) {
434                        logger.warn("Object does not implement cloneable");
435                        e.printStackTrace();
436                        return null;
437                }
438        }       
439
440}
Note: See TracBrowser for help on using the browser.