merge taxeditor validation2 into trunk
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / store / CdmStore.java
index b0492bf8453503fb106d28521f83a29f4fe8e181..e1957a87ffef4c0fc3ce56466588fc6aeb48b66b 100644 (file)
@@ -1,8 +1,8 @@
 /**
  * Copyright (C) 2007 EDIT
- * European Distributed Institute of Taxonomy 
+ * European Distributed Institute of Taxonomy
  * http://www.e-taxonomy.eu
- * 
+ *
  * The contents of this file are subject to the Mozilla Public License Version 1.1
  * See LICENSE.TXT at the top of this package for the full license terms.
  */
@@ -12,25 +12,37 @@ package eu.etaxonomy.taxeditor.store;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
+import java.util.EnumSet;
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.swt.widgets.Display;
 import org.springframework.core.io.ClassPathResource;
 import org.springframework.core.io.Resource;
+import org.springframework.security.access.PermissionEvaluator;
 import org.springframework.security.authentication.ProviderManager;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
 
-import eu.etaxonomy.cdm.api.application.CdmApplicationController;
 import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration;
 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
+import eu.etaxonomy.cdm.api.service.ICommonService;
 import eu.etaxonomy.cdm.api.service.IService;
+import eu.etaxonomy.cdm.config.ICdmSource;
 import eu.etaxonomy.cdm.database.DbSchemaValidation;
-import eu.etaxonomy.cdm.database.ICdmDataSource;
 import eu.etaxonomy.cdm.ext.geo.IEditGeoService;
+import eu.etaxonomy.cdm.model.common.CdmBase;
 import eu.etaxonomy.cdm.model.common.Language;
+import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
+import eu.etaxonomy.cdm.persistence.hibernate.permission.ICdmPermissionEvaluator;
+import eu.etaxonomy.cdm.persistence.hibernate.permission.Role;
+import eu.etaxonomy.cdm.remote.CdmRemoteSourceException;
 import eu.etaxonomy.taxeditor.datasource.CdmDataSourceRepository;
 import eu.etaxonomy.taxeditor.io.ExportManager;
 import eu.etaxonomy.taxeditor.io.ImportManager;
+import eu.etaxonomy.taxeditor.model.AbstractUtility;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
 import eu.etaxonomy.taxeditor.view.datasource.CdmDataSourceViewPart;
@@ -39,10 +51,10 @@ import eu.etaxonomy.taxeditor.view.datasource.CdmDataSourceViewPart;
  * This implementation of ICdmDataRepository depends on hibernate sessions to
  * store the data correctly for the current session. No state is held in this
  * class.
- * 
+ *
  * Only methods that either get or manipulate data are exposed here. So this
  * class acts as a facade for the methods in cdmlib-service.
- * 
+ *
  * @author n.hoffmann
  * @created 17.03.2009
  * @version 1.0
