1 package com.atlassian.cache.ehcache;
2
3 import java.util.SortedMap;
4
5 import javax.annotation.Nonnull;
6 import javax.annotation.Nullable;
7
8 import com.atlassian.cache.CacheException;
9 import com.atlassian.cache.CacheSettings;
10 import com.atlassian.cache.CacheStatisticsKey;
11 import com.atlassian.cache.CachedReference;
12 import com.atlassian.cache.CachedReferenceListener;
13 import com.atlassian.cache.impl.CachedReferenceListenerSupport;
14 import com.atlassian.cache.impl.LazyCachedReferenceListenerSupport;
15 import com.atlassian.cache.impl.ReferenceKey;
16 import com.atlassian.util.concurrent.Supplier;
17
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 DelegatingCachedReference<V> extends ManagedCacheSupport implements CachedReference<V>
30 {
31 private final Ehcache delegate;
32 private final CachedReferenceListenerSupport<V> listenerSupport = new LazyCachedReferenceListenerSupport<V>()
33 {
34 @Override
35 protected void init()
36 {
37 delegate.getCacheEventNotificationService().registerListener(new DelegatingReferenceCacheEventListener());
38 }
39 };
40
41 private DelegatingCachedReference(final Ehcache delegate, CacheSettings settings)
42 {
43 super(delegate, settings);
44 this.delegate = delegate;
45 }
46
47 static <V> DelegatingCachedReference<V> create(final Ehcache delegate, CacheSettings settings)
48 {
49 return new DelegatingCachedReference<V>(delegate, settings);
50 }
51
52 @Nonnull
53 @SuppressWarnings("unchecked")
54 @Override
55 public V get()
56 {
57 try
58 {
59 Element element = delegate.get(ReferenceKey.KEY);
60 return element == null ? null : (V) element.getObjectValue();
61 }
62 catch (net.sf.ehcache.CacheException e)
63 {
64 throw new CacheException(e.getCause());
65 }
66 catch (Exception e)
67 {
68 throw new CacheException(e);
69 }
70 }
71
72 @Override
73 public void reset()
74 {
75 try
76 {
77 try
78 {
79 delegate.get(ReferenceKey.KEY);
80 }
81 finally
82 {
83 delegate.remove(ReferenceKey.KEY);
84 }
85 }
86 catch (Exception e)
87 {
88 throw new CacheException(e);
89 }
90 }
91
92 @Override
93 public void clear()
94 {
95 reset();
96 }
97
98 public boolean equals(@Nullable final Object other)
99 {
100 if (other instanceof DelegatingCachedReference)
101 {
102 DelegatingCachedReference<?> otherDelegatingReference = (DelegatingCachedReference<?>) other;
103 if (delegate.equals(otherDelegatingReference.delegate))
104 {
105 return true;
106 }
107 }
108 return false;
109 }
110
111 @Override
112 public int hashCode()
113 {
114 return 3 + delegate.hashCode();
115 }
116
117 @Nonnull
118 @Override
119 public SortedMap<CacheStatisticsKey,Supplier<Long>> getStatistics()
120 {
121 return toStatistics(delegate.getStatistics());
122 }
123
124 @Override
125 public void addListener(@Nonnull CachedReferenceListener<V> listener, boolean includeValues)
126 {
127 listenerSupport.add(listener, includeValues);
128 }
129
130 @Override
131 public void removeListener(@Nonnull CachedReferenceListener<V> listener)
132 {
133 listenerSupport.remove(listener);
134 }
135
136 private class DelegatingReferenceCacheEventListener implements CacheEventListener
137 {
138 @Override
139 public void notifyElementRemoved(Ehcache ehcache, Element element) throws net.sf.ehcache.CacheException
140 {
141 listenerSupport.notifyReset((V) element.getObjectValue());
142 }
143
144 @Override
145 public void notifyElementPut(Ehcache ehcache, Element element) throws net.sf.ehcache.CacheException
146 {
147 listenerSupport.notifySet((V) element.getObjectValue());
148 }
149
150 @Override
151 public void notifyElementUpdated(Ehcache ehcache, Element element) throws net.sf.ehcache.CacheException
152 {
153 listenerSupport.notifySet((V) element.getObjectValue());
154 }
155
156 @Override
157 public void notifyElementExpired(Ehcache ehcache, Element element)
158 {
159 listenerSupport.notifyEvict((V) element.getObjectValue());
160 }
161
162 @Override
163 public void notifyElementEvicted(Ehcache ehcache, Element element)
164 {
165 listenerSupport.notifyEvict((V) element.getObjectValue());
166 }
167
168 @Override
169 public void notifyRemoveAll(Ehcache ehcache)
170 {
171 listenerSupport.notifyReset((V) null);
172 }
173
174 @Override
175 public void dispose()
176 {
177
178 }
179
180 public Object clone() throws CloneNotSupportedException
181 {
182 throw new CloneNotSupportedException();
183 }
184 }
185 }