1 package com.atlassian.cache.ehcache;
2
3 import com.atlassian.cache.CacheSettings;
4 import net.sf.ehcache.CacheManager;
5 import net.sf.ehcache.Ehcache;
6 import net.sf.ehcache.config.CacheConfiguration;
7 import net.sf.ehcache.config.CacheConfiguration.CacheEventListenerFactoryConfiguration;
8 import net.sf.ehcache.config.PersistenceConfiguration;
9
10 import java.io.UnsupportedEncodingException;
11 import java.net.URLEncoder;
12
13 import static java.util.concurrent.TimeUnit.MILLISECONDS;
14 import static java.util.concurrent.TimeUnit.SECONDS;
15 import static net.sf.ehcache.config.PersistenceConfiguration.Strategy.NONE;
16
17
18
19
20
21
22 class EhCacheHelper
23 {
24
25 private static final String CACHE_PROPERTIES =
26 "replicateAsynchronously=%s," +
27 "replicatePuts=%s," +
28 "replicatePutsViaCopy=%s," +
29 "replicateUpdates=true," +
30 "replicateUpdatesViaCopy=%s," +
31 "replicateRemovals=true";
32
33 static final PersistenceConfiguration.Strategy PERSISTENCE_STRATEGY = NONE;
34
35 private static final PersistenceConfiguration PERSISTENCE_CONFIGURATION =
36 new PersistenceConfiguration().strategy(PERSISTENCE_STRATEGY);
37
38 private static final String URL_ENCODING = "UTF-8";
39
40 private static CacheEventListenerFactoryConfiguration getCacheEventListenerFactoryConfiguration(
41 final CacheSettings settings, final boolean selfLoading)
42 {
43 final boolean replicateAsynchronously = settings.getReplicateAsynchronously(false);
44 final boolean replicateViaCopy = settings.getReplicateViaCopy(false);
45 final boolean replicatePuts = !selfLoading;
46
47 final String cacheProperties =
48 String.format(CACHE_PROPERTIES, replicateAsynchronously, replicatePuts, replicateViaCopy, replicateViaCopy);
49 return new CacheEventListenerFactoryConfiguration()
50 .className(RMICacheReplicatorFactory.class.getName())
51 .properties(cacheProperties);
52 }
53
54 Ehcache getEhcache(final String name, final CacheManager ehMgr, final CacheSettings settings, final boolean selfLoading)
55 {
56
57 CacheConfiguration config = ehMgr.getConfiguration().getDefaultCacheConfiguration().clone()
58 .name(name)
59 .statistics(true)
60 .persistence(PERSISTENCE_CONFIGURATION);
61
62 final boolean replicateCache = isReplicateCache(ehMgr, settings);
63 if (replicateCache)
64 {
65 config.cacheEventListenerFactory(
66 getCacheEventListenerFactoryConfiguration(settings, selfLoading));
67 }
68
69 if (null != settings.getMaxEntries())
70 {
71 config.setMaxEntriesLocalHeap(settings.getMaxEntries());
72 }
73
74 if (null != settings.getExpireAfterAccess())
75 {
76 config.timeToIdleSeconds(SECONDS.convert(settings.getExpireAfterAccess(), MILLISECONDS));
77 }
78
79 if (null != settings.getExpireAfterWrite())
80 {
81 config.timeToLiveSeconds(SECONDS.convert(settings.getExpireAfterWrite(), MILLISECONDS));
82 }
83
84
85 if (settings.getExpireAfterAccess() != null || settings.getExpireAfterWrite() != null)
86 {
87 config.setEternal(false);
88 }
89
90 ehMgr.addCacheIfAbsent(new net.sf.ehcache.Cache(config));
91 return ehMgr.getCache(getCacheName(name, replicateCache));
92 }
93
94 private String getCacheName(final String name, final boolean replicateCache)
95 {
96 if (replicateCache)
97 {
98 try
99 {
100 return URLEncoder.encode(name, URL_ENCODING);
101 }
102 catch (final UnsupportedEncodingException e)
103 {
104 throw new IllegalStateException(e);
105 }
106 }
107 return name;
108 }
109
110 private boolean isReplicateCache(final CacheManager ehMgr, final CacheSettings settings)
111 {
112 final boolean isLocalCacheSetting = settings.getLocal(false);
113 return !isLocalCacheSetting && ehMgr.getCacheManagerPeerProvider("RMI") != null;
114 }
115 }