@@ -56,11 +68,11 @@ public class CdmStore {
 
        private static CdmStore instance;
 
-       private final CdmApplicationController applicationController;
+       private final ICdmApplicationConfiguration applicationConfiguration;
 
-       private static LoginManager loginManager = new LoginManager();
+       private static ContextManager contextManager = new ContextManager();
 
-       private static ContextManager contextManager = new ContextManager();;
+       private static LoginManager loginManager = new LoginManager();
 
        private static TermManager termManager = new TermManager();
 
@@ -72,7 +84,7 @@ public class CdmStore {
 
        private Language language;
 
-       private ICdmDataSource cdmDatasource;
+       private ICdmSource cdmSource;
 
        private boolean isConnected;
 
@@ -80,26 +92,19 @@ public class CdmStore {
         * <p>
         * getDefault
         * </p>
-        * 
+        *
         * @return a {@link eu.etaxonomy.taxeditor.store.CdmStore} object.
         */
        protected static CdmStore getDefault() {
                if (instance != null && instance.isConnected) {
                        return instance;
-               } else if (instance == null || !instance.isConnected) {
+               } else{// if (instance == null || !instance.isConnected) {
 
-                       StoreUtil
-                                       .warningDialog(
-                                                       "Application is not connected to a datastore",
-                                                       instance,
-                                                       "The requested operation is only available when "
-                                                                       + "connected to a datasource. You may choose a datasource to connect to or create a new one in the datasource view.");
-
-                       StoreUtil.showView(CdmDataSourceViewPart.ID);
+                       MessagingUtils.noDataSourceWarningDialog(instance);
 
+                       AbstractUtility.showView(CdmDataSourceViewPart.ID);
+                       return null;
                }
-
-               throw new RuntimeException();
        }
 
        /**
@@ -107,36 +112,41 @@ public class CdmStore {
         */
        public static void connect() {
 
-               ICdmDataSource datasource = CdmDataSourceRepository
-                               .getCurrentDataSource();
+               ICdmSource cdmSource;
+               try {
+                       cdmSource = CdmDataSourceRepository.getCurrentCdmSource();
+                       connect(cdmSource);
+               } catch (CdmRemoteSourceException e) {
+                       MessagingUtils.messageDialog("Connection to CDM Source Failed", CdmStore.class, "Could not connect to target CDM Source", e);
+               }
+
 
-               connect(datasource);
        }
 
        /**
         * Initialize with a specific datasource
-        * 
+        *
         * @param datasource
         *            a {@link eu.etaxonomy.cdm.database.ICdmDataSource} object.
         */
-       public static void connect(ICdmDataSource datasource) {
-               connect(datasource, DEFAULT_DB_SCHEMA_VALIDATION,
+       public static void connect(ICdmSource cdmSource) {
+               connect(cdmSource, DEFAULT_DB_SCHEMA_VALIDATION,
                                DEFAULT_APPLICATION_CONTEXT);
        }
 
        /**
         * Initialize and provide
-        * 
+        *
         * @param datasource
         * @param dbSchemaValidation
         * @param applicationContextBean
         */
-       private static void connect(final ICdmDataSource datasource,
+       private static void connect(final ICdmSource cdmSource,
                        final DbSchemaValidation dbSchemaValidation,
                        final Resource applicationContextBean) {
-               StoreUtil.info("Connecting to datasource: " + datasource);
+               MessagingUtils.info("Connecting to datasource: " + cdmSource);
 
-               job = new CdmStoreConnector(Display.getDefault(), datasource,
+               job = new CdmStoreConnector(Display.getDefault(), cdmSource,
                                dbSchemaValidation, applicationContextBean);
                job.setUser(true);
                job.setPriority(Job.BUILD);
@@ -150,7 +160,7 @@ public class CdmStore {
 
        /**
         * Closes the current application context
-        * 
+        *
         * @param monitor
         *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
         */
@@ -158,7 +168,7 @@ public class CdmStore {
                Display.getDefault().asyncExec(new Runnable() {
                        /*
                         * (non-Javadoc)
-                        * 
+                        *
                         * @see java.lang.Runnable#run()
                         */
                        @Override
@@ -166,9 +176,6 @@ public class CdmStore {
                                getContextManager().notifyContextAboutToStop(monitor);
                                if ((monitor == null || (!monitor.isCanceled()) && isActive())) {
                                        getContextManager().notifyContextStop(monitor);
-                                       if (instance.getApplicationController() != null) {
-                                               instance.getApplicationController().close();
-                                       }
                                        instance.close();
                                }
                        }
@@ -177,31 +184,31 @@ public class CdmStore {
 
        private void close() {
                isConnected = false;
-               cdmDatasource = null;
+               cdmSource = null;
        }
 
-       static void setInstance(CdmApplicationController applicationController,
-                       ICdmDataSource dataSource) {
-               instance = new CdmStore(applicationController, dataSource);
+       static void setInstance(ICdmApplicationConfiguration applicationController,
+                       ICdmSource cdmSource) {
+               instance = new CdmStore(applicationController, cdmSource);
        }
 
-       private CdmStore(CdmApplicationController applicationController,
-                       ICdmDataSource dataSource) {
-               this.applicationController = applicationController;
-               this.cdmDatasource = dataSource;
+       private CdmStore(ICdmApplicationConfiguration applicationController,
+                       ICdmSource cdmSource) {
+               this.applicationConfiguration = applicationController;
+               this.cdmSource = cdmSource;
                isConnected = true;
        }
 
        /**
         * All calls to the datastore require
-        * 
+        *
         * @return
         */
-       private CdmApplicationController getApplicationController() {
+       private ICdmApplicationConfiguration getApplicationConfiguration() {
                try {
-                       return applicationController;
+                       return applicationConfiguration;
                } catch (Exception e) {
-                       StoreUtil.error(CdmStore.class, e);
+                       MessagingUtils.error(CdmStore.class, e);
                }
                return null;
        }
@@ -210,14 +217,14 @@ public class CdmStore {
         * <p>
         * getCurrentApplicationController
         * </p>
-        * 
+        *
         * @return a
-        *         {@link eu.etaxonomy.cdm.api.application.CdmApplicationController}
+        *         {@link eu.etaxonomy.cdm.remote.api.application.CdmApplicationController}
         *         object.
         */
-       public static CdmApplicationController getCurrentApplicationController() {
+       public static ICdmApplicationConfiguration getCurrentApplicationConfiguration() {
                if (getDefault() != null) {
-                       return getDefault().getApplicationController();
+                       return getDefault().getApplicationConfiguration();
                }
                return null;
        }
@@ -229,31 +236,34 @@ public class CdmStore {
        /**
         * Creates a new conversation, binds resources to the conversation and start
         * a transaction for this conversation.
-        * 
+        *
         * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
         *         object.
         */
        public static ConversationHolder createConversation() {
-               ConversationHolder conversation = getCurrentApplicationController()
+               ConversationHolder conversation = getCurrentApplicationConfiguration()
                                .NewConversation();
-
-               conversation.startTransaction();
+               try{
+                       conversation.startTransaction();
+               }catch(Exception e){
+                       MessagingUtils.messageDialog("No database connection", CdmStore.class, "No database connection available", e);
+               }
                return conversation;
        }
 
        /**
-        * Generic method that will return an implementation of the given service
-        * interface or <code>null</code> if the
-        * 
+        * Generic method that will scan the getters of {@link ICdmApplicationConfiguration} for the given service
+        * interface. If a matching getter is found the according service implementation is returned by
+        * invoking the getter otherwise the method returns <code>null</code>.
+        *
         * @param <T>
         * @param serviceClass
-        * @return
+        * @return the configured implementation of <code>serviceClass</code> or <code>null</code>
         */
        public static <T extends IService> T getService(Class<T> serviceClass) {
-               ICdmApplicationConfiguration configuration = getCurrentApplicationController();
+               ICdmApplicationConfiguration configuration = getCurrentApplicationConfiguration();
 
-               Method[] methods = ICdmApplicationConfiguration.class
-                               .getDeclaredMethods();
+               Method[] methods = ICdmApplicationConfiguration.class.getDeclaredMethods();
 
                T service = null;
 
@@ -265,52 +275,135 @@ public class CdmStore {
                                        service = (T) method.invoke(configuration, null);
                                        break;
                                } catch (IllegalArgumentException e) {
-                                       StoreUtil.error(CdmStore.class, e);
+                                       MessagingUtils.error(CdmStore.class, e);
                                } catch (IllegalAccessException e) {
-                                       StoreUtil.error(CdmStore.class, e);
+                                       MessagingUtils.error(CdmStore.class, e);
                                } catch (InvocationTargetException e) {
-                                       StoreUtil.error(CdmStore.class, e);
+                                       MessagingUtils.error(CdmStore.class, e);
                                }
                        }
                }
 
                return service;
        }
+       
+       /**
+        * Generic method that will scan the getters of {@link ICdmApplicationConfiguration} for the given service
+        * interface. If a matching getter is found the according service implementation is returned by
+        * invoking the getter otherwise the method returns <code>null</code>.
+        *
+        * @param <T>
+        * @param serviceClass
+        * @return the configured implementation of <code>serviceClass</code> or <code>null</code>
+        */
+       public static ICommonService getCommonService() {
+               ICdmApplicationConfiguration configuration = getCurrentApplicationConfiguration();
+
+               return configuration.getCommonService();
+
+       }
 
        /**
         * <p>
         * getAuthenticationManager
         * </p>
-        * 
+        *
         * @return a
         *         {@link org.springframework.security.authentication.ProviderManager}
         *         object.
         */
        public static ProviderManager getAuthenticationManager() {
-               return getCurrentApplicationController().getAuthenticationManager();
+               return getCurrentApplicationConfiguration().getAuthenticationManager();
+       }
+
+       /**
+        * <p>
+        * getAuthenticationManager
+        * </p>
+        *
+        * @return a
+        *         {@link ICdmPermissionEvaluator} object.
+        */
+       public static ICdmPermissionEvaluator getPermissionEvaluator() {
+               return getCurrentApplicationConfiguration().getPermissionEvaluator();
        }
 
        /**
         * <p>
         * getGeoService
         * </p>
-        * 
+        *
         * @return a {@link eu.etaxonomy.cdm.ext.geo.IEditGeoService} object.
         */
        public static IEditGeoService getGeoService() {
-               return (IEditGeoService) getCurrentApplicationController().getBean(
+               return (IEditGeoService) getCurrentApplicationConfiguration().getBean(
                                "editGeoService");
        }
 
+       /*
+        * SECURITY RELATED CONVENIENCE METHODS
+        */
+
+       /**
+        * @see org.springframework.security.access.PermissionEvaluator#hasPermission(org.springframework.security.core.Authentication, java.lang.Object, java.lang.Object)
+     *
+        * @param targetDomainObject
+        * @param permission
+        * @return
+        */
+       public static boolean currentAuthentiationHasPermission(CdmBase targetDomainObject, EnumSet<CRUD> permission){
+               //TODO use getCurrentApplicationConfiguration().currentAuthentiationHasPermission(CdmBase targetDomainObject, Operation permission) instead
+               SecurityContext context = SecurityContextHolder.getContext();
+               PermissionEvaluator pe = getPermissionEvaluator();
+               boolean hasPermission = false;
+               try {
+            hasPermission = getPermissionEvaluator().hasPermission(context.getAuthentication(), targetDomainObject,
+                    permission);
+        } catch (org.springframework.security.access.AccessDeniedException e) {
+            /* IGNORE */
+        }
+        return hasPermission;
+       }
+
+       /**
+        * @see org.springframework.security.access.PermissionEvaluator#hasPermission(org.springframework.security.core.Authentication, java.lang.Object, java.lang.Object)
+     *
+        * @param targetDomainObject
+        * @param permission
+        * @return
+        */
+       public static boolean currentAuthentiationHasPermission(Class<? extends CdmBase> targetType, EnumSet<CRUD> permission){
+           boolean hasPermission = false;
+        try {
+            hasPermission = getPermissionEvaluator().hasPermission(getCurrentAuthentiation(), null, targetType.getName(), permission);
+        } catch (org.springframework.security.access.AccessDeniedException e) {
+            /* IGNORE */
+        }
+        return hasPermission;
+       }
+
+       public static boolean currentAuthentiationHasOneOfRoles(Role ... roles){
+           boolean hasPermission = false;
+        try {
+            hasPermission =  getPermissionEvaluator().hasOneOfRoles(getCurrentAuthentiation(), roles);
+        } catch (org.springframework.security.access.AccessDeniedException e) {
+            /* IGNORE */
+        }
+        return hasPermission;
+       }
+
+       public static Authentication getCurrentAuthentiation() {
+               SecurityContext context = SecurityContextHolder.getContext();
+               return context.getAuthentication();
+       }
+
        /*
         * LANGUAGE
         */
 
        /**
-        * <p>
-        * getDefaultLanguage
-        * </p>
-        * 
+        * Provides access to the global default language set in the application preferences.
+        *
         * @return a {@link eu.etaxonomy.cdm.model.common.Language} object.
         */
        public static Language getDefaultLanguage() {
@@ -324,7 +417,7 @@ public class CdmStore {
         * <p>
         * setDefaultLanguage
         * </p>
-        * 
+        *
         * @param language
         *            a {@link eu.etaxonomy.cdm.model.common.Language} object.
         */
@@ -355,7 +448,7 @@ public class CdmStore {
         * <p>
         * Getter for the field <code>loginManager</code>.
         * </p>
-        * 
+        *
         * @return a {@link eu.etaxonomy.taxeditor.store.LoginManager} object.
         */
        public static LoginManager getLoginManager() {
@@ -366,7 +459,7 @@ public class CdmStore {
         * <p>
         * Getter for the field <code>contextManager</code>.
         * </p>
-        * 
+        *
         * @return a {@link eu.etaxonomy.taxeditor.store.ContextManager} object.
         */
        public static ContextManager getContextManager() {
@@ -393,52 +486,60 @@ public class CdmStore {
         * <p>
         * Getter for the field <code>importHandler</code>.
         * </p>
-        * 
+        *
         * @return a {@link eu.etaxonomy.taxeditor.io.ImportManager} object.
         */
        public static ImportManager getImportManager() {
-               return ImportManager.NewInstance(getCurrentApplicationController());
+               return ImportManager.NewInstance(getCurrentApplicationConfiguration());
        }
 
        /**
         * <p>
         * Getter for the field <code>exportHandler</code>.
         * </p>
-        * 
+        *
         * @return a {@link eu.etaxonomy.taxeditor.io.ExportManager} object.
         */
        public static ExportManager getExportManager() {
-               return ExportManager.NewInstance(getCurrentApplicationController());
+               return ExportManager.NewInstance(getCurrentApplicationConfiguration());
        }
 
        /**
         * Whether this CdmStore is currently connected to a datasource
-        * 
+        *
         * @return a boolean.
         */
        public static boolean isActive() {
                return instance != null && instance.isConnected;
        }
 
+       public static ICdmSource getActiveCdmSource() {
+               if (isActive()) {
+                       return instance.getCdmSource();
+               }
+               return null;
+       }
+
        /**
         * <p>
         * getDataSource
         * </p>
-        * 
+        *
         * @return a {@link eu.etaxonomy.cdm.database.ICdmDataSource} object.
+        * @deprecated currently retained for backward compatibility - use {@link getActiveCdmSource()} instead
         */
-       public static ICdmDataSource getDataSource() {
-               if (isActive()) {
-                       return instance.getDatasource();
-               }
-               return null;
-       }
+//     public static ICdmDataSource getDataSource() {
+//             if (isActive()) {
+//                     return (ICdmDataSource)instance.getCdmSource();
+//             }
+//             return null;
+//     }
 
        /**
         * @return
         */
-       private ICdmDataSource getDatasource() {
-               return cdmDatasource;
+       private ICdmSource getCdmSource() {
+               return cdmSource;
        }
 
 }