3 * Copyright (C) 2014 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.api
.cache
;
12 import java
.util
.ArrayList
;
13 import java
.util
.List
;
15 import java
.util
.UUID
;
17 import net
.sf
.ehcache
.Cache
;
18 import net
.sf
.ehcache
.Element
;
19 import net
.sf
.ehcache
.config
.CacheConfiguration
;
20 import net
.sf
.ehcache
.store
.MemoryStoreEvictionPolicy
;
22 import org
.apache
.log4j
.Logger
;
23 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
25 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
33 public class CdmTransientEntityCacher
extends CdmServiceCacher
{
35 private static final Logger logger
= Logger
.getLogger(CdmTransientEntityCacher
.class);
38 private CdmEntityCachingUtils cdmEntityCachingUtils
;
40 private String cacheId
;
44 private Cache cdmlibModelCache
;
46 private static boolean isRecursiveEnabled
;
48 public CdmTransientEntityCacher(String cacheId
) {
49 this.cacheId
= cacheId
;
50 // Create entity cache
51 cache
= new Cache(getEntityCacheConfiguration(cacheId
));
52 getDefaultCacheManager().addCache(cache
);
54 cdmlibModelCache
= CdmRemoteCacheManager
.getInstance().getCdmModelGetMethodsCache();
58 public CdmTransientEntityCacher(Object obj
) {
59 this(obj
.getClass().getName() + String
.valueOf(obj
.hashCode()));
63 * Returns the default cache configuration.
67 private CacheConfiguration
getEntityCacheConfiguration(String cacheId
) {
68 // For a better understanding on how to size caches, refer to
69 // http://ehcache.org/documentation/configuration/cache-size
70 return new CacheConfiguration(cacheId
, 500)
71 .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy
.LFU
)
73 // default ttl and tti set to 2 hours
74 .timeToLiveSeconds(60*60*2)
75 .timeToIdleSeconds(60*60*2);
78 //.maxEntriesLocalDisk(1000);
79 //.persistence(new PersistenceConfiguration().strategy(Strategy.LOCALTEMPSWAP));
84 * Returns the cache corresponding to the cache id
89 private Cache
getCache() {
90 return getDefaultCacheManager().getCache(cacheId
);
95 * Puts the (Key,Value) pair of ({@link java.util.UUID}, {@link eu.etaxonomy.cdm.model.common.CdmBase}),
96 * in the cache corresponding to the given cache id
102 public CdmBase
load(CdmBase cdmEntity
, boolean recursive
) {
103 CdmEntityCacheKey id
= new CdmEntityCacheKey(cdmEntity
);
104 // first look in 'this' cache
105 CdmBase cachedCdmEntity
= getFromCache(id
);
107 if(cachedCdmEntity
== null) {
108 // then try the permanent (uuid-based) cache
109 cachedCdmEntity
= getFromCache(cdmEntity
.getUuid());
111 if(isRecursiveEnabled
&& recursive
) {
112 String className
= cdmEntity
.getClass().getName();
113 CdmModelGetMethodFromClass cmgmfc
= getFromCdmlibModelCache(className
);
115 List
<String
> getMethods
= cmgmfc
.getGetMethods();
118 if(cachedCdmEntity
!= null) {
119 return cachedCdmEntity
;
121 getCache().put(new Element(id
, cdmEntity
));
126 public void put(CdmBase cdmEntity
) {
127 CdmEntityCacheKey id
= new CdmEntityCacheKey(cdmEntity
);
128 Element cachedCdmEntityElement
= getCacheElement(id
);
130 if(cachedCdmEntityElement
== null) {
131 cachedCdmEntityElement
= getCacheElement(cdmEntity
.getUuid());
132 if(cachedCdmEntityElement
!= null) {
133 logger
.info("Cdm Entity with id : " + cdmEntity
.getId() + " already exists in permanent cache. Ignoring put.");
138 getCache().put(new Element(id
, cdmEntity
));
142 private Element
getCacheElement(CdmEntityCacheKey key
) {
143 return getCache().get(key
);
146 public CdmModelGetMethodFromClass
getFromCdmlibModelCache(String className
) {
147 Element e
= cdmlibModelCache
.get(className
);
151 return (CdmModelGetMethodFromClass
) e
.getObjectValue();
155 public CdmBase
getFromCache(CdmEntityCacheKey id
) {
156 Element e
= getCacheElement(id
);
160 return (CdmBase
) e
.getObjectValue();
164 public CdmBase
getFromCache(Class
<?
extends CdmBase
> clazz
, int id
) {
165 CdmEntityCacheKey cacheId
= generateKey(clazz
,id
);
166 return getFromCache(cacheId
);
169 public CdmBase
getFromCache(CdmBase cdmBase
) {
170 CdmEntityCacheKey cacheId
= generateKey(cdmBase
);
171 return getFromCache(cacheId
);
174 public List
<CdmBase
> getAllEntities() {
175 List
<CdmBase
> entities
= new ArrayList
<CdmBase
>();
176 Map
<String
, CdmBase
> elementsMap
= getCache().getAllWithLoader(getCache().getKeys(), null);
177 for (Map
.Entry
<String
, CdmBase
> entry
: elementsMap
.entrySet()) {
178 entities
.add(entry
.getValue());
187 * @see eu.etaxonomy.cdm.model.ICdmCacher#exists(java.util.UUID)
190 public boolean exists(UUID uuid
) {
191 return (getCacheElement(uuid
) != null || super.getCacheElement(uuid
) != null);
194 public boolean exists(CdmEntityCacheKey key
) {
195 return (getCacheElement(key
) != null);
200 * @see eu.etaxonomy.cdm.model.ICdmCacher#existsAndIsNotNull(java.util.UUID)
203 public boolean existsAndIsNotNull(UUID uuid
) {
204 return getFromCache(uuid
) != null;
207 public boolean existsAndIsNotNull(CdmEntityCacheKey id
) {
208 return getFromCache(id
) != null;
212 public static CdmEntityCacheKey
generateKey(Class
<?
extends CdmBase
> clazz
, int id
) {
213 return new CdmEntityCacheKey(clazz
, id
);
217 public static CdmEntityCacheKey
generateKey(CdmBase cdmBase
) {
218 Class
<?
extends CdmBase
> entityClass
= cdmBase
.getClass();
219 int id
= cdmBase
.getId();
220 return new CdmEntityCacheKey(entityClass
, id
);
223 public static boolean isRecursiveEnabled() {
224 return isRecursiveEnabled
;
227 public static void setRecursiveEnabled(boolean ire
) {
228 isRecursiveEnabled
= ire
;