Project

General

Profile

Download (9.91 KB) Statistics
| Branch: | Tag: | Revision:
1 9479da48 Andreas Müller
/**
2
* Copyright (C) 2007 EDIT
3 1120db75 Andreas Kohlbecker
* European Distributed Institute of Taxonomy
4 9479da48 Andreas Müller
* http://www.e-taxonomy.eu
5 1120db75 Andreas Kohlbecker
*
6 9479da48 Andreas Müller
* 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 03abbcde Andreas Müller
import java.util.ArrayList;
13 e27511ac Andreas Müller
import java.util.Arrays;
14 03abbcde Andreas Müller
import java.util.List;
15 9479da48 Andreas Müller
16 03abbcde Andreas Müller
import javax.persistence.Entity;
17 f6765014 ben.clark
import javax.persistence.FetchType;
18 a7f52c55 Andreas Müller
import javax.persistence.OneToMany;
19 1e2f5c73 Andreas Müller
import javax.persistence.Transient;
20 519bff7b Andreas Müller
import javax.validation.constraints.NotEmpty;
21 01b7ddbf a.babadshanjan
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.XmlRootElement;
26 e9829ef9 Andreas Müller
import javax.xml.bind.annotation.XmlTransient;
27 01b7ddbf a.babadshanjan
import javax.xml.bind.annotation.XmlType;
28 9479da48 Andreas Müller
29 23de68fc Andreas Müller
import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
30 03abbcde Andreas Müller
import org.hibernate.annotations.Cascade;
31
import org.hibernate.annotations.CascadeType;
32 ee91bcd9 ben.clark
import org.hibernate.envers.Audited;
33 17a0cbe8 ben.clark
import org.hibernate.search.annotations.Indexed;
34 51db8d4a ben.clark
import org.hibernate.search.annotations.IndexedEmbedded;
35 a1587c24 ben.clark
36
import eu.etaxonomy.cdm.validation.Level2;
37 03abbcde Andreas Müller
38 9479da48 Andreas Müller
/**
39 50c72f11 m.geoffroy
 * This class represents information pieces expressed in categorical type of
40 f51e2565 m.geoffroy
 * data (in opposition to {@link QuantitativeData quantitative data} on one side and to literal data on
41 4daf2f37 m.geoffroy
 * the other side). Only {@link TaxonDescription taxon descriptions} and
42
 * {@link SpecimenDescription specimen descriptions} may contain categorical data.<BR>
43 f51e2565 m.geoffroy
 * 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 3a9870fa m.geoffroy
 * "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 1120db75 Andreas Kohlbecker
 * interpreted as being related by the inclusive disjunction "or".
51 50c72f11 m.geoffroy
 * <P>
52
 * This class corresponds partially to CodedDescriptionType according to
53
 * the SDD schema.
54 1120db75 Andreas Kohlbecker
 *
55 9479da48 Andreas Müller
 * @author m.doering
56 a88578ce Andreas Müller
 * @since 08-Nov-2007 13:06:15
57 9479da48 Andreas Müller
 */
58 01b7ddbf a.babadshanjan
@XmlAccessorType(XmlAccessType.FIELD)
59
@XmlType(name = "CategoricalData", propOrder = {
60
    "orderRelevant",
61 6f00d6f6 Andreas Müller
    "stateData",
62
    "unknownData"
63 01b7ddbf a.babadshanjan
})
64
@XmlRootElement(name = "CategoricalData")
65 9479da48 Andreas Müller
@Entity
66 ee91bcd9 ben.clark
@Audited
67 17a0cbe8 ben.clark
@Indexed(index = "eu.etaxonomy.cdm.model.description.DescriptionElementBase")
68 50e52e0f Andreas Müller
public class CategoricalData extends DescriptionElementBase {
69 93ad7e54 Andreas Müller
70 1120db75 Andreas Kohlbecker
    private static final long serialVersionUID = -6298361966947668998L;
71 23de68fc Andreas Müller
    private static final Logger logger = LogManager.getLogger(CategoricalData.class);
72 1120db75 Andreas Kohlbecker
73
    //whether the sequence of ordered states is important
74
    @XmlElement(name = "OrderRelevant")
75
    private boolean orderRelevant;
76
77
    @XmlElementWrapper(name = "States")
78
    @XmlElement(name = "State")
79 7d39593c Andreas Müller
    @OneToMany(fetch = FetchType.LAZY, mappedBy="categoricalData", orphanRemoval=true)
80 a7f52c55 Andreas Müller
    @Cascade({ CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE})
81 0930d1c2 Andreas Kohlbecker
    @IndexedEmbedded(depth = 3)
82 1120db75 Andreas Kohlbecker
    @NotEmpty(groups = Level2.class)
83 07d5561c Andreas Müller
    private List<StateData> stateData = new ArrayList<>();
84 73ee5c85 Andreas Kohlbecker
85
    @XmlElement(name = "UnknownData")
86
    private final Boolean unknownData = false;
87 1120db75 Andreas Kohlbecker
88
//****************************** FACTORY METHOD *******************************/
89
90
    /**
91
     * Creates a new empty categorical data instance.
92
     */
93
    public static CategoricalData NewInstance(){
94
        return new CategoricalData();
95
    }
96 73ee5c85 Andreas Kohlbecker
97 a774af50 unknown
98
    /**
99
     * @param habitat
100
     * @return
101
     */
102
    public static CategoricalData NewInstance(Feature feature) {
103
        return new CategoricalData( new ArrayList<>() , feature);
104
    }
105
106 e27511ac Andreas Müller
    /**
107
     * Creates a new empty categorical data instance.
108
     */
109
    public static CategoricalData NewInstance(State state, Feature feature){
110
        return new CategoricalData( Arrays.asList( new State[]{state}) , feature);
111
    }
112 1120db75 Andreas Kohlbecker
113
//*******************  CONSTRUCTOR *********************************************/
114
115
    /**
116
     * Class constructor: creates a new empty categorical data instance.
117
     */
118
    protected CategoricalData() {
119
        super(null);
120
    }
121
122 e27511ac Andreas Müller
    /**
123
     * Class constructor: creates a new empty categorical data instance.
124
     */
125
    protected CategoricalData(List<State> states, Feature feature) {
126
        super(feature);
127
        for (State state : states){
128 73ee5c85 Andreas Kohlbecker
            addStateData(state);
129 e27511ac Andreas Müller
        }
130 73ee5c85 Andreas Kohlbecker
131 e27511ac Andreas Müller
    }
132
133 1120db75 Andreas Kohlbecker
// ****************** GETTER / SETTER *********************************************/
134
135
    /**
136
     * Returns the (ordered) list of {@link State states} describing the {@link Feature feature}
137
     * corresponding to <i>this</i> categorical data.
138
     */
139
140 f3dabfca Andreas Müller
    public List<StateData> getStateData(){
141
        return this.stateData;
142 1120db75 Andreas Kohlbecker
    }
143
144 7d39593c Andreas Müller
    @Deprecated
145 73ee5c85 Andreas Kohlbecker
    protected void setStateData(List<StateData> stateData){
146 f3dabfca Andreas Müller
        this.stateData = stateData;
147 1120db75 Andreas Kohlbecker
    }
148
149
    /**
150 f3dabfca Andreas Müller
     * Adds a {@link State state} to the list of {@link #getStateData() states}
151 1120db75 Andreas Kohlbecker
     * describing the {@link Feature feature} corresponding to <i>this</i> categorical data.
152
     *
153
     * @param state	the state to be added to <i>this</i> categorical data
154 f3dabfca Andreas Müller
     * @see    	   	#getStateData()
155 1120db75 Andreas Kohlbecker
     */
156 b3bec3a9 Andreas M��ller
    @SuppressWarnings("deprecation")
157 f3dabfca Andreas Müller
    public void addStateData(StateData stateData){
158
        this.stateData.add(stateData);
159 7d39593c Andreas Müller
        stateData.setCategoricalData(this);
160 1120db75 Andreas Kohlbecker
    }
161
162
    /**
163
     * Convenience method which creates a state data from a given state with no modifiers
164
     * and adds it to the list of state data
165 f3dabfca Andreas Müller
     * @see #addStateData(StateData)
166 1120db75 Andreas Kohlbecker
     * @param state
167
     */
168 2eb8c59a Andreas Müller
    public StateData addStateData(State state){
169 1120db75 Andreas Kohlbecker
        StateData stateData = StateData.NewInstance(state);
170 7d39593c Andreas Müller
        addStateData(stateData);
171 2eb8c59a Andreas Müller
        return stateData;
172 1120db75 Andreas Kohlbecker
    }
173
174
175
    /**
176 f3dabfca Andreas Müller
     * Removes one element from the set of {@link #getStateData() states}
177 1120db75 Andreas Kohlbecker
     * describing the {@link Feature feature} corresponding to <i>this</i> categorical data.
178
     *
179
     * @param  state	the state which should be removed
180 f3dabfca Andreas Müller
     * @see     		#getStateData()
181
     * @see     		#addStateData(State)
182 1120db75 Andreas Kohlbecker
     */
183 b3bec3a9 Andreas M��ller
    @SuppressWarnings("deprecation")
184 f3dabfca Andreas Müller
    public void removeStateData(StateData stateData){
185
        this.stateData.remove(stateData);
186 b3bec3a9 Andreas M��ller
        stateData.setCategoricalData(null);
187 1120db75 Andreas Kohlbecker
    }
188
189
    //rename to isStateSequenceIntentional ??
190
    /**
191
     * Returns the boolean value of the flag indicating whether the sequence of
192
     * {@link StateData state data} belonging to <i>this</i> categorical data is intentional
193
     * (true) and therefore relevant for interpretation or analysis or not (false).
194
     * The use of this flag depends mostly on the {@link Feature feature} of <i>this</i> categorical data.
195
     *
196
     * @return  the boolean value of the orderRelevant flag
197
     */
198
    public boolean getOrderRelevant(){
199
        return this.orderRelevant;
200
    }
201
    /**
202
     * @see	#getOrderRelevant()
203
     */
204
    public void setOrderRelevant(boolean orderRelevant){
205
        this.orderRelevant = orderRelevant;
206
    }
207
208
// ********************* CONVENIENCE ******************************************/
209
210 3cdfd4b6 Andreas Müller
    /**
211
     * Convenience method to test the existence of a given state in the state data.
212
     * Note: the method ignores modifiers so state data having the state may still be
213
     * modified by its modifiers.
214
     *
215
     * @param state the given {@link State}
216
     * @return <code>true</code> if the state exists
217
     */
218
    public boolean hasState(State state) {
219
        return getStatesOnly().contains(state);
220
    }
221
222 1120db75 Andreas Kohlbecker
    /**
223 9b8a8049 Andreas Müller
     * Convenience method returning only the list of states. Leaving out modifiers and modifying text.
224 1120db75 Andreas Kohlbecker
     */
225
    @Transient
226
    public List<State> getStatesOnly(){
227 9b8a8049 Andreas Müller
        List<State> result = new ArrayList<>();
228 f3dabfca Andreas Müller
        for (StateData stateData : getStateData()){
229 1120db75 Andreas Kohlbecker
            State state = stateData.getState();
230 9b8a8049 Andreas Müller
            if (state != null){
231
                result.add(state);
232
            }
233 1120db75 Andreas Kohlbecker
        }
234
        return result;
235
    }
236
237
    /**
238
     * Convenience method which to set the list of states (no modifiers or modifying text allowed).
239
     * All existing state data are removed.
240
     * @return
241
     */
242 f3dabfca Andreas Müller
    public List<StateData> setStateDataOnly(List<State> states){
243 6a65a580 Patrick Plitzner
        List<StateData> stateDataList = new ArrayList<>(getStateData());
244
        for (StateData stateData : stateDataList) {
245
            removeStateData(stateData);
246
        }
247
        for (State state : states) {
248
            addStateData(state);
249 1120db75 Andreas Kohlbecker
        }
250 f3dabfca Andreas Müller
        return this.stateData;
251 1120db75 Andreas Kohlbecker
    }
252
253 e9829ef9 Andreas Müller
    @Transient
254
    @XmlTransient
255
    @Override
256
    public boolean isCharacterData() {
257
        return true;
258
    }
259
260 50e52e0f Andreas Müller
//********************************** toString **************************************/
261
262
    @Override
263
    public String toString() {
264 0f720e98 Andreas Müller
        return (getFeature()!=null ? getFeature().getLabel(): "") +
265
                "[" + stateData +
266
                    (orderRelevant? ", orderRelevant=" + orderRelevant:"") +
267
                    (unknownData? ", unknownData=" + unknownData:"")
268 e0d15cb3 Andreas Müller
                + "]";
269 50e52e0f Andreas Müller
    }
270
271 a42e27ce Andreas Müller
272
//*********************************** CLONE *****************************************/
273
274 1120db75 Andreas Kohlbecker
    /**
275
     * Clones <i>this</i> categorical data. This is a shortcut that enables to create
276
     * a new instance that differs only slightly from <i>this</i> categorical data by
277
     * modifying only some of the attributes.
278 ee0b6690 Andreas Müller
     * @throws CloneNotSupportedException
279 1120db75 Andreas Kohlbecker
     *
280
     * @see eu.etaxonomy.cdm.model.description.DescriptionElementBase#clone()
281
     * @see java.lang.Object#clone()
282
     */
283
    @Override
284 ee0b6690 Andreas Müller
    public CategoricalData clone() {
285 1120db75 Andreas Kohlbecker
286 44900eab Andreas Müller
        CategoricalData result = (CategoricalData)super.clone();
287
288
        //states
289
        result.stateData = new ArrayList<>();
290
        for (StateData stateData : getStateData()){
291
            StateData newState = stateData.clone();
292
            result.addStateData(newState);
293 1120db75 Andreas Kohlbecker
        }
294 44900eab Andreas Müller
295
        //no changes to: orderRelevant
296
        return result;
297 1120db75 Andreas Kohlbecker
    }
298 ee0b6690 Andreas Müller
}