Project

General

Profile

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

    
3
import java.util.UUID;
4

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

    
9
import eu.etaxonomy.cdm.model.ICdmUuidCacher;
10
import eu.etaxonomy.cdm.model.common.CdmBase;
11
import net.sf.ehcache.Cache;
12
import net.sf.ehcache.CacheManager;
13
import net.sf.ehcache.Element;
14
import net.sf.ehcache.config.CacheConfiguration;
15
import net.sf.ehcache.config.CacheConfiguration.CacheEventListenerFactoryConfiguration;
16
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
17

    
18
/**
19
 * CDM Entity Cacher class based on EhCache using UUID as key.
20
 * The cacher allows null values to be cached.
21
 *
22
 * @author cmathew
23
 */
24
public abstract class CdmCacherBase implements ICdmUuidCacher {
25

    
26
    public static final Logger logger = LogManager.getLogger(CdmCacherBase.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 initializes a singleton {@link net.sf.ehcache.CacheManager}
35
     */
36
    public CdmCacherBase() {
37
        init();
38
    }
39

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

    
48
    protected abstract void setup();
49

    
50
    /**
51
     * Returns the singleton default cache manager.
52
     */
53
    public void addCacheManager(CacheManager cacheManager) {
54

    
55
        if(this.cacheManager == null){
56
            this.cacheManager = cacheManager;
57
        } else {
58
            logger.error("There is already a CacheManager configured.");
59
        }
60
    }
61

    
62
    /**
63
     * Returns the default cache configuration.
64
     */
65
    protected CacheConfiguration getDefaultCacheConfiguration() {
66
        CacheEventListenerFactoryConfiguration factory;
67
        // For a better understanding on how to size caches, refer to
68
        // http://ehcache.org/documentation/configuration/cache-size
69

    
70
        CacheConfiguration cc = new CacheConfiguration(DEFAULT_CACHE_NAME, 500)
71
                .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LFU)
72
                .eternal(false)
73
                // default ttl and tti set to 2 hours
74
                .timeToLiveSeconds(60*60*2)
75
                .timeToIdleSeconds(60*60*2)
76
                .statistics(true);
77

    
78
        return cc;
79
    }
80

    
81
    /**
82
     * Returns the default cache
83
     *
84
     * @return
85
     */
86
    public Cache getDefaultCache() {
87
        Cache defaultCache = cacheManager.getCache(DEFAULT_CACHE_NAME);
88
        if(defaultCache == null) {
89
            // Create default cache
90
            cacheManager.addCache(DEFAULT_CACHE_NAME);
91
            defaultCache = cacheManager.getCache(DEFAULT_CACHE_NAME);
92
            //FIXME write test to check if default config as defined in EhCacheConfiguration is being used
93
        }
94
        return defaultCache;
95
    }
96

    
97
    @Override
98
    public void dispose(){
99
        cacheManager.getCache(DEFAULT_CACHE_NAME).dispose();
100
    }
101

    
102
    /**
103
     * Gets the cache element corresponding to the given {@link java.util.UUID}
104
     */
105
    public Element getCacheElement(UUID uuid) {
106
        return getDefaultCache().get(uuid);
107
    }
108

    
109
    @Override
110
    public  void put(UUID uuid, CdmBase cdmEntity) {
111
        CdmBase cachedCdmEntity = getFromCache(uuid);
112
        if(cachedCdmEntity == null) {
113
            getDefaultCache().put(new Element(uuid, cdmEntity));
114
        }
115
    }
116

    
117
    @Override
118
    public CdmBase load(UUID uuid) {
119
        Element e = getCacheElement(uuid);
120

    
121
        CdmBase cdmEntity;
122
        if (e == null) {
123
            // nothing in the cache for "key" (or expired) ... re-load the entity
124
            cdmEntity = findByUuid(uuid);
125
            // currently default cache is a non-null cache
126
            // We would like to have the possibility to put null values in the cache,
127
            // but we need to first distinguish between real null values and null values
128
            // returned by the service is the type of class does not match
129
            if(cdmEntity != null) {
130
                put(uuid, cdmEntity);
131
            }
132
        } else {
133
            // there is a valid element in the cache, however getObjectValue() may be null
134
            cdmEntity = (CdmBase)e.getObjectValue();
135
        }
136
        return cdmEntity;
137
    }
138

    
139
    @Override
140
    public  CdmBase getFromCache(UUID uuid) {
141
        Element e = getCacheElement(uuid);
142
        if (e == null) {
143
            return null;
144
        } else {
145
            return(CdmBase)e.getObjectValue();
146
        }
147
    }
148

    
149
    @Override
150
    public <T extends CdmBase> T getFromCache(T cdmBase) {
151
        return (T)getFromCache(cdmBase.getUuid());
152
    }
153

    
154
    @Override
155
    public void putToCache(CdmBase cdmEntity) {
156
        if(cdmEntity != null) {
157
            put(cdmEntity.getUuid(), cdmEntity);
158
        }
159
    }
160

    
161
    @Override
162
    public abstract <T extends CdmBase> T load(T cdmEntity);
163

    
164

    
165
    @Override
166
    public boolean exists(UUID uuid) {
167
        return getCacheElement(uuid) != null;
168
    }
169

    
170
    @Override
171
    public boolean exists(CdmBase cdmBase) {
172
        if(cdmBase != null) {
173
            return exists(cdmBase.getUuid());
174
        }
175
        return false;
176
    }
177

    
178
    @Override
179
    public boolean existsAndIsNotNull(UUID uuid) {
180
        Element e = getCacheElement(uuid);
181
        if (e != null) {
182
            return e.getObjectValue() != null;
183
        }
184
        return false;
185
    }
186

    
187
    /**
188
     * Finds CDM Entity by uuid
189
     */
190
    protected abstract CdmBase findByUuid(UUID uuid);
191

    
192
    @Override
193
    public boolean ignoreRecursiveLoad(CdmBase cdmBase){
194
        return false;
195
    }
196
}
(1-1/2)