cleanup
[taxeditor.git] / eu.etaxonomy.taxeditor.cdmlib / src / main / java / eu / etaxonomy / cdm / api / cache / CdmServiceCacher.java
1 package eu.etaxonomy.cdm.api.cache;
2
3 import java.io.File;
4 import java.util.UUID;
5
6 import org.springframework.beans.factory.annotation.Autowired;
7 import org.springframework.stereotype.Component;
8
9 import eu.etaxonomy.cdm.api.application.CdmApplicationState;
10 import eu.etaxonomy.cdm.api.config.EhCacheConfiguration;
11 import eu.etaxonomy.cdm.cache.CacheLoader;
12 import eu.etaxonomy.cdm.cache.CdmEntityCacheKey;
13 import eu.etaxonomy.cdm.cache.CdmTransientEntityCacher;
14 import eu.etaxonomy.cdm.config.ConfigFileUtil;
15 import eu.etaxonomy.cdm.model.common.CdmBase;
16 import eu.etaxonomy.cdm.model.term.DefinedTermBase;
17 import eu.etaxonomy.cdm.model.term.TermBase;
18 import eu.etaxonomy.taxeditor.service.RemoteInvocationTermCacher;
19 import eu.etaxonomy.taxeditor.session.CdmEntitySession;
20 import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
21 import eu.etaxonomy.taxeditor.session.ICdmEntitySessionManager;
22 import eu.etaxonomy.taxeditor.session.ICdmEntitySessionManagerObserver;
23 import net.sf.ehcache.config.CacheConfiguration;
24 import net.sf.ehcache.config.DiskStoreConfiguration;
25 import net.sf.ehcache.config.SizeOfPolicyConfiguration;
26
27 /**
28 * Class which uses CDM services to cache cdm entities
29 *
30 * FIXME: Currently only handles term entities. It would be
31 * interesting to have a generic method which finds the
32 * correct service to load / cache the entity.
33 *
34 * @author cmathew
35 */
36 @Component //FIXME This indicates that the CdmServiceCacher is initialized as Spring Component but it seems only to be instantiated directly
37 public class CdmServiceCacher extends CdmCacher implements ICdmEntitySessionManagerObserver {
38
39 private ICdmEntitySessionManager cdmEntitySessionManager;
40
41 private CdmTransientEntityCacher cdmTransientEntityCacher;
42
43 private CacheLoader cacheLoader;
44
45 @Autowired
46 private ConfigFileUtil configFileUtil = null;
47
48 @Override
49 protected void setup() {
50
51 setUpCacheManager();
52
53 DefinedTermBase.setCacher(this);
54 CdmTransientEntityCacher.setPermanentCacher(this);
55 //TermServiceRequestExecutor.setDefaultCacher(this);
56 RemoteInvocationTermCacher.setDefaultCacher(this);
57
58 cacheLoader = new CacheLoader(this);
59 }
60
61 private void setUpCacheManager() {
62
63 EhCacheConfiguration cacheConfig = new EhCacheConfiguration();
64
65 DiskStoreConfiguration diskStoreConfiguration = new DiskStoreConfiguration();
66 File ehcacheFolder = null;
67 if(configFileUtil != null){
68 try {
69 ehcacheFolder = configFileUtil.getCdmHomeSubDir("taxeditor-ehcache");
70 } catch (Exception e){
71 logger.warn("Cannot determine CdmHomeSubDir for ./taxeditor-ehcache, will use fallback method.", e);
72 }
73 }
74 if(ehcacheFolder == null){
75 ehcacheFolder = ConfigFileUtil.getCdmHomeSubDirFallback("taxeditor-ehcache");
76 }
77
78 // FIXME use subfolder per taxeditor version to allow running multiple installations in parallel
79 // String taxEditorVersion = ..;
80 // File ehcacheFolder = new File(ehcacheFolder, taxEditorVersion);
81 diskStoreConfiguration.setPath(ehcacheFolder.getAbsolutePath());
82
83 cacheConfig.setDiskStoreConfiguration(diskStoreConfiguration);
84 addCacheManager(cacheConfig.cacheManager());
85 }
86
87 @Override
88 protected CacheConfiguration getDefaultCacheConfiguration() {
89 // For a better understanding on how to size caches, refer to
90 // http://ehcache.org/documentation/configuration/cache-size
91
92 SizeOfPolicyConfiguration sizeOfConfig = new SizeOfPolicyConfiguration();
93 sizeOfConfig.setMaxDepth(100);
94 sizeOfConfig.setMaxDepthExceededBehavior("abort");
95
96 return new CacheConfiguration(DEFAULT_CACHE_NAME, 0)
97 .eternal(true)
98 .statistics(true)
99 .sizeOfPolicy(sizeOfConfig)
100 .overflowToOffHeap(false);
101 }
102
103 @Override
104 protected CdmBase findByUuid(UUID uuid) {
105 CdmBase term = CdmApplicationState.getCurrentAppConfig().getTermService().findWithoutFlush(uuid);
106 return load(term);
107 }
108
109 @Override
110 public boolean isCachable(CdmBase cdmEntity) {
111 // if(cdmEntity != null && cdmEntity instanceof DefinedTermBase) {
112 if(cdmEntity != null && cdmEntity instanceof TermBase) {
113 return true;
114 }
115 return false;
116 }
117
118 public void setCdmEntitySessionManager(ICdmEntitySessionManager cdmEntitySessionManager) {
119 this.cdmEntitySessionManager = cdmEntitySessionManager;
120 if(cdmEntitySessionManager != null) {
121 cdmEntitySessionManager.addSessionObserver(this);
122 }
123 }
124
125 public CdmTransientEntityCacher getCurrentCacher() {
126 ICdmEntitySession cdmEntitySession = cdmEntitySessionManager.getActiveSession();
127 if(cdmEntitySession != null && cdmEntitySession instanceof CdmEntitySession) {
128 return ((CdmEntitySession) cdmEntitySession).getCacher();
129 }
130 return null;
131 }
132
133 @Override
134 public <T extends CdmBase> T getFromCache(T cdmBase) {
135 T cachedCdmEntity = null;
136 // first we check in the active session cache if the
137 // entity has been loaded there
138 // FIXME:Remoting do we really need the cdmTransientEntityCacher
139 // here. Is it not guaranteed that all every entity which 'isCachable'
140 // by this cacher is cached only in this cacher ?
141 if(!isCachable(cdmBase) && cdmTransientEntityCacher != null) {
142 CdmEntityCacheKey<T> key = CdmTransientEntityCacher.generateKey(cdmBase);
143 cachedCdmEntity = cdmTransientEntityCacher.getFromCache(key);
144 }
145 if(cachedCdmEntity == null) {
146 cachedCdmEntity = super.getFromCache(cdmBase);
147 }
148 return cachedCdmEntity;
149 }
150
151 @Override
152 public <T extends CdmBase> T load(T cdmEntity) {
153 T cachedCdmEntity = (T)getFromCache(cdmEntity.getUuid());
154
155 if(isCachable(cdmEntity) && cachedCdmEntity == null) {
156 cachedCdmEntity = cacheLoader.load(cdmEntity, false, true);
157 }
158 return cachedCdmEntity;
159 }
160
161 @Override
162 public void changed() {
163 ICdmEntitySession cdmEntitySession = cdmEntitySessionManager.getActiveSession();
164 if(cdmEntitySession != null && cdmEntitySession instanceof CdmEntitySession) {
165 this.cdmTransientEntityCacher = ((CdmEntitySession) cdmEntitySession).getCacher();
166 } else {
167 this.cdmTransientEntityCacher = null;
168 }
169 }
170 }