2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.taxeditor
.store
;
12 import java
.util
.ArrayList
;
13 import java
.util
.List
;
15 import org
.apache
.log4j
.Logger
;
16 import org
.eclipse
.core
.runtime
.Status
;
17 import org
.eclipse
.ui
.PlatformUI
;
18 import org
.springframework
.core
.io
.ClassPathResource
;
19 import org
.springframework
.core
.io
.Resource
;
20 import org
.springframework
.security
.providers
.ProviderManager
;
22 import eu
.etaxonomy
.cdm
.api
.application
.CdmApplicationController
;
23 import eu
.etaxonomy
.cdm
.api
.conversation
.ConversationHolder
;
24 import eu
.etaxonomy
.cdm
.api
.service
.IAgentService
;
25 import eu
.etaxonomy
.cdm
.api
.service
.ICommonService
;
26 import eu
.etaxonomy
.cdm
.api
.service
.ILocationService
;
27 import eu
.etaxonomy
.cdm
.api
.service
.INameService
;
28 import eu
.etaxonomy
.cdm
.api
.service
.IReferenceService
;
29 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonService
;
30 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonTreeService
;
31 import eu
.etaxonomy
.cdm
.api
.service
.ITermService
;
32 import eu
.etaxonomy
.cdm
.api
.service
.IUserService
;
33 import eu
.etaxonomy
.cdm
.api
.service
.IVocabularyService
;
34 import eu
.etaxonomy
.cdm
.api
.service
.config
.IIdentifiableEntityServiceConfigurator
;
35 import eu
.etaxonomy
.cdm
.api
.service
.config
.ITaxonServiceConfigurator
;
36 import eu
.etaxonomy
.cdm
.database
.DataSourceNotFoundException
;
37 import eu
.etaxonomy
.cdm
.database
.DatabaseSchemaMismatchException
;
38 import eu
.etaxonomy
.cdm
.database
.DbSchemaValidation
;
39 import eu
.etaxonomy
.cdm
.database
.ICdmDataSource
;
40 import eu
.etaxonomy
.cdm
.ext
.IEditGeoService
;
41 import eu
.etaxonomy
.cdm
.model
.agent
.AgentBase
;
42 import eu
.etaxonomy
.cdm
.model
.agent
.TeamOrPersonBase
;
43 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
44 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
45 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
46 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
47 import eu
.etaxonomy
.taxeditor
.datasource
.CdmDataSourceRepository
;
48 import eu
.etaxonomy
.taxeditor
.dialogs
.DatasourceLauncherDialog
;
49 import eu
.etaxonomy
.taxeditor
.io
.ExportHandler
;
50 import eu
.etaxonomy
.taxeditor
.io
.ImportHandler
;
51 import eu
.etaxonomy
.taxeditor
.preference
.PreferencesUtil
;
52 import eu
.etaxonomy
.taxeditor
.store
.internal
.TaxeditorStorePlugin
;
55 * This implementation of ICdmDataRepository depends on hibernate sessions to store the data correctly
56 * for the current session. No state is held in this class.
58 * Only methods that either get or manipulate data are exposed here. So this class acts as a facade
59 * for the methods in cdmlib-service.
66 public class CdmStore
{
67 private static final Logger logger
= Logger
.getLogger(CdmStore
.class);
69 // FIXME change this to ClassPathResources as soon as it is included into the plugin
70 private static final Resource DEFAULT_APPLICATION_CONTEXT
= new ClassPathResource("/eu/etaxonomy/cdm/editorApplicationContext.xml", TaxeditorStorePlugin
.class.getClassLoader());
71 private static final DbSchemaValidation DEFAULT_DB_SCHEMA_VALIDATION
= DbSchemaValidation
.UPDATE
;
73 private static CdmStore instance
;
75 private CdmApplicationController applicationController
;
77 private static LoginManager loginManager
;
79 private static ImportHandler importHandler
;
81 private static ExportHandler exportHandler
;
83 private Language language
;
85 private static ICdmDataSource cdmDatasource
;
90 * @param applicationContextBean
93 protected static CdmStore
getDefault(){
96 // Prompt user for datasource if there are more than one
97 if(PreferencesUtil
.getPreferenceStore().getBoolean(PreferencesUtil
.SHOW_DATASOURCE_CHOOSER
)
98 && CdmDataSourceRepository
.getAll().size() > 1){
99 createDatasourceChooser(null);
101 // Start default cdm database
102 instance
= initialize(DEFAULT_DB_SCHEMA_VALIDATION
, DEFAULT_APPLICATION_CONTEXT
);
110 private static CdmStore
initialize(DbSchemaValidation dbSchemaValidation
, Resource applicationContextBean
){
112 logger
.info("Initializing application context ...");
114 cdmDatasource
= CdmDataSourceRepository
.getCurrentDataSource();
117 if (!cdmDatasource
.testConnection()) {
118 createDatasourceChooser("The database for the chosen datasource '" + cdmDatasource
+ "' \n could not be connected to." +
119 "Please choose a new data source to connect to");
121 instance
= new CdmStore(cdmDatasource
, dbSchemaValidation
, applicationContextBean
);
122 logger
.info("Application context initialized.");
124 if (!getCommonService().isDatabaseSchemaCompatible()) {
125 // Show the datasource chooser
126 if(CdmDataSourceRepository
.getAll().size() > 1){
127 createDatasourceChooser("The database schema for the chosen " +
128 "datasource '" + cdmDatasource
+ "' \n is not valid for this version of the taxonomic editor. \n" +
129 "Please choose a new data source to connect to");
131 throw new DatabaseSchemaMismatchException();
136 } catch (DataSourceNotFoundException e
) {
137 StoreUtil
.errorDialog("Chosen Datasource is not available", "Could not connect to the chosen " +
138 "datasource '" + cdmDatasource
+ "'. Please check settings in datasources.xml. If the datasource " +
139 "is located on a remote machine, make sure you are connected to the network.");
141 } catch (NullPointerException e
){
142 StoreUtil
.errorDialog("Corrupt Datasource", "The configuration for the chosen " +
143 "datasource '" + cdmDatasource
+ "' is corrupt. Please check settings in datasources.xml.");
145 } catch (DatabaseSchemaMismatchException e
){
146 StoreUtil
.errorDialog("Database Schema incompatible", "The database schema for the chosen " +
147 "datasource '" + cdmDatasource
+ "' is not valid for this version of the taxonomic editor.");
149 } catch (Exception e
){
150 StoreUtil
.errorDialog("Unknown Datasource Error", "An error occurred while connecting to the datasource." +
151 "Please refer to the error log.");
155 // FIXME present datasource chooser dialog instead of closing the workbench
156 PlatformUI
.getWorkbench().close();
161 * Creates the datasource chooser.
162 * @param message Message to show. Specify null if none.
164 private static void createDatasourceChooser(String message
) {
165 DatasourceLauncherDialog chooseDataSource
= new DatasourceLauncherDialog(StoreUtil
.getShell(), message
);
166 if(chooseDataSource
.open() == Status
.OK
){
167 instance
= initialize(DEFAULT_DB_SCHEMA_VALIDATION
, DEFAULT_APPLICATION_CONTEXT
);
169 // no datasource chosen.
170 logger
.warn("No datasource chosen. Exiting now.");
171 PlatformUI
.getWorkbench().close();
178 private CdmStore(ICdmDataSource dataSource
, DbSchemaValidation dbSchemaValidation
, Resource applicationContextBean
) {
180 applicationController
= CdmApplicationController
.NewInstance(applicationContextBean
, dataSource
, dbSchemaValidation
, false);
181 } catch (Exception e
) {
182 throw new RuntimeException(e
);
187 * All calls to the datastore require
191 private CdmApplicationController
getApplicationController(){
193 return applicationController
;
195 logger
.error("Exception thrown", e
);
202 public static CdmApplicationController
getApplicationControllerWillBeObsolete(){
203 return getDefault().getApplicationController();
211 * Create a new conversation and bind resources to it
215 public static ConversationHolder
NewConversation(){
217 ConversationHolder conversation
= getDefault().getApplicationController().NewConversation();
223 * Creates a new conversation, binds resources to the conversation and
224 * start a transaction for this conversation.
228 public static ConversationHolder
NewTransactionalConversation() {
229 ConversationHolder conversation
= NewConversation();
231 conversation
.startTransaction();
239 public static ITaxonService
getTaxonService(){ return getDefault().getApplicationController().getTaxonService();}
241 public static ITaxonTreeService
getTaxonTreeService() { return getDefault().getApplicationController().getTaxonTreeService();}
243 public static INameService
getNameService(){ return getDefault().getApplicationController().getNameService();}
245 public static IReferenceService
getReferenceService(){ return getDefault().getApplicationController().getReferenceService();}
247 public static ILocationService
getLocationService(){ return getDefault().getApplicationController().getLocationService();}
249 public static ProviderManager
getAuthenticationManager() { return getDefault().getApplicationController().getAuthenticationManager();}
251 public static IUserService
getUserService() { return getDefault().getApplicationController().getUserService(); }
253 public static ICommonService
getCommonService() { return getDefault().getApplicationController().getCommonService(); }
255 public static IAgentService
getAgentService() { return getDefault().getApplicationController().getAgentService(); }
257 public static ITermService
getTermService() { return getDefault().getApplicationController().getTermService(); }
259 public static IVocabularyService
getVocabularyService() { return getDefault().getApplicationController().getVocabularyService(); }
261 public static IEditGeoService
getGeoService(){
262 return (IEditGeoService
) getDefault().getApplicationController().getBean("editGeoService");
266 * METHODS TO FIND ENTITIES
271 * @param configurator
274 public static List
<TaxonNameBase
> findNames(IIdentifiableEntityServiceConfigurator configurator
){
275 // TODO we want to use IIdentifiableEntityServiceConfigurator for all find methods
276 // unfortunately this is not consistently implemented in the library.
277 // FIXME use proper method once it is implemented in the library
278 String titleSearchString
= configurator
.getTitleSearchString().replace("*", "%");
280 return getNameService().getNamesByName(titleSearchString
);
285 * @param configurator
288 public static List
<IdentifiableEntity
> findTaxaAndNames(ITaxonServiceConfigurator configurator
){
289 return getTaxonService().findTaxaAndNames(configurator
).getRecords();
294 * @param configurator
297 public static List
<ReferenceBase
> findReferences(IIdentifiableEntityServiceConfigurator configurator
){
298 // TODO we want to use IIdentifiableEntityServiceConfigurator for all find methods
299 // unfortunately this is not consistently implemented in the library.
300 // FIXME use proper method once it is implemented in the library
301 String titleSearchString
= configurator
.getTitleSearchString().replace("*", "%");
303 return getReferenceService().findByTitle(null, titleSearchString
, null, null, null, null, null, null).getRecords();
308 * @param configurator
311 public static List
<AgentBase
> findAgents(IIdentifiableEntityServiceConfigurator configurator
){
312 // TODO we want to use IIdentifiableEntityServiceConfigurator for all find methods
313 // unfortunately this is not consistently implemented in the library.
314 // FIXME use proper method once it is implemented in the library
315 String titleSearchString
= configurator
.getTitleSearchString().replace("*", "%");
317 return getAgentService().findByTitle(null, titleSearchString
, null, null, null, null, null, null).getRecords();
320 public static List
<TeamOrPersonBase
> findTeamOrPersons(IIdentifiableEntityServiceConfigurator configurator
){
321 // TODO move this to cdmlib
322 List
<TeamOrPersonBase
> result
= new ArrayList
<TeamOrPersonBase
>();
323 for (AgentBase agent
: findAgents(configurator
)) {
324 if (agent
instanceof TeamOrPersonBase
) {
325 result
.add((TeamOrPersonBase
) agent
);
338 public static Language
getDefaultLanguage(){
339 if(getDefault().getLanguage() == null){
340 getDefault().setLanguage(Language
.DEFAULT());
342 return getDefault().getLanguage();
345 public static void setDefaultLanguage(Language language
){
346 getDefault().setLanguage(language
);
350 * @return the language
352 private Language
getLanguage() {
357 * @param language the language to set
359 private void setLanguage(Language language
) {
360 this.language
= language
;
370 public static LoginManager
getLoginManager(){
371 if(loginManager
== null){
372 loginManager
= new LoginManager();
378 * IMPORT/EXPORT FACTORIES
384 public static synchronized ImportHandler
getImportHandler(){
385 if(importHandler
== null){
386 importHandler
= ImportHandler
.NewInstance(getDefault().getApplicationController());
388 return importHandler
;
395 public static synchronized ExportHandler
getExportHandler(){
396 if(exportHandler
== null){
397 exportHandler
= ExportHandler
.NewInstance(getDefault().getApplicationController());
399 return exportHandler
;