cleanup
[taxeditor.git] / eu.etaxonomy.taxeditor.cdmlib / src / main / java / eu / etaxonomy / cdm / api / cache / CdmServiceCacher.java
index 96c94964cc2fb0698048ac580b0051a8d103a068..c8538625bc41f1ed46117e2bf68aad3f87c172ac 100644 (file)
@@ -1,56 +1,97 @@
+/**
+ * Copyright (C) 2015 EDIT
+ * 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.
+ */
 package eu.etaxonomy.cdm.api.cache;
 
+import java.io.File;
 import java.util.UUID;
 
-import net.sf.ehcache.config.CacheConfiguration;
-import net.sf.ehcache.config.SizeOfPolicyConfiguration;
-
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import eu.etaxonomy.cdm.api.service.ITermService;
+import eu.etaxonomy.cdm.api.application.CdmApplicationState;
+import eu.etaxonomy.cdm.api.config.EhCacheConfiguration;
+import eu.etaxonomy.cdm.cache.CacheLoader;
+import eu.etaxonomy.cdm.cache.CdmEntityCacheKey;
+import eu.etaxonomy.cdm.cache.CdmTransientEntityCacher;
+import eu.etaxonomy.cdm.config.ConfigFileUtil;
 import eu.etaxonomy.cdm.model.common.CdmBase;
-import eu.etaxonomy.cdm.model.common.DefinedTermBase;
-import eu.etaxonomy.taxeditor.remoting.cache.CacheLoader;
-import eu.etaxonomy.taxeditor.remoting.cache.CdmEntityCacheKey;
-import eu.etaxonomy.taxeditor.remoting.cache.CdmTransientEntityCacher;
-import eu.etaxonomy.taxeditor.service.TermServiceRequestExecutor;
+import eu.etaxonomy.cdm.model.term.DefinedTermBase;
+import eu.etaxonomy.cdm.model.term.Representation;
+import eu.etaxonomy.cdm.model.term.TermBase;
+import eu.etaxonomy.taxeditor.service.RemoteInvocationTermCacher;
 import eu.etaxonomy.taxeditor.session.CdmEntitySession;
-import eu.etaxonomy.taxeditor.session.CdmEntitySessionManager;
 import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
+import eu.etaxonomy.taxeditor.session.ICdmEntitySessionManager;
+import eu.etaxonomy.taxeditor.session.ICdmEntitySessionManagerObserver;
+import net.sf.ehcache.config.CacheConfiguration;
+import net.sf.ehcache.config.DiskStoreConfiguration;
+import net.sf.ehcache.config.SizeOfPolicyConfiguration;
 
 /**
  * Class which uses CDM services to cache cdm entities
  *
- * FIXME: Currently only handles terms entities. It would be
+ * FIXME: Currently only handles term entities. It would be
  *        interesting to have a generic method which finds the
  *        correct service to load / cache the entity.
  *
  * @author cmathew
- *
- * @param <T>
  */
-@Component
-public class CdmServiceCacher extends CdmCacher {
+public class CdmServiceCacher extends CdmCacherBase implements ICdmEntitySessionManagerObserver {
 
-    @Autowired
-    ITermService termService;
-
-    @Autowired
-    private CdmEntitySessionManager cdmEntitySessionManager;
+    private ICdmEntitySessionManager cdmEntitySessionManager;
 
     private CdmTransientEntityCacher cdmTransientEntityCacher;
 
     private CacheLoader cacheLoader;
 
+    @Autowired
+    private ConfigFileUtil configFileUtil = null;
+
     @Override
     protected void setup() {
+
+        setUpCacheManager();
+
         DefinedTermBase.setCacher(this);
-        CdmTransientEntityCacher.setDefaultCacher(this);
-        TermServiceRequestExecutor.setDefaultCacher(this);
+        CdmTransientEntityCacher.setPermanentCacher(this);
+        //TermServiceRequestExecutor.setDefaultCacher(this);
+        RemoteInvocationTermCacher.setDefaultCacher(this);
+
         cacheLoader = new CacheLoader(this);
     }
 
+    private void setUpCacheManager() {
+
+        EhCacheConfiguration cacheConfig = new EhCacheConfiguration();
+
+        DiskStoreConfiguration diskStoreConfiguration = new DiskStoreConfiguration();
+        File ehcacheFolder = null;
+        if(configFileUtil != null){
+            try {
+                ehcacheFolder = configFileUtil.getCdmHomeSubDir("taxeditor-ehcache");
+            } catch (Exception e){
+                logger.warn("Cannot determine CdmHomeSubDir for ./taxeditor-ehcache, will use fallback method.", e);
+            }
+        }
+        if(ehcacheFolder == null){
+            ehcacheFolder = ConfigFileUtil.getCdmHomeSubDirFallback("taxeditor-ehcache");
+        }
+
+        // FIXME use subfolder per taxeditor version to allow running multiple installations in parallel
+        // String taxEditorVersion = ..;
+        // File ehcacheFolder = new File(ehcacheFolder, taxEditorVersion);
+        diskStoreConfiguration.setPath(ehcacheFolder.getAbsolutePath());
+
+        cacheConfig.setDiskStoreConfiguration(diskStoreConfiguration);
+        addCacheManager(cacheConfig.cacheManager());
+    }
+
     @Override
     protected CacheConfiguration getDefaultCacheConfiguration() {
         // For a better understanding on how to size caches, refer to
@@ -61,46 +102,55 @@ public class CdmServiceCacher extends CdmCacher {
         sizeOfConfig.setMaxDepthExceededBehavior("abort");
 
         return new CacheConfiguration(DEFAULT_CACHE_NAME, 0)
-        .eternal(true)
-        .statistics(true)
-        .sizeOfPolicy(sizeOfConfig)
-        .overflowToOffHeap(false);
-
+               .eternal(true)
+               .statistics(true)
+               .sizeOfPolicy(sizeOfConfig)
+               .overflowToOffHeap(false);
     }
 
     @Override
     protected CdmBase findByUuid(UUID uuid) {
-        CdmBase term = termService.findWithoutFlush(uuid);
+        CdmBase term = CdmApplicationState.getCurrentAppConfig().getTermService().findWithoutFlush(uuid);
         return load(term);
     }
 
-    /* (non-Javadoc)
-     * @see eu.etaxonomy.cdm.model.ICdmCacher#isCachable(eu.etaxonomy.cdm.model.common.CdmBase)
-     */
     @Override
     public boolean isCachable(CdmBase cdmEntity) {
-        if(cdmEntity != null && cdmEntity instanceof DefinedTermBase) {
+       if(cdmEntity == null){
+           return false;
+       }else if (cdmEntity instanceof TermBase || cdmEntity instanceof Representation){
             return true;
+        }else{
+            return false;
         }
-        return false;
     }
 
-    public void setActiveSession(ICdmEntitySession cdmEntitySession) {
+    public void setCdmEntitySessionManager(ICdmEntitySessionManager cdmEntitySessionManager) {
+        this.cdmEntitySessionManager = cdmEntitySessionManager;
+        if(cdmEntitySessionManager != null) {
+            cdmEntitySessionManager.addSessionObserver(this);
+        }
+    }
+
+    public CdmTransientEntityCacher getCurrentCacher() {
+        ICdmEntitySession cdmEntitySession = cdmEntitySessionManager.getActiveSession();
         if(cdmEntitySession != null && cdmEntitySession instanceof CdmEntitySession) {
-            this.cdmTransientEntityCacher = ((CdmEntitySession) cdmEntitySession).getCacher();
-        } else {
-            this.cdmTransientEntityCacher = null;
+            return ((CdmEntitySession) cdmEntitySession).getCacher();
         }
+        return null;
     }
 
     @Override
-    public CdmBase getFromCache(CdmBase cdmBase) {
-        CdmBase cachedCdmEntity = null;
+    public <T extends CdmBase> T  getFromCache(T cdmBase) {
+        T cachedCdmEntity = null;
         // first we check in the active session cache if the
+        // entity has been loaded there
+        // FIXME:Remoting do we really need the cdmTransientEntityCacher
+        // here. Is it not guaranteed that all every entity which 'isCachable'
+        // by this cacher is cached only in this cacher ?
         if(!isCachable(cdmBase) && cdmTransientEntityCacher != null) {
-            CdmEntityCacheKey key = CdmTransientEntityCacher.generateKey(cdmBase);
+            CdmEntityCacheKey<T> key = CdmTransientEntityCacher.generateKey(cdmBase);
             cachedCdmEntity = cdmTransientEntityCacher.getFromCache(key);
-
         }
         if(cachedCdmEntity == null) {
             cachedCdmEntity = super.getFromCache(cdmBase);
@@ -108,19 +158,23 @@ public class CdmServiceCacher extends CdmCacher {
         return cachedCdmEntity;
     }
 
-
-    /* (non-Javadoc)
-     * @see eu.etaxonomy.cdm.api.cache.CdmCacher#load(eu.etaxonomy.cdm.model.common.CdmBase)
-     */
     @Override
-    public CdmBase load(CdmBase cdmEntity) {
-        CdmBase cachedCdmEntity = getFromCache(cdmEntity.getUuid());
+    public <T extends CdmBase> T load(T cdmEntity) {
+        T cachedCdmEntity = (T)getFromCache(cdmEntity.getUuid());
 
-        if(isCachable(cdmEntity)) {
-            cachedCdmEntity =  cacheLoader.load(cdmEntity, true, false);
+        if(isCachable(cdmEntity) && cachedCdmEntity == null) {
+            cachedCdmEntity =  cacheLoader.load(cdmEntity, false, true);
         }
         return cachedCdmEntity;
     }
 
-
+    @Override
+    public void changed() {
+        ICdmEntitySession cdmEntitySession = cdmEntitySessionManager.getActiveSession();
+        if(cdmEntitySession != null && cdmEntitySession instanceof CdmEntitySession) {
+            this.cdmTransientEntityCacher = ((CdmEntitySession) cdmEntitySession).getCacher();
+        } else {
+            this.cdmTransientEntityCacher = null;
+        }
+    }
 }