View Javadoc

1   package com.atlassian.cache.ehcache;
2   
3   import com.atlassian.cache.CacheLoader;
4   import com.atlassian.cache.CacheSettings;
5   import com.atlassian.cache.CacheSettingsBuilder;
6   import com.atlassian.cache.CachedReference;
7   import com.atlassian.cache.ManagedCache;
8   import com.atlassian.cache.impl.AbstractCacheManager;
9   import com.atlassian.cache.impl.StrongSupplier;
10  import com.atlassian.cache.impl.WeakSupplier;
11  import com.atlassian.cache.impl.jmx.MBeanRegistrar;
12  import com.atlassian.util.concurrent.Supplier;
13  import net.sf.ehcache.Ehcache;
14  import net.sf.ehcache.management.ManagementService;
15  
16  import javax.annotation.Nullable;
17  import javax.management.MBeanServer;
18  
19  /**
20   * Maintains a mapping of name -> Cache and provides factory methods for creating ad getting caches.
21   *
22   * @since 2.0
23   */
24  public class EhCacheManager extends AbstractCacheManager implements MBeanRegistrar
25  {
26      private net.sf.ehcache.CacheManager delegate;
27  
28      /**
29       * Creates an instance backed by a new instance of {@link net.sf.ehcache.CacheManager}.
30       */
31      public EhCacheManager()
32      {
33          this(net.sf.ehcache.CacheManager.create());
34      }
35  
36      /**
37       * Creates an instance backed by the provided instance of {@link net.sf.ehcache.CacheManager}.
38       *
39       * @param delegate an Ehcache's cache manager
40       */
41      public EhCacheManager(net.sf.ehcache.CacheManager delegate)
42      {
43          this.delegate = delegate;
44      }
45  
46      net.sf.ehcache.CacheManager getEh()
47      {
48          return delegate;
49      }
50  
51      @SuppressWarnings("unchecked")
52      @Override
53      public <V> CachedReference<V> getCachedReference(final String name,
54                                                       final com.atlassian.cache.Supplier<V> supplier,
55                                                       final CacheSettings settings)
56      {
57          // Force the cache settings to be flushable and a maximum size of one.
58          final CacheSettings overridenSettings = settings.override(
59                  new CacheSettingsBuilder().flushable().maxEntries(1).build());
60  
61          // If the cache already exists we aggressively remove it from EHCache,
62          // unless ReplicateViaCopy in which case we reuse it.
63          if (caches.containsKey(name))
64          {
65              if (settings.getReplicateViaCopy(false))
66              {
67                  Ehcache ehCache = delegate.getCache(name);
68                  DelegatingCachedReference cache = DelegatingCachedReference.create(ehCache, supplier, settings);
69                  caches.put(name,  new WeakSupplier<ManagedCache>(cache));
70                  return cache;
71              }
72              else
73              {
74                  delegate.removeCache(name);
75              }
76          }
77  
78          return cacheCreationLocks.get(name).withLock(new com.atlassian.util.concurrent.Supplier<DelegatingCachedReference<V>>()
79              {
80                  @Override
81                  public DelegatingCachedReference<V> get()
82                  {
83                      final Ehcache ehcache = createCache(name, overridenSettings, true);
84                      final DelegatingCachedReference<V> cache = DelegatingCachedReference.create(ehcache, supplier, overridenSettings);
85                      caches.put(name, new WeakSupplier<ManagedCache>(cache));
86                      return cache;
87                  }
88              });
89      }
90  
91      @Override
92      protected ManagedCache createSimpleCache(final String name, final CacheSettings settings)
93      {
94          final Supplier<ManagedCache> cacheSupplier = caches.get(name);
95          if (cacheSupplier != null)
96          {
97              ManagedCache cache = cacheSupplier.get();
98              if (cache != null)
99              {
100                 return cache;
101             }
102         }
103         return cacheCreationLocks.get(name).withLock(new com.atlassian.util.concurrent.Supplier<ManagedCache>()
104             {
105                 @Override
106                 public ManagedCache get()
107                 {
108                     if (!caches.containsKey(name))
109                     {
110                         final Ehcache simpleCache = createCache(name, settings, false);
111                         DelegatingCache cache = DelegatingCache.create(simpleCache, null, settings);
112                         caches.put(name,  new StrongSupplier<ManagedCache>(cache));
113                     }
114                     return  caches.get(name).get();
115                 }
116             });
117 
118     }
119 
120     @SuppressWarnings("unchecked")
121     protected <K, V> ManagedCache createComputingCache(final String name, final CacheSettings settings, final CacheLoader<K, V> loader)
122     {
123         // If the cache already exists we aggressively remove it from EHCache,
124         // unless ReplicateViaCopy in which case we reuse it.
125         if (caches.containsKey(name))
126         {
127             if (settings.getReplicateViaCopy(false))
128             {
129                 Ehcache delegateCache = delegate.getCache(name);
130                 DelegatingCache cache = DelegatingCache.create(delegateCache, loader, settings);
131                 caches.put(name,  new WeakSupplier<ManagedCache>(cache));
132                 return cache;
133             }
134             else
135             {
136                 delegate.removeCache(name);
137             }
138         }
139         return cacheCreationLocks.get(name).withLock(new com.atlassian.util.concurrent.Supplier<ManagedCache>()
140         {
141             @Override
142             public ManagedCache get()
143             {
144                 final Ehcache delegateCache = createCache(name, settings, true);
145                 DelegatingCache cache = DelegatingCache.create(delegateCache, loader, settings);
146                 caches.put(name,  new WeakSupplier<ManagedCache>(cache));
147                 return cache;
148             }
149         });
150     }
151 
152     private Ehcache createCache(String name, CacheSettings settings, boolean selfLoading)
153     {
154         return new EhCacheHelper().getEhcache(name, delegate, settings, selfLoading);
155     }
156 
157     @Override
158     public void registerMBeans(@Nullable final MBeanServer mBeanServer)
159     {
160         if (mBeanServer != null)
161         {
162             ManagementService.registerMBeans(delegate, mBeanServer, true, true, true, true);
163         }
164     }
165 
166 }