(no commit message)
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / store / TermStore.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.taxeditor.store;
12
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.Collections;
16 import java.util.Comparator;
17 import java.util.HashSet;
18 import java.util.List;
19 import java.util.Set;
20
21 import eu.etaxonomy.cdm.api.service.ITermService;
22 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
23 import eu.etaxonomy.cdm.model.common.MarkerType;
24 import eu.etaxonomy.cdm.model.description.AbsenceTerm;
25 import eu.etaxonomy.cdm.model.description.Feature;
26 import eu.etaxonomy.cdm.model.description.PresenceAbsenceTermBase;
27 import eu.etaxonomy.cdm.model.description.PresenceTerm;
28 import eu.etaxonomy.cdm.model.name.Rank;
29 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
30 import eu.etaxonomy.taxeditor.model.DefaultTermComparator;
31 import eu.etaxonomy.taxeditor.model.TaxonRelationshipTypeInverseContainer;
32 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
33
34 /**
35 * All terms may be accessed through this store.
36 * Note: This is for internal use. When using vocabularies in the UI, try to use the preferred terms from
37 * PreferenceUtil
38 *
39 * @author n.hoffmann
40 * @created 25.06.2009
41 * @version 1.0
42 */
43 public class TermStore {
44
45 /**
46 * Returns an alphabetically sorted list of terms (anything that extends {@link DefinedTermBase}) of the given type currently available in the system.
47 *
48 * @param clazz a class that inherits from {@link DefinedTermBase}
49 * @return an alphabetically sorted list of terms
50 */
51 public static <TERM extends DefinedTermBase> List<TERM> getTerms(Class<TERM> clazz){
52 return getTerms(clazz, null, true);
53 }
54
55 /**
56 * Returns a list of terms of the given type currently available in the system.
57 * If <code>filtered</code> is set to <code>true</code>, all terms for certain types will be
58 * gathered from edge cases.
59 *
60 * @param clazz a class that inherits from {@link DefinedTermBase}
61 * @param comparator a {@link Comparator} that defines the sorting algorithm. If set to null, {@link DefaultTermComparator} will be used
62 * @param filtered if set to true, some terms are filtered from the result (according to definition in {@link ITermStoreEdgeCase}s)
63 * @return a sorted list of terms
64 */
65 public static <TERM extends DefinedTermBase> List<TERM> getTerms(Class<TERM> clazz, Comparator<TERM> comparator, boolean filtered){
66 List<TERM> terms = new ArrayList<TERM>();
67
68 ITermStoreEdgeCase<TERM> edgeCase = getEdgeCase(clazz);
69 if(filtered && edgeCase != null){
70 terms = edgeCase.getTerms();
71 }else{
72 terms = getTermsFromService(clazz, comparator);
73 }
74
75 return terms;
76
77 }
78
79 /**
80 *
81 * @param termClass
82 * @param comparator
83 * @return
84 */
85 private static <T extends DefinedTermBase> List<T> getTermsFromService(Class<T> termClass, Comparator<T> comparator){
86 if (comparator == null){
87 comparator = new DefaultTermComparator<T>();
88 }
89
90 List<T> terms = CdmStore.getService(ITermService.class).listByTermClass(termClass, null, null, null, null);
91 Collections.sort(terms, comparator);
92 return terms;
93 }
94
95 /**
96 * @param term a {@link eu.etaxonomy.cdm.model.common.DefinedTermBase} object.
97 */
98 public static void saveTerm(DefinedTermBase term){
99 CdmStore.getService(ITermService.class).saveOrUpdate(term);
100 }
101
102 /**
103 * <p>delete</p>
104 *
105 * @param selected a {@link eu.etaxonomy.cdm.model.common.DefinedTermBase} object.
106 */
107 public static void delete(DefinedTermBase selected) {
108 CdmStore.getService(ITermService.class).delete(selected);
109 }
110
111 /**
112 * Save a vacabulary to data store
113 *
114 * @param term a {@link eu.etaxonomy.cdm.model.common.DefinedTermBase} object.
115 */
116 public static void updateVocabulary(DefinedTermBase term) {
117 CdmStore.getService(ITermService.class).saveOrUpdate(term);
118 }
119
120 /**
121 * Handingling of special cases
122 */
123
124 private static Set<ITermStoreEdgeCase<? extends DefinedTermBase>> termStoreEdgeCases = new HashSet<ITermStoreEdgeCase<? extends DefinedTermBase>>();
125
126 static {
127 termStoreEdgeCases.add(new ITermStoreEdgeCase<Feature>() {
128
129 @Override
130 public Class<Feature> getTermClass() {
131 return Feature.class;
132 }
133
134 @Override
135 public List<Feature> getTerms() {
136 List<Feature> features = TermStore.getTermsFromService(Feature.class, null);
137 features.remove(Feature.IMAGE());
138 return features;
139 }
140 });
141 termStoreEdgeCases.add(new ITermStoreEdgeCase<MarkerType>(){
142
143 @Override
144 public Class<MarkerType> getTermClass() {
145 return MarkerType.class;
146 }
147
148 @Override
149 public List<MarkerType> getTerms() {
150 // filter out non technical markers
151 List<MarkerType> nonTechnicalMarkerTypes = new ArrayList<MarkerType>();
152 List<MarkerType> markerTypes = TermStore.getTermsFromService(MarkerType.class, null);
153
154 for (Object type : markerTypes) {
155 if (((MarkerType) type).isTechnical() == false) {
156 nonTechnicalMarkerTypes.add((MarkerType) type);
157 }
158 }
159
160 return nonTechnicalMarkerTypes;
161 }
162
163 });
164 termStoreEdgeCases.add(new ITermStoreEdgeCase<Rank>() {
165
166 @Override
167 public Class<Rank> getTermClass() {
168 return Rank.class;
169 }
170
171 @Override
172 public List<Rank> getTerms() {
173 if(PreferencesUtil.getSortRanksHierarchichally()){
174 return TermStore.getTermsFromService(Rank.class, new Comparator<Rank>(){
175
176 @Override
177 public int compare(Rank o1, Rank o2) {
178 return o1.compareTo(o2);
179 }
180
181 });
182 }else{
183 return TermStore.getTermsFromService(Rank.class, null);
184 }
185 }
186
187 });
188 termStoreEdgeCases.add(new ITermStoreEdgeCase<PresenceAbsenceTermBase>() {
189
190 @Override
191 public Class<PresenceAbsenceTermBase> getTermClass() {
192 return PresenceAbsenceTermBase.class;
193 }
194
195 @Override
196 public List<PresenceAbsenceTermBase> getTerms() {
197 List presenceAbsenceTerms = TermStore.getTermsFromService(PresenceTerm.class, null);
198 presenceAbsenceTerms.addAll(TermStore.getTermsFromService(AbsenceTerm.class, null));
199
200 return presenceAbsenceTerms;
201 }
202 });
203 termStoreEdgeCases.add(new ITermStoreEdgeCase<TaxonRelationshipTypeInverseContainer>() {
204
205 @Override
206 public Class<TaxonRelationshipTypeInverseContainer> getTermClass() {
207 return TaxonRelationshipTypeInverseContainer.class;
208 }
209
210 @Override
211 public List<TaxonRelationshipTypeInverseContainer> getTerms() {
212 List<TaxonRelationshipType> excludeTaxonRelationshipTypes = Arrays.asList(new TaxonRelationshipType[]{
213 TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN(),
214 TaxonRelationshipType.MISAPPLIED_NAME_FOR(),
215 TaxonRelationshipType.ALL_RELATIONSHIPS()
216 });
217
218 List<TaxonRelationshipTypeInverseContainer> relationshipTypeInverseContainers = new ArrayList<TaxonRelationshipTypeInverseContainer>();
219
220 List<TaxonRelationshipType> relationshipTypes = TermStore.getTerms(TaxonRelationshipType.class);
221
222 relationshipTypes.removeAll(excludeTaxonRelationshipTypes);
223
224 for (TaxonRelationshipType relationshipType : relationshipTypes){
225 if(!relationshipType.isSymmetric()){
226 TaxonRelationshipTypeInverseContainer inverseContainer = new TaxonRelationshipTypeInverseContainer(relationshipType, true);
227 relationshipTypeInverseContainers.add(inverseContainer);
228 }
229 TaxonRelationshipTypeInverseContainer container = new TaxonRelationshipTypeInverseContainer(relationshipType, false);
230 relationshipTypeInverseContainers.add(container);
231 }
232
233 return relationshipTypeInverseContainers;
234 }
235 });
236 }
237
238 private static <T extends DefinedTermBase> ITermStoreEdgeCase<T> getEdgeCase(Class<T> termClass) {
239
240 for (ITermStoreEdgeCase termStoreEdgeCase : termStoreEdgeCases){
241 if (termStoreEdgeCase.getTermClass().equals(termClass)){
242 return termStoreEdgeCase;
243 }
244 }
245
246 return null;
247 }
248
249 private interface ITermStoreEdgeCase<TERM> {
250
251 public abstract Class<TERM> getTermClass();
252
253 public abstract List<TERM> getTerms();
254
255 }
256 }