Fixed #528 - Dropping ConceptComposite onto other groups not yet implemented
[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
21 import eu.etaxonomy.cdm.api.application.CdmApplicationController;
22 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
23 import eu.etaxonomy.cdm.api.service.ILocationService;
24 import eu.etaxonomy.cdm.api.service.INameService;
25 import eu.etaxonomy.cdm.api.service.IReferenceService;
26 import eu.etaxonomy.cdm.api.service.ITaxonService;
27 import eu.etaxonomy.cdm.api.service.ITermService;
28 import eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator;
29 import eu.etaxonomy.cdm.api.service.config.impl.TaxonServiceConfiguratorImpl;
30 import eu.etaxonomy.cdm.database.DbSchemaValidation;
31 import eu.etaxonomy.cdm.database.ICdmDataSource;
32 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
33 import eu.etaxonomy.cdm.model.common.CdmBase;
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.persistence.query.MatchMode;
53 import eu.etaxonomy.taxeditor.datasource.CdmDataSourceRepository;
54 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
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 TermVocabulary<Feature> getFeatures() {
155 return getDefault().getFeaturesInternal();
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 public OrderedTermVocabulary<Rank> getRanksInternal(){
172 TermVocabulary<Rank> vocabulary = applicationController.getTermService().getVocabulary(VocabularyEnum.Rank);
173 return HibernateProxyHelper.deproxy(vocabulary, OrderedTermVocabulary.class);
174 }
175
176 public static List<Rank> getPreferredRanks(){
177 return PreferencesUtil.getPreferredRanks();
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 public OrderedTermVocabulary<TaxonRelationshipType> getTaxonRelationshipTypes() {
189 TermVocabulary vocabulary = HibernateProxyHelper.deproxy
190 (applicationController.getTermService().getVocabulary(VocabularyEnum.TaxonRelationshipType), TermVocabulary.class);
191 return (OrderedTermVocabulary<TaxonRelationshipType>) vocabulary;
192 }
193
194 public TermVocabulary<SpecimenTypeDesignationStatus> getSpecimenTypeDesignationStatus() {
195 return applicationController.getTermService().getVocabulary(VocabularyEnum.SpecimenTypeDesignationStatus);
196 }
197
198
199 public UUID saveTaxon(Taxon taxon) {
200 return applicationController.getTaxonService().save(taxon);
201 }
202
203 public void setApplicationController(
204 CdmApplicationController applicationController) {
205 this.applicationController = applicationController;
206 }
207
208 public CdmApplicationController getApplicationController(){
209 return applicationController;
210 }
211
212
213 /**
214 * Create a new conversation and bind resources to it
215 *
216 * @return
217 */
218 public static ConversationHolder NewConversation(){
219
220 CdmStore store = getDefault();
221 CdmApplicationController controller = store.getApplicationController();
222
223 ConversationHolder conversation = controller.NewConversation();
224
225 return conversation;
226 }
227
228 /**
229 * Creates a new conversation, binds resources to the conversation and
230 * start a transaction for this conversation.
231 *
232 * @return
233 */
234 public static ConversationHolder NewTransactionalConversation() {
235 ConversationHolder conversation = NewConversation();
236
237 conversation.startTransaction();
238 return conversation;
239 }
240
241
242 private ConversationHolder getGlobalReadOnlyConversation() {
243 ConversationHolder conversation = globalReadOnlyConversation == null
244 ? NewConversation()
245 : globalReadOnlyConversation;
246 conversation.bind();
247 return conversation;
248 }
249
250 public static ConversationHolder getGlobalConversation(){
251 return getDefault().getGlobalReadOnlyConversation();
252 }
253
254 public static ITaxonService getTaxonService(){
255 return getDefault().getApplicationController().getTaxonService();
256 }
257
258 public static INameService getNameService(){
259 return getDefault().getApplicationController().getNameService();
260 }
261
262 public static IReferenceService getReferenceService(){
263 return getDefault().getApplicationController().getReferenceService();
264 }
265
266 public static ILocationService getLocationService(){
267 return getDefault().getApplicationController().getLocationService();
268 }
269
270 /**
271 * @param searchText
272 * @return
273 */
274 @SuppressWarnings("unchecked")
275 public static List<TaxonNameBase> searchNameString(String searchText) {
276 List<TaxonNameBase> resultSet = new ArrayList<TaxonNameBase>();
277 resultSet.addAll(getNameService()
278 .getNamesByName(searchText.replace("*", "%")));
279 return resultSet;
280 }
281
282 private List<IdentifiableEntity> findTaxaByName(String queryString, boolean restrictToTaxonObjs) {
283
284 ITaxonServiceConfigurator configurator = new TaxonServiceConfiguratorImpl();
285
286 configurator.setSearchString(queryString);
287 configurator.setDoTaxa(true);
288 configurator.setMatchMode(MatchMode.BEGINNING);
289 if (restrictToTaxonObjs) {
290 configurator.setDoNamesWithoutTaxa(false);
291 configurator.setDoSynonyms(false);
292 } else {
293 configurator.setDoNamesWithoutTaxa(true);
294 configurator.setDoSynonyms(true);
295 }
296 configurator.setReferenceBase(null);
297 configurator.setPageNumber(0);
298 // TODO currently limit results to 1000
299 configurator.setPageSize(1000);
300
301 List<IdentifiableEntity> result = getTaxonService().findTaxaAndNames(configurator).getRecords();
302
303 return result;
304 }
305
306 public static List<IdentifiableEntity> searchTaxaByName(String queryString){
307 return getDefault().findTaxaByName(queryString, false);
308 }
309
310 public static List<IdentifiableEntity> searchTaxaByName(String queryString, boolean restrictToTaxonObjs){
311 return getDefault().findTaxaByName(queryString, restrictToTaxonObjs);
312 }
313
314 /**
315 * Searches for references by string. "%" is used as a wildcard.
316 *
317 * @param text
318 * @return
319 */
320 public static List<ReferenceBase> getReferencesByTitle(String reference) {
321
322 reference = reference.replace("*", "%");
323 List<ReferenceBase> resultsList = null;
324 try {
325 resultsList = getReferenceService().getReferencesByTitle(reference);
326 } catch (RuntimeException e) {
327 // MessageDialog.openError(GlobalController.getShell(), "Search reference error",
328 // "Reference search returned an error. This could be a Hibernate concurrency problem. " +
329 // "Please try saving your work, then searching again.");
330 e.printStackTrace();
331 }
332 return resultsList;
333 }
334
335
336 public static List<Language> getLanguages() {
337 ITermService termService = getDefault().getApplicationController().getTermService();
338 ArrayList<Language> languages = new ArrayList<Language>();
339 for (Language language : termService.getLanguageVocabulary()) {
340 languages.add(language);
341 }
342
343 // TODO sort languages
344
345 // languages.add(Language.ENGLISH());
346 // languages.add(Language.GERMAN());
347 return languages;
348 }
349
350 /**
351 * FIXME mock
352 *
353 * @return
354 */
355 public static Language getDefaultLanguage(){
356 return Language.ENGLISH();
357 }
358
359 /**
360 * @return
361 */
362 private static String getApplicationContextBean() {
363 return DEFAULT_APPLICATION_CONTEXT;
364 }
365
366 /**
367 * @return
368 */
369 public static LinkedHashMap<Class<?>, String> getReferenceTypes() {
370 LinkedHashMap<Class<?>, String> nomReferenceTypeMap = new LinkedHashMap<Class<?>, String>();
371
372 // referenceTypeMap.put(BibtexReference.class, "BibTeX Reference");
373 nomReferenceTypeMap.put(Article.class, "Article");
374 nomReferenceTypeMap.put(Generic.class, "Generic");
375 nomReferenceTypeMap.put(Book.class, "Book");
376 nomReferenceTypeMap.put(BookSection.class, "Book Section");
377
378 return nomReferenceTypeMap;
379 }
380 }