Project

General

Profile

Download (9.03 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<StateData>();
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
     * Creates a new empty categorical data instance.
98
     */
99
    public static CategoricalData NewInstance(State state, Feature feature){
100
        return new CategoricalData( Arrays.asList( new State[]{state}) , feature);
101
    }
102

    
103
//*******************  CONSTRUCTOR *********************************************/
104

    
105
    /**
106
     * Class constructor: creates a new empty categorical data instance.
107
     */
108
    protected CategoricalData() {
109
        super(null);
110
    }
111

    
112
    /**
113
     * Class constructor: creates a new empty categorical data instance.
114
     */
115
    protected CategoricalData(List<State> states, Feature feature) {
116
        super(feature);
117
        for (State state : states){
118
            addStateData(state);
119
        }
120

    
121
    }
122

    
123
// ****************** GETTER / SETTER *********************************************/
124

    
125
    /**
126
     * Returns the (ordered) list of {@link State states} describing the {@link Feature feature}
127
     * corresponding to <i>this</i> categorical data.
128
     */
129

    
130
    public List<StateData> getStateData(){
131
        return this.stateData;
132
    }
133

    
134
    @Deprecated
135
    protected void setStateData(List<StateData> stateData){
136
        this.stateData = stateData;
137
    }
138

    
139
    /**
140
     * Adds a {@link State state} to the list of {@link #getStateData() states}
141
     * describing the {@link Feature feature} corresponding to <i>this</i> categorical data.
142
     *
143
     * @param state	the state to be added to <i>this</i> categorical data
144
     * @see    	   	#getStateData()
145
     */
146
    @SuppressWarnings("deprecation")
147
    public void addStateData(StateData stateData){
148
        this.stateData.add(stateData);
149
        stateData.setCategoricalData(this);
150
    }
151

    
152
    /**
153
     * Convenience method which creates a state data from a given state with no modifiers
154
     * and adds it to the list of state data
155
     * @see #addStateData(StateData)
156
     * @param state
157
     */
158
    public void addStateData(State state){
159
        StateData stateData = StateData.NewInstance(state);
160
        addStateData(stateData);
161
    }
162

    
163

    
164
    /**
165
     * Removes one element from the set of {@link #getStateData() states}
166
     * describing the {@link Feature feature} corresponding to <i>this</i> categorical data.
167
     *
168
     * @param  state	the state which should be removed
169
     * @see     		#getStateData()
170
     * @see     		#addStateData(State)
171
     */
172
    @SuppressWarnings("deprecation")
173
    public void removeStateData(StateData stateData){
174
        this.stateData.remove(stateData);
175
        stateData.setCategoricalData(null);
176
    }
177

    
178
    //rename to isStateSequenceIntentional ??
179
    /**
180
     * Returns the boolean value of the flag indicating whether the sequence of
181
     * {@link StateData state data} belonging to <i>this</i> categorical data is intentional
182
     * (true) and therefore relevant for interpretation or analysis or not (false).
183
     * The use of this flag depends mostly on the {@link Feature feature} of <i>this</i> categorical data.
184
     *
185
     * @return  the boolean value of the orderRelevant flag
186
     */
187
    public boolean getOrderRelevant(){
188
        return this.orderRelevant;
189
    }
190
    /**
191
     * @see	#getOrderRelevant()
192
     */
193
    public void setOrderRelevant(boolean orderRelevant){
194
        this.orderRelevant = orderRelevant;
195
    }
196

    
197
// ********************* CONVENIENCE ******************************************/
198

    
199
    /**
200
     * Convenience method which returns only the list of states. Leaving out modifiers and modifying text.
201
     * @return
202
     */
203
    @Transient
204
    public List<State> getStatesOnly(){
205
        List<State> result = new ArrayList<State>();
206
        for (StateData stateData : getStateData()){
207
            State state = stateData.getState();
208
            result.add(state);
209
        }
210
        return result;
211
    }
212

    
213
    /**
214
     * Convenience method which to set the list of states (no modifiers or modifying text allowed).
215
     * All existing state data are removed.
216
     * @return
217
     */
218
    @Transient
219
    public List<StateData> setStateDataOnly(List<State> states){
220
        this.stateData.clear();
221
        for (State state : states){
222
            StateData stateDate = StateData.NewInstance(state);
223
            this.stateData.add(stateDate);
224
        }
225
        return this.stateData;
226
    }
227

    
228
    @Transient
229
    @XmlTransient
230
    @Override
231
    public boolean isCharacterData() {
232
        return true;
233
    }
234

    
235

    
236
//*********************************** CLONE *****************************************/
237

    
238
    /**
239
     * Clones <i>this</i> categorical data. This is a shortcut that enables to create
240
     * a new instance that differs only slightly from <i>this</i> categorical data by
241
     * modifying only some of the attributes.
242
     *
243
     * @see eu.etaxonomy.cdm.model.description.DescriptionElementBase#clone()
244
     * @see java.lang.Object#clone()
245
     */
246
    @Override
247
    public Object clone() {
248

    
249
        try {
250
            CategoricalData result = (CategoricalData)super.clone();
251

    
252
            //states
253
            result.stateData = new ArrayList<StateData>();
254
            for (StateData stateData : getStateData()){
255
                //TODO do we need to clone here?
256
                //StateData newState = (StateData)stateData.clone();
257
                result.stateData.add(stateData);
258
            }
259

    
260
            return result;
261
            //no changes to: orderRelevant
262
        } catch (CloneNotSupportedException e) {
263
            logger.warn("Object does not implement cloneable");
264
            e.printStackTrace();
265
            return null;
266
        }
267
    }
268

    
269
}
(1-1/36)