View Javadoc

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   * A Lazy Reference that delegates to EhCache.
26   *
27   * @since 2.0
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             // We don't hold onto any resources so there is nothing to be done.
178         }
179 
180         public Object clone() throws CloneNotSupportedException
181         {
182             throw new CloneNotSupportedException();
183         }
184     }
185 }