Project

General

Profile

Download (7.09 KB) Statistics
| Branch: | Tag: | Revision:
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
}
(7-7/9)