| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.commons.jcs3.jcache.proxy; |
| |
| import javax.cache.Cache; |
| import javax.cache.CacheManager; |
| import javax.cache.configuration.CacheEntryListenerConfiguration; |
| import javax.cache.configuration.Configuration; |
| import javax.cache.integration.CompletionListener; |
| import javax.cache.processor.EntryProcessor; |
| import javax.cache.processor.EntryProcessorException; |
| import javax.cache.processor.EntryProcessorResult; |
| |
| import org.apache.commons.jcs3.jcache.JCSCache; |
| |
| import java.io.Serializable; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Set; |
| |
| // don't use a proxy, reflection is too slow here :( |
| public class ClassLoaderAwareCache<K, V> implements Cache<K, V> |
| { |
| private final ClassLoader loader; |
| private final JCSCache<K, V> delegate; |
| |
| public ClassLoaderAwareCache(final ClassLoader loader, final JCSCache<K, V> delegate) |
| { |
| this.loader = loader; |
| this.delegate = delegate; |
| } |
| |
| private ClassLoader before(final Thread thread) |
| { |
| final ClassLoader tccl = thread.getContextClassLoader(); |
| thread.setContextClassLoader(loader); |
| return tccl; |
| } |
| |
| @Override |
| public V get(final K key) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.get(key); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public Map<K, V> getAll(final Set<? extends K> keys) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.getAll(keys); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public boolean containsKey(final K key) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.containsKey(key); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public void loadAll(final Set<? extends K> keys, boolean replaceExistingValues, final CompletionListener completionListener) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| delegate.loadAll(keys, replaceExistingValues, completionListener); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public void put(final K key, final V value) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| delegate.put(key, value); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public V getAndPut(final K key, final V value) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.getAndPut(key, value); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public void putAll(final Map<? extends K, ? extends V> map) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| delegate.putAll(map); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public boolean putIfAbsent(final K key, final V value) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.putIfAbsent(key, value); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public boolean remove(final K key) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.remove(key); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public boolean remove(final K key, final V oldValue) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.remove(key, oldValue); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public V getAndRemove(final K key) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.getAndRemove(key); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public boolean replace(final K key, final V oldValue, final V newValue) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.replace(key, oldValue, newValue); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public boolean replace(final K key, final V value) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.replace(key, value); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public V getAndReplace(final K key, final V value) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.getAndReplace(key, value); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public void removeAll(final Set<? extends K> keys) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| delegate.removeAll(keys); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public void removeAll() |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| delegate.removeAll(); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public void clear() |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| delegate.clear(); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public <C extends Configuration<K, V>> C getConfiguration(final Class<C> clazz) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.getConfiguration(clazz); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public <T> T invoke(final K key, final EntryProcessor<K, V, T> entryProcessor, final Object... arguments) throws EntryProcessorException |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.invoke(key, entryProcessor, arguments); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public <T> Map<K, EntryProcessorResult<T>> invokeAll(Set<? extends K> keys, EntryProcessor<K, V, T> entryProcessor, Object... arguments) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.invokeAll(keys, entryProcessor, arguments); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public String getName() |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.getName(); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public CacheManager getCacheManager() |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.getCacheManager(); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public void close() |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| delegate.close(); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public boolean isClosed() |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.isClosed(); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public <T> T unwrap(final Class<T> clazz) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.unwrap(clazz); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public void registerCacheEntryListener(final CacheEntryListenerConfiguration<K, V> cacheEntryListenerConfiguration) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| delegate.registerCacheEntryListener(cacheEntryListenerConfiguration); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public void deregisterCacheEntryListener(final CacheEntryListenerConfiguration<K, V> cacheEntryListenerConfiguration) |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| delegate.deregisterCacheEntryListener(cacheEntryListenerConfiguration); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public Iterator<Entry<K, V>> iterator() |
| { |
| final Thread thread = Thread.currentThread(); |
| final ClassLoader loader = before(thread); |
| try |
| { |
| return delegate.iterator(); |
| } |
| finally |
| { |
| thread.setContextClassLoader(loader); |
| } |
| } |
| |
| @Override |
| public boolean equals(final Object obj) |
| { |
| if (ClassLoaderAwareCache.class.isInstance(obj)) |
| { |
| return delegate.equals(ClassLoaderAwareCache.class.cast(obj).delegate); |
| } |
| return super.equals(obj); |
| } |
| |
| @Override |
| public int hashCode() |
| { |
| return delegate.hashCode(); |
| } |
| |
| public static <K extends Serializable, V extends Serializable> Cache<K, V> wrap(final ClassLoader loader, final JCSCache<K, V> delegate) |
| { |
| ClassLoader dontWrapLoader = ClassLoaderAwareCache.class.getClassLoader(); |
| while (dontWrapLoader != null) |
| { |
| if (loader == dontWrapLoader) |
| { |
| return delegate; |
| } |
| dontWrapLoader = dontWrapLoader.getParent(); |
| } |
| return new ClassLoaderAwareCache<>(loader, delegate); |
| } |
| |
| public static <K extends Serializable, V extends Serializable> JCSCache<K, V> getDelegate(final Cache<?, ?> cache) |
| { |
| if (JCSCache.class.isInstance(cache)) |
| { |
| return (JCSCache<K, V>) cache; |
| } |
| return ((ClassLoaderAwareCache<K, V>) cache).delegate; |
| } |
| } |