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 }