Project

General

Profile

Download (8.91 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.term;
11

    
12
import javax.persistence.Entity;
13
import javax.persistence.Transient;
14
import javax.xml.bind.annotation.XmlAccessType;
15
import javax.xml.bind.annotation.XmlAccessorType;
16
import javax.xml.bind.annotation.XmlElement;
17
import javax.xml.bind.annotation.XmlSeeAlso;
18
import javax.xml.bind.annotation.XmlType;
19

    
20
import org.apache.log4j.Logger;
21
import org.hibernate.envers.Audited;
22

    
23
import eu.etaxonomy.cdm.model.common.CdmBase;
24
import eu.etaxonomy.cdm.model.common.RelationshipTermBase;
25
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
26
import eu.etaxonomy.cdm.model.description.State;
27
import eu.etaxonomy.cdm.model.location.NamedArea;
28
import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
29
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
30
import eu.etaxonomy.cdm.model.name.Rank;
31

    
32
/**
33
 * @author m.doering
34
 * @since 08-Nov-2007 13:06:23
35
 */
36
@XmlAccessorType(XmlAccessType.FIELD)
37
@XmlType(name = "OrderedTermBase", propOrder = {
38
    "orderIndex"
39
})
40
@XmlSeeAlso({
41
    RelationshipTermBase.class,
42
    PresenceAbsenceTerm.class,
43
    State.class,
44
    NamedArea.class,
45
    NamedAreaLevel.class,
46
    NomenclaturalStatusType.class,
47
    Rank.class
48
})
49
@Entity
50
@Audited
51
public abstract class OrderedTermBase<T extends OrderedTermBase<?>>
52
        extends DefinedTermBase<T> {
53

    
54
    private static final long serialVersionUID = 8000797926720467399L;
55
    @SuppressWarnings("unused")
56
    private static final Logger logger = Logger.getLogger(OrderedTermBase.class);
57

    
58
    //Order index, value < 1 means that this Term is not in order yet
59
    @XmlElement(name = "OrderIndex")
60
    protected int orderIndex;
61

    
62
    /**
63
     * Higher ordered terms have a lower order index,
64
     * lower ordered terms have a higher order index:
65
     * <p>
66
     * <b>a.oderIndex &lt; b.oderIndex : a &gt; b</b>
67
     * @return the order index of a term
68
     */
69
    public int getOrderIndex() {
70
        return orderIndex;
71
    }
72

    
73
// *********************** CONSTRUCTOR *************************/
74

    
75
    //for JAXB only, TODO needed?
76
    @Deprecated
77
    protected OrderedTermBase(){}
78

    
79
    protected OrderedTermBase(TermType type) {
80
        super(type);
81
    }
82
    public OrderedTermBase(TermType type, String description, String label, String labelAbbrev) {
83
        super(type, description, label, labelAbbrev);
84
    }
85

    
86
// **************************** METHODS ******************************/
87

    
88
    /**
89
     * Compares this OrderedTermBase with the specified OrderedTermBase for
90
     * order. Returns a -1, 0, or +1 if the orderIndex of this object is greater
91
     * than, equal to, or less than the specified object. In case the parameter
92
     * is <code>null</code> the
93
     * <p>
94
     * <b>Note:</b> The compare logic of this method might appear to be <b>inverse</b>
95
     * to the one mentioned in
96
     * {@link java.lang.Comparable#compareTo(java.lang.Object)}. This is, because the logic here
97
     * is that the lower the orderIndex the higher the term. E.g. the very high {@link Rank}
98
     * Kingdom may have an orderIndex close to 1.
99
     *
100
     * @param orderedTerm
101
     *            the OrderedTermBase to be compared
102
     * @throws NullPointerException
103
     *             if the specified object is null
104
     */
105
    @Override
106
    public int compareTo(T orderedTerm) {
107
        return performCompareTo(orderedTerm, false);
108
    }
109

    
110
    /**
111
     * Compares this OrderedTermBase with the specified OrderedTermBase for
112
     * order. Returns a -1, 0, or +1 if the orderId of this object is greater
113
     * than, equal to, or less than the specified object.
114
     * <p>
115
     * <b>Note:</b> The compare logic of this method is the <b>inverse logic</b>
116
     * of the the one implemented in
117
     * {@link java.lang.Comparable#compareTo(java.lang.Object)}
118
     *
119
     * @param orderedTerm
120
     *            the OrderedTermBase to be compared
121
     * @param skipVocabularyCheck
122
     *            whether to skip checking if both terms to compare are in the
123
     *            same vocabulary
124
     * @throws NullPointerException
125
     *             if the specified object is null
126
     */
127
    protected int performCompareTo(T orderedTerm, boolean skipVocabularyCheck) {
128

    
129
    	OrderedTermBase<?> orderedTermLocal = CdmBase.deproxy(orderedTerm, OrderedTermBase.class);
130
    	if(!skipVocabularyCheck){
131
            if (this.vocabulary == null || orderedTermLocal.vocabulary == null){
132
                throw new IllegalStateException("An ordered term (" + this.toString() + " or " + orderedTermLocal.toString() + ") of class " + this.getClass() + " or " + orderedTermLocal.getClass() + " does not belong to a vocabulary and therefore can not be compared");
133
            }
134
            if (! this.getVocabulary().getUuid().equals(orderedTermLocal.vocabulary.getUuid())){
135
               throw new IllegalStateException("2 terms do not belong to the same vocabulary and therefore can not be compared: " + this.getTitleCache() + " and " + orderedTermLocal.getTitleCache());
136
            }
137
        }
138

    
139
        int orderThat;
140
        int orderThis;
141
        try {
142
            orderThat = orderedTermLocal.orderIndex;//OLD: this.getVocabulary().getTerms().indexOf(orderedTerm);
143
            orderThis = orderIndex; //OLD: this.getVocabulary().getTerms().indexOf(this);
144
        } catch (RuntimeException e) {
145
            throw e;
146
        }
147
        if (orderThis > orderThat){
148
            return -1;
149
        }else if (orderThis < orderThat){
150
            return 1;
151
        }else {
152
            if (skipVocabularyCheck){
153
                String errorStr = "The term %s (ID: %s) is not attached to any vocabulary. This should not happen. "
154
                        + "Please add the term to an vocabulary";
155
                if (this.getVocabulary() == null){
156
                    throw new IllegalStateException(String.format(errorStr, this.getLabel(), String.valueOf(this.getId())));
157
                }else if (orderedTermLocal.vocabulary == null){
158
                    throw new IllegalStateException(String.format(errorStr, orderedTermLocal.getLabel(), String.valueOf(orderedTermLocal.getId())));
159
                }
160
                return this.getVocabulary().getUuid().compareTo(orderedTermLocal.vocabulary.getUuid());
161
            }else{
162
                return 0;
163
            }
164
        }
165
    }
166

    
167

    
168
    /**
169
     * If this term is lower than the parameter term, true is returned, else false.
170
     * If the parameter term is null, an Exception is thrown.
171
     * @param orderedTerm
172
     * @return boolean result of the comparison
173
     */
174
    public boolean isLower(T orderedTerm){
175
        return (this.compareTo(orderedTerm) < 0 );
176
    }
177

    
178

    
179
    /**
180
     * If this term is higher than the parameter term, true is returned, else false.
181
     * If the parameter term is null, an Exception is thrown.
182
     * @param orderedTerm
183
     * @return boolean result of the comparison
184
     */
185
    public boolean isHigher(T orderedTerm){
186
        return (this.compareTo(orderedTerm) > 0 );
187
    }
188

    
189

    
190
    /**
191
     * @deprecated To be used only by OrderedTermVocabulary
192
     **/
193
    @Deprecated
194
    protected boolean decreaseIndex(OrderedTermVocabulary vocabulary){
195
        if (vocabulary.indexChangeAllowed(this) == true){
196
            orderIndex--;
197
            return true;
198
        }else{
199
            return false;
200
        }
201
    }
202

    
203
    /**
204
     * @deprecated To be used only by OrderedTermVocabulary
205
     **/
206
    @Deprecated
207
    protected boolean incrementIndex(OrderedTermVocabulary vocabulary){
208
        if (vocabulary.indexChangeAllowed(this) == true){
209
            orderIndex++;
210
            return true;
211
        }else{
212
            return false;
213
        }
214
    }
215

    
216

    
217
    @SuppressWarnings("unchecked")
218
    @Transient
219
    public T getNextHigherTerm(){  //#3327
220
        if (getVocabulary() == null){
221
            return null;
222
        }else{
223
            OrderedTermBase<T> result = CdmBase.deproxy(getVocabulary(), OrderedTermVocabulary.class).getNextHigherTerm(this);
224
            return (T)result;
225
        }
226
    }
227

    
228
    @SuppressWarnings("unchecked")
229
    @Transient
230
    public T getNextLowerTerm(){ //#3327
231
        if (getVocabulary() == null){
232
            return null;
233
        }else{
234
            OrderedTermBase<T> result = CdmBase.deproxy(getVocabulary(), OrderedTermVocabulary.class).getNextLowerTerm(this);
235
            return (T)result;
236
        }
237
    }
238

    
239
//*********************** CLONE ********************************************************/
240

    
241
    /**
242
     * Clones <i>this</i> OrderedTermBase. This is a shortcut that enables to create
243
     * a new instance that differs only slightly from <i>this</i> OrderedTermBase.
244
     *
245
     * @see eu.etaxonomy.cdm.model.term.DefinedTermBase#clone()
246
     * @see java.lang.Object#clone()
247
     */
248
    @Override
249
    public OrderedTermBase<T> clone() {
250
        OrderedTermBase<T> result = (OrderedTermBase<T>) super.clone();
251
        //no changes to orderIndex
252
        return result;
253
    }
254
}
(15-15/33)