View Javadoc

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   * Helper for building EhCache caches
19   *
20   * @since 2.0
21   */
22  class EhCacheHelper
23  {
24      // These are all the flags supported by RMICacheReplicatorFactory
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          //Create a Cache specifying its configuration.
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          // Cache should not be eternal if expiry has been set
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); // default to non-local as per API
113         return !isLocalCacheSetting && ehMgr.getCacheManagerPeerProvider("RMI") != null;
114     }
115 }