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