com.maxifier.mxcache.ehcache.EhcacheStorage Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mxcache-ehcache-integration Show documentation
Show all versions of mxcache-ehcache-integration Show documentation
A set of custom caching strategies for EhCache framework
/*
* Copyright (c) 2008-2014 Maxifier Ltd. All Rights Reserved.
*/
package com.maxifier.mxcache.ehcache;
import com.maxifier.mxcache.provider.CacheDescriptor;
import com.maxifier.mxcache.provider.StrategyProperty;
import com.maxifier.mxcache.storage.elementlocked.ObjectObjectElementLockedStorage;
import gnu.trove.map.hash.THashMap;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sf.ehcache.constructs.locking.ExplicitLockingCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* EhcacheStorage
*
* @see com.maxifier.mxcache.ehcache.UseEhcache
*
* @author Alexander Kochurov ([email protected])
*/
public class EhcacheStorage implements ObjectObjectElementLockedStorage {
private static final Logger logger = LoggerFactory.getLogger(EhcacheStorage.class);
private static final String CLASSPATH_PREFIX = "classpath://";
private static final StrategyProperty CONFIG_URL_PROPERTY = StrategyProperty.create("ehcache.configURL.url", String.class, UseEhcache.class, "configURL");
private static final CacheManager DEFAULT_CACHE_MANAGER = new CacheManager();
private static final Map CONFIGURATION_CACHE = new THashMap();
private final ExplicitLockingCache underlyingCache;
private final Lock readLock;
private final Lock writeLock;
public EhcacheStorage(CacheDescriptor descriptor) {
CacheManager cacheManager = getCacheManager(descriptor);
this.underlyingCache = new ExplicitLockingCache(cacheManager.getCache(descriptor.getCacheName()));
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
readLock = lock.readLock();
writeLock = lock.writeLock();
}
private static CacheManager getCacheManager(CacheDescriptor descriptor) {
String configURL = descriptor.getProperty(CONFIG_URL_PROPERTY);
if (configURL.isEmpty()) {
return DEFAULT_CACHE_MANAGER;
}
synchronized (CONFIGURATION_CACHE) {
CacheManager cacheManager = CONFIGURATION_CACHE.get(configURL);
if (cacheManager == null) {
try {
URL url = getConfigurationURL(descriptor, configURL);
cacheManager = new CacheManager(url);
} catch (CacheException e) {
logger.error("Cannot load ehcache configuration", e);
cacheManager = DEFAULT_CACHE_MANAGER;
} catch (MalformedURLException e) {
logger.error("Invalid ehcache configURL url", e);
cacheManager = DEFAULT_CACHE_MANAGER;
}
CONFIGURATION_CACHE.put(configURL, cacheManager);
}
return cacheManager;
}
}
private static URL getConfigurationURL(CacheDescriptor descriptor, String configURL) throws MalformedURLException {
if (configURL.startsWith(CLASSPATH_PREFIX)) {
String path = configURL.substring(CLASSPATH_PREFIX.length());
return descriptor.getDeclaringClass().getClassLoader().getResource(path);
}
return new URL(configURL);
}
@Override
public void lock(E key) {
readLock.lock();
underlyingCache.acquireWriteLockOnKey(key);
}
@Override
public void unlock(E key) {
underlyingCache.releaseWriteLockOnKey(key);
readLock.unlock();
}
@Override
public Lock getLock() {
return writeLock;
}
@Override
public Object load(E key) {
Element element = underlyingCache.get(key);
if (element == null) {
return UNDEFINED;
}
return element.getObjectValue();
}
@Override
public void save(E key, Object value) {
underlyingCache.put(new Element(key, value));
}
@Override
public void clear() {
underlyingCache.removeAll();
}
@Override
public int size() {
return (int) underlyingCache.getStatistics().getMemoryStoreObjectCount();
}
@Override
public String toString() {
return underlyingCache.toString();
}
}