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
package eu.etaxonomy.cdm.model.term;
10

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

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

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

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

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

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

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

    
72
// *********************** CONSTRUCTOR *************************/
73

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

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

    
85
// **************************** METHODS ******************************/
86

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

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

    
128
    	OrderedTermBase<?> orderedTermLocal = CdmBase.deproxy(orderedTerm, OrderedTermBase.class);
129
    	if(!skipVocabularyCheck){
130
            if (this.vocabulary == null || orderedTermLocal.vocabulary == null){
131
                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");
132
            }
133
            if (! this.getVocabulary().getUuid().equals(orderedTermLocal.vocabulary.getUuid())){
134
               throw new IllegalStateException("2 terms do not belong to the same vocabulary and therefore can not be compared: " + this.getTitleCache() + " and " + orderedTermLocal.getTitleCache());
135
            }
136
        }
137

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

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

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

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

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

    
212

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

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

    
235
//*********************** CLONE ********************************************************/
236

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