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
.EnumSet
;
14 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
15 import org
.eclipse
.core
.runtime
.jobs
.Job
;
16 import org
.eclipse
.swt
.widgets
.Display
;
17 import org
.springframework
.core
.io
.ClassPathResource
;
18 import org
.springframework
.core
.io
.Resource
;
19 import org
.springframework
.security
.access
.PermissionEvaluator
;
20 import org
.springframework
.security
.authentication
.AuthenticationManager
;
21 import org
.springframework
.security
.core
.Authentication
;
22 import org
.springframework
.security
.core
.context
.SecurityContext
;
23 import org
.springframework
.security
.core
.context
.SecurityContextHolder
;
25 import eu
.etaxonomy
.cdm
.api
.application
.CdmApplicationException
;
26 import eu
.etaxonomy
.cdm
.api
.application
.CdmApplicationRemoteController
;
27 import eu
.etaxonomy
.cdm
.api
.application
.CdmApplicationState
;
28 import eu
.etaxonomy
.cdm
.api
.application
.ICdmApplicationConfiguration
;
29 import eu
.etaxonomy
.cdm
.api
.conversation
.ConversationHolder
;
30 import eu
.etaxonomy
.cdm
.api
.service
.ICommonService
;
31 import eu
.etaxonomy
.cdm
.api
.service
.IService
;
32 import eu
.etaxonomy
.cdm
.config
.ICdmSource
;
33 import eu
.etaxonomy
.cdm
.database
.DbSchemaValidation
;
34 import eu
.etaxonomy
.cdm
.ext
.geo
.IEditGeoService
;
35 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
36 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
37 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.CRUD
;
38 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.ICdmPermissionEvaluator
;
39 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.Role
;
40 import eu
.etaxonomy
.taxeditor
.datasource
.CdmDataSourceRepository
;
41 import eu
.etaxonomy
.taxeditor
.io
.ExportManager
;
42 import eu
.etaxonomy
.taxeditor
.io
.ImportManager
;
43 import eu
.etaxonomy
.taxeditor
.model
.AbstractUtility
;
44 import eu
.etaxonomy
.taxeditor
.model
.MessagingUtils
;
45 import eu
.etaxonomy
.taxeditor
.preference
.PreferencesUtil
;
46 import eu
.etaxonomy
.taxeditor
.remoting
.cache
.CdmRemoteCacheManager
;
47 import eu
.etaxonomy
.taxeditor
.session
.ICdmEntitySessionManager
;
48 import eu
.etaxonomy
.taxeditor
.session
.mock
.MockCdmEntitySessionManager
;
49 import eu
.etaxonomy
.taxeditor
.store
.internal
.TaxeditorStorePlugin
;
50 import eu
.etaxonomy
.taxeditor
.ui
.dialog
.RemotingLoginDialog
;
51 import eu
.etaxonomy
.taxeditor
.view
.datasource
.CdmDataSourceViewPart
;
54 * This implementation of ICdmDataRepository depends on hibernate sessions to
55 * store the data correctly for the current session. No state is held in this
58 * Only methods that either get or manipulate data are exposed here. So this
59 * class acts as a facade for the methods in cdmlib-service.
65 public class CdmStore
{
67 private static final Resource DEFAULT_APPLICATION_CONTEXT
= new ClassPathResource(
68 "/eu/etaxonomy/cdm/editorApplicationContext.xml",
69 TaxeditorStorePlugin
.class);
70 private static final DbSchemaValidation DEFAULT_DB_SCHEMA_VALIDATION
= DbSchemaValidation
.VALIDATE
;
72 private static CdmStore instance
;
74 //private final ICdmApplicationConfiguration applicationConfiguration;
76 private static ContextManager contextManager
= new ContextManager();
78 private static LoginManager loginManager
= new LoginManager();
80 private static TermManager termManager
= new TermManager();
82 private static SearchManager searchManager
= new SearchManager();
84 private static EditorManager editorManager
= new EditorManager();
86 private static UseObjectStore useObjectInitializer
= new UseObjectStore();
88 private static CdmStoreConnector job
;
90 private Language language
;
92 private ICdmSource cdmSource
;
94 private boolean isConnected
;
103 * @return a {@link eu.etaxonomy.taxeditor.store.CdmStore} object.
105 protected static CdmStore
getDefault() {
106 if (instance
!= null && instance
.isConnected
) {
108 } else{// if (instance == null || !instance.isConnected) {
110 MessagingUtils
.noDataSourceWarningDialog(instance
);
112 AbstractUtility
.showView(CdmDataSourceViewPart
.ID
);
118 * Initialize the with the last edited datasource
120 public static void connect() {
122 ICdmSource cdmSource
;
125 cdmSource
= CdmDataSourceRepository
.getCurrentCdmSource();
127 } catch (Exception e
) {
128 MessagingUtils
.messageDialog("Connection to CDM Source Failed", CdmStore
.class, "Could not connect to target CDM Source", e
);
135 * Initialize with a specific datasource
138 * a {@link eu.etaxonomy.cdm.database.ICdmDataSource} object.
140 public static void connect(ICdmSource cdmSource
) {
141 connect(cdmSource
, DEFAULT_DB_SCHEMA_VALIDATION
,
142 DEFAULT_APPLICATION_CONTEXT
);
145 public static void connect(ICdmSource cdmSource
, RemotingLoginDialog loginDialog
) {
147 DEFAULT_DB_SCHEMA_VALIDATION
,
148 DEFAULT_APPLICATION_CONTEXT
,
153 * Initialize and provide
156 * @param dbSchemaValidation
157 * @param applicationContextBean
159 private static void connect(final ICdmSource cdmSource
,
160 final DbSchemaValidation dbSchemaValidation
,
161 final Resource applicationContextBean
) {
163 MessagingUtils
.info("Connecting to datasource: " + cdmSource
);
165 job
= new CdmStoreConnector(Display
.getDefault(), cdmSource
,
166 dbSchemaValidation
, applicationContextBean
);
168 job
.setPriority(Job
.BUILD
);
173 private static void connect(final ICdmSource cdmSource
,
174 final DbSchemaValidation dbSchemaValidation
,
175 final Resource applicationContextBean
,
176 RemotingLoginDialog loginDialog
) {
178 // before we connect we clear the entity caches and the sessions
179 CdmRemoteCacheManager
.removeEntityCaches();
180 if(getCurrentSessionManager() != null) {
181 getCurrentSessionManager().disposeAll();
184 MessagingUtils
.info("Connecting to datasource: " + cdmSource
);
185 job
= new CdmStoreConnector(Display
.getDefault(),
188 applicationContextBean
);
189 job
.start(loginDialog
);
192 public static boolean isConnecting() {
193 return job
!= null && job
.getState() == Job
.RUNNING
;
197 * Closes the current application context
200 * a {@link org.eclipse.core.runtime.IProgressMonitor} object.
202 public static void close(final IProgressMonitor monitor
) {
203 Display
.getDefault().asyncExec(new Runnable() {
207 * @see java.lang.Runnable#run()
211 getContextManager().notifyContextAboutToStop(monitor
);
212 if ((monitor
== null || (!monitor
.isCanceled()) && isActive())) {
213 getContextManager().notifyContextStop(monitor
);
220 public static void close(IProgressMonitor monitor
, boolean async
) {
224 getContextManager().notifyContextAboutToStop(monitor
);
225 if ((monitor
== null || (!monitor
.isCanceled()) && isActive())) {
226 getContextManager().notifyContextStop(monitor
);
232 private void close() {
235 CdmApplicationState
.dispose();
238 static void setInstance(ICdmApplicationConfiguration applicationController
,
239 ICdmSource cdmSource
) {
240 instance
= new CdmStore(applicationController
, cdmSource
);
243 private CdmStore(ICdmApplicationConfiguration applicationController
,
244 ICdmSource cdmSource
) {
245 CdmApplicationState
.setCurrentAppConfig(applicationController
);
246 CdmApplicationState
.setCurrentDataChangeService(new CdmUIDataChangeService());
247 this.cdmSource
= cdmSource
;
252 * All calls to the datastore require
256 private ICdmApplicationConfiguration
getApplicationConfiguration() {
258 return CdmApplicationState
.getCurrentAppConfig();
259 } catch (Exception e
) {
260 MessagingUtils
.error(CdmStore
.class, e
);
267 * getCurrentApplicationController
271 * {@link eu.etaxonomy.cdm.remote.api.application.CdmApplicationController}
274 public static ICdmApplicationConfiguration
getCurrentApplicationConfiguration() {
275 if (getDefault() != null) {
276 return getDefault().getApplicationConfiguration();
286 * Creates a new conversation, binds resources to the conversation and start
287 * a transaction for this conversation.
289 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
292 public static ConversationHolder
createConversation() {
293 ConversationHolder conversation
= getCurrentApplicationConfiguration()
296 conversation
.startTransaction();
298 MessagingUtils
.messageDialog("No database connection", CdmStore
.class, "No database connection available", e
);
303 //FIXME:Remoting should be removed after moving completely to remoting
304 private MockCdmEntitySessionManager mockCdmEntitySessionManager
;
306 private ICdmEntitySessionManager
getSessionManager() {
307 //FIXME:Remoting we should only have CdmApplicationRemoteConfiguration after move to remoting
308 // bad hack which should be finally removed
309 if(getCurrentApplicationConfiguration() instanceof CdmApplicationRemoteController
) {
310 return ((CdmApplicationRemoteController
)getCurrentApplicationConfiguration()).getCdmEntitySessionManager();
312 if(mockCdmEntitySessionManager
== null) {
313 mockCdmEntitySessionManager
= new MockCdmEntitySessionManager();
315 return mockCdmEntitySessionManager
;
319 public static ICdmEntitySessionManager
getCurrentSessionManager() {
320 if (getDefault() != null) {
321 return getDefault().getSessionManager();
328 * Generic method that will scan the getters of {@link ICdmApplicationConfiguration} for the given service
329 * interface. If a matching getter is found the according service implementation is returned by
330 * invoking the getter otherwise the method returns <code>null</code>.
333 * @param serviceClass
334 * @return the configured implementation of <code>serviceClass</code> or <code>null</code>
336 public static <T
extends IService
> T
getService(Class
<T
> serviceClass
) {
339 service
= CdmApplicationState
.getService(serviceClass
);
340 } catch (CdmApplicationException cae
) {
341 MessagingUtils
.error(CdmStore
.class, cae
);
348 * @see #getService(Class)
349 * As ICommonService is not extending IService we need a specific request here
351 public static ICommonService
getCommonService() {
352 return CdmApplicationState
.getCommonService();
358 * getAuthenticationManager
362 * {@link org.springframework.security.authentication.ProviderManager}
365 public static AuthenticationManager
getAuthenticationManager() {
366 return getCurrentApplicationConfiguration().getAuthenticationManager();
371 * getAuthenticationManager
375 * {@link ICdmPermissionEvaluator} object.
377 public static ICdmPermissionEvaluator
getPermissionEvaluator() {
378 return getCurrentApplicationConfiguration().getPermissionEvaluator();
386 * @return a {@link eu.etaxonomy.cdm.ext.geo.IEditGeoService} object.
388 public static IEditGeoService
getGeoService() {
389 return (IEditGeoService
) getCurrentApplicationConfiguration().getBean(
394 * SECURITY RELATED CONVENIENCE METHODS
398 * @see org.springframework.security.access.PermissionEvaluator#hasPermission(org.springframework.security.core.Authentication, java.lang.Object, java.lang.Object)
400 * @param targetDomainObject
404 public static boolean currentAuthentiationHasPermission(CdmBase targetDomainObject
, EnumSet
<CRUD
> permission
){
405 //TODO use getCurrentApplicationConfiguration().currentAuthentiationHasPermission(CdmBase targetDomainObject, Operation permission) instead
406 SecurityContext context
= SecurityContextHolder
.getContext();
407 PermissionEvaluator pe
= getPermissionEvaluator();
408 boolean hasPermission
= false;
410 hasPermission
= getPermissionEvaluator().hasPermission(context
.getAuthentication(), targetDomainObject
,
412 } catch (org
.springframework
.security
.access
.AccessDeniedException e
) {
415 return hasPermission
;
419 * @see org.springframework.security.access.PermissionEvaluator#hasPermission(org.springframework.security.core.Authentication, java.lang.Object, java.lang.Object)
421 * @param targetDomainObject
425 public static boolean currentAuthentiationHasPermission(Class
<?
extends CdmBase
> targetType
, EnumSet
<CRUD
> permission
){
426 boolean hasPermission
= false;
428 hasPermission
= getPermissionEvaluator().hasPermission(getCurrentAuthentiation(), null, targetType
.getName(), permission
);
429 } catch (org
.springframework
.security
.access
.AccessDeniedException e
) {
432 return hasPermission
;
435 public static boolean currentAuthentiationHasOneOfRoles(Role
... roles
){
436 boolean hasPermission
= false;
438 hasPermission
= getPermissionEvaluator().hasOneOfRoles(getCurrentAuthentiation(), roles
);
439 } catch (org
.springframework
.security
.access
.AccessDeniedException e
) {
442 return hasPermission
;
445 public static Authentication
getCurrentAuthentiation() {
446 SecurityContext context
= SecurityContextHolder
.getContext();
447 return context
.getAuthentication();
455 * Provides access to the global default language set in the application preferences.
457 * @return a {@link eu.etaxonomy.cdm.model.common.Language} object.
459 public static Language
getDefaultLanguage() {
460 if (getDefault().getLanguage() == null) {
461 getDefault().setLanguage(PreferencesUtil
.getGlobalLanguage());
463 return getDefault().getLanguage();
472 * a {@link eu.etaxonomy.cdm.model.common.Language} object.
474 public static void setDefaultLanguage(Language language
) {
475 getDefault().setLanguage(language
);
479 * @return the language
481 private Language
getLanguage() {
487 * the language to set
489 private void setLanguage(Language language
) {
490 this.language
= language
;
499 * Getter for the field <code>loginManager</code>.
502 * @return a {@link eu.etaxonomy.taxeditor.store.LoginManager} object.
504 public static LoginManager
getLoginManager() {
510 * Getter for the field <code>contextManager</code>.
513 * @return a {@link eu.etaxonomy.taxeditor.store.ContextManager} object.
515 public static ContextManager
getContextManager() {
516 return contextManager
;
519 public static TermManager
getTermManager() {
523 public static SearchManager
getSearchManager() {
524 return searchManager
;
527 public static EditorManager
getEditorManager() {
528 return editorManager
;
532 * IMPORT/EXPORT FACTORIES
537 * Getter for the field <code>importHandler</code>.
540 * @return a {@link eu.etaxonomy.taxeditor.io.ImportManager} object.
542 public static ImportManager
getImportManager() {
543 return ImportManager
.NewInstance(getCurrentApplicationConfiguration());
548 * Getter for the field <code>exportHandler</code>.
551 * @return a {@link eu.etaxonomy.taxeditor.io.ExportManager} object.
553 public static ExportManager
getExportManager() {
554 return ExportManager
.NewInstance(getCurrentApplicationConfiguration());
558 * Whether this CdmStore is currently connected to a datasource
562 public static boolean isActive() {
563 return instance
!= null && instance
.isConnected
;
566 public static ICdmSource
getActiveCdmSource() {
568 return instance
.getCdmSource();
578 * @return a {@link eu.etaxonomy.cdm.database.ICdmDataSource} object.
579 * @deprecated currently retained for backward compatibility - use {@link getActiveCdmSource()} instead
581 // public static ICdmDataSource getDataSource() {
583 // return (ICdmDataSource)instance.getCdmSource();
591 private ICdmSource
getCdmSource() {