Project

General

Profile

Download (5.62 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
public abstract class CdmCacherBase implements ICdmUuidCacher {
24

    
25
    public static final Logger logger = Logger.getLogger(CdmCacherBase.class);
26

    
27
    @Autowired
28
    public CacheManager cacheManager;
29

    
30
    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

    
32
    /**
33
     * Constructor which initializes a singleton {@link net.sf.ehcache.CacheManager}
34
     */
35
    public CdmCacherBase() {
36
        init();
37
    }
38

    
39
    /**
40
     * Initializes an empty singleton {@link net.sf.ehcache.CacheManager} and
41
     * 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
    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

    
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

    
69
        CacheConfiguration cc = new CacheConfiguration(DEFAULT_CACHE_NAME, 500)
70
                .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

    
77
        return cc;
78
    }
79

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

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

    
101
    /**
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

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

    
116
    @Override
117
    public CdmBase load(UUID uuid) {
118
        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
    public  CdmBase getFromCache(UUID uuid) {
140
        Element e = getCacheElement(uuid);
141
        if (e == null) {
142
            return null;
143
        } else {
144
            return(CdmBase)e.getObjectValue();
145
        }
146
    }
147

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

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

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

    
163

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

    
169
    @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
    public boolean existsAndIsNotNull(UUID uuid) {
179
        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

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