View Javadoc

1   /**
2    *  Copyright 2003-2007 Greg Luck
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  
17  package net.sf.ehcache.jcache;
18  
19  import net.sf.ehcache.event.CacheEventListener;
20  import net.sf.ehcache.Ehcache;
21  import net.sf.ehcache.Element;
22  import net.sf.ehcache.CacheException;
23  
24  import net.sf.jsr107cache.CacheListener;
25  
26  /**
27   * This adaptor permits JCACHE {@link CacheListener}s to be registered as Ehcache {@link CacheEventListener}s.
28   * @author Greg Luck
29   * @version $Id: JCacheListenerAdaptor.java 512 2007-07-10 09:18:45Z gregluck $
30   */
31  public class JCacheListenerAdaptor implements CacheEventListener {
32  
33      private CacheListener cacheListener;
34  
35      /**
36       * Creates an adaptor that delegates to a {@link CacheListener}
37       * @param cacheListener the JCACHE listener.
38       */
39      public JCacheListenerAdaptor(CacheListener cacheListener) {
40          this.cacheListener = cacheListener;
41      }
42  
43  
44      /**
45       * Called immediately after an element has been removed. The remove method will block until
46       * this method returns.
47       * <p/>
48       * As the {@link net.sf.ehcache.Element} has been removed, only what was the key of the element is known.
49       * <p/>
50       * This method delegates to onRemove. After the last element is removed, a call to onClear is also made.
51       * @param cache   the cache emitting the notification
52       * @param element just deleted
53       */
54      public void notifyElementRemoved(final Ehcache cache, final Element element) throws CacheException {
55          if (element != null) {
56              cacheListener.onRemove(element.getObjectKey());
57              if (cache.getSize() == 0) {
58                  cacheListener.onClear();
59              }
60          }
61      }
62  
63      /**
64       * Called immediately after an element has been put into the cache. The {@link net.sf.ehcache.Cache#put(net.sf.ehcache.Element)} method
65       * will block until this method returns.
66       * <p/>
67       * Implementers may wish to have access to the Element's fields, including value, so the element is provided.
68       * Implementers should be careful not to modify the element. The effect of any modifications is undefined.
69       *
70       * @param cache   the cache emitting the notification
71       * @param element the element which was just put into the cache.
72       */
73      public void notifyElementPut(final Ehcache cache, final Element element) throws CacheException {
74          if (element != null) {
75              cacheListener.onPut(element.getObjectKey());
76          }
77      }
78  
79      /**
80       * Called immediately after an element has been put into the cache and the element already
81       * existed in the cache. This is thus an update.
82       * <p/>
83       * The {@link net.sf.ehcache.Cache#put(net.sf.ehcache.Element)} method
84       * will block until this method returns.
85       * <p/>
86       * Implementers may wish to have access to the Element's fields, including value, so the element is provided.
87       * Implementers should be careful not to modify the element. The effect of any modifications is undefined.
88       * <p/>
89       * This method delegates to onPut in the underlying CacheListener, because JCACHE CacheListener does not
90       * have update notifications.
91       * @param cache   the cache emitting the notification
92       * @param element the element which was just put into the cache.
93       */
94      public void notifyElementUpdated(final Ehcache cache, final Element element) throws CacheException {
95          if (element != null) {
96              cacheListener.onPut(element.getObjectKey());
97          }
98      }
99  
100     /**
101      * Called immediately after an element is <i>found</i> to be expired. The
102      * {@link net.sf.ehcache.Cache#remove(Object)} method will block until this method returns.
103      * <p/>
104      * As the {@link net.sf.ehcache.Element} has been expired, only what was the key of the element is known.
105      * <p/>
106      * Elements are checked for expiry in ehcache at the following times:
107      * <ul>
108      * <li>When a get request is made
109      * <li>When an element is spooled to the diskStore in accordance with a MemoryStore eviction policy
110      * <li>In the DiskStore when the expiry thread runs, which by default is
111      * {@link net.sf.ehcache.Cache#DEFAULT_EXPIRY_THREAD_INTERVAL_SECONDS}
112      * </ul>
113      * If an element is found to be expired, it is deleted and this method is notified.
114      * <p/>
115      * JCACHE CacheListener does not support an expiry notification, so onEvict is called instead. Expiry is a
116      * type of eviction.
117      *
118      * @param cache   the cache emitting the notification
119      * @param element the element that has just expired
120      *                <p/>
121      *                Deadlock Warning: expiry will often come from the <code>DiskStore</code> expiry thread. It holds a lock to the
122      *                DiskStorea the time the notification is sent. If the implementation of this method calls into a
123      *                synchronized <code>Cache</code> method and that subsequently calls into DiskStore a deadlock will result.
124      *                Accordingly implementers of this method should not call back into Cache.
125      */
126     public void notifyElementExpired(final Ehcache cache, final Element element) {
127         if (element != null) {
128             cacheListener.onEvict(element.getObjectKey());
129         }
130     }
131 
132     /**
133      * Called immediately after an element is evicted from the cache. Evicted in this sense
134      * means evicted from one store and not moved to another, so that it exists nowhere in the
135      * local cache.
136      * <p/>
137      * In a sense the Element has been <i>removed</i> from the cache, but it is different,
138      * thus the separate notification.
139      *
140      * @param cache   the cache emitting the notification
141      * @param element the element that has just been evicted
142      */
143     public void notifyElementEvicted(final Ehcache cache, final Element element) {
144         if (element != null) {
145             cacheListener.onEvict(element.getObjectKey());
146         }
147     }
148 
149     /**
150      * Called during {@link net.sf.ehcache.Ehcache#removeAll()} to indicate that the all
151      * elements have been removed from the cache in a bulk operation. The usual
152      * {@link #notifyElementRemoved(net.sf.ehcache.Ehcache,net.sf.ehcache.Element)}
153      * is not called.
154      * <p/>
155      * This notification exists because clearing a cache is a special case. It is often
156      * not practical to serially process notifications where potentially millions of elements
157      * have been bulk deleted.
158      * <p/>
159      * Note: There is no analogue in JCACHE to this method. It is not possible to know what
160      * elements were removed. Accordingly, no notification is done.
161      *
162      * @param cache the cache emitting the notification
163      */
164     public void notifyRemoveAll(final Ehcache cache) {
165         cacheListener.onClear();
166     }
167 
168     /**
169      * Give the listener a chance to cleanup and free resources when no longer needed.
170      * <p/>
171      * JCACHE CacheListener does not support on dispose. This method does not delegate to anything.
172      * JCACHE CacheListener implementations should consider registering a CacheManagerEventListener
173      * so that they know when a cache is removed and they can perform an cleanup required.
174      */
175     public void dispose() {
176         //noop
177     }
178 
179     /**
180      * Gets the underlying CacheListener
181      * @return the underlying CacheListener
182      */
183     public CacheListener getCacheListener() {
184         return cacheListener;
185     }
186 
187     /**
188      * Creates a clone of this listener. This method will only be called by ehcache before a cache is initialized.
189      * <p/>
190      * This may not be possible for listeners after they have been initialized. Implementations should throw
191      * CloneNotSupportedException if they do not support clone.
192      * @return a clone
193      * @throws CloneNotSupportedException if the listener could not be cloned.
194      */
195     public Object clone() throws CloneNotSupportedException {
196         //shut
197         super.clone();
198         throw new CloneNotSupportedException("Cannot clone JCacheListenerAdaptor");
199     }
200 
201 }