+/**
+ * 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
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);
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;
+ }
+ }
}