public abstract class RefreshableCache<K,V> {
private Map<K, V> cacheMap = new HashMap<K, V>();
private Long lastUpdateTimestamp = 0l;
public RefreshableCache() {
CacheUtil.register(this);
}
public K getDefaultKey(){
return null;
}
public V getDefaultValue(){
return null;
}
public V getEmptyValue(){
return null;
}
public abstract boolean isEmptyValue(V value);
public void clearCache() {
synchronized (cacheMap) {
cacheMap.clear();
}
}
public V getValue(K key){
return getValue(key, false);
}
public V getValue(K key, boolean refresh){
if (key==null){
key = getDefaultKey();
if (key == null)
return getDefaultValue();
}
checkUpdate();
V value = getDefaultValue();
if (!refresh && cacheMap.containsKey(key)){
value = cacheMap.get(key);
if (isEmptyValue(value)){
if (!key.equals(getDefaultKey()))
return getValue(getDefaultKey(), refresh);
else
return getDefaultValue();
}
return value;
}
synchronized (cacheMap) {
if (!refresh && cacheMap.containsKey(key)){
value = cacheMap.get(key);
if (isEmptyValue(value) && !key.equals(getDefaultKey()))
return getDefaultValue();
}
value = loadValue(key);
if (value == null) {
cacheMap.put(key, getEmptyValue());
return getDefaultValue();
}
cacheMap.put(key, value);
}
return value;
}
public abstract V loadValue(K key);
private synchronized void checkUpdate() {
Long updateTimestamp = ConfigUtil.getDbConfigUpdateTimestamp();
if (updateTimestamp != null && lastUpdateTimestamp < updateTimestamp){
if (updateTimestamp != null && lastUpdateTimestamp < updateTimestamp){
clearCache();
Long current = Long.valueOf(DateUtil.Format.PARAM.getFormat().format(new Date()));
lastUpdateTimestamp = current;
}
}
}
}
private Map<K, V> cacheMap = new HashMap<K, V>();
private Long lastUpdateTimestamp = 0l;
public RefreshableCache() {
CacheUtil.register(this);
}
public K getDefaultKey(){
return null;
}
public V getDefaultValue(){
return null;
}
public V getEmptyValue(){
return null;
}
public abstract boolean isEmptyValue(V value);
public void clearCache() {
synchronized (cacheMap) {
cacheMap.clear();
}
}
public V getValue(K key){
return getValue(key, false);
}
public V getValue(K key, boolean refresh){
if (key==null){
key = getDefaultKey();
if (key == null)
return getDefaultValue();
}
checkUpdate();
V value = getDefaultValue();
if (!refresh && cacheMap.containsKey(key)){
value = cacheMap.get(key);
if (isEmptyValue(value)){
if (!key.equals(getDefaultKey()))
return getValue(getDefaultKey(), refresh);
else
return getDefaultValue();
}
return value;
}
synchronized (cacheMap) {
if (!refresh && cacheMap.containsKey(key)){
value = cacheMap.get(key);
if (isEmptyValue(value) && !key.equals(getDefaultKey()))
return getDefaultValue();
}
value = loadValue(key);
if (value == null) {
cacheMap.put(key, getEmptyValue());
return getDefaultValue();
}
cacheMap.put(key, value);
}
return value;
}
public abstract V loadValue(K key);
private synchronized void checkUpdate() {
Long updateTimestamp = ConfigUtil.getDbConfigUpdateTimestamp();
if (updateTimestamp != null && lastUpdateTimestamp < updateTimestamp){
if (updateTimestamp != null && lastUpdateTimestamp < updateTimestamp){
clearCache();
Long current = Long.valueOf(DateUtil.Format.PARAM.getFormat().format(new Date()));
lastUpdateTimestamp = current;
}
}
}
}