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
.lang
.reflect
.InvocationTargetException
;
13 import java
.lang
.reflect
.Method
;
14 import java
.lang
.reflect
.Type
;
15 import java
.util
.EnumSet
;
17 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
18 import org
.eclipse
.core
.runtime
.jobs
.Job
;
19 import org
.eclipse
.swt
.widgets
.Display
;
20 import org
.springframework
.core
.io
.ClassPathResource
;
21 import org
.springframework
.core
.io
.Resource
;
22 import org
.springframework
.security
.access
.PermissionEvaluator
;
23 import org
.springframework
.security
.authentication
.ProviderManager
;
24 import org
.springframework
.security
.core
.Authentication
;
25 import org
.springframework
.security
.core
.context
.SecurityContext
;
26 import org
.springframework
.security
.core
.context
.SecurityContextHolder
;
29 import eu
.etaxonomy
.cdm
.api
.application
.CdmApplicationRemoteConfiguration
;
30 import eu
.etaxonomy
.cdm
.api
.application
.CdmApplicationRemoteController
;
31 import eu
.etaxonomy
.cdm
.api
.application
.ICdmApplicationConfiguration
;
32 import eu
.etaxonomy
.cdm
.api
.conversation
.ConversationHolder
;
33 import eu
.etaxonomy
.cdm
.api
.service
.IService
;
34 import eu
.etaxonomy
.cdm
.config
.ICdmSource
;
35 import eu
.etaxonomy
.cdm
.database
.DbSchemaValidation
;
36 import eu
.etaxonomy
.cdm
.ext
.geo
.IEditGeoService
;
37 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
38 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
39 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.CRUD
;
40 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.ICdmPermissionEvaluator
;
41 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.Role
;
42 import eu
.etaxonomy
.taxeditor
.datasource
.CdmDataSourceRepository
;
43 import eu
.etaxonomy
.taxeditor
.io
.ExportManager
;
44 import eu
.etaxonomy
.taxeditor
.io
.ImportManager
;
45 import eu
.etaxonomy
.taxeditor
.model
.AbstractUtility
;
46 import eu
.etaxonomy
.taxeditor
.model
.MessagingUtils
;
47 import eu
.etaxonomy
.taxeditor
.preference
.PreferencesUtil
;
49 import eu
.etaxonomy
.taxeditor
.session
.ICdmEntitySessionManager
;
50 import eu
.etaxonomy
.taxeditor
.session
.mock
.MockCdmEntitySessionManager
;
51 import eu
.etaxonomy
.taxeditor
.store
.internal
.TaxeditorStorePlugin
;
52 import eu
.etaxonomy
.taxeditor
.view
.datasource
.CdmDataSourceViewPart
;
55 * This implementation of ICdmDataRepository depends on hibernate sessions to
56 * store the data correctly for the current session. No state is held in this
59 * Only methods that either get or manipulate data are exposed here. So this
60 * class acts as a facade for the methods in cdmlib-service.
66 public class CdmStore
{
68 private static final Resource DEFAULT_APPLICATION_CONTEXT
= new ClassPathResource(
69 "/eu/etaxonomy/cdm/editorApplicationContext.xml",
70 TaxeditorStorePlugin
.class);
71 private static final DbSchemaValidation DEFAULT_DB_SCHEMA_VALIDATION
= DbSchemaValidation
.VALIDATE
;
73 private static CdmStore instance
;
75 private final ICdmApplicationConfiguration applicationConfiguration
;
77 private static ContextManager contextManager
= new ContextManager();
79 private static LoginManager loginManager
= new LoginManager();
81 private static TermManager termManager
= new TermManager();
83 private static SearchManager searchManager
= new SearchManager();
85 private static EditorManager editorManager
= new EditorManager();
87 private static CdmStoreConnector job
;
89 private Language language
;
91 private ICdmSource cdmSource
;
93 private boolean isConnected
;
102 * @return a {@link eu.etaxonomy.taxeditor.store.CdmStore} object.
104 protected static CdmStore
getDefault() {
105 if (instance
!= null && instance
.isConnected
) {
107 } else{// if (instance == null || !instance.isConnected) {
109 MessagingUtils
.noDataSourceWarningDialog(instance
);
111 AbstractUtility
.showView(CdmDataSourceViewPart
.ID
);
117 * Initialize the with the last edited datasource
119 public static void connect() {
121 ICdmSource cdmSource
;
123 cdmSource
= CdmDataSourceRepository
.getCurrentCdmSource();
125 } catch (Exception e
) {
126 MessagingUtils
.messageDialog("Connection to CDM Source Failed", CdmStore
.class, "Could not connect to target CDM Source", e
);
133 * Initialize with a specific datasource
136 * a {@link eu.etaxonomy.cdm.database.ICdmDataSource} object.
138 public static void connect(ICdmSource cdmSource
) {
139 connect(cdmSource
, DEFAULT_DB_SCHEMA_VALIDATION
,
140 DEFAULT_APPLICATION_CONTEXT
);
144 * Initialize and provide
147 * @param dbSchemaValidation
148 * @param applicationContextBean
150 private static void connect(final ICdmSource cdmSource
,
151 final DbSchemaValidation dbSchemaValidation
,
152 final Resource applicationContextBean
) {
153 MessagingUtils
.info("Connecting to datasource: " + cdmSource
);
155 job
= new CdmStoreConnector(Display
.getDefault(), cdmSource
,
156 dbSchemaValidation
, applicationContextBean
);
158 job
.setPriority(Job
.BUILD
);
163 public static boolean isConnecting() {
164 return job
!= null && job
.getState() == Job
.RUNNING
;
168 * Closes the current application context
171 * a {@link org.eclipse.core.runtime.IProgressMonitor} object.
173 public static void close(final IProgressMonitor monitor
) {
174 Display
.getDefault().asyncExec(new Runnable() {
178 * @see java.lang.Runnable#run()
182 getContextManager().notifyContextAboutToStop(monitor
);
183 if ((monitor
== null || (!monitor
.isCanceled()) && isActive())) {
184 getContextManager().notifyContextStop(monitor
);
191 private void close() {
196 static void setInstance(ICdmApplicationConfiguration applicationController
,
197 ICdmSource cdmSource
) {
198 instance
= new CdmStore(applicationController
, cdmSource
);
201 private CdmStore(ICdmApplicationConfiguration applicationController
,
202 ICdmSource cdmSource
) {
203 this.applicationConfiguration
= applicationController
;
204 this.cdmSource
= cdmSource
;
209 * All calls to the datastore require
213 private ICdmApplicationConfiguration
getApplicationConfiguration() {
215 return applicationConfiguration
;
216 } catch (Exception e
) {
217 MessagingUtils
.error(CdmStore
.class, e
);
224 * getCurrentApplicationController
228 * {@link eu.etaxonomy.cdm.remote.api.application.CdmApplicationController}
231 public static ICdmApplicationConfiguration
getCurrentApplicationConfiguration() {
232 if (getDefault() != null) {
233 return getDefault().getApplicationConfiguration();
243 * Creates a new conversation, binds resources to the conversation and start
244 * a transaction for this conversation.
246 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
249 public static ConversationHolder
createConversation() {
250 ConversationHolder conversation
= getCurrentApplicationConfiguration()
253 conversation
.startTransaction();
255 MessagingUtils
.messageDialog("No database connection", CdmStore
.class, "No database connection available", e
);
260 //FIXME:Remoting should be removed after moving completely to remoting
261 private MockCdmEntitySessionManager mockCdmEntitySessionManager
;
263 private ICdmEntitySessionManager
getSessionManager() {
264 //FIXME:Remoting we should only have CdmApplicationRemoteConfiguration after move to remoting
265 // bad hack which should be finally removed
266 if(getCurrentApplicationConfiguration() instanceof CdmApplicationRemoteController
) {
267 return ((CdmApplicationRemoteController
)getCurrentApplicationConfiguration()).getCdmEntitySessionManager();
269 if(mockCdmEntitySessionManager
== null) {
270 mockCdmEntitySessionManager
= new MockCdmEntitySessionManager();
272 return mockCdmEntitySessionManager
;
276 public static ICdmEntitySessionManager
getCurrentSessionManager() {
277 if (getDefault() != null) {
278 return getDefault().getSessionManager();
285 * Generic method that will scan the getters of {@link ICdmApplicationConfiguration} for the given service
286 * interface. If a matching getter is found the according service implementation is returned by
287 * invoking the getter otherwise the method returns <code>null</code>.
290 * @param serviceClass
291 * @return the configured implementation of <code>serviceClass</code> or <code>null</code>
293 public static <T
extends IService
> T
getService(Class
<T
> serviceClass
) {
294 ICdmApplicationConfiguration configuration
= getCurrentApplicationConfiguration();
296 Method
[] methods
= ICdmApplicationConfiguration
.class.getDeclaredMethods();
300 for (Method method
: methods
) {
301 Type type
= method
.getGenericReturnType();
303 if (type
.equals(serviceClass
)) {
305 service
= (T
) method
.invoke(configuration
, null);
307 } catch (IllegalArgumentException e
) {
308 MessagingUtils
.error(CdmStore
.class, e
);
309 } catch (IllegalAccessException e
) {
310 MessagingUtils
.error(CdmStore
.class, e
);
311 } catch (InvocationTargetException e
) {
312 MessagingUtils
.error(CdmStore
.class, e
);
322 * getAuthenticationManager
326 * {@link org.springframework.security.authentication.ProviderManager}
329 public static ProviderManager
getAuthenticationManager() {
330 return getCurrentApplicationConfiguration().getAuthenticationManager();
335 * getAuthenticationManager
339 * {@link ICdmPermissionEvaluator} object.
341 public static ICdmPermissionEvaluator
getPermissionEvaluator() {
342 return getCurrentApplicationConfiguration().getPermissionEvaluator();
350 * @return a {@link eu.etaxonomy.cdm.ext.geo.IEditGeoService} object.
352 public static IEditGeoService
getGeoService() {
353 return (IEditGeoService
) getCurrentApplicationConfiguration().getBean(
358 * SECURITY RELATED CONVENIENCE METHODS
362 * @see org.springframework.security.access.PermissionEvaluator#hasPermission(org.springframework.security.core.Authentication, java.lang.Object, java.lang.Object)
364 * @param targetDomainObject
368 public static boolean currentAuthentiationHasPermission(CdmBase targetDomainObject
, EnumSet
<CRUD
> permission
){
369 //TODO use getCurrentApplicationConfiguration().currentAuthentiationHasPermission(CdmBase targetDomainObject, Operation permission) instead
370 SecurityContext context
= SecurityContextHolder
.getContext();
371 PermissionEvaluator pe
= getPermissionEvaluator();
372 boolean hasPermission
= false;
374 hasPermission
= getPermissionEvaluator().hasPermission(context
.getAuthentication(), targetDomainObject
,
376 } catch (org
.springframework
.security
.access
.AccessDeniedException e
) {
379 return hasPermission
;
383 * @see org.springframework.security.access.PermissionEvaluator#hasPermission(org.springframework.security.core.Authentication, java.lang.Object, java.lang.Object)
385 * @param targetDomainObject
389 public static boolean currentAuthentiationHasPermission(Class
<?
extends CdmBase
> targetType
, EnumSet
<CRUD
> permission
){
390 boolean hasPermission
= false;
392 hasPermission
= getPermissionEvaluator().hasPermission(getCurrentAuthentiation(), null, targetType
.getName(), permission
);
393 } catch (org
.springframework
.security
.access
.AccessDeniedException e
) {
396 return hasPermission
;
399 public static boolean currentAuthentiationHasOneOfRoles(Role
... roles
){
400 boolean hasPermission
= false;
402 hasPermission
= getPermissionEvaluator().hasOneOfRoles(getCurrentAuthentiation(), roles
);
403 } catch (org
.springframework
.security
.access
.AccessDeniedException e
) {
406 return hasPermission
;
409 public static Authentication
getCurrentAuthentiation() {
410 SecurityContext context
= SecurityContextHolder
.getContext();
411 return context
.getAuthentication();
419 * Provides access to the global default language set in the application preferences.
421 * @return a {@link eu.etaxonomy.cdm.model.common.Language} object.
423 public static Language
getDefaultLanguage() {
424 if (getDefault().getLanguage() == null) {
425 getDefault().setLanguage(PreferencesUtil
.getGlobalLanguage());
427 return getDefault().getLanguage();
436 * a {@link eu.etaxonomy.cdm.model.common.Language} object.
438 public static void setDefaultLanguage(Language language
) {
439 getDefault().setLanguage(language
);
443 * @return the language
445 private Language
getLanguage() {
451 * the language to set
453 private void setLanguage(Language language
) {
454 this.language
= language
;
463 * Getter for the field <code>loginManager</code>.
466 * @return a {@link eu.etaxonomy.taxeditor.store.LoginManager} object.
468 public static LoginManager
getLoginManager() {
474 * Getter for the field <code>contextManager</code>.
477 * @return a {@link eu.etaxonomy.taxeditor.store.ContextManager} object.
479 public static ContextManager
getContextManager() {
480 return contextManager
;
483 public static TermManager
getTermManager() {
487 public static SearchManager
getSearchManager() {
488 return searchManager
;
491 public static EditorManager
getEditorManager() {
492 return editorManager
;
496 * IMPORT/EXPORT FACTORIES
501 * Getter for the field <code>importHandler</code>.
504 * @return a {@link eu.etaxonomy.taxeditor.io.ImportManager} object.
506 public static ImportManager
getImportManager() {
507 return ImportManager
.NewInstance(getCurrentApplicationConfiguration());
512 * Getter for the field <code>exportHandler</code>.
515 * @return a {@link eu.etaxonomy.taxeditor.io.ExportManager} object.
517 public static ExportManager
getExportManager() {
518 return ExportManager
.NewInstance(getCurrentApplicationConfiguration());
522 * Whether this CdmStore is currently connected to a datasource
526 public static boolean isActive() {
527 return instance
!= null && instance
.isConnected
;
530 public static ICdmSource
getActiveCdmSource() {
532 return instance
.getCdmSource();
542 * @return a {@link eu.etaxonomy.cdm.database.ICdmDataSource} object.
543 * @deprecated currently retained for backward compatibility - use {@link getActiveCdmSource()} instead
545 // public static ICdmDataSource getDataSource() {
547 // return (ICdmDataSource)instance.getCdmSource();
555 private ICdmSource
getCdmSource() {