083de428acb2ba2d3477c8e58229a4b595cc5d6f
[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 private CdmApplicationController getApplicationControllerInternal(){
216 return applicationController;
217 }
218
219 public static CdmApplicationController getApplicationController(){
220 return getDefault().getApplicationControllerInternal();
221 }
222
223
224 /**
225 * Create a new conversation and bind resources to it
226 *
227 * @return
228 */
229 public static ConversationHolder NewConversation(){
230
231 CdmStore store = getDefault();
232 CdmApplicationController controller = store.getApplicationController();
233
234 ConversationHolder conversation = controller.NewConversation();
235
236 return conversation;
237 }
238
239 /**
240 * Creates a new conversation, binds resources to the conversation and
241 * start a transaction for this conversation.
242 *
243 * @return
244 */
245 public static ConversationHolder NewTransactionalConversation() {
246 ConversationHolder conversation = NewConversation();
247
248 conversation.startTransaction();
249 return conversation;
250 }
251
252
253 private ConversationHolder getGlobalReadOnlyConversation() {
254 ConversationHolder conversation = globalReadOnlyConversation == null
255 ? NewConversation()
256 : globalReadOnlyConversation;
257 conversation.bind();
258 return conversation;
259 }
260
261 public static ConversationHolder getGlobalConversation(){
262 return getDefault().getGlobalReadOnlyConversation();
263 }
264
265 public static ITaxonService getTaxonService(){
266 return getDefault().getApplicationController().getTaxonService();
267 }
268
269 public static INameService getNameService(){
270 return getDefault().getApplicationController().getNameService();
271 }
272
273 public static IReferenceService getReferenceService(){
274 return getDefault().getApplicationController().getReferenceService();
275 }
276
277 public static ILocationService getLocationService(){
278 return getDefault().getApplicationController().getLocationService();
279 }
280
281 public static ProviderManager getAuthenticationManager() {
282 return getDefault().getApplicationController().getAuthenticationManager();
283 }
284
285
286 /**
287 * @param searchText
288 * @return
289 */
290 @SuppressWarnings("unchecked")
291 public static List<TaxonNameBase> searchNameString(String searchText) {
292 List<TaxonNameBase> resultSet = new ArrayList<TaxonNameBase>();
293 resultSet.addAll(getNameService()
294 .getNamesByName(searchText.replace("*", "%")));
295 return resultSet;
296 }
297
298 private List<IdentifiableEntity> findTaxaByName(String queryString, boolean restrictToTaxonObjs) {
299
300 ITaxonServiceConfigurator configurator = new TaxonServiceConfiguratorImpl();
301
302 configurator.setSearchString(queryString);
303 configurator.setDoTaxa(true);
304 configurator.setMatchMode(MatchMode.BEGINNING);
305 if (restrictToTaxonObjs) {
306 configurator.setDoNamesWithoutTaxa(false);
307 configurator.setDoSynonyms(false);
308 } else {
309 configurator.setDoNamesWithoutTaxa(true);
310 configurator.setDoSynonyms(true);
311 }
312 configurator.setSec(null);
313 configurator.setPageNumber(0);
314 // TODO currently limit results to 1000
315 configurator.setPageSize(1000);
316
317 List<IdentifiableEntity> result = getTaxonService().findTaxaAndNames(configurator).getRecords();
318
319 return result;
320 }
321
322 public static List<IdentifiableEntity> searchTaxaByName(String queryString){
323 return getDefault().findTaxaByName(queryString, false);
324 }
325
326 public static List<IdentifiableEntity> searchTaxaByName(String queryString, boolean restrictToTaxonObjs){
327 return getDefault().findTaxaByName(queryString, restrictToTaxonObjs);
328 }
329
330 /**
331 * Searches for references by string. "%" is used as a wildcard.
332 *
333 * @param text
334 * @return
335 */
336 public static List<ReferenceBase> getReferencesByTitle(String reference) {
337
338 reference = reference.replace("*", "%");
339 List<ReferenceBase> resultsList = null;
340 try {
341 resultsList = getReferenceService().getReferencesByTitle(reference);
342 } catch (RuntimeException e) {
343 // MessageDialog.openError(GlobalController.getShell(), "Search reference error",
344 // "Reference search returned an error. This could be a Hibernate concurrency problem. " +
345 // "Please try saving your work, then searching again.");
346 e.printStackTrace();
347 }
348 return resultsList;
349 }
350
351
352 public static List<Language> getLanguages() {
353 ITermService termService = getDefault().getApplicationController().getTermService();
354 ArrayList<Language> languages = new ArrayList<Language>();
355 for (Language language : termService.getLanguageVocabulary()) {
356 languages.add(language);
357 }
358
359 // TODO sort languages
360
361 // languages.add(Language.ENGLISH());
362 // languages.add(Language.GERMAN());
363 return languages;
364 }
365
366 /**
367 * FIXME mock
368 *
369 * @return
370 */
371 public static Language getDefaultLanguage(){
372 return Language.ENGLISH();
373 }
374
375 /**
376 * @return
377 */
378 private static String getApplicationContextBean() {
379 return DEFAULT_APPLICATION_CONTEXT;
380 }
381
382 /**
383 * @return
384 */
385 public static LinkedHashMap<Class<?>, String> getReferenceTypes() {
386 LinkedHashMap<Class<?>, String> nomReferenceTypeMap = new LinkedHashMap<Class<?>, String>();
387
388 // referenceTypeMap.put(BibtexReference.class, "BibTeX Reference");
389 nomReferenceTypeMap.put(Article.class, "Article");
390 nomReferenceTypeMap.put(Generic.class, "Generic");
391 nomReferenceTypeMap.put(Book.class, "Book");
392 nomReferenceTypeMap.put(BookSection.class, "Book Section");
393
394 return nomReferenceTypeMap;
395 }
396
397 /**
398 * @param feature
399 */
400 public static void saveFeature(Feature feature) {
401 TermVocabulary<Feature> vocabulary = getDefault().getFeaturesInternal();
402
403 vocabulary.addTerm(feature);
404
405 getDefault().getApplicationController().getTermService().saveTermVocabulary(vocabulary);
406 }
407
408 /**
409 * TODO make this more generic
410 *
411 * @param feature
412 */
413 public static void updateFeature(Feature feature) {
414 TermVocabulary<Feature> vocabulary = getDefault().getFeaturesInternal();
415
416 getDefault().getApplicationController().getTermService().saveTermVocabulary(vocabulary);
417 }
418 }