package eu.etaxonomy.taxeditor.remoting.cache;
-import java.io.File;
-import java.io.InputStream;
-import java.util.HashSet;
-import java.util.Set;
-
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.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.Resource;
-
-import eu.etaxonomy.cdm.common.CdmUtils;
+import org.apache.log4j.Logger;
public class CdmRemoteCacheManager {
- private CacheManager cdmlibModelCacheManager;
+ private static final Logger logger = Logger.getLogger(CdmRemoteCacheManager.class);
- private static CdmRemoteCacheManager cdmRemoteCacheManager = null;
- private final Set<CdmTransientEntityCacher> transientEntityCachers = new HashSet<CdmTransientEntityCacher>();
+ private Cache cdmlibModelCache;
- public static final Resource CDMLIB_CACHE_MANAGER_CONFIG_RESOURCE =
- new ClassPathResource("cdmlib-ehcache.xml");
+ private static CdmRemoteCacheManager cdmRemoteCacheManager = null;
public static final String CDM_MODEL_CACHE_NAME = "cdmModelGetMethodsCache";
+ private static Thread initThread;
+
+ private static boolean cacheInitialised = false;
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(){
+ //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);
+ }
+ }
}
- public Cache getCdmModelGetMethodsCache(){
- return cdmlibModelCacheManager.getCache(CDM_MODEL_CACHE_NAME);
- }
-
- public CacheManager getCdmModelGetMethodsCacheManager() {
- return cdmlibModelCacheManager;
- }
-
- public CacheManager getDefaultCacheManager() {
- return CacheManager.create();
- }
-
- 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");
- }
- }
}