1 |
93f50b5e
|
Cherian Mathew
|
package eu.etaxonomy.cdm.api.cache;
|
2 |
|
|
|
3 |
|
|
import java.util.UUID;
|
4 |
|
|
|
5 |
2339128f
|
Andreas Kohlbecker
|
import org.apache.log4j.Logger;
|
6 |
7a0bcdb6
|
Andreas Kohlbecker
|
import org.springframework.beans.factory.annotation.Autowired;
|
7 |
|
|
|
8 |
c4f09aa4
|
Andreas Müller
|
import eu.etaxonomy.cdm.model.ICdmUuidCacher;
|
9 |
|
|
import eu.etaxonomy.cdm.model.common.CdmBase;
|
10 |
93f50b5e
|
Cherian Mathew
|
import net.sf.ehcache.Cache;
|
11 |
|
|
import net.sf.ehcache.CacheManager;
|
12 |
|
|
import net.sf.ehcache.Element;
|
13 |
|
|
import net.sf.ehcache.config.CacheConfiguration;
|
14 |
51a3a962
|
Cherian Mathew
|
import net.sf.ehcache.config.CacheConfiguration.CacheEventListenerFactoryConfiguration;
|
15 |
93f50b5e
|
Cherian Mathew
|
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
|
16 |
|
|
|
17 |
|
|
/**
|
18 |
481d494a
|
Andreas Müller
|
* CDM Entity Cacher class based on EhCache using UUID as key.
|
19 |
6af1e386
|
Cherian Mathew
|
* The cacher allows null values to be cached.
|
20 |
731f8a84
|
Cherian Mathew
|
*
|
21 |
93f50b5e
|
Cherian Mathew
|
* @author cmathew
|
22 |
|
|
*/
|
23 |
4b2b6fc7
|
Andreas Müller
|
public abstract class CdmCacherBase implements ICdmUuidCacher {
|
24 |
93f50b5e
|
Cherian Mathew
|
|
25 |
4b2b6fc7
|
Andreas Müller
|
public static final Logger logger = Logger.getLogger(CdmCacherBase.class);
|
26 |
2339128f
|
Andreas Kohlbecker
|
|
27 |
7a0bcdb6
|
Andreas Kohlbecker
|
@Autowired
|
28 |
|
|
public CacheManager cacheManager;
|
29 |
731f8a84
|
Cherian Mathew
|
|
30 |
8b9e2e71
|
Andreas Kohlbecker
|
public static final String DEFAULT_CACHE_NAME = "cdmDefaultCache"; //TODO compare with CacheConfiguration where the name for the default cache is 'default', Why another name here?
|
31 |
2c8c883f
|
Cherian Mathew
|
|
32 |
|
|
/**
|
33 |
6197d70a
|
Andreas Müller
|
* Constructor which initializes a singleton {@link net.sf.ehcache.CacheManager}
|
34 |
2c8c883f
|
Cherian Mathew
|
*/
|
35 |
4b2b6fc7
|
Andreas Müller
|
public CdmCacherBase() {
|
36 |
2c8c883f
|
Cherian Mathew
|
init();
|
37 |
|
|
}
|
38 |
|
|
|
39 |
|
|
/**
|
40 |
6197d70a
|
Andreas Müller
|
* Initializes an empty singleton {@link net.sf.ehcache.CacheManager} and
|
41 |
2c8c883f
|
Cherian Mathew
|
* sets itself as the cacher object in specific CDM Entity objects.
|
42 |
|
|
*/
|
43 |
|
|
private void init() {
|
44 |
|
|
setup();
|
45 |
|
|
}
|
46 |
|
|
|
47 |
|
|
protected abstract void setup();
|
48 |
|
|
|
49 |
|
|
/**
|
50 |
|
|
* Returns the singleton default cache manager.
|
51 |
|
|
*/
|
52 |
2339128f
|
Andreas Kohlbecker
|
public void addCacheManager(CacheManager cacheManager) {
|
53 |
|
|
|
54 |
|
|
if(this.cacheManager == null){
|
55 |
|
|
this.cacheManager = cacheManager;
|
56 |
|
|
} else {
|
57 |
|
|
logger.error("There is already a CacheManager configured.");
|
58 |
|
|
}
|
59 |
|
|
}
|
60 |
2c8c883f
|
Cherian Mathew
|
|
61 |
|
|
/**
|
62 |
|
|
* Returns the default cache configuration.
|
63 |
|
|
*/
|
64 |
|
|
protected CacheConfiguration getDefaultCacheConfiguration() {
|
65 |
|
|
CacheEventListenerFactoryConfiguration factory;
|
66 |
|
|
// For a better understanding on how to size caches, refer to
|
67 |
|
|
// http://ehcache.org/documentation/configuration/cache-size
|
68 |
7a0bcdb6
|
Andreas Kohlbecker
|
|
69 |
|
|
CacheConfiguration cc = new CacheConfiguration(DEFAULT_CACHE_NAME, 500)
|
70 |
c4f09aa4
|
Andreas Müller
|
.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LFU)
|
71 |
|
|
.eternal(false)
|
72 |
|
|
// default ttl and tti set to 2 hours
|
73 |
|
|
.timeToLiveSeconds(60*60*2)
|
74 |
|
|
.timeToIdleSeconds(60*60*2)
|
75 |
|
|
.statistics(true);
|
76 |
2c8c883f
|
Cherian Mathew
|
|
77 |
7a0bcdb6
|
Andreas Kohlbecker
|
return cc;
|
78 |
2c8c883f
|
Cherian Mathew
|
}
|
79 |
abcbf7be
|
Cherian Mathew
|
|
80 |
2c8c883f
|
Cherian Mathew
|
/**
|
81 |
|
|
* Returns the default cache
|
82 |
|
|
*
|
83 |
|
|
* @return
|
84 |
|
|
*/
|
85 |
abcbf7be
|
Cherian Mathew
|
public Cache getDefaultCache() {
|
86 |
7a0bcdb6
|
Andreas Kohlbecker
|
Cache defaultCache = cacheManager.getCache(DEFAULT_CACHE_NAME);
|
87 |
abcbf7be
|
Cherian Mathew
|
if(defaultCache == null) {
|
88 |
|
|
// Create default cache
|
89 |
7a0bcdb6
|
Andreas Kohlbecker
|
cacheManager.addCache(DEFAULT_CACHE_NAME);
|
90 |
2339128f
|
Andreas Kohlbecker
|
defaultCache = cacheManager.getCache(DEFAULT_CACHE_NAME);
|
91 |
7a0bcdb6
|
Andreas Kohlbecker
|
//FIXME write test to check if default config as defined in EhCacheConfiguration is being used
|
92 |
abcbf7be
|
Cherian Mathew
|
}
|
93 |
|
|
return defaultCache;
|
94 |
2c8c883f
|
Cherian Mathew
|
}
|
95 |
|
|
|
96 |
cbfdc57b
|
Andreas Kohlbecker
|
@Override
|
97 |
|
|
public void dispose(){
|
98 |
|
|
cacheManager.getCache(DEFAULT_CACHE_NAME).dispose();
|
99 |
|
|
}
|
100 |
|
|
|
101 |
2c8c883f
|
Cherian Mathew
|
/**
|
102 |
|
|
* Gets the cache element corresponding to the given {@link java.util.UUID}
|
103 |
|
|
*/
|
104 |
|
|
public Element getCacheElement(UUID uuid) {
|
105 |
|
|
return getDefaultCache().get(uuid);
|
106 |
|
|
}
|
107 |
731f8a84
|
Cherian Mathew
|
|
108 |
03aae089
|
Cherian Mathew
|
@Override
|
109 |
2c8c883f
|
Cherian Mathew
|
public void put(UUID uuid, CdmBase cdmEntity) {
|
110 |
933e5ac3
|
Cherian Mathew
|
CdmBase cachedCdmEntity = getFromCache(uuid);
|
111 |
2c8c883f
|
Cherian Mathew
|
if(cachedCdmEntity == null) {
|
112 |
03aae089
|
Cherian Mathew
|
getDefaultCache().put(new Element(uuid, cdmEntity));
|
113 |
|
|
}
|
114 |
|
|
}
|
115 |
731f8a84
|
Cherian Mathew
|
|
116 |
2c8c883f
|
Cherian Mathew
|
@Override
|
117 |
933e5ac3
|
Cherian Mathew
|
public CdmBase load(UUID uuid) {
|
118 |
2c8c883f
|
Cherian Mathew
|
Element e = getCacheElement(uuid);
|
119 |
|
|
|
120 |
|
|
CdmBase cdmEntity;
|
121 |
|
|
if (e == null) {
|
122 |
|
|
// nothing in the cache for "key" (or expired) ... re-load the entity
|
123 |
|
|
cdmEntity = findByUuid(uuid);
|
124 |
|
|
// currently default cache is a non-null cache
|
125 |
|
|
// We would like to have the possibility to put null values in the cache,
|
126 |
|
|
// but we need to first distinguish between real null values and null values
|
127 |
|
|
// returned by the service is the type of class does not match
|
128 |
|
|
if(cdmEntity != null) {
|
129 |
|
|
put(uuid, cdmEntity);
|
130 |
|
|
}
|
131 |
|
|
} else {
|
132 |
|
|
// there is a valid element in the cache, however getObjectValue() may be null
|
133 |
|
|
cdmEntity = (CdmBase)e.getObjectValue();
|
134 |
|
|
}
|
135 |
|
|
return cdmEntity;
|
136 |
|
|
}
|
137 |
|
|
|
138 |
|
|
@Override
|
139 |
933e5ac3
|
Cherian Mathew
|
public CdmBase getFromCache(UUID uuid) {
|
140 |
2c8c883f
|
Cherian Mathew
|
Element e = getCacheElement(uuid);
|
141 |
|
|
if (e == null) {
|
142 |
|
|
return null;
|
143 |
|
|
} else {
|
144 |
|
|
return(CdmBase)e.getObjectValue();
|
145 |
|
|
}
|
146 |
|
|
}
|
147 |
731f8a84
|
Cherian Mathew
|
|
148 |
933e5ac3
|
Cherian Mathew
|
@Override
|
149 |
2e6db6fc
|
Andreas Kohlbecker
|
public <T extends CdmBase> T getFromCache(T cdmBase) {
|
150 |
b4c19aff
|
Andreas Müller
|
return (T)getFromCache(cdmBase.getUuid());
|
151 |
933e5ac3
|
Cherian Mathew
|
}
|
152 |
|
|
|
153 |
|
|
@Override
|
154 |
d7be01af
|
Andreas Müller
|
public void putToCache(CdmBase cdmEntity) {
|
155 |
933e5ac3
|
Cherian Mathew
|
if(cdmEntity != null) {
|
156 |
|
|
put(cdmEntity.getUuid(), cdmEntity);
|
157 |
|
|
}
|
158 |
|
|
}
|
159 |
|
|
|
160 |
|
|
@Override
|
161 |
2e6db6fc
|
Andreas Kohlbecker
|
public abstract <T extends CdmBase> T load(T cdmEntity);
|
162 |
933e5ac3
|
Cherian Mathew
|
|
163 |
|
|
|
164 |
2c8c883f
|
Cherian Mathew
|
@Override
|
165 |
731f8a84
|
Cherian Mathew
|
public boolean exists(UUID uuid) {
|
166 |
2c8c883f
|
Cherian Mathew
|
return getCacheElement(uuid) != null;
|
167 |
|
|
}
|
168 |
731f8a84
|
Cherian Mathew
|
|
169 |
2c8c883f
|
Cherian Mathew
|
@Override
|
170 |
|
|
public boolean exists(CdmBase cdmBase) {
|
171 |
|
|
if(cdmBase != null) {
|
172 |
|
|
return exists(cdmBase.getUuid());
|
173 |
|
|
}
|
174 |
|
|
return false;
|
175 |
|
|
}
|
176 |
|
|
|
177 |
|
|
@Override
|
178 |
731f8a84
|
Cherian Mathew
|
public boolean existsAndIsNotNull(UUID uuid) {
|
179 |
2c8c883f
|
Cherian Mathew
|
Element e = getCacheElement(uuid);
|
180 |
|
|
if (e != null) {
|
181 |
|
|
return e.getObjectValue() != null;
|
182 |
|
|
}
|
183 |
|
|
return false;
|
184 |
|
|
}
|
185 |
|
|
|
186 |
|
|
/**
|
187 |
|
|
* Finds CDM Entity by uuid
|
188 |
|
|
*/
|
189 |
|
|
protected abstract CdmBase findByUuid(UUID uuid);
|
190 |
731f8a84
|
Cherian Mathew
|
|
191 |
4b2b6fc7
|
Andreas Müller
|
@Override
|
192 |
|
|
public boolean ignoreRecursiveLoad(CdmBase cdmBase){
|
193 |
|
|
return false;
|
194 |
|
|
}
|
195 |
93f50b5e
|
Cherian Mathew
|
}
|