2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.model
.common
;
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
;
20 import org
.apache
.log4j
.Logger
;
21 import org
.hibernate
.envers
.Audited
;
22 import org
.hibernate
.search
.annotations
.Indexed
;
24 import eu
.etaxonomy
.cdm
.model
.description
.PresenceAbsenceTermBase
;
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
;
33 * @created 08-Nov-2007 13:06:23
35 @XmlAccessorType(XmlAccessType
.FIELD
)
36 @XmlType(name
= "OrderedTermBase", propOrder
= {
40 RelationshipTermBase
.class,
41 PresenceAbsenceTermBase
.class,
45 NomenclaturalStatusType
.class,
49 @Indexed(index
= "eu.etaxonomy.cdm.model.common.DefinedTermBase")
51 public abstract class OrderedTermBase
<T
extends OrderedTermBase
<?
>> extends DefinedTermBase
<T
> implements Comparable
<T
> {
52 private static final long serialVersionUID
= 8000797926720467399L;
53 @SuppressWarnings("unused")
54 private static final Logger logger
= Logger
.getLogger(OrderedTermBase
.class);
56 //Order index, value < 1 means that this Term is not in order yet
57 @XmlElement(name
= "OrderIndex")
58 protected int orderIndex
;
61 * Higher ordered terms have a lower order index,
62 * lower ordered terms have a higher order index:
64 * <b>a.oderIndex < b.oderIndex : a > b</b>
65 * @return the order index of a term
67 public int getOrderIndex() {
71 // *********************** CONSTRUCTOR *************************/
73 //for JAXB only, TODO needed?
75 protected OrderedTermBase(){}
77 protected OrderedTermBase(TermType type
) {
80 public OrderedTermBase(TermType type
, String term
, String label
, String labelAbbrev
) {
81 super(type
, term
, label
, labelAbbrev
);
84 // **************************** METHODS ******************************/
87 * Compares this OrderedTermBase with the specified OrderedTermBase for
88 * order. Returns a -1, 0, or +1 if the orderIndex of this object is greater
89 * than, equal to, or less than the specified object. In case the parameter
90 * is <code>null</code> the
92 * <b>Note:</b> The compare logic of this method might appear to be <b>inverse</b>
93 * to the one mentioned in
94 * {@link java.lang.Comparable#compareTo(java.lang.Object)}. This is, because the logic here
95 * is that the lower the orderIndex the higher the term. E.g. the very high {@link Rank}
96 * Kingdom may have an orderIndex close to 1.
99 * the OrderedTermBase to be compared
100 * @throws NullPointerException
101 * if the specified object is null
104 public int compareTo(T orderedTerm
) {
105 return performCompareTo(orderedTerm
, false);
109 * Compares this OrderedTermBase with the specified OrderedTermBase for
110 * order. Returns a -1, 0, or +1 if the orderId of this object is greater
111 * than, equal to, or less than the specified object.
113 * <b>Note:</b> The compare logic of this method is the <b>inverse logic</b>
114 * of the the one implemented in
115 * {@link java.lang.Comparable#compareTo(java.lang.Object)}
118 * the OrderedTermBase to be compared
119 * @param skipVocabularyCheck
120 * whether to skip checking if both terms to compare are in the
122 * @throws NullPointerException
123 * if the specified object is null
125 protected int performCompareTo(T orderedTerm
, boolean skipVocabularyCheck
) {
127 OrderedTermBase
<?
> orderedTermLocal
= CdmBase
.deproxy(orderedTerm
, OrderedTermBase
.class);
128 if(!skipVocabularyCheck
){
129 if (this.vocabulary
== null || orderedTermLocal
.vocabulary
== null){
130 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 if (! this.getVocabulary().getUuid().equals(orderedTermLocal
.vocabulary
.getUuid())){
133 throw new IllegalStateException("2 terms do not belong to the same vocabulary and therefore can not be compared: " + this.getTitleCache() + " and " + orderedTermLocal
.getTitleCache());
140 orderThat
= orderedTermLocal
.orderIndex
;//OLD: this.getVocabulary().getTerms().indexOf(orderedTerm);
141 orderThis
= orderIndex
; //OLD: this.getVocabulary().getTerms().indexOf(this);
142 } catch (RuntimeException e
) {
145 if (orderThis
> orderThat
){
147 }else if (orderThis
< orderThat
){
154 // public int compareTo(IdentifiableEntity o) {
155 // if (o instanceof OrderedTermBase){
156 // return compareTo((OrderedTermBase)o);
158 // return super.compareTo(o);
163 * If this term is lower than the parameter term, true is returned, else false.
164 * If the parameter term is null, an Exception is thrown.
166 * @return boolean result of the comparison
168 public boolean isLower(T orderedTerm
){
169 return (this.compareTo(orderedTerm
) < 0 );
174 * If this term is higher than the parameter term, true is returned, else false.
175 * If the parameter term is null, an Exception is thrown.
177 * @return boolean result of the comparison
179 public boolean isHigher(T orderedTerm
){
180 return (this.compareTo(orderedTerm
) > 0 );
185 * @deprecated To be used only by OrderedTermVocabulary
188 protected boolean decreaseIndex(OrderedTermVocabulary
<T
> vocabulary
){
189 if (vocabulary
.indexChangeAllowed(this) == true){
198 * @deprecated To be used only by OrderedTermVocabulary
201 protected boolean incrementIndex(OrderedTermVocabulary
<T
> vocabulary
){
202 if (vocabulary
.indexChangeAllowed(this) == true){
211 public boolean equals(Object object
){
215 if((object
== null) || (!OrderedTermBase
.class.isAssignableFrom(object
.getClass()))) {
218 OrderedTermBase
<?
> orderedTermBase
= (OrderedTermBase
<?
>)object
;
219 if (orderedTermBase
.getUuid().equals(this.getUuid())){
228 public T
getNextHigherTerm(){ //#3327
229 if (getVocabulary() == null){
232 @SuppressWarnings("unchecked")
233 OrderedTermBase
<T
> result
= CdmBase
.deproxy(getVocabulary(), OrderedTermVocabulary
.class).getNextHigherTerm(this);
239 public T
getNextLowerTerm(){ //#3327
240 if (getVocabulary() == null){
243 @SuppressWarnings("unchecked")
244 OrderedTermBase
<T
> result
= CdmBase
.deproxy(getVocabulary(), OrderedTermVocabulary
.class).getNextLowerTerm(this);
249 //*********************** CLONE ********************************************************/
252 * Clones <i>this</i> OrderedTermBase. This is a shortcut that enables to create
253 * a new instance that differs only slightly from <i>this</i> OrderedTermBase.
255 * @see eu.etaxonomy.cdm.model.common.DefinedTermBase#clone()
256 * @see java.lang.Object#clone()
259 public Object
clone() {
260 OrderedTermBase
<?
> result
= (OrderedTermBase
<?
>) super.clone();
261 //no changes to orderIndex