1 package com.atlassian.cache.ehcache;
2
3 import java.util.Collection;
4 import java.util.SortedMap;
5
6 import javax.annotation.Nonnull;
7 import javax.annotation.Nullable;
8
9 import com.atlassian.cache.Cache;
10 import com.atlassian.cache.CacheEntryListener;
11 import com.atlassian.cache.CacheException;
12 import com.atlassian.cache.CacheSettings;
13 import com.atlassian.cache.CacheStatisticsKey;
14 import com.atlassian.util.concurrent.Supplier;
15
16 import com.atlassian.cache.impl.CacheEntryListenerSupport;
17 import com.atlassian.cache.impl.LazyCacheEntryListenerSupport;
18 import net.sf.ehcache.Ehcache;
19 import net.sf.ehcache.Element;
20 import net.sf.ehcache.event.CacheEventListener;
21
22 import static com.atlassian.cache.ehcache.DelegatingCacheStatistics.toStatistics;
23
24
25
26
27
28
29 class DelegatingCache<K, V> extends ManagedCacheSupport implements Cache<K, V>
30 {
31 private final Ehcache delegate;
32
33 private final CacheEntryListenerSupport<K, V> listenerSupport = new LazyCacheEntryListenerSupport<K, V>()
34 {
35 @Override
36 protected void init() {
37 delegate.getCacheEventNotificationService().registerListener(new DelegatingCacheEventListener());
38 }
39 };
40
41 private DelegatingCache(final Ehcache delegate, CacheSettings settings)
42 {
43 super(delegate, settings);
44 this.delegate = delegate;
45 }
46
47 static <K, V> DelegatingCache<K, V> create(final Ehcache delegate, CacheSettings settings)
48 {
49 return new DelegatingCache<K, V>(delegate, settings);
50 }
51
52 @Override
53 public boolean containsKey(@Nonnull K key)
54 {
55 return delegate.isKeyInCache(key);
56 }
57
58 @Nonnull
59 @SuppressWarnings("unchecked")
60 @Override
61 public Collection<K> getKeys()
62 {
63 try
64 {
65 return delegate.getKeys();
66 }
67 catch (Exception e)
68 {
69 throw new CacheException(e);
70 }
71 }
72
73 @Override
74 public void put(@Nonnull final K key, @Nonnull final V value)
75 {
76 try
77 {
78 delegate.put(new Element(key, value));
79 }
80 catch (Exception e)
81 {
82 throw new CacheException(e);
83 }
84 }
85
86 @SuppressWarnings("unchecked")
87 @Nullable
88 @Override
89 public V get(@Nonnull final K key)
90 {
91 try
92 {
93 Element element = delegate.get(key);
94 return element == null ? null : (V) element.getObjectValue();
95 }
96 catch (net.sf.ehcache.CacheException e)
97 {
98 throw new CacheException(e.getCause());
99 }
100 catch (Exception e)
101 {
102 throw new CacheException(e);
103 }
104 }
105
106 @Override
107 public void remove(@Nonnull final K key)
108 {
109 try
110 {
111 delegate.remove(key);
112 }
113 catch (Exception e)
114 {
115 throw new CacheException(e);
116 }
117 }
118
119 @Override
120 public void removeAll()
121 {
122 try
123 {
124 delegate.removeAll();
125 }
126 catch (Exception e)
127 {
128 throw new CacheException(e);
129 }
130 }
131
132 @Override
133 public void clear()
134 {
135 removeAll();
136 }
137
138 @Nullable
139 @Override
140 @SuppressWarnings("unchecked")
141 public V putIfAbsent(@Nonnull K key, @Nonnull V value)
142 {
143 try
144 {
145 Element previous = delegate.putIfAbsent(new Element(key, value));
146 if (previous != null)
147 {
148 return (V) previous.getObjectValue();
149 }
150 else
151 {
152 return null;
153 }
154 }
155 catch (Exception e)
156 {
157 throw new CacheException(e);
158 }
159 }
160
161 @Override
162 public boolean remove(@Nonnull K key, @Nonnull V value)
163 {
164 try
165 {
166 return delegate.removeElement(new Element(key, value));
167 }
168 catch (Exception e)
169 {
170 throw new CacheException(e);
171 }
172 }
173
174 @Override
175 public boolean replace(@Nonnull K key, @Nonnull V oldValue, @Nonnull V newValue)
176 {
177 try
178 {
179 return delegate.replace(new Element(key, oldValue), new Element(key, newValue));
180 }
181 catch (Exception e)
182 {
183 throw new CacheException(e);
184 }
185 }
186
187 @Nonnull
188 @Override
189 public SortedMap<CacheStatisticsKey,Supplier<Long>> getStatistics()
190 {
191 return toStatistics(delegate.getStatistics());
192 }
193
194 @Override
195 public boolean equals(@Nullable final Object other)
196 {
197 if (other instanceof DelegatingCache)
198 {
199 DelegatingCache<?,?> otherDelegatingCache = (DelegatingCache<?,?>)other;
200 if (delegate.equals(otherDelegatingCache.delegate))
201 {
202 return true;
203 }
204 }
205 return false;
206 }
207
208 @Override
209 public int hashCode()
210 {
211 return 3 + delegate.hashCode();
212 }
213
214 @Override
215 public void addListener(@Nonnull CacheEntryListener<K, V> listener, boolean includeValues)
216 {
217 listenerSupport.add(listener, includeValues);
218 }
219
220 @Override
221 public void removeListener(@Nonnull CacheEntryListener<K, V> listener)
222 {
223 listenerSupport.remove(listener);
224 }
225
226 private class DelegatingCacheEventListener implements CacheEventListener
227 {
228 @Override
229 public void notifyElementRemoved(Ehcache ehcache, Element element) throws net.sf.ehcache.CacheException
230 {
231 listenerSupport.notifyRemove((K) element.getObjectKey(), (V) element.getObjectValue());
232 }
233
234 @Override
235 public void notifyElementPut(Ehcache ehcache, Element element) throws net.sf.ehcache.CacheException
236 {
237 listenerSupport.notifyAdd((K) element.getObjectKey(), (V) element.getObjectValue());
238 }
239
240 @Override
241 public void notifyElementUpdated(Ehcache ehcache, Element element) throws net.sf.ehcache.CacheException
242 {
243 listenerSupport.notifyUpdate((K) element.getObjectKey(), (V) element.getObjectValue(), null);
244 }
245
246 @Override
247 public void notifyElementExpired(Ehcache ehcache, Element element)
248 {
249 listenerSupport.notifyEvict((K) element.getObjectKey(), (V) element.getObjectValue());
250 }
251
252 @Override
253 public void notifyElementEvicted(Ehcache ehcache, Element element)
254 {
255 listenerSupport.notifyEvict((K) element.getObjectKey(), (V) element.getObjectValue());
256 }
257
258 @Override
259 public void notifyRemoveAll(Ehcache ehcache)
260 {
261
262
263 }
264
265 @Override
266 public void dispose()
267 {
268
269 }
270
271 public Object clone() throws CloneNotSupportedException
272 {
273 throw new CloneNotSupportedException();
274 }
275 }
276 }