1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.jcs.jcache.proxy;
20
21 import org.apache.commons.jcs.jcache.JCSCache;
22
23 import javax.cache.Cache;
24 import javax.cache.CacheManager;
25 import javax.cache.configuration.CacheEntryListenerConfiguration;
26 import javax.cache.configuration.Configuration;
27 import javax.cache.integration.CompletionListener;
28 import javax.cache.processor.EntryProcessor;
29 import javax.cache.processor.EntryProcessorException;
30 import javax.cache.processor.EntryProcessorResult;
31 import java.io.Serializable;
32 import java.util.Iterator;
33 import java.util.Map;
34 import java.util.Set;
35
36
37 public class ClassLoaderAwareCache<K, V> implements Cache<K, V>
38 {
39 private final ClassLoader loader;
40 private final JCSCache<K, V> delegate;
41
42 public ClassLoaderAwareCache(final ClassLoader loader, final JCSCache<K, V> delegate)
43 {
44 this.loader = loader;
45 this.delegate = delegate;
46 }
47
48 private ClassLoader before(final Thread thread)
49 {
50 final ClassLoader tccl = thread.getContextClassLoader();
51 thread.setContextClassLoader(loader);
52 return tccl;
53 }
54
55 public V get(final K key)
56 {
57 final Thread thread = Thread.currentThread();
58 final ClassLoader loader = before(thread);
59 try
60 {
61 return delegate.get(key);
62 }
63 finally
64 {
65 thread.setContextClassLoader(loader);
66 }
67 }
68
69 public Map<K, V> getAll(final Set<? extends K> keys)
70 {
71 final Thread thread = Thread.currentThread();
72 final ClassLoader loader = before(thread);
73 try
74 {
75 return delegate.getAll(keys);
76 }
77 finally
78 {
79 thread.setContextClassLoader(loader);
80 }
81 }
82
83 public boolean containsKey(final K key)
84 {
85 final Thread thread = Thread.currentThread();
86 final ClassLoader loader = before(thread);
87 try
88 {
89 return delegate.containsKey(key);
90 }
91 finally
92 {
93 thread.setContextClassLoader(loader);
94 }
95 }
96
97 public void loadAll(final Set<? extends K> keys, boolean replaceExistingValues, final CompletionListener completionListener)
98 {
99 final Thread thread = Thread.currentThread();
100 final ClassLoader loader = before(thread);
101 try
102 {
103 delegate.loadAll(keys, replaceExistingValues, completionListener);
104 }
105 finally
106 {
107 thread.setContextClassLoader(loader);
108 }
109 }
110
111 public void put(final K key, final V value)
112 {
113 final Thread thread = Thread.currentThread();
114 final ClassLoader loader = before(thread);
115 try
116 {
117 delegate.put(key, value);
118 }
119 finally
120 {
121 thread.setContextClassLoader(loader);
122 }
123 }
124
125 public V getAndPut(final K key, final V value)
126 {
127 final Thread thread = Thread.currentThread();
128 final ClassLoader loader = before(thread);
129 try
130 {
131 return delegate.getAndPut(key, value);
132 }
133 finally
134 {
135 thread.setContextClassLoader(loader);
136 }
137 }
138
139 public void putAll(final Map<? extends K, ? extends V> map)
140 {
141 final Thread thread = Thread.currentThread();
142 final ClassLoader loader = before(thread);
143 try
144 {
145 delegate.putAll(map);
146 }
147 finally
148 {
149 thread.setContextClassLoader(loader);
150 }
151 }
152
153 public boolean putIfAbsent(final K key, final V value)
154 {
155 final Thread thread = Thread.currentThread();
156 final ClassLoader loader = before(thread);
157 try
158 {
159 return delegate.putIfAbsent(key, value);
160 }
161 finally
162 {
163 thread.setContextClassLoader(loader);
164 }
165 }
166
167 public boolean remove(final K key)
168 {
169 final Thread thread = Thread.currentThread();
170 final ClassLoader loader = before(thread);
171 try
172 {
173 return delegate.remove(key);
174 }
175 finally
176 {
177 thread.setContextClassLoader(loader);
178 }
179 }
180
181 public boolean remove(final K key, final V oldValue)
182 {
183 final Thread thread = Thread.currentThread();
184 final ClassLoader loader = before(thread);
185 try
186 {
187 return delegate.remove(key, oldValue);
188 }
189 finally
190 {
191 thread.setContextClassLoader(loader);
192 }
193 }
194
195 public V getAndRemove(final K key)
196 {
197 final Thread thread = Thread.currentThread();
198 final ClassLoader loader = before(thread);
199 try
200 {
201 return delegate.getAndRemove(key);
202 }
203 finally
204 {
205 thread.setContextClassLoader(loader);
206 }
207 }
208
209 public boolean replace(final K key, final V oldValue, final V newValue)
210 {
211 final Thread thread = Thread.currentThread();
212 final ClassLoader loader = before(thread);
213 try
214 {
215 return delegate.replace(key, oldValue, newValue);
216 }
217 finally
218 {
219 thread.setContextClassLoader(loader);
220 }
221 }
222
223 public boolean replace(final K key, final V value)
224 {
225 final Thread thread = Thread.currentThread();
226 final ClassLoader loader = before(thread);
227 try
228 {
229 return delegate.replace(key, value);
230 }
231 finally
232 {
233 thread.setContextClassLoader(loader);
234 }
235 }
236
237 public V getAndReplace(final K key, final V value)
238 {
239 final Thread thread = Thread.currentThread();
240 final ClassLoader loader = before(thread);
241 try
242 {
243 return delegate.getAndReplace(key, value);
244 }
245 finally
246 {
247 thread.setContextClassLoader(loader);
248 }
249 }
250
251 public void removeAll(final Set<? extends K> keys)
252 {
253 final Thread thread = Thread.currentThread();
254 final ClassLoader loader = before(thread);
255 try
256 {
257 delegate.removeAll(keys);
258 }
259 finally
260 {
261 thread.setContextClassLoader(loader);
262 }
263 }
264
265 @Override
266 public void removeAll()
267 {
268 final Thread thread = Thread.currentThread();
269 final ClassLoader loader = before(thread);
270 try
271 {
272 delegate.removeAll();
273 }
274 finally
275 {
276 thread.setContextClassLoader(loader);
277 }
278 }
279
280 @Override
281 public void clear()
282 {
283 final Thread thread = Thread.currentThread();
284 final ClassLoader loader = before(thread);
285 try
286 {
287 delegate.clear();
288 }
289 finally
290 {
291 thread.setContextClassLoader(loader);
292 }
293 }
294
295 public <C extends Configuration<K, V>> C getConfiguration(final Class<C> clazz)
296 {
297 final Thread thread = Thread.currentThread();
298 final ClassLoader loader = before(thread);
299 try
300 {
301 return delegate.getConfiguration(clazz);
302 }
303 finally
304 {
305 thread.setContextClassLoader(loader);
306 }
307 }
308
309 public <T> T invoke(final K key, final EntryProcessor<K, V, T> entryProcessor, final Object... arguments) throws EntryProcessorException
310 {
311 final Thread thread = Thread.currentThread();
312 final ClassLoader loader = before(thread);
313 try
314 {
315 return delegate.invoke(key, entryProcessor, arguments);
316 }
317 finally
318 {
319 thread.setContextClassLoader(loader);
320 }
321 }
322
323 public <T> Map<K, EntryProcessorResult<T>> invokeAll(Set<? extends K> keys, EntryProcessor<K, V, T> entryProcessor, Object... arguments)
324 {
325 final Thread thread = Thread.currentThread();
326 final ClassLoader loader = before(thread);
327 try
328 {
329 return delegate.invokeAll(keys, entryProcessor, arguments);
330 }
331 finally
332 {
333 thread.setContextClassLoader(loader);
334 }
335 }
336
337 @Override
338 public String getName()
339 {
340 final Thread thread = Thread.currentThread();
341 final ClassLoader loader = before(thread);
342 try
343 {
344 return delegate.getName();
345 }
346 finally
347 {
348 thread.setContextClassLoader(loader);
349 }
350 }
351
352 @Override
353 public CacheManager getCacheManager()
354 {
355 final Thread thread = Thread.currentThread();
356 final ClassLoader loader = before(thread);
357 try
358 {
359 return delegate.getCacheManager();
360 }
361 finally
362 {
363 thread.setContextClassLoader(loader);
364 }
365 }
366
367 @Override
368 public void close()
369 {
370 final Thread thread = Thread.currentThread();
371 final ClassLoader loader = before(thread);
372 try
373 {
374 delegate.close();
375 }
376 finally
377 {
378 thread.setContextClassLoader(loader);
379 }
380 }
381
382 @Override
383 public boolean isClosed()
384 {
385 final Thread thread = Thread.currentThread();
386 final ClassLoader loader = before(thread);
387 try
388 {
389 return delegate.isClosed();
390 }
391 finally
392 {
393 thread.setContextClassLoader(loader);
394 }
395 }
396
397 @Override
398 public <T> T unwrap(final Class<T> clazz)
399 {
400 final Thread thread = Thread.currentThread();
401 final ClassLoader loader = before(thread);
402 try
403 {
404 return delegate.unwrap(clazz);
405 }
406 finally
407 {
408 thread.setContextClassLoader(loader);
409 }
410 }
411
412 public void registerCacheEntryListener(final CacheEntryListenerConfiguration<K, V> cacheEntryListenerConfiguration)
413 {
414 final Thread thread = Thread.currentThread();
415 final ClassLoader loader = before(thread);
416 try
417 {
418 delegate.registerCacheEntryListener(cacheEntryListenerConfiguration);
419 }
420 finally
421 {
422 thread.setContextClassLoader(loader);
423 }
424 }
425
426 public void deregisterCacheEntryListener(final CacheEntryListenerConfiguration<K, V> cacheEntryListenerConfiguration)
427 {
428 final Thread thread = Thread.currentThread();
429 final ClassLoader loader = before(thread);
430 try
431 {
432 delegate.deregisterCacheEntryListener(cacheEntryListenerConfiguration);
433 }
434 finally
435 {
436 thread.setContextClassLoader(loader);
437 }
438 }
439
440 @Override
441 public Iterator<Entry<K, V>> iterator()
442 {
443 final Thread thread = Thread.currentThread();
444 final ClassLoader loader = before(thread);
445 try
446 {
447 return delegate.iterator();
448 }
449 finally
450 {
451 thread.setContextClassLoader(loader);
452 }
453 }
454
455 @Override
456 public boolean equals(final Object obj)
457 {
458 if (ClassLoaderAwareCache.class.isInstance(obj))
459 {
460 return delegate.equals(ClassLoaderAwareCache.class.cast(obj).delegate);
461 }
462 return super.equals(obj);
463 }
464
465 @Override
466 public int hashCode()
467 {
468 return delegate.hashCode();
469 }
470
471 public static <K extends Serializable, V extends Serializable> Cache<K, V> wrap(final ClassLoader loader, final JCSCache<K, V> delegate)
472 {
473 ClassLoader dontWrapLoader = ClassLoaderAwareCache.class.getClassLoader();
474 while (dontWrapLoader != null)
475 {
476 if (loader == dontWrapLoader)
477 {
478 return delegate;
479 }
480 dontWrapLoader = dontWrapLoader.getParent();
481 }
482 return new ClassLoaderAwareCache<K, V>(loader, delegate);
483 }
484
485 public static <K extends Serializable, V extends Serializable> JCSCache<K, V> getDelegate(final Cache<?, ?> cache)
486 {
487 if (JCSCache.class.isInstance(cache))
488 {
489 return (JCSCache<K, V>) cache;
490 }
491 return ((ClassLoaderAwareCache<K, V>) cache).delegate;
492 }
493 }