Project

General

Profile

Download (8.69 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2009 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 java.util.Iterator;
12
import java.util.NoSuchElementException;
13
import java.util.Set;
14
import java.util.SortedSet;
15
import java.util.TreeSet;
16

    
17
import javax.persistence.Entity;
18
import javax.persistence.Transient;
19
import javax.xml.bind.annotation.XmlAccessType;
20
import javax.xml.bind.annotation.XmlAccessorType;
21
import javax.xml.bind.annotation.XmlRootElement;
22
import javax.xml.bind.annotation.XmlType;
23

    
24
import org.apache.logging.log4j.LogManager;
25
import org.apache.logging.log4j.Logger;
26
import org.hibernate.envers.Audited;
27

    
28
import eu.etaxonomy.cdm.common.URI;
29
import eu.etaxonomy.cdm.model.common.CdmBase;
30
import eu.etaxonomy.cdm.model.common.Language;
31

    
32
/**
33
 * @author a.mueller
34
 */
35
@XmlAccessorType(XmlAccessType.FIELD)
36
@XmlType(name = "OrderedTermVocabulary")
37
@XmlRootElement(name = "OrderedTermVocabulary")
38
@Entity
39
@Audited
40
public class OrderedTermVocabulary<T extends OrderedTermBase>
41
        extends TermVocabulary<T>
42
        implements ITermGraph<T, TermNode>    {
43

    
44
	private static final long serialVersionUID = 7871741306306371242L;
45
	@SuppressWarnings("unused")
46
	private static final Logger logger = LogManager.getLogger(OrderedTermVocabulary.class);
47

    
48
// ************************* FACTORY METHODS ***********************************************/
49

    
50
	/**
51
	 * @param type the {@link TermType term type}, must be the same as for all included terms
52
	 * @return
53
	 * @throws NullPointerException if type is <code>null</code>
54
	 */
55
	public static OrderedTermVocabulary NewInstance(TermType type){
56
		return new OrderedTermVocabulary(type);
57
	}
58

    
59
	/**
60
     * @param type the {@link TermType term type}, must be the same as for all included terms
61
     * @param class the parameter is only used for correct generics handling
62
     * @param description the description of this vocabulary
63
     * @param label
64
     * @param labelAbbrev
65
     * @param termSourceUri
66
     * @return
67
     * @throws NullPointerException if type is <code>null</code>
68
     */
69
    public static <T extends OrderedTermBase<T>> OrderedTermVocabulary<T> NewOrderedInstance(TermType type, Class<T> clazz, String description, String label, String labelAbbrev, URI termSourceUri){
70
        return new OrderedTermVocabulary<T>(type, description, label, labelAbbrev, termSourceUri, null);
71
    }
72

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

    
75
    //for hibernate use only, *packet* private required by bytebuddy
76
	@Deprecated
77
	OrderedTermVocabulary() {}
78

    
79
	protected OrderedTermVocabulary(TermType type) {
80
		super(type);
81
	}
82

    
83
	protected OrderedTermVocabulary(TermType type, String term, String label, String labelAbbrev, URI termSourceUri, Language language) {
84
		super(type, term, label, labelAbbrev, termSourceUri, language);
85
	}
86

    
87
//************************* METHODS **************************************/
88

    
89
	@Transient
90
	@Override
91
	protected Set<T> newTermSet() {
92
		return new TreeSet<T>();
93
	}
94

    
95
	@Transient
96
	public SortedSet<T> getOrderedTerms() {
97
		SortedSet<T> result = getSortedSetOfTerms();
98
		return result;
99
	}
100

    
101
	public SortedSet<T> getHigherAndEqualTerms(T otb) {
102
		SortedSet<T> result = new TreeSet<>();
103
		SortedSet<T> sortedSet = getSortedSetOfTerms();
104
		result.addAll( sortedSet.tailSet(otb));
105
		return result;
106
	}
107

    
108
	public SortedSet<T> getHigherTerms(T otb) {
109
		SortedSet<T> result = getHigherAndEqualTerms(otb);
110
		for (DefinedTermBase<?> setObjectUnproxied : terms){
111
		    @SuppressWarnings("unchecked")
112
            T setObject = (T)CdmBase.deproxy(setObjectUnproxied, OrderedTermBase.class);
113
            if (setObject.compareTo(otb) == 0){
114
				result.remove(setObject);
115
			}
116
		}
117
		return result;
118
	}
119

    
120
	public SortedSet<T> getLowerAndEqualTerms(T otb) {
121
		SortedSet<T> result = new TreeSet<>();
122
		result = getLowerTerms(otb);
123
		/*SortedSet<T> sortedSet = getSortedSetOfTerms();
124

    
125
		result.addAll( sortedSet.headSet(otb));*/
126
		//getLowerTerms Returns a view of the portion of this set whose elements are STRICTLY less than toElement
127
		for (DefinedTermBase<?> setObjectUnproxied : terms){
128
		    @SuppressWarnings("unchecked")
129
            T setObject = (T)CdmBase.deproxy(setObjectUnproxied, OrderedTermBase.class);
130
            if (setObject.compareTo(otb) == 0){
131
				result.add(setObject);
132
			}
133
		}
134
		return result;
135
	}
136

    
137
	public SortedSet<T> getLowerTerms(T otb) {
138
		/*SortedSet<T> result = getLowerAndEqualTerms(otb);
139
		for (T setObject : terms){
140
			if (setObject.compareTo(otb) == 0){
141
				result.remove(setObject);
142
			}
143
		}*/
144
	    SortedSet<T> result = new TreeSet<>();
145
        SortedSet<T> sortedSet = getSortedSetOfTerms();
146
        //headSet Returns a view of the portion of this set whose elements are STRICTLY less than toElement
147
        result.addAll( sortedSet.headSet(otb));
148
		return result;
149
	}
150

    
151
	public SortedSet<T> getEqualTerms(T otb) {
152
		SortedSet<T> result = new TreeSet<>();
153
		for (DefinedTermBase<?> setObjectUnproxied : terms){  //use Unproxied to avoid ClassCastException in certain contexts
154
		    @SuppressWarnings("unchecked")
155
            T setObject = (T)CdmBase.deproxy(setObjectUnproxied, OrderedTermBase.class);
156
			if (setObject.compareTo(otb) == 0){
157
				result.add(setObject);
158
			}
159
		}
160
		return result;
161
	}
162

    
163
	public T getNextHigherTerm(T otb) {
164
		try {
165
			return getHigherTerms(otb).first();
166
		} catch (NoSuchElementException e) {
167
			return null;
168
		}
169
	}
170

    
171
	public T getNextLowerTerm(T otb) {
172
		try {
173
			return getLowerTerms(otb).last();
174
		} catch (NoSuchElementException e) {
175
			return null;
176
		}
177
	}
178

    
179
	@Transient
180
	public T getLowestTerm() {
181
		try {
182
			SortedSet<T> sortedSet = getSortedSetOfTerms();
183
			return sortedSet.first();
184
			//return ((SortedSet<T>)terms).first();
185
		} catch (NoSuchElementException e) {
186
			return null;
187
		}
188
	}
189

    
190
	@Transient
191
	public T getHighestTerm() {
192
		try {
193
			SortedSet<T> sortedSet = getSortedSetOfTerms();
194
			return sortedSet.last();
195
		} catch (NoSuchElementException e) {
196
			return null;
197
		}
198
	}
199

    
200
	/**
201
	 * Adds a term to the the end / lowest
202
	 * @see eu.etaxonomy.cdm.model.term.TermVocabulary#addTerm(eu.etaxonomy.cdm.model.term.DefinedTermBase)
203
	 */
204
	@Override
205
    public void addTerm(T term) {
206
		SortedSet<T> sortedTerms = getSortedSetOfTerms();
207
		int lowestOrderIndex;
208
		if (sortedTerms.isEmpty()){
209
			lowestOrderIndex = 0;
210
		}else{
211
			T first = sortedTerms.first();
212
			lowestOrderIndex = first.orderIndex;
213
		}
214
		term.orderIndex = lowestOrderIndex + 1;
215
		super.addTerm(term);
216
	}
217

    
218
	public void addTermAbove(T termToBeAdded, T lowerTerm)  {
219
		int orderInd = lowerTerm.orderIndex;
220
		termToBeAdded.orderIndex = orderInd;
221
		//increment all orderIndexes of terms below
222
		Set<T> myTerms = getSortedSetOfTerms();
223
		for(T term : myTerms){
224
		    if (term.orderIndex >= orderInd){  //should always be true
225
				term.orderIndex++;
226
			}
227
		}
228
		super.addTerm(termToBeAdded);
229
	}
230

    
231
	public void addTermBelow(T termToBeAdded, T higherTerm)  {
232
		int orderInd = higherTerm.orderIndex;
233
		termToBeAdded.orderIndex = orderInd + 1;
234
		//increment all orderIndexes of terms below
235
		Iterator<T> iterator = getLowerTerms(higherTerm).iterator();
236
		while(iterator.hasNext()){
237
			T term = iterator.next();
238
			if (term.orderIndex > orderInd){
239
				term.orderIndex++;
240
			}
241
		}
242
		super.addTerm(termToBeAdded);
243
	}
244

    
245
	public void addTermEqualLevel(T termToBeAdded, T equalLevelTerm) {
246
		int orderInd = equalLevelTerm.orderIndex;
247
		termToBeAdded.orderIndex = orderInd;
248
		super.addTerm(termToBeAdded);
249
	}
250

    
251
	@Override
252
	public void removeTerm(T term) {
253
		if (term == null){
254
			return;
255
		}
256
		if (this.getEqualTerms(term).size() == 0){
257
			Iterator<T> iterator = getLowerTerms(term).iterator();
258
			while (iterator.hasNext()){
259
				T otb = iterator.next();
260
				toBeChangedByObject = otb;
261
				otb.decreaseIndex(this);
262
				toBeChangedByObject = null;
263
			}
264
		}
265
		super.removeTerm(term);
266
	}
267

    
268
	@Transient
269
	private T toBeChangedByObject;
270

    
271
	public boolean indexChangeAllowed(OrderedTermBase orderedTermBase){
272
		return orderedTermBase == toBeChangedByObject ;
273
	}
274

    
275

    
276
	@Transient
277
	private SortedSet<T> getSortedSetOfTerms(){
278
		SortedSet<T> sortedSet = new TreeSet<>();
279
		for (DefinedTermBase<?> termUnproxied : terms){
280
            @SuppressWarnings("unchecked")
281
            T term = (T)CdmBase.deproxy(termUnproxied, OrderedTermBase.class);
282
            sortedSet.add(term);
283
        }
284
		return sortedSet;
285
	}
286

    
287
    @Override
288
    public Set<TermNode> getTermRelations() {
289
        return super.termRelations();
290
    }
291
    /**
292
     * For now protected to avoid type checking etc. Might become
293
     * public in future
294
     * @param termRelations
295
     */
296
//    @Override  //not yet public
297
    protected void setTermRelations(Set<TermNode> termRelations) {
298
        super.termRelations(termRelations);
299
    }
300

    
301
}
(18-18/32)