Project

General

Profile

Download (5.67 KB) Statistics
| Branch: | Tag: | Revision:
1
package eu.etaxonomy.cdm.api.cache;
2

    
3
import java.util.UUID;
4

    
5
import org.apache.log4j.Logger;
6
import org.springframework.beans.factory.annotation.Autowired;
7

    
8
import eu.etaxonomy.cdm.model.ICdmUuidCacher;
9
import eu.etaxonomy.cdm.model.common.CdmBase;
10
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
import net.sf.ehcache.config.CacheConfiguration.CacheEventListenerFactoryConfiguration;
15
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
16

    
17
/**
18
 * CDM Entity Cacher class based on EhCache using UUID as key.
19
 * The cacher allows null values to be cached.
20
 *
21
 * @author cmathew
22
 */
23

    
24
public abstract class CdmCacher implements ICdmUuidCacher {
25

    
26
    public static final Logger logger = Logger.getLogger(CdmCacher.class);
27

    
28
    @Autowired
29
    public CacheManager cacheManager;
30

    
31
    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?
32

    
33
    /**
34
     * Constructor which initialises a singleton {@link net.sf.ehcache.CacheManager}
35
     *
36
     */
37
    public CdmCacher() {
38
        init();
39
    }
40

    
41
    /**
42
     * Initialises an empty singleton {@link net.sf.ehcache.CacheManager} and
43
     * sets itself as the cacher object in specific CDM Entity objects.
44
     *
45
     */
46
    private void init() {
47
        setup();
48
    }
49

    
50
    protected abstract void setup();
51

    
52
    /**
53
     * Returns the singleton default cache manager.
54
     * @param conf
55
     *
56
     * @return
57
     */
58
    public void addCacheManager(CacheManager cacheManager) {
59

    
60
        if(this.cacheManager == null){
61
            this.cacheManager = cacheManager;
62
        } else {
63
            logger.error("There is already a CacheManager configured.");
64
        }
65
    }
66

    
67
    /**
68
     * Returns the default cache configuration.
69
     *
70
     * @return
71
     */
72
    protected CacheConfiguration getDefaultCacheConfiguration() {
73
        CacheEventListenerFactoryConfiguration factory;
74
        // For a better understanding on how to size caches, refer to
75
        // http://ehcache.org/documentation/configuration/cache-size
76

    
77
        CacheConfiguration cc = new CacheConfiguration(DEFAULT_CACHE_NAME, 500)
78
                .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LFU)
79
                .eternal(false)
80
                // default ttl and tti set to 2 hours
81
                .timeToLiveSeconds(60*60*2)
82
                .timeToIdleSeconds(60*60*2)
83
                .statistics(true);
84

    
85
        return cc;
86
    }
87

    
88
    /**
89
     * Returns the default cache
90
     *
91
     * @return
92
     */
93
    public Cache getDefaultCache() {
94
        Cache defaultCache = cacheManager.getCache(DEFAULT_CACHE_NAME);
95
        if(defaultCache == null) {
96
            // Create default cache
97
            cacheManager.addCache(DEFAULT_CACHE_NAME);
98
            defaultCache = cacheManager.getCache(DEFAULT_CACHE_NAME);
99
            //FIXME write test to check if default config as defined in EhCacheConfiguration is being used
100
        }
101
        return defaultCache;
102
    }
103

    
104
    @Override
105
    public void dispose(){
106
        cacheManager.getCache(DEFAULT_CACHE_NAME).dispose();
107
    }
108

    
109
    /**
110
     * Gets the cache element corresponding to the given {@link java.util.UUID}
111
     *
112
     * @param uuid
113
     * @return
114
     */
115
    public Element getCacheElement(UUID uuid) {
116
        return getDefaultCache().get(uuid);
117
    }
118

    
119
    @Override
120
    public  void put(UUID uuid, CdmBase cdmEntity) {
121
        CdmBase cachedCdmEntity = getFromCache(uuid);
122
        if(cachedCdmEntity == null) {
123
            getDefaultCache().put(new Element(uuid, cdmEntity));
124
        }
125
    }
126

    
127
    @Override
128
    public CdmBase load(UUID uuid) {
129
        Element e = getCacheElement(uuid);
130

    
131
        CdmBase cdmEntity;
132
        if (e == null) {
133
            // nothing in the cache for "key" (or expired) ... re-load the entity
134
            cdmEntity = findByUuid(uuid);
135
            // currently default cache is a non-null cache
136
            // We would like to have the possibility to put null values in the cache,
137
            // but we need to first distinguish between real null values and null values
138
            // returned by the service is the type of class does not match
139
            if(cdmEntity != null) {
140
                put(uuid, cdmEntity);
141
            }
142
        } else {
143
            // there is a valid element in the cache, however getObjectValue() may be null
144
            cdmEntity = (CdmBase)e.getObjectValue();
145
        }
146
        return cdmEntity;
147
    }
148

    
149

    
150
    @Override
151
    public  CdmBase getFromCache(UUID uuid) {
152
        Element e = getCacheElement(uuid);
153
        if (e == null) {
154
            return null;
155
        } else {
156
            return(CdmBase)e.getObjectValue();
157
        }
158
    }
159

    
160
    @Override
161
    public <T extends CdmBase> T getFromCache(T cdmBase) {
162
        return (T) getFromCache(cdmBase.getUuid());
163
    }
164

    
165

    
166
    @Override
167
    public void put(CdmBase cdmEntity) {
168
        if(cdmEntity != null) {
169
            put(cdmEntity.getUuid(), cdmEntity);
170
        }
171
    }
172

    
173
    @Override
174
    public abstract <T extends CdmBase> T load(T cdmEntity);
175

    
176

    
177
    @Override
178
    public boolean exists(UUID uuid) {
179
        return getCacheElement(uuid) != null;
180
    }
181

    
182
    @Override
183
    public boolean exists(CdmBase cdmBase) {
184
        if(cdmBase != null) {
185
            return exists(cdmBase.getUuid());
186
        }
187
        return false;
188

    
189
    }
190

    
191
    @Override
192
    public boolean existsAndIsNotNull(UUID uuid) {
193
        Element e = getCacheElement(uuid);
194
        if (e != null) {
195
            return e.getObjectValue() != null;
196
        }
197
        return false;
198
    }
199

    
200
    /**
201
     * Finds CDM Entity by uuid
202
     *
203
     * @param uuid
204
     * @return
205
     */
206
    protected abstract CdmBase findByUuid(UUID uuid);
207

    
208
}
(1-1/2)