Project

General

Profile

Download (9.2 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.description;
11

    
12
import java.util.ArrayList;
13
import java.util.Arrays;
14
import java.util.List;
15

    
16
import javax.persistence.Entity;
17
import javax.persistence.FetchType;
18
import javax.persistence.OneToMany;
19
import javax.persistence.Transient;
20
import javax.xml.bind.annotation.XmlAccessType;
21
import javax.xml.bind.annotation.XmlAccessorType;
22
import javax.xml.bind.annotation.XmlElement;
23
import javax.xml.bind.annotation.XmlElementWrapper;
24
import javax.xml.bind.annotation.XmlRootElement;
25
import javax.xml.bind.annotation.XmlTransient;
26
import javax.xml.bind.annotation.XmlType;
27

    
28
import org.apache.log4j.Logger;
29
import org.hibernate.annotations.Cascade;
30
import org.hibernate.annotations.CascadeType;
31
import org.hibernate.envers.Audited;
32
import org.hibernate.search.annotations.Indexed;
33
import org.hibernate.search.annotations.IndexedEmbedded;
34
import org.hibernate.validator.constraints.NotEmpty;
35

    
36
import eu.etaxonomy.cdm.validation.Level2;
37

    
38
/**
39
 * This class represents information pieces expressed in categorical type of
40
 * data (in opposition to {@link QuantitativeData quantitative 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 categorical data.<BR>
43
 * The "color of petals" {@link Feature feature} for instance can be described with
44
 * {@link State state terms} such as "blue" or "white". If the color of petals of a
45
 * particular tree is described as "mostly blue" and "exceptionally white" two
46
 * {@link StateData state data} instances must be assigned to an instance of the
47
 * present class: the first one with the state "blue" and the {@link Modifier modifier}
48
 * "mostly" and the second one with the state "white" and the modifier "exceptionally".
49
 * Whenever more than one state data belongs to a categorical data they should be
50
 * interpreted as being related by the inclusive disjunction "or".
51
 * <P>
52
 * This class corresponds partially to CodedDescriptionType according to
53
 * the SDD schema.
54
 *
55
 * @author m.doering
56
 * @created 08-Nov-2007 13:06:15
57
 */
58
@XmlAccessorType(XmlAccessType.FIELD)
59
@XmlType(name = "CategoricalData", propOrder = {
60
    "orderRelevant",
61
    "stateData",
62
    "unknownData"
63
})
64
@XmlRootElement(name = "CategoricalData")
65
@Entity
66
@Audited
67
@Indexed(index = "eu.etaxonomy.cdm.model.description.DescriptionElementBase")
68
public class CategoricalData extends DescriptionElementBase implements Cloneable{
69
    private static final long serialVersionUID = -6298361966947668998L;
70
    private static final Logger logger = Logger.getLogger(CategoricalData.class);
71

    
72
    //whether the sequence of ordered states is important
73
    @XmlElement(name = "OrderRelevant")
74
    private boolean orderRelevant;
75

    
76
    @XmlElementWrapper(name = "States")
77
    @XmlElement(name = "State")
78
    @OneToMany(fetch = FetchType.LAZY, mappedBy="categoricalData", orphanRemoval=true)
79
    @Cascade({ CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE})
80
    @IndexedEmbedded(depth = 3)
81
    @NotEmpty(groups = Level2.class)
82
    private List<StateData> stateData = new ArrayList<>();
83

    
84
    @XmlElement(name = "UnknownData")
85
    private final Boolean unknownData = false;
86

    
87
//****************************** FACTORY METHOD *******************************/
88

    
89
    /**
90
     * Creates a new empty categorical data instance.
91
     */
92
    public static CategoricalData NewInstance(){
93
        return new CategoricalData();
94
    }
95

    
96

    
97
    /**
98
     * @param habitat
99
     * @return
100
     */
101
    public static CategoricalData NewInstance(Feature feature) {
102
        return new CategoricalData( new ArrayList<>() , feature);
103
    }
104

    
105
    /**
106
     * Creates a new empty categorical data instance.
107
     */
108
    public static CategoricalData NewInstance(State state, Feature feature){
109
        return new CategoricalData( Arrays.asList( new State[]{state}) , feature);
110
    }
111

    
112
//*******************  CONSTRUCTOR *********************************************/
113

    
114
    /**
115
     * Class constructor: creates a new empty categorical data instance.
116
     */
117
    protected CategoricalData() {
118
        super(null);
119
    }
120

    
121
    /**
122
     * Class constructor: creates a new empty categorical data instance.
123
     */
124
    protected CategoricalData(List<State> states, Feature feature) {
125
        super(feature);
126
        for (State state : states){
127
            addStateData(state);
128
        }
129

    
130
    }
131

    
132
// ****************** GETTER / SETTER *********************************************/
133

    
134
    /**
135
     * Returns the (ordered) list of {@link State states} describing the {@link Feature feature}
136
     * corresponding to <i>this</i> categorical data.
137
     */
138

    
139
    public List<StateData> getStateData(){
140
        return this.stateData;
141
    }
142

    
143
    @Deprecated
144
    protected void setStateData(List<StateData> stateData){
145
        this.stateData = stateData;
146
    }
147

    
148
    /**
149
     * Adds a {@link State state} to the list of {@link #getStateData() states}
150
     * describing the {@link Feature feature} corresponding to <i>this</i> categorical data.
151
     *
152
     * @param state	the state to be added to <i>this</i> categorical data
153
     * @see    	   	#getStateData()
154
     */
155
    @SuppressWarnings("deprecation")
156
    public void addStateData(StateData stateData){
157
        this.stateData.add(stateData);
158
        stateData.setCategoricalData(this);
159
    }
160

    
161
    /**
162
     * Convenience method which creates a state data from a given state with no modifiers
163
     * and adds it to the list of state data
164
     * @see #addStateData(StateData)
165
     * @param state
166
     */
167
    public void addStateData(State state){
168
        StateData stateData = StateData.NewInstance(state);
169
        addStateData(stateData);
170
    }
171

    
172

    
173
    /**
174
     * Removes one element from the set of {@link #getStateData() states}
175
     * describing the {@link Feature feature} corresponding to <i>this</i> categorical data.
176
     *
177
     * @param  state	the state which should be removed
178
     * @see     		#getStateData()
179
     * @see     		#addStateData(State)
180
     */
181
    @SuppressWarnings("deprecation")
182
    public void removeStateData(StateData stateData){
183
        this.stateData.remove(stateData);
184
        stateData.setCategoricalData(null);
185
    }
186

    
187
    //rename to isStateSequenceIntentional ??
188
    /**
189
     * Returns the boolean value of the flag indicating whether the sequence of
190
     * {@link StateData state data} belonging to <i>this</i> categorical data is intentional
191
     * (true) and therefore relevant for interpretation or analysis or not (false).
192
     * The use of this flag depends mostly on the {@link Feature feature} of <i>this</i> categorical data.
193
     *
194
     * @return  the boolean value of the orderRelevant flag
195
     */
196
    public boolean getOrderRelevant(){
197
        return this.orderRelevant;
198
    }
199
    /**
200
     * @see	#getOrderRelevant()
201
     */
202
    public void setOrderRelevant(boolean orderRelevant){
203
        this.orderRelevant = orderRelevant;
204
    }
205

    
206
// ********************* CONVENIENCE ******************************************/
207

    
208
    /**
209
     * Convenience method which returns only the list of states. Leaving out modifiers and modifying text.
210
     * @return
211
     */
212
    @Transient
213
    public List<State> getStatesOnly(){
214
        List<State> result = new ArrayList<State>();
215
        for (StateData stateData : getStateData()){
216
            State state = stateData.getState();
217
            result.add(state);
218
        }
219
        return result;
220
    }
221

    
222
    /**
223
     * Convenience method which to set the list of states (no modifiers or modifying text allowed).
224
     * All existing state data are removed.
225
     * @return
226
     */
227
    public List<StateData> setStateDataOnly(List<State> states){
228
        List<StateData> stateDataList = new ArrayList<>(getStateData());
229
        for (StateData stateData : stateDataList) {
230
            removeStateData(stateData);
231
        }
232
        for (State state : states) {
233
            addStateData(state);
234
        }
235
        return this.stateData;
236
    }
237

    
238
    @Transient
239
    @XmlTransient
240
    @Override
241
    public boolean isCharacterData() {
242
        return true;
243
    }
244

    
245

    
246
//*********************************** CLONE *****************************************/
247

    
248
    /**
249
     * Clones <i>this</i> categorical data. This is a shortcut that enables to create
250
     * a new instance that differs only slightly from <i>this</i> categorical data by
251
     * modifying only some of the attributes.
252
     *
253
     * @see eu.etaxonomy.cdm.model.description.DescriptionElementBase#clone()
254
     * @see java.lang.Object#clone()
255
     */
256
    @Override
257
    public Object clone() {
258

    
259
        try {
260
            CategoricalData result = (CategoricalData)super.clone();
261

    
262
            //states
263
            result.stateData = new ArrayList<>();
264
            for (StateData stateData : getStateData()){
265
                StateData newState = (StateData)stateData.clone();
266
                result.addStateData(newState);
267
            }
268

    
269
            return result;
270
            //no changes to: orderRelevant
271
        } catch (CloneNotSupportedException e) {
272
            logger.warn("Object does not implement cloneable");
273
            e.printStackTrace();
274
            return null;
275
        }
276
    }
277

    
278

    
279
}
(1-1/37)