1 package eu
.etaxonomy
.cdm
.api
.cache
;
6 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
7 import org
.springframework
.stereotype
.Component
;
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
;
28 * Class which uses CDM services to cache cdm entities
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.
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
{
39 private ICdmEntitySessionManager cdmEntitySessionManager
;
41 private CdmTransientEntityCacher cdmTransientEntityCacher
;
43 private CacheLoader cacheLoader
;
46 private ConfigFileUtil configFileUtil
= null;
49 protected void setup() {
53 DefinedTermBase
.setCacher(this);
54 CdmTransientEntityCacher
.setPermanentCacher(this);
55 //TermServiceRequestExecutor.setDefaultCacher(this);
56 RemoteInvocationTermCacher
.setDefaultCacher(this);
58 cacheLoader
= new CacheLoader(this);
61 private void setUpCacheManager() {
63 EhCacheConfiguration cacheConfig
= new EhCacheConfiguration();
65 DiskStoreConfiguration diskStoreConfiguration
= new DiskStoreConfiguration();
66 File ehcacheFolder
= null;
67 if(configFileUtil
!= null){
69 ehcacheFolder
= configFileUtil
.getCdmHomeSubDir("taxeditor-ehcache");
70 } catch (Exception e
){
71 logger
.warn("Cannot determine CdmHomeSubDir for ./taxeditor-ehcache, will use fallback method.", e
);
74 if(ehcacheFolder
== null){
75 ehcacheFolder
= ConfigFileUtil
.getCdmHomeSubDirFallback("taxeditor-ehcache");
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());
83 cacheConfig
.setDiskStoreConfiguration(diskStoreConfiguration
);
84 addCacheManager(cacheConfig
.cacheManager());
88 protected CacheConfiguration
getDefaultCacheConfiguration() {
89 // For a better understanding on how to size caches, refer to
90 // http://ehcache.org/documentation/configuration/cache-size
92 SizeOfPolicyConfiguration sizeOfConfig
= new SizeOfPolicyConfiguration();
93 sizeOfConfig
.setMaxDepth(100);
94 sizeOfConfig
.setMaxDepthExceededBehavior("abort");
96 return new CacheConfiguration(DEFAULT_CACHE_NAME
, 0)
99 .sizeOfPolicy(sizeOfConfig
)
100 .overflowToOffHeap(false);
104 protected CdmBase
findByUuid(UUID uuid
) {
105 CdmBase term
= CdmApplicationState
.getCurrentAppConfig().getTermService().findWithoutFlush(uuid
);
110 public boolean isCachable(CdmBase cdmEntity
) {
111 // if(cdmEntity != null && cdmEntity instanceof DefinedTermBase) {
112 if(cdmEntity
!= null && cdmEntity
instanceof TermBase
) {
118 public void setCdmEntitySessionManager(ICdmEntitySessionManager cdmEntitySessionManager
) {
119 this.cdmEntitySessionManager
= cdmEntitySessionManager
;
120 if(cdmEntitySessionManager
!= null) {
121 cdmEntitySessionManager
.addSessionObserver(this);
125 public CdmTransientEntityCacher
getCurrentCacher() {
126 ICdmEntitySession cdmEntitySession
= cdmEntitySessionManager
.getActiveSession();
127 if(cdmEntitySession
!= null && cdmEntitySession
instanceof CdmEntitySession
) {
128 return ((CdmEntitySession
) cdmEntitySession
).getCacher();
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
);
145 if(cachedCdmEntity
== null) {
146 cachedCdmEntity
= super.getFromCache(cdmBase
);
148 return cachedCdmEntity
;
152 public <T
extends CdmBase
> T
load(T cdmEntity
) {
153 T cachedCdmEntity
= (T
)getFromCache(cdmEntity
.getUuid());
155 if(isCachable(cdmEntity
) && cachedCdmEntity
== null) {
156 cachedCdmEntity
= cacheLoader
.load(cdmEntity
, false, true);
158 return cachedCdmEntity
;
162 public void changed() {
163 ICdmEntitySession cdmEntitySession
= cdmEntitySessionManager
.getActiveSession();
164 if(cdmEntitySession
!= null && cdmEntitySession
instanceof CdmEntitySession
) {
165 this.cdmTransientEntityCacher
= ((CdmEntitySession
) cdmEntitySession
).getCacher();
167 this.cdmTransientEntityCacher
= null;