package message.cache.oscache;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;
import message.cache.Cache;
import message.cache.CacheManager;
import message.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.*;
/**
* oscache cache manager impl.
*
* @author sunhao(sunhao.java@gmail.com)
* @version V1.0, 13-3-30 上午4:58
*/
public class OsCacheManagerImpl implements CacheManager {
private static final Logger logger = LoggerFactory.getLogger(OsCacheManagerImpl.class);
/**oscache general cache administrator**/
private static GeneralCacheAdministrator admin;
/**ehcache configuration file path**/
private String configuration;
/**for synchronized**/
private Object syncGetCacheObject;
/**make what like region**/
private Map<String, Cache> caches;
/**default timeout, how long can this object stay in cache by second!**/
private long defaultTimeout;
/**
* The configuration key that specifies whether we should block waiting for new
* content to be generated, or just serve the old content instead. The default
* behaviour is to serve the old content since that provides the best performance
* (at the cost of serving slightly stale data).
*/
protected final static String CACHE_BLOCKING_KEY = "cache.blocking";
/**
* A boolean cache configuration property that indicates whether the cache
* should cache objects in memory. Set this property to <code>false</code>
* to disable in-memory caching.
*/
protected final static String CACHE_MEMORY_KEY = "cache.memory";
/**
* A boolean cache configuration property that indicates whether the persistent
* cache should be unlimited in size, or should be restricted to the same size
* as the in-memory cache. Set this property to <code>true</code> to allow the
* persistent cache to grow without bound.
*/
protected final static String CACHE_DISK_UNLIMITED_KEY = "cache.unlimited.disk";
/**
* Whether the cache blocks waiting for content to be build, or serves stale
* content instead. This value can be specified using the {@link #CACHE_BLOCKING_KEY}
* configuration property.
*/
private boolean blocking = false;
/**
* Whether or not to store the cache entries in memory. This is configurable using the
* {@link #CACHE_MEMORY_KEY} property.
*/
private boolean memoryCaching = true;
/**
* Whether the disk cache should be unlimited in size, or matched 1-1 to the memory cache.
* This can be set via the {@link #CACHE_DISK_UNLIMITED_KEY} configuration property.
*/
private boolean unlimitedDiskCache = false;
private static final String DEFAULT_OSCACHE_CONFIG = "/com/message/base/cache/oscache/oscache.properties";
public void afterPropertiesSet() throws Exception {
syncGetCacheObject = new Object();
caches = new HashMap<String, Cache>();
InputStream in = null;
if(StringUtils.isEmpty(this.configuration) || !new File(this.configuration).exists()){
logger.debug("file '{}' is not exist, use default config!");
in = OsCacheManagerImpl.class.getResourceAsStream(DEFAULT_OSCACHE_CONFIG);
} else {
in = new FileInputStream(new File(this.configuration));
}
Properties p = new Properties();
p.load(in);
p.put(CACHE_BLOCKING_KEY, this.blocking);
p.put(CACHE_MEMORY_KEY, this.memoryCaching);
p.put(CACHE_DISK_UNLIMITED_KEY, this.unlimitedDiskCache);
this.admin = new GeneralCacheAdministrator(p);
}
public void destroy() throws Exception {
this.caches.clear();
this.caches = null;
this.admin.flushAll();
}
public List getCacheNames() {
if(this.caches != null && this.caches.size() > 0){
Set<String> keys = caches.keySet();
List<String> cacheNames = new ArrayList<String>(keys.size());
for(String key : keys){
cacheNames.add(key);
}
return cacheNames;
}
return Collections.EMPTY_LIST;
}
public Cache getCache(String region) {
Cache cache = this.caches.get(region);
if(cache == null){
synchronized (this.syncGetCacheObject){
cache = new OsCacheImpl(admin, defaultTimeout);
this.caches.put(region, cache);
}
}
return cache;
}
public void removeCache(String region) {
Cache cache = this.caches.remove(region);
cache = null;
}
public void flush() {
admin.flushAll();
}
public void setConfiguration(String configuration) {
this.configuration = configuration;
}
public void setDefaultTimeout(long defaultTimeout) {
this.defaultTimeout = defaultTimeout;
}
public void setBlocking(boolean blocking) {
this.blocking = blocking;
}
public void setMemoryCaching(boolean memoryCaching) {
this.memoryCaching = memoryCaching;
}
public void setUnlimitedDiskCache(boolean unlimitedDiskCache) {
this.unlimitedDiskCache = unlimitedDiskCache;
}
}