6fb1108e0430615ab3a496604722726a594606ae
[taxeditor.git] / taxeditor-store / src / main / java / eu / etaxonomy / taxeditor / store / CdmStore.java
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
10 package eu.etaxonomy.taxeditor.store;
11
12 import java.util.ArrayList;
13 import java.util.LinkedHashMap;
14 import java.util.List;
15 import java.util.Set;
16 import java.util.SortedSet;
17 import java.util.UUID;
18
19 import org.apache.log4j.Logger;
20 import org.springframework.security.providers.ProviderManager;
21
22 import eu.etaxonomy.cdm.api.application.CdmApplicationController;
23 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
24 import eu.etaxonomy.cdm.api.service.ILocationService;
25 import eu.etaxonomy.cdm.api.service.INameService;
26 import eu.etaxonomy.cdm.api.service.IReferenceService;
27 import eu.etaxonomy.cdm.api.service.ITaxonService;
28 import eu.etaxonomy.cdm.api.service.ITermService;
29 import eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator;
30 import eu.etaxonomy.cdm.api.service.config.impl.TaxonServiceConfiguratorImpl;
31 import eu.etaxonomy.cdm.database.DbSchemaValidation;
32 import eu.etaxonomy.cdm.database.ICdmDataSource;
33 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
34 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
35 import eu.etaxonomy.cdm.model.common.Language;
36 import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
37 import eu.etaxonomy.cdm.model.common.TermVocabulary;
38 import eu.etaxonomy.cdm.model.common.VocabularyEnum;
39 import eu.etaxonomy.cdm.model.description.Feature;
40 import eu.etaxonomy.cdm.model.name.NameRelationshipType;
41 import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
42 import eu.etaxonomy.cdm.model.name.Rank;
43 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
44 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
45 import eu.etaxonomy.cdm.model.reference.Article;
46 import eu.etaxonomy.cdm.model.reference.Book;
47 import eu.etaxonomy.cdm.model.reference.BookSection;
48 import eu.etaxonomy.cdm.model.reference.Generic;
49 import eu.etaxonomy.cdm.model.reference.ReferenceBase;
50 import eu.etaxonomy.cdm.model.taxon.Taxon;
51 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
52 import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;
53 import eu.etaxonomy.cdm.persistence.query.MatchMode;
54 import eu.etaxonomy.taxeditor.datasource.CdmDataSourceRepository;
55
56 /**
57 * This implementation of ICdmDataRepository depends on hibernate sessions to store the data correctly
58 * for the current session. No state is held in this class.
59 *
60 * Only methods that either get or manipulate data are exposed here. So this class acts as a facade
61 * for the methods in cdmlib-service.
62 *
63 *
64 * @author n.hoffmann
65 * @created 17.03.2009
66 * @version 1.0
67 */
68 public class CdmStore{
69 private static final Logger logger = Logger.getLogger(CdmStore.class);
70
71 // FIXME change this to ClassPathResources as soon as it is included into the plugin
72 private static String DEFAULT_APPLICATION_CONTEXT = null;
73 private static DbSchemaValidation DEFAULT_DB_SCHEMA_VALIDATION = DbSchemaValidation.UPDATE;
74
75 private static CdmStore instance;
76
77 private CdmApplicationController applicationController;
78
79 private ConversationHolder globalReadOnlyConversation;
80
81 private static DbSchemaValidation dbSchemaValidation;
82
83 /**
84 *
85 * @return
86 */
87 public static CdmStore getDefault(){
88 return getDefault(DEFAULT_APPLICATION_CONTEXT);
89 }
90
91 /**
92 *
93 * @param applicationContextBean
94 * @return
95 */
96 public static CdmStore getDefault(String applicationContextBean){
97 if(instance == null){
98 logger.info("Initializing application context ...");
99 ICdmDataSource cdmDatasource = CdmDataSourceRepository.getDefault().
100 getCurrentDataSource();
101
102 instance = new CdmStore(cdmDatasource, getDbSchemaValidation(), applicationContextBean);
103
104 logger.info("Application context initialized.");
105 }
106 return instance;
107 }
108
109 /**
110 * @return
111 */
112 private static DbSchemaValidation getDbSchemaValidation() {
113 return (dbSchemaValidation == null) ? DEFAULT_DB_SCHEMA_VALIDATION : dbSchemaValidation;
114 }
115
116 /**
117 *
118 */
119 private CdmStore(ICdmDataSource dataSource, DbSchemaValidation dbSchemaValidation, String applicationContextBean) {
120 // TODO application context bean is not honored by application controller at the moment.
121 // cdmDefaultApplicationController bean gets loaded per default always.
122
123 try {
124 CdmStore.DEFAULT_APPLICATION_CONTEXT = applicationContextBean;
125 // applicationController = CdmApplicationController.NewInstance(applicationContextBean, dataSource, dbSchemaValidation, false);
126
127 // logger.warn("OMITTING TERM LOADING FOR DEBUGGING");
128 // applicationController = CdmApplicationController.NewInstance(dataSource, dbSchemaValidation, true);
129 applicationController = CdmApplicationController.NewInstance(dataSource, dbSchemaValidation);
130 } catch (Exception e) {
131 throw new RuntimeException(e);
132 }
133 }
134
135 public Set<TaxonRelationshipType> getConceptRelationshipTypes() {
136 Set<TaxonRelationshipType> conceptRelationshipTypes = getTaxonRelationshipTypes().getTerms();
137 // remove these two relations as they are considered standard taxon relations
138 conceptRelationshipTypes.remove(TaxonRelationshipType.MISAPPLIED_NAME_FOR());
139 conceptRelationshipTypes.remove(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN());
140
141 return conceptRelationshipTypes;
142 }
143
144 public ReferenceBase<?> getDefaultSec() {
145 // TODO why is this returning null? and of course, replace w the real deal
146 return applicationController.getReferenceService().getReferenceByUuid(
147 UUID.fromString("f3593c18-a8d2-4e51-bdad-0befbf8fb2d1"));
148 }
149
150 private TermVocabulary<Feature> getFeaturesInternal() {
151 return applicationController.getTermService().getVocabulary(VocabularyEnum.Feature);
152 }
153
154 public static SortedSet<Feature> getFeatures() {
155 return getDefault().getFeaturesInternal().getTermsOrderedByLabels(getDefaultLanguage());
156 }
157
158 public SortedSet<NameRelationshipType> getNameRelationshipTypes() {
159 return applicationController.getTermService().getVocabulary(VocabularyEnum.NameRelationshipType).getTermsOrderedByLabels(Language.DEFAULT());
160 }
161
162 public TermVocabulary<NomenclaturalStatusType> getNomenclaturalStatusTypesInternal() {
163 return applicationController.getTermService().getVocabulary(VocabularyEnum.NomenclaturalStatusType);
164 }
165
166 public static Set<NomenclaturalStatusType> getNomenclaturalStatusTypes(){
167 // TODO sort types
168 return getDefault().getNomenclaturalStatusTypesInternal().getTerms();
169 }
170
171 private OrderedTermVocabulary<Rank> getRanksInternal(){
172 TermVocabulary<Rank> vocabulary = applicationController.getTermService().getVocabulary(VocabularyEnum.Rank);
173 return HibernateProxyHelper.deproxy(vocabulary, OrderedTermVocabulary.class);
174 }
175
176 public static SortedSet<Rank> getRanks(){
177 return getDefault().getRanksInternal().getOrderedTerms(null);
178 }
179
180 public List<Taxon> getRootTaxa() {
181 boolean onlyWithChildren = false;
182 boolean withMisapplications = true;
183
184 return applicationController.getTaxonService().getRootTaxa(
185 getDefaultSec(), onlyWithChildren, withMisapplications);
186 }
187
188 /**
189 * @return
190 */
191 public List<TaxonomicTree> getTaxonomicTrees() {
192 return applicationController.getTaxonService().getAllTaxonomicTrees(10000, 0);
193 }
194
195 public OrderedTermVocabulary<TaxonRelationshipType> getTaxonRelationshipTypes() {
196 TermVocabulary vocabulary = HibernateProxyHelper.deproxy
197 (applicationController.getTermService().getVocabulary(VocabularyEnum.TaxonRelationshipType), TermVocabulary.class);
198 return (OrderedTermVocabulary<TaxonRelationshipType>) vocabulary;
199 }
200
201 public TermVocabulary<SpecimenTypeDesignationStatus> getSpecimenTypeDesignationStatus() {
202 return applicationController.getTermService().getVocabulary(VocabularyEnum.SpecimenTypeDesignationStatus);
203 }
204
205
206 public UUID saveTaxon(Taxon taxon) {
207 return applicationController.getTaxonService().save(taxon);
208 }
209
210 public void setApplicationController(
211 CdmApplicationController applicationController) {
212 this.applicationController = applicationController;
213 }
214
215 public CdmApplicationController getApplicationController(){
216 return applicationController;
217 }
218
219
220 /**
221 * Create a new conversation and bind resources to it
222 *
223 * @return
224 */
225 public static ConversationHolder NewConversation(){
226
227 CdmStore store = getDefault();
228 CdmApplicationController controller = store.getApplicationController();
229
230 ConversationHolder conversation = controller.NewConversation();
231
232 return conversation;
233 }
234
235 /**
236 * Creates a new conversation, binds resources to the conversation and
237 * start a transaction for this conversation.
238 *
239 * @return
240 */
241 public static ConversationHolder NewTransactionalConversation() {
242 ConversationHolder conversation = NewConversation();
243
244 conversation.startTransaction();
245 return conversation;
246 }
247
248
249 private ConversationHolder getGlobalReadOnlyConversation() {
250 ConversationHolder conversation = globalReadOnlyConversation == null
251 ? NewConversation()
252 : globalReadOnlyConversation;
253 conversation.bind();
254 return conversation;
255 }
256
257 public static ConversationHolder getGlobalConversation(){
258 return getDefault().getGlobalReadOnlyConversation();
259 }
260
261 public static ITaxonService getTaxonService(){
262 return getDefault().getApplicationController().getTaxonService();
263 }
264
265 public static INameService getNameService(){
266 return getDefault().getApplicationController().getNameService();
267 }
268
269 public static IReferenceService getReferenceService(){
270 return getDefault().getApplicationController().getReferenceService();
271 }
272
273 public static ILocationService getLocationService(){
274 return getDefault().getApplicationController().getLocationService();
275 }
276
277 public static ProviderManager getAuthenticationManager() {
278 return getDefault().getApplicationController().getAuthenticationManager();
279 }
280
281
282 /**
283 * @param searchText
284 * @return
285 */
286 @SuppressWarnings("unchecked")
287 public static List<TaxonNameBase> searchNameString(String searchText) {
288 List<TaxonNameBase> resultSet = new ArrayList<TaxonNameBase>();
289 resultSet.addAll(getNameService()
290 .getNamesByName(searchText.replace("*", "%")));
291 return resultSet;
292 }
293
294 private List<IdentifiableEntity> findTaxaByName(String queryString, boolean restrictToTaxonObjs) {
295
296 ITaxonServiceConfigurator configurator = new TaxonServiceConfiguratorImpl();
297
298 configurator.setSearchString(queryString);
299 configurator.setDoTaxa(true);
300 configurator.setMatchMode(MatchMode.BEGINNING);
301 if (restrictToTaxonObjs) {
302 configurator.setDoNamesWithoutTaxa(false);
303 configurator.setDoSynonyms(false);
304 } else {
305 configurator.setDoNamesWithoutTaxa(true);
306 configurator.setDoSynonyms(true);
307 }
308 configurator.setReferenceBase(null);
309 configurator.setPageNumber(0);
310 // TODO currently limit results to 1000
311 configurator.setPageSize(1000);
312
313 List<IdentifiableEntity> result = getTaxonService().findTaxaAndNames(configurator).getRecords();
314
315 return result;
316 }
317
318 public static List<IdentifiableEntity> searchTaxaByName(String queryString){
319 return getDefault().findTaxaByName(queryString, false);
320 }
321
322 public static List<IdentifiableEntity> searchTaxaByName(String queryString, boolean restrictToTaxonObjs){
323 return getDefault().findTaxaByName(queryString, restrictToTaxonObjs);
324 }
325
326 /**
327 * Searches for references by string. "%" is used as a wildcard.
328 *
329 * @param text
330 * @return
331 */
332 public static List<ReferenceBase> getReferencesByTitle(String reference) {
333
334 reference = reference.replace("*", "%");
335 List<ReferenceBase> resultsList = null;
336 try {
337 resultsList = getReferenceService().getReferencesByTitle(reference);
338 } catch (RuntimeException e) {
339 // MessageDialog.openError(GlobalController.getShell(), "Search reference error",
340 // "Reference search returned an error. This could be a Hibernate concurrency problem. " +
341 // "Please try saving your work, then searching again.");
342 e.printStackTrace();
343 }
344 return resultsList;
345 }
346
347
348 public static List<Language> getLanguages() {
349 ITermService termService = getDefault().getApplicationController().getTermService();
350 ArrayList<Language> languages = new ArrayList<Language>();
351 for (Language language : termService.getLanguageVocabulary()) {
352 languages.add(language);
353 }
354
355 // TODO sort languages
356
357 // languages.add(Language.ENGLISH());
358 // languages.add(Language.GERMAN());
359 return languages;
360 }
361
362 /**
363 * FIXME mock
364 *
365 * @return
366 */
367 public static Language getDefaultLanguage(){
368 return Language.ENGLISH();
369 }
370
371 /**
372 * @return
373 */
374 private static String getApplicationContextBean() {
375 return DEFAULT_APPLICATION_CONTEXT;
376 }
377
378 /**
379 * @return
380 */
381 public static LinkedHashMap<Class<?>, String> getReferenceTypes() {
382 LinkedHashMap<Class<?>, String> nomReferenceTypeMap = new LinkedHashMap<Class<?>, String>();
383
384 // referenceTypeMap.put(BibtexReference.class, "BibTeX Reference");
385 nomReferenceTypeMap.put(Article.class, "Article");
386 nomReferenceTypeMap.put(Generic.class, "Generic");
387 nomReferenceTypeMap.put(Book.class, "Book");
388 nomReferenceTypeMap.put(BookSection.class, "Book Section");
389
390 return nomReferenceTypeMap;
391 }
392
393 /**
394 * @param feature
395 */
396 public static void saveFeature(Feature feature) {
397 TermVocabulary<Feature> vocabulary = getDefault().getFeaturesInternal();
398
399 vocabulary.addTerm(feature);
400
401 getDefault().getApplicationController().getTermService().saveTermVocabulary(vocabulary);
402 }
403
404 /**
405 * TODO make this more generic
406 *
407 * @param feature
408 */
409 public static void updateFeature(Feature feature) {
410 TermVocabulary<Feature> vocabulary = getDefault().getFeaturesInternal();
411
412 getDefault().getApplicationController().getTermService().saveTermVocabulary(vocabulary);
413 }
414 }