View Javadoc

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