1 package com.atlassian.cache.ehcache;
2
3 import javax.annotation.Nonnull;
4 import javax.annotation.Nullable;
5 import javax.annotation.ParametersAreNonnullByDefault;
6 import javax.management.MBeanServer;
7
8 import com.atlassian.cache.CacheLoader;
9 import com.atlassian.cache.CacheSettings;
10 import com.atlassian.cache.CacheSettingsBuilder;
11 import com.atlassian.cache.CacheSettingsDefaultsProvider;
12 import com.atlassian.cache.CachedReference;
13 import com.atlassian.cache.ManagedCache;
14 import com.atlassian.cache.ehcache.replication.EhCacheReplicatorConfigFactory;
15 import com.atlassian.cache.ehcache.replication.rmi.RMICacheReplicatorConfigFactory;
16 import com.atlassian.cache.impl.AbstractCacheManager;
17 import com.atlassian.cache.impl.ReferenceKey;
18 import com.atlassian.cache.impl.StrongSupplier;
19 import com.atlassian.cache.impl.WeakSupplier;
20 import com.atlassian.cache.impl.jmx.MBeanRegistrar;
21 import com.atlassian.util.concurrent.Supplier;
22
23 import net.sf.ehcache.Ehcache;
24 import net.sf.ehcache.management.ManagementService;
25
26
27
28
29
30
31 @ParametersAreNonnullByDefault
32 public class EhCacheManager extends AbstractCacheManager implements MBeanRegistrar
33 {
34 private final net.sf.ehcache.CacheManager delegate;
35 private final @Nullable
36 EhCacheReplicatorConfigFactory replicatorConfigFactory;
37
38 private boolean statisticsEnabled = true;
39
40
41
42
43
44
45 @Deprecated
46 public EhCacheManager()
47 {
48 this(net.sf.ehcache.CacheManager.create(), null);
49 }
50
51
52
53
54
55
56
57
58 @Deprecated
59 public EhCacheManager(net.sf.ehcache.CacheManager delegate, @Nullable CacheSettingsDefaultsProvider cacheSettingsDefaultsProvider)
60 {
61 this(delegate, new RMICacheReplicatorConfigFactory(), cacheSettingsDefaultsProvider);
62 }
63
64
65
66
67
68
69 public EhCacheManager(net.sf.ehcache.CacheManager delegate, @Nullable EhCacheReplicatorConfigFactory replicatorConfigFactory, @Nullable CacheSettingsDefaultsProvider cacheSettingsDefaultsProvider)
70 {
71 super(cacheSettingsDefaultsProvider);
72 this.delegate = delegate;
73 this.replicatorConfigFactory = replicatorConfigFactory;
74 }
75
76 net.sf.ehcache.CacheManager getEh()
77 {
78 return delegate;
79 }
80
81 public boolean isStatisticsEnabled()
82 {
83 return statisticsEnabled;
84 }
85
86 public void setStatisticsEnabled(final boolean statisticsEnabled)
87 {
88 this.statisticsEnabled = statisticsEnabled;
89 }
90
91 @Nonnull
92 @SuppressWarnings("unchecked")
93 @Override
94 public <V> CachedReference<V> getCachedReference(@Nonnull final String name,
95 @Nonnull final com.atlassian.cache.Supplier<V> supplier,
96 @Nonnull final CacheSettings settings)
97 {
98
99 final CacheSettings overridenSettings = settings.override(
100 new CacheSettingsBuilder().flushable().maxEntries(1).build());
101
102 return cacheCreationLocks.get(name).withLock(new com.atlassian.util.concurrent.Supplier<DelegatingCachedReference<V>>()
103 {
104 @Override
105 public DelegatingCachedReference<V> get()
106 {
107 Ehcache ehCache = getCleanCache(name, overridenSettings);
108 final Ehcache spCache = new LoadingCache<ReferenceKey,V>(ehCache, new SupplierAdapter<V>(supplier));
109 final DelegatingCachedReference<V> cache = DelegatingCachedReference.create(spCache, overridenSettings);
110 caches.put(name, new WeakSupplier<ManagedCache>(cache));
111 return cache;
112 }
113 });
114 }
115
116 @Override
117 protected ManagedCache createSimpleCache(@Nonnull final String name, @Nonnull final CacheSettings settings)
118 {
119 final Supplier<ManagedCache> cacheSupplier = caches.get(name);
120 if (cacheSupplier != null)
121 {
122 ManagedCache cache = cacheSupplier.get();
123 if (cache != null)
124 {
125 return cache;
126 }
127
128 return createManagedCacheInternal(name, settings);
129 }
130 return createManagedCacheInternal(name, settings);
131
132 }
133
134 private ManagedCache createManagedCacheInternal(@Nonnull final String name, @Nonnull final CacheSettings settings) {
135 return cacheCreationLocks.get(name).withLock(new Supplier<ManagedCache>()
136 {
137 @Override
138 public ManagedCache get()
139 {
140 final ManagedCache result = caches.get(name) == null ? null : caches.get(name).get();
141 if (null == result)
142 {
143 final Ehcache simpleCache = createCache(name, settings, false);
144 DelegatingCache<?,?> cache = DelegatingCache.create(simpleCache, settings);
145 caches.put(name, new StrongSupplier<ManagedCache>(cache));
146 return cache;
147 }
148 return result;
149 }
150 });
151 }
152
153 @SuppressWarnings("unchecked")
154 protected <K, V> ManagedCache createComputingCache(@Nonnull final String name, @Nonnull final CacheSettings settings, final CacheLoader<K, V> loader)
155 {
156 return cacheCreationLocks.get(name).withLock(new com.atlassian.util.concurrent.Supplier<ManagedCache>()
157 {
158 @Override
159 public ManagedCache get()
160 {
161 Ehcache ehCache = getCleanCache(name, settings);
162 Ehcache spCache = new LoadingCache(ehCache, loader);
163 DelegatingCache<K,V> cache = DelegatingCache.create(spCache, settings);
164 caches.put(name, new WeakSupplier<ManagedCache>(cache));
165 return cache;
166 }
167 });
168 }
169
170 private Ehcache getCleanCache(final String name, final CacheSettings settings)
171 {
172
173
174
175
176
177 Ehcache ehCache = delegate.getCache(name);
178 if (ehCache != null)
179 {
180
181 ehCache.removeAll(true);
182 }
183 else
184 {
185 ehCache = createCache(name, settings, true);
186 }
187 return ehCache;
188 }
189
190 private Ehcache createCache(String name, CacheSettings settings, boolean selfLoading)
191 {
192 return new EhCacheHelper(replicatorConfigFactory).getEhcache(name, delegate, settings, selfLoading, statisticsEnabled);
193 }
194
195 @Override
196 public void shutdown()
197 {
198
199 delegate.shutdown();
200 }
201
202 @Override
203 public void registerMBeans(@Nullable final MBeanServer mBeanServer)
204 {
205 if (mBeanServer != null)
206 {
207 ManagementService.registerMBeans(delegate, mBeanServer, true, true, true, true);
208 }
209 }
210
211 @Override
212 public void unregisterMBeans(@Nullable final MBeanServer mBeanServer)
213 {
214 if (mBeanServer != null)
215 {
216 final ManagementService managementService = new ManagementService(delegate, mBeanServer, true, true, true, true);
217 managementService.dispose();
218 }
219 }
220
221 static class SupplierAdapter<V> implements CacheLoader<ReferenceKey, V>
222 {
223 private final com.atlassian.cache.Supplier<V> supplier;
224
225 SupplierAdapter(com.atlassian.cache.Supplier<V> supplier)
226 {
227 this.supplier = supplier;
228 }
229
230 @Nonnull
231 @Override
232 public V load(@Nonnull ReferenceKey key)
233 {
234 return supplier.get();
235 }
236 }
237 }