Merge branch 'develop' into remoting-4.0
[taxeditor.git] / eu.etaxonomy.taxeditor.cdmlib / src / main / java / eu / etaxonomy / taxeditor / remoting / cache / CdmRemoteCacheManager.java
index 88074638fac88e27dcc35264e0890dd47ec361b0..84f88c24fb3c51a19b1d4d70bb0e12aa271b2f2e 100644 (file)
 package eu.etaxonomy.taxeditor.remoting.cache;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-
 import net.sf.ehcache.Cache;
 import net.sf.ehcache.CacheException;
 import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.config.CacheConfiguration;
+import net.sf.ehcache.config.SizeOfPolicyConfiguration;
+
+import org.apache.log4j.Logger;
+
+
+public class CdmRemoteCacheManager {
+
+    private static final Logger logger = Logger.getLogger(CdmRemoteCacheManager.class);
+
+
+    private Cache cdmlibModelCache;
 
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.Resource;
-import org.springframework.stereotype.Component;
+    private static CdmRemoteCacheManager cdmRemoteCacheManager = null;
 
-import eu.etaxonomy.cdm.common.CdmUtils;
+    public static final String CDM_MODEL_CACHE_NAME = "cdmModelGetMethodsCache";
 
+    private static Thread initThread;
+
+    private static boolean cacheInitialised = false;
 
-public class CdmRemoteCacheManager {   
-       
-       private CacheManager cdmlibModelCacheManager;
-       
-       private static CdmRemoteCacheManager cdmRemoteCacheManager = null;
-       
-    public static final Resource CDMLIB_CACHE_MANAGER_CONFIG_RESOURCE =
-            new ClassPathResource("cdmlib-ehcache.xml");
-    
-       
     public enum CdmCacheManagerType {
-       CDMLIB_MODEL,
-       DEFAULT
+        CDMLIB_MODEL,
+        DEFAULT
     }
 
     public static CdmRemoteCacheManager getInstance(){
-       if(cdmRemoteCacheManager == null) {             
-               cdmRemoteCacheManager = new CdmRemoteCacheManager();            
-       }
-       return cdmRemoteCacheManager;
+
+        if(cdmRemoteCacheManager == null) {
+            cdmRemoteCacheManager = new CdmRemoteCacheManager();
+        }
+        return cdmRemoteCacheManager;
     }
     private CdmRemoteCacheManager() {
-       
-       System.setProperty("ehcache.disk.store.dir", CdmUtils.getCdmHomeDir().getAbsolutePath() + File.separator + "cdmlib-model");                     
-       try {
-               // NOTE:Programmatically creating the cache manager may solve the problem of 
-               //      recreating data written to disk on startup
-               //      see https://stackoverflow.com/questions/1729605/ehcache-persist-to-disk-issues
-               //String cacheFilePath = CDMLIB_CACHE_MANAGER_CONFIG_RESOURCE.getFile().getAbsolutePath();
-               InputStream in = this.getClass().getClassLoader().getResourceAsStream("cdmlib-ehcache.xml");
-                       cdmlibModelCacheManager = new CacheManager(in);
-                       
-               } catch (CacheException e) {
-                       throw new CdmClientCacheException(e);
-               }
-//             } catch (IOException e) {
-//                     throw new CdmClientCacheException(e);
-//             }
+
+
+        try {
+            // NOTE:Programmatically creating the cache manager may solve the problem of
+            //      recreating data written to disk on startup
+            //      see https://stackoverflow.com/questions/1729605/ehcache-persist-to-disk-issues
+            //String cacheFilePath = CDMLIB_CACHE_MANAGER_CONFIG_RESOURCE.getFile().getAbsolutePath();
+            //InputStream in = this.getClass().getClassLoader().getResourceAsStream("cdmlib-ehcache.xml");
+
+            SizeOfPolicyConfiguration sizeOfConfig = new SizeOfPolicyConfiguration();
+            sizeOfConfig.setMaxDepth(1000);
+            sizeOfConfig.setMaxDepthExceededBehavior("abort");
+
+            CacheConfiguration modelcc = new CacheConfiguration(CDM_MODEL_CACHE_NAME, 0)
+            .eternal(true)
+            .statistics(true)
+            .sizeOfPolicy(sizeOfConfig)
+            .overflowToOffHeap(false);
+
+            cdmlibModelCache = new Cache(modelcc);
+
+            CacheManager.create().addCache(cdmlibModelCache);
+            initCdmModelCache(cdmlibModelCache);
+
+        } catch (CacheException e) {
+            throw new CdmClientCacheException(e);
+        }
+
+    }
+
+    private void initCdmModelCache(final Cache cache) {
+
+        initThread = new Thread() {
+            @Override
+            public void run(){
+                synchronized (cdmlibModelCache) {
+                    CdmModelCacher cmdmc = new CdmModelCacher();
+                    cmdmc.cacheGetterFields(cache);
+                    cacheInitialised = true;
+                    logger.info("Initialisation of CDM getter fields complete");
+                    cdmlibModelCache.notify();
+                }
+            }
+
+        };
+        initThread.start();
     }
-    
-       public Cache getCdmModelGetMethodsCache(){
-               return cdmlibModelCacheManager.getCache("cdmModelGetMethodsCache");
-       }
-       
-       public void shutdown(CdmCacheManagerType ccmt) {
-               CacheManager cm;
-               switch(ccmt) {          
-               case CDMLIB_MODEL:                      
-                       cdmlibModelCacheManager.shutdown();
-                       break;
-               case DEFAULT:
-                       cm = CacheManager.create();
-                       cm.shutdown();
-                       break;
-               default:
-                       //do nothing
-               }               
-       }
-       
-       public static void checkCacheProperties() {
-               String pathToCache = System.getProperty("ehcache.disk.store.dir");
-               if(pathToCache == null || pathToCache.isEmpty()) {
-                       throw new CdmClientCacheException("'ehcache.disk.store.dir' property is not set");
-               }
-       }
+
+    public Cache getCdmModelGetMethodsCache(){
+        //Note : Even though we synchronize this method, the cache can be simply
+        //       retrieved using CacheManager.create().getCache(CDM_MODEL_CACHE_NAME)
+        //       in which case the cache may not be fully initialised
+        synchronized (cdmlibModelCache) {
+            while(!cacheInitialised) {
+                try {
+                    logger.info("Waiting for initialisation of CDM getter fields to complete ...");
+                    cdmlibModelCache.wait();
+                } catch (InterruptedException e) {}
+            }
+        }
+        logger.info("CDM getter fields cache initialised");
+        return cdmlibModelCache;
+    }
+
+    public static void removeEntityCaches() {
+        CacheManager cm = CacheManager.create();
+        String[] cacheNames = CacheManager.create().getCacheNames();
+        for(String cacheName : cacheNames) {
+            if(!cacheName.equals(CDM_MODEL_CACHE_NAME)) {
+                cm.removeCache(cacheName);
+            }
+        }
+    }
+
+
 
 }