added a readme file
[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.lang.reflect.InvocationTargetException;
13 import java.sql.DatabaseMetaData;
14 import java.sql.ResultSet;
15 import java.sql.SQLException;
16 import java.util.ArrayList;
17 import java.util.List;
18
19 import org.eclipse.core.runtime.IProgressMonitor;
20 import org.eclipse.jface.dialogs.ProgressMonitorDialog;
21 import org.eclipse.jface.operation.IRunnableWithProgress;
22 import org.springframework.core.io.ClassPathResource;
23 import org.springframework.core.io.Resource;
24 import org.springframework.security.authentication.ProviderManager;
25
26 import eu.etaxonomy.cdm.api.application.CdmApplicationController;
27 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
28 import eu.etaxonomy.cdm.api.service.IAgentService;
29 import eu.etaxonomy.cdm.api.service.IClassificationService;
30 import eu.etaxonomy.cdm.api.service.ICollectionService;
31 import eu.etaxonomy.cdm.api.service.ICommonService;
32 import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
33 import eu.etaxonomy.cdm.api.service.IFeatureTreeService;
34 import eu.etaxonomy.cdm.api.service.ILocationService;
35 import eu.etaxonomy.cdm.api.service.IMediaService;
36 import eu.etaxonomy.cdm.api.service.INameService;
37 import eu.etaxonomy.cdm.api.service.IOccurrenceService;
38 import eu.etaxonomy.cdm.api.service.IReferenceService;
39 import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
40 import eu.etaxonomy.cdm.api.service.ITaxonService;
41 import eu.etaxonomy.cdm.api.service.ITermService;
42 import eu.etaxonomy.cdm.api.service.IUserService;
43 import eu.etaxonomy.cdm.api.service.IVocabularyService;
44 import eu.etaxonomy.cdm.api.service.config.IIdentifiableEntityServiceConfigurator;
45 import eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator;
46 import eu.etaxonomy.cdm.database.DatabaseTypeEnum;
47 import eu.etaxonomy.cdm.database.DbSchemaValidation;
48 import eu.etaxonomy.cdm.database.ICdmDataSource;
49 import eu.etaxonomy.cdm.ext.geo.IEditGeoService;
50 import eu.etaxonomy.cdm.model.agent.AgentBase;
51 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
52 import eu.etaxonomy.cdm.model.common.CdmMetaData;
53 import eu.etaxonomy.cdm.model.common.CdmMetaData.MetaDataPropertyName;
54 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
55 import eu.etaxonomy.cdm.model.common.Language;
56 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
57 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
58 import eu.etaxonomy.cdm.model.reference.Reference;
59 import eu.etaxonomy.cdm.model.taxon.Classification;
60 import eu.etaxonomy.taxeditor.datasource.CdmDataSourceRepository;
61 import eu.etaxonomy.taxeditor.datasource.view.CdmDataSourceViewPart;
62 import eu.etaxonomy.taxeditor.io.ExportHandler;
63 import eu.etaxonomy.taxeditor.io.ImportHandler;
64 import eu.etaxonomy.taxeditor.model.CdmProgressMonitorAdapter;
65 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
66
67 /**
68 * This implementation of ICdmDataRepository depends on hibernate sessions to store the data correctly
69 * for the current session. No state is held in this class.
70 *
71 * Only methods that either get or manipulate data are exposed here. So this class acts as a facade
72 * for the methods in cdmlib-service.
73 *
74 * @author n.hoffmann
75 * @created 17.03.2009
76 * @version 1.0
77 */
78 public class CdmStore{
79
80 private static class CdmDataStoreConnector implements IRunnableWithProgress{
81 private ICdmDataSource dataSource;
82 private DbSchemaValidation dbSchemaValidation;
83 private Resource applicationContextBean;
84
85 /**
86 * @param datasource
87 * @param dbSchemaValidation
88 * @param applicationContextBean
89 */
90 public CdmDataStoreConnector(ICdmDataSource datasource,
91 DbSchemaValidation dbSchemaValidation,
92 Resource applicationContextBean) {
93 this.dataSource = datasource;
94 this.dbSchemaValidation = dbSchemaValidation;
95 this.applicationContextBean = applicationContextBean;
96 }
97
98
99 public void run(final IProgressMonitor monitor) {
100
101 monitor.beginTask(getConnectionMessage(), 10);
102
103 // check if database is up and running
104 checkDatabaseReachable(monitor);
105
106 if(! monitor.isCanceled()){
107 // check if the datasource actually holds data
108 checkDatabaseNotEmpty(monitor);
109 }
110
111 if(dbSchemaValidation != DbSchemaValidation.CREATE && ! monitor.isCanceled()){
112 // if we do not create the datasource, we want to check if the datasource is compatible with this editor
113 checkDbSchemaVersionCompatibility(monitor);
114 }
115
116 // we are done with our low level checking and will free resources now
117 dataSource.closeOpenConnections();
118
119 if(! monitor.isCanceled()){
120 close(monitor);
121 }
122
123 CdmApplicationController applicationController = null;
124
125 if(! monitor.isCanceled()){
126 CdmProgressMonitorAdapter subprogressMonitor = CdmProgressMonitorAdapter.CreateSubMonitor(monitor, 5);
127 // This is where we instantiate the application controller
128 try{
129 applicationController = CdmApplicationController.NewInstance(applicationContextBean, dataSource, dbSchemaValidation, false, subprogressMonitor);
130 }catch(Exception e){
131 StoreUtil.error(this.getClass(), e.getMessage(), e);
132 }
133 }
134
135 if(! monitor.isCanceled()){
136 setInstance(applicationController, dataSource);
137
138 getContextManager().notifyContextStart(monitor);
139
140 monitor.done();
141 StoreUtil.info("Application context initialized.");
142 }else{
143 // Show datasource view if not shown yet
144 StoreUtil.showView(CdmDataSourceViewPart.ID);
145 }
146 }
147
148
149
150 /**
151 * @return
152 */
153 private String getConnectionMessage() {
154 String message = "";
155 if(dataSource.getDatabaseType().equals(DatabaseTypeEnum.H2)){
156 message = " local CDM Store ";
157 }else{
158 message = " CDM Community Store ";
159 }
160 message += "'" + dataSource.getName() + "'";
161
162 message = "Connecting to" + message + ".";
163
164 return message;
165 }
166
167 /**
168 * @return
169 * @throws SQLException
170 */
171 private void checkDbSchemaVersionCompatibility(IProgressMonitor monitor) {
172 monitor.subTask("Checking if datasource is compatible with this editor.");
173 String dbSchemaVersion;
174 boolean result = false;
175 try {
176 dbSchemaVersion = (String) dataSource.getSingleValue(MetaDataPropertyName.DB_SCHEMA_VERSION.getSqlQuery());
177 // we assume that empty dbSchemaVersion means an empty database and skip version checking
178 result = dbSchemaVersion == null ? true : CdmMetaData.isDbSchemaVersionCompatible(dbSchemaVersion);
179 monitor.worked(1);
180 } catch (SQLException e) {
181 //
182 }
183
184 if(!result){
185 // Show an error message
186 StoreUtil.errorDialog("DatabaseCompatibilityCheck failed", this, "The database schema for the chosen " +
187 "datasource '" + dataSource + "' \n is not valid for this version of the taxonomic editor. \n" +
188 "Please update the chosen datasource or choose a new data source to connect to in the Datasource View.", null);
189
190 monitor.setCanceled(true);
191 }
192
193 }
194
195 private void checkDatabaseNotEmpty(IProgressMonitor monitor) {
196 monitor.subTask("Checking if datasource is not empty.");
197 DatabaseMetaData metaData = dataSource.getMetaData();
198 if(metaData != null){
199 try {
200 ResultSet resultSet = metaData.getTables(dataSource.getDatabase(), null, null, null);
201 if (resultSet != null){
202 if(! resultSet.next()){
203 dbSchemaValidation = DbSchemaValidation.CREATE;
204 }
205 monitor.worked(1);
206 return;
207 }
208 } catch (SQLException e) {
209 StoreUtil.errorDialog("Error while trying to retrieve database metadata", this, "Something is utterly wrong with your database.", e);
210 StoreUtil.error(this.getClass(), e.getMessage(), e);
211 }
212 }
213
214 monitor.setCanceled(true);
215 }
216
217 private void checkDatabaseReachable(IProgressMonitor monitor){
218 try {
219 monitor.subTask("Checking if datasource is reachable.");
220 dataSource.testConnection();
221 monitor.worked(1);
222 } catch (ClassNotFoundException e) {
223 StoreUtil.errorDialog("Could not connect to chosen datasource", this, "Reason: " + e.getMessage(), e);
224 monitor.setCanceled(true);
225 } catch (SQLException e) {
226 StoreUtil.errorDialog("Could not connect to chosen datasource", this, "Reason: " + e.getMessage(), e);
227 monitor.setCanceled(true);
228 }
229
230 }
231 }
232
233
234
235 private static final Resource DEFAULT_APPLICATION_CONTEXT = new ClassPathResource("/eu/etaxonomy/cdm/editorApplicationContext.xml", TaxeditorStorePlugin.class);
236 private static final DbSchemaValidation DEFAULT_DB_SCHEMA_VALIDATION = DbSchemaValidation.VALIDATE;
237
238 private static CdmStore instance;
239
240 private CdmApplicationController applicationController;
241
242 private static LoginManager loginManager;
243
244 private static ImportHandler importHandler;
245
246 private static ExportHandler exportHandler;
247
248 private static ContextManager contextManager;
249
250 private Language language;
251
252 private ICdmDataSource cdmDatasource;
253
254 private boolean isConnected;
255
256 /**
257 * <p>getDefault</p>
258 *
259 * @return a {@link eu.etaxonomy.taxeditor.store.CdmStore} object.
260 */
261 protected static CdmStore getDefault(){
262 if(instance != null && instance.isConnected){
263 return instance;
264 }else if(instance == null || !instance.isConnected){
265
266 StoreUtil.warningDialog("Application is not connected to a datastore", instance, "The requested operation is only available when " +
267 "connected to a datasource. You may choose a datasource to connect to or create a new one in the datasource view.");
268
269 StoreUtil.showView(CdmDataSourceViewPart.ID);
270
271 }
272 return null;
273 }
274
275 /**
276 * Initialize the with the last edited datasource
277 */
278 public static void connect() {
279
280 ICdmDataSource datasource = CdmDataSourceRepository.getCurrentDataSource();
281
282 connect(datasource);
283 }
284
285 /**
286 * Initialize with a specific datasource
287 *
288 * @param datasource a {@link eu.etaxonomy.cdm.database.ICdmDataSource} object.
289 */
290 public static void connect(ICdmDataSource datasource) {
291 connect(datasource, DEFAULT_DB_SCHEMA_VALIDATION, DEFAULT_APPLICATION_CONTEXT);
292 }
293
294 /**
295 * Initialize and provide
296 *
297 * @param datasource
298 * @param dbSchemaValidation
299 * @param applicationContextBean
300 */
301 private static void connect(final ICdmDataSource datasource, final DbSchemaValidation dbSchemaValidation, final Resource applicationContextBean){
302 StoreUtil.info("Connecting to datasource: " + datasource);
303
304 try {
305 ProgressMonitorDialog dialog = new ProgressMonitorDialog(StoreUtil.getShell());
306 dialog.run(false, true, new CdmDataStoreConnector(datasource, dbSchemaValidation, applicationContextBean));
307 } catch (InvocationTargetException e) {
308 StoreUtil.error(CdmStore.class, e);
309 } catch (InterruptedException e) {
310 StoreUtil.error(CdmStore.class, e);
311 }
312
313 }
314
315
316
317 /**
318 * Closes the current application context
319 *
320 * @param monitor a {@link org.eclipse.core.runtime.IProgressMonitor} object.
321 */
322 public static void close(IProgressMonitor monitor){
323 getContextManager().notifyContextAboutToStop(monitor);
324 if((monitor == null || (!monitor.isCanceled()) && isActive() && StoreUtil.closeAll())){
325 getContextManager().notifyContextStop(monitor);
326 if(instance.getApplicationController() != null){
327 instance.getApplicationController().close();
328 }
329 instance.close();
330 }
331 }
332
333 private void close() {
334 isConnected = false;
335 cdmDatasource = null;
336 }
337
338 private static void setInstance(CdmApplicationController applicationController, ICdmDataSource dataSource){
339 instance = new CdmStore(applicationController, dataSource);
340 }
341
342 private CdmStore(CdmApplicationController applicationController, ICdmDataSource dataSource){
343 this.applicationController = applicationController;
344 this.cdmDatasource = dataSource;
345 isConnected = true;
346 }
347
348 /**
349 * All calls to the datastore require
350 *
351 * @return
352 */
353 private CdmApplicationController getApplicationController(){
354 try{
355 return applicationController;
356 }catch(Exception e){
357 StoreUtil.error(CdmStore.class, e);
358 }
359 return null;
360 }
361
362 /**
363 * <p>getCurrentApplicationController</p>
364 *
365 * @return a {@link eu.etaxonomy.cdm.api.application.CdmApplicationController} object.
366 */
367 public static CdmApplicationController getCurrentApplicationController(){
368 if(getDefault() != null){
369 return getDefault().getApplicationController();
370 }
371 return null;
372 }
373
374 /*
375 * CONVERSATIONS
376 */
377
378 /**
379 * Creates a new conversation, binds resources to the conversation and
380 * start a transaction for this conversation.
381 *
382 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
383 */
384 public static ConversationHolder createConversation() {
385 ConversationHolder conversation = getCurrentApplicationController().NewConversation();
386
387 conversation.startTransaction();
388 return conversation;
389 }
390
391 /*
392 * EXPOSING SERVICES
393 */
394
395 /**
396 * <p>getTaxonService</p>
397 *
398 * @return a {@link eu.etaxonomy.cdm.api.service.ITaxonService} object.
399 */
400 public static ITaxonService getTaxonService(){ return getCurrentApplicationController().getTaxonService();}
401
402 /**
403 * <p>getTaxonTreeService</p>
404 *
405 * @return a {@link eu.etaxonomy.cdm.api.service.ITaxonTreeService} object.
406 */
407 public static IClassificationService getClassificationService() { return getCurrentApplicationController().getClassificationService();}
408
409 /**
410 * <p>getTaxonNodeService</p>
411 *
412 * @return a {@link eu.etaxonomy.cdm.api.service.ITaxonNodeService} object.
413 */
414 public static ITaxonNodeService getTaxonNodeService() { return getCurrentApplicationController().getTaxonNodeService();}
415
416 /**
417 * <p>getNameService</p>
418 *
419 * @return a {@link eu.etaxonomy.cdm.api.service.INameService} object.
420 */
421 public static INameService getNameService(){ return getCurrentApplicationController().getNameService();}
422
423 /**
424 * <p>getReferenceService</p>
425 *
426 * @return a {@link eu.etaxonomy.cdm.api.service.IReferenceService} object.
427 */
428 public static IReferenceService getReferenceService(){ return getCurrentApplicationController().getReferenceService();}
429
430 /**
431 * <p>getLocationService</p>
432 *
433 * @return a {@link eu.etaxonomy.cdm.api.service.ILocationService} object.
434 */
435 public static ILocationService getLocationService(){ return getCurrentApplicationController().getLocationService();}
436
437 /**
438 * <p>getAuthenticationManager</p>
439 *
440 * @return a {@link org.springframework.security.authentication.ProviderManager} object.
441 */
442 public static ProviderManager getAuthenticationManager() { return getCurrentApplicationController().getAuthenticationManager();}
443
444 /**
445 * <p>getUserService</p>
446 *
447 * @return a {@link eu.etaxonomy.cdm.api.service.IUserService} object.
448 */
449 public static IUserService getUserService() { return getCurrentApplicationController().getUserService(); }
450
451 /**
452 * <p>getCommonService</p>
453 *
454 * @return a {@link eu.etaxonomy.cdm.api.service.ICommonService} object.
455 */
456 public static ICommonService getCommonService() { return getCurrentApplicationController().getCommonService(); }
457
458 /**
459 * <p>getAgentService</p>
460 *
461 * @return a {@link eu.etaxonomy.cdm.api.service.IAgentService} object.
462 */
463 public static IAgentService getAgentService() { return getCurrentApplicationController().getAgentService(); }
464
465 /**
466 * <p>getTermService</p>
467 *
468 * @return a {@link eu.etaxonomy.cdm.api.service.ITermService} object.
469 */
470 public static ITermService getTermService() { return getCurrentApplicationController() != null ? getCurrentApplicationController().getTermService() : null; }
471
472 /**
473 * <p>getVocabularyService</p>
474 *
475 * @return a {@link eu.etaxonomy.cdm.api.service.IVocabularyService} object.
476 */
477 public static IVocabularyService getVocabularyService() { return getCurrentApplicationController().getVocabularyService(); }
478
479 /**
480 * <p>getMediaService</p>
481 *
482 * @return a {@link eu.etaxonomy.cdm.api.service.IMediaService} object.
483 */
484 public static IMediaService getMediaService() { return getCurrentApplicationController().getMediaService(); }
485
486 /**
487 * <p>getOccurrenceService</p>
488 *
489 * @return a {@link eu.etaxonomy.cdm.api.service.IOccurrenceService} object.
490 */
491 public static IOccurrenceService getOccurrenceService() { return getCurrentApplicationController().getOccurrenceService(); }
492
493 /**
494 * <p>getFeatureTreeService</p>
495 *
496 * @return a {@link eu.etaxonomy.cdm.api.service.IFeatureTreeService} object.
497 */
498 public static IFeatureTreeService getFeatureTreeService() { return getCurrentApplicationController().getFeatureTreeService(); }
499
500 /**
501 * <p>getFeatureNodeService</p>
502 *
503 * @return a {@link eu.etaxonomy.cdm.api.service.IFeatureNodeService} object.
504 */
505 public static IFeatureNodeService getFeatureNodeService() { return getCurrentApplicationController().getFeatureNodeService(); }
506
507 /**
508 * <p>getCollectionService</p>
509 *
510 * @return a {@link eu.etaxonomy.cdm.api.service.ICollectionService} object.
511 */
512 public static ICollectionService getCollectionService() { return getCurrentApplicationController().getCollectionService(); }
513
514 /**
515 * <p>getGeoService</p>
516 *
517 * @return a {@link eu.etaxonomy.cdm.ext.geo.IEditGeoService} object.
518 */
519 public static IEditGeoService getGeoService(){
520 return (IEditGeoService) getCurrentApplicationController().getBean("editGeoService");
521 }
522
523 /*
524 * METHODS TO FIND ENTITIES
525 */
526
527 /**
528 * <p>findNames</p>
529 *
530 * @param configurator a {@link eu.etaxonomy.cdm.api.service.config.IIdentifiableEntityServiceConfigurator} object.
531 * @return a {@link java.util.List} object.
532 */
533 public static List<TaxonNameBase> findNames(IIdentifiableEntityServiceConfigurator configurator){
534 // TODO we want to use IIdentifiableEntityServiceConfigurator for all find methods
535 // unfortunately this is not consistently implemented in the library.
536 // FIXME use proper method once it is implemented in the library
537 String titleSearchString = configurator.getTitleSearchString().replace("*", "%");
538
539 return getNameService().getNamesByName(titleSearchString);
540 }
541
542 /**
543 * <p>findTaxaAndNames</p>
544 *
545 * @param configurator a {@link eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator} object.
546 * @return a {@link java.util.List} object.
547 */
548 public static List<IdentifiableEntity> findTaxaAndNames(ITaxonServiceConfigurator configurator){
549 return getTaxonService().findTaxaAndNames(configurator).getRecords();
550 }
551
552 /**
553 * <p>findReferences</p>
554 *
555 * @param configurator a {@link eu.etaxonomy.cdm.api.service.config.IIdentifiableEntityServiceConfigurator} object.
556 * @return a {@link java.util.List} object.
557 */
558 public static List<Reference> findReferences(IIdentifiableEntityServiceConfigurator configurator){
559 // TODO we want to use IIdentifiableEntityServiceConfigurator for all find methods
560 // unfortunately this is not consistently implemented in the library.
561 // FIXME use proper method once it is implemented in the library
562 String titleSearchString = configurator.getTitleSearchString().replace("*", "%");
563
564 return getReferenceService().findByTitle(null, titleSearchString, null, null, null, null, null, null).getRecords();
565 }
566
567 /**
568 * <p>findAgents</p>
569 *
570 * @param configurator a {@link eu.etaxonomy.cdm.api.service.config.IIdentifiableEntityServiceConfigurator} object.
571 * @return a {@link java.util.List} object.
572 */
573 public static List<AgentBase> findAgents(IIdentifiableEntityServiceConfigurator configurator){
574 // TODO we want to use IIdentifiableEntityServiceConfigurator for all find methods
575 // unfortunately this is not consistently implemented in the library.
576 // FIXME use proper method once it is implemented in the library
577 String titleSearchString = configurator.getTitleSearchString().replace("*", "%");
578
579 return getAgentService().findByTitle(null, titleSearchString, null, null, null, null, null, null).getRecords();
580 }
581
582 /**
583 * <p>findTeamOrPersons</p>
584 *
585 * @param configurator a {@link eu.etaxonomy.cdm.api.service.config.IIdentifiableEntityServiceConfigurator} object.
586 * @return a {@link java.util.List} object.
587 */
588 public static List<TeamOrPersonBase> findTeamOrPersons(IIdentifiableEntityServiceConfigurator configurator){
589 // TODO move this to cdmlib
590 List<TeamOrPersonBase> result = new ArrayList<TeamOrPersonBase>();
591 for (AgentBase agent : findAgents(configurator)) {
592 if (agent instanceof TeamOrPersonBase) {
593 result.add((TeamOrPersonBase) agent);
594 }
595 }
596 return result;
597 }
598
599 /**
600 * <p>findOccurrences</p>
601 *
602 * @param configurator a {@link eu.etaxonomy.cdm.api.service.config.IIdentifiableEntityServiceConfigurator} object.
603 * @return a {@link java.util.List} object.
604 */
605 public static List<SpecimenOrObservationBase> findOccurrences(IIdentifiableEntityServiceConfigurator configurator){
606 // TODO we want to use IIdentifiableEntityServiceConfigurator for all find methods
607 // unfortunately this is not consistently implemented in the library.
608 // FIXME use proper method once it is implemented in the library
609 String titleSearchString = configurator.getTitleSearchString().replace("*", "%");
610
611 return getOccurrenceService().findByTitle(SpecimenOrObservationBase.class, titleSearchString, null, null, null, null, null, null).getRecords();
612 }
613
614 /*
615 * LANGUAGE
616 */
617
618 /**
619 * <p>getDefaultLanguage</p>
620 *
621 * @return a {@link eu.etaxonomy.cdm.model.common.Language} object.
622 */
623 public static Language getDefaultLanguage(){
624 if(getDefault().getLanguage() == null){
625 getDefault().setLanguage(Language.DEFAULT());
626 }
627 return getDefault().getLanguage();
628 }
629
630 /**
631 * <p>setDefaultLanguage</p>
632 *
633 * @param language a {@link eu.etaxonomy.cdm.model.common.Language} object.
634 */
635 public static void setDefaultLanguage(Language language){
636 getDefault().setLanguage(language);
637 }
638
639 /**
640 * @return the language
641 */
642 private Language getLanguage() {
643 return language;
644 }
645
646 /**
647 * @param language the language to set
648 */
649 private void setLanguage(Language language) {
650 this.language = language;
651 }
652
653 /*
654 * LOGIN
655 */
656
657 /**
658 * <p>Getter for the field <code>loginManager</code>.</p>
659 *
660 * @return a {@link eu.etaxonomy.taxeditor.store.LoginManager} object.
661 */
662 public static LoginManager getLoginManager(){
663 if(loginManager == null){
664 loginManager = new LoginManager();
665 }
666 return loginManager;
667 }
668
669 /**
670 * <p>Getter for the field <code>contextManager</code>.</p>
671 *
672 * @return a {@link eu.etaxonomy.taxeditor.store.ContextManager} object.
673 */
674 public static synchronized ContextManager getContextManager(){
675 if(contextManager == null){
676 contextManager = new ContextManager();
677 }
678 return contextManager;
679 }
680
681 /*
682 * IMPORT/EXPORT FACTORIES
683 */
684
685 /**
686 * <p>Getter for the field <code>importHandler</code>.</p>
687 *
688 * @return a {@link eu.etaxonomy.taxeditor.io.ImportHandler} object.
689 */
690 public static synchronized ImportHandler getImportHandler(){
691 if(importHandler == null){
692 importHandler = ImportHandler.NewInstance(getCurrentApplicationController());
693 }
694 return importHandler;
695 }
696
697 /**
698 * <p>Getter for the field <code>exportHandler</code>.</p>
699 *
700 * @return a {@link eu.etaxonomy.taxeditor.io.ExportHandler} object.
701 */
702 public static synchronized ExportHandler getExportHandler(){
703 if(exportHandler == null){
704 exportHandler = ExportHandler.NewInstance(getCurrentApplicationController());
705 }
706 return exportHandler;
707 }
708
709 /**
710 * Whether this CdmStore is currently connected to a datasource
711 *
712 * @return a boolean.
713 */
714 public static boolean isActive(){
715 return instance != null && instance.isConnected;
716 }
717
718 /**
719 * <p>getDataSource</p>
720 *
721 * @return a {@link eu.etaxonomy.cdm.database.ICdmDataSource} object.
722 */
723 public static ICdmDataSource getDataSource(){
724 if(isActive()){
725 return instance.getDatasource();
726 }
727 return null;
728 }
729
730 /**
731 * @return
732 */
733 private ICdmDataSource getDatasource() {
734 return cdmDatasource;
735 }
736
737 /**
738 * <p>createDefaultClassification</p>
739 *
740 * @param conversation a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
741 */
742 public static void createDefaultClassification(ConversationHolder conversation){
743 Classification defaultClassification = Classification.NewInstance("My Classification");
744 getClassificationService().saveOrUpdate(defaultClassification);
745 conversation.commit(true);
746 }
747 }