ICachedCommonService, CachedCommonServiceImpl : moved class to service package
[taxeditor.git] / eu.etaxonomy.taxeditor.cdmlib / src / main / java / eu / etaxonomy / taxeditor / remoting / cache / CdmTransientEntityCacher.java
1 // $Id$
2 /**
3 * Copyright (C) 2014 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10 package eu.etaxonomy.taxeditor.remoting.cache;
11
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.List;
15 import java.util.Map;
16
17 import net.sf.ehcache.Cache;
18 import net.sf.ehcache.Element;
19 import net.sf.ehcache.config.CacheConfiguration;
20 import net.sf.ehcache.config.SizeOfPolicyConfiguration;
21 import net.sf.ehcache.statistics.LiveCacheStatistics;
22 import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
23
24 import org.apache.log4j.Logger;
25
26 import eu.etaxonomy.cdm.api.cache.CdmServiceCacher;
27 import eu.etaxonomy.cdm.model.ICdmCacher;
28 import eu.etaxonomy.cdm.model.common.CdmBase;
29 import eu.etaxonomy.taxeditor.session.ICdmEntitySessionManager;
30
31 /**
32 *
33 * This cache guarantees that
34 * - all objects put will be ancestors of CdmBase
35 * - all CdmBase objects in the cache will be already de-proxied
36 * - after any CdmBase object is put in the cache,
37 * all non-null / non-proxy CdmBase objects in the sub-graph
38 * will also be present in the cache.
39 *
40 * @author cmathew
41 * @date 14 Oct 2014
42 *
43 */
44
45 public class CdmTransientEntityCacher implements ICdmCacher {
46
47 private static final Logger logger = Logger.getLogger(CdmTransientEntityCacher.class);
48
49
50 private final ICdmEntitySessionManager cdmEntitySessionManager;
51
52 private static CdmServiceCacher cdmServiceCacher;
53
54 private final String cacheId;
55
56 private final Cache cache;
57
58 private final CacheLoader cacheLoader;
59
60
61
62 public static enum CollectionType {
63 SET,
64 LIST,
65 MAP;
66
67 @Override
68 public String toString() {
69 return this.name().toLowerCase();
70 }
71 }
72
73
74 public CdmTransientEntityCacher(String cacheId, ICdmEntitySessionManager cdmEntitySessionManager) {
75 this.cacheId = cacheId;
76
77 cache = new Cache(getEntityCacheConfiguration(cacheId));
78 CdmRemoteCacheManager.getInstance().getDefaultCacheManager().addCache(cache);
79
80 cacheLoader = new CacheLoader(this);
81 this.cdmEntitySessionManager = cdmEntitySessionManager;
82
83
84 }
85
86 public CdmTransientEntityCacher(Object obj, ICdmEntitySessionManager cdmEntitySessionManager) {
87 this(obj.getClass().getName() + String.valueOf(obj.hashCode()), cdmEntitySessionManager);
88 }
89
90 /**
91 * Returns the default cache configuration.
92 *
93 * @return
94 */
95 private CacheConfiguration getEntityCacheConfiguration(String cacheId) {
96 SizeOfPolicyConfiguration sizeOfConfig = new SizeOfPolicyConfiguration();
97 sizeOfConfig.setMaxDepth(10000);
98 sizeOfConfig.setMaxDepthExceededBehavior("abort");
99 // For a better understanding on how to size caches, refer to
100 // http://ehcache.org/documentation/configuration/cache-size
101 return new CacheConfiguration(cacheId, 500)
102 .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LFU)
103 //.eternal(true);
104 // default ttl and tti set to 2 hours
105 .timeToLiveSeconds(60*60*2)
106 .timeToIdleSeconds(60*60*2)
107 .statistics(true)
108 .sizeOfPolicy(sizeOfConfig);
109
110
111
112 }
113
114 public static void setDefaultCacher(CdmServiceCacher css) {
115 cdmServiceCacher = css;
116 }
117
118 public LiveCacheStatistics getCacheStatistics() {
119 return cache.getLiveCacheStatistics();
120 }
121
122 /**
123 * Returns the cache corresponding to the cache id
124 *
125 * @param cacheId
126 * @return
127 */
128 private Cache getCache() {
129 return CdmRemoteCacheManager.getInstance().getDefaultCacheManager().getCache(cacheId);
130 }
131
132 public <T extends Object> T load(T obj, boolean recursive) {
133 return cacheLoader.load(obj, recursive);
134 }
135
136 public <T extends Object> Map<T,T> load(Map<T,T> map, boolean recursive){
137 return cacheLoader.load(map, recursive);
138 }
139
140 public <T extends Object> Collection<T> load(Collection<T> collection, boolean recursive){
141 return cacheLoader.load(collection, recursive);
142 }
143
144 public CdmBase load(CdmBase cdmEntity, boolean recursive) {
145 return cacheLoader.load(cdmEntity, recursive);
146 }
147
148 public CdmModelFieldPropertyFromClass getFromCdmlibModelCache(String className) {
149 return cacheLoader.getFromCdmlibModelCache(className);
150 }
151
152
153
154
155 @Override
156 public void put(CdmBase cdmEntity) {
157 CdmEntityCacheKey id = new CdmEntityCacheKey(cdmEntity);
158 Element cachedCdmEntityElement = cdmServiceCacher.getCacheElement(cdmEntity.getUuid());
159 if(cachedCdmEntityElement != null) {
160 logger.info("Cdm Entity with id : " + cdmEntity.getId() + " already exists in permanent cache. Ignoring put.");
161 return;
162 }
163 getCache().put(new Element(id, cdmEntity));
164 }
165
166
167 private Element getCacheElement(CdmEntityCacheKey key) {
168 return getCache().get(key);
169 }
170
171
172 public CdmBase getFromCache(CdmEntityCacheKey id) {
173 Element e = getCacheElement(id);
174 if (e == null) {
175 return null;
176 } else {
177 return (CdmBase) e.getObjectValue();
178 }
179 }
180
181 public CdmBase getFromCache(Class<? extends CdmBase> clazz, int id) {
182 CdmEntityCacheKey cacheId = generateKey(clazz,id);
183 return getFromCache(cacheId);
184 }
185
186 @Override
187 public CdmBase getFromCache(CdmBase cdmBase) {
188
189 CdmEntityCacheKey cacheId = generateKey(cdmBase);
190 // first try this cache
191 CdmBase cachedCdmEntity = getFromCache(cacheId);
192
193 if(cachedCdmEntity == null) {
194 // ... then try the permanent cache
195 cachedCdmEntity = cdmServiceCacher.load(cdmBase);
196 }
197
198 return cachedCdmEntity;
199 }
200
201 public CdmBase getFromCache(CdmBase cdmBase, Class<? extends CdmBase> clazz) {
202
203 cdmBase = CdmBase.deproxy(cdmBase, clazz);
204 return getFromCache(cdmBase);
205 }
206
207 public List<CdmBase> getAllEntities() {
208 List<CdmBase> entities = new ArrayList<CdmBase>();
209 Map<String, CdmBase> elementsMap = getCache().getAllWithLoader(getCache().getKeys(), null);
210 for (Map.Entry<String, CdmBase> entry : elementsMap.entrySet()) {
211 entities.add(entry.getValue());
212 }
213 return entities;
214 }
215
216 public boolean exists(CdmEntityCacheKey key) {
217 return (getCacheElement(key) != null);
218 }
219
220 public boolean existsAndIsNotNull(CdmEntityCacheKey id) {
221 return getFromCache(id) != null;
222 }
223
224 public void clear() {
225 cache.removeAll();
226 }
227
228 public void dispose() {
229 cache.removeAll();
230 cache.flush();
231 CdmRemoteCacheManager.getInstance().getDefaultCacheManager().removeCache(cacheId);
232 }
233
234
235 public static CdmEntityCacheKey generateKey(Class<? extends CdmBase> clazz, int id) {
236 return new CdmEntityCacheKey(clazz, id);
237 }
238
239
240 public static CdmEntityCacheKey generateKey(CdmBase cdmBase) {
241 Class<? extends CdmBase> entityClass = cdmBase.getClass();
242 int id = cdmBase.getId();
243 return new CdmEntityCacheKey(entityClass, id);
244 }
245
246
247
248 }