package ri.cache;
import ri.cache.util.CacheManagerListenerSupport;
import javax.cache.CacheManager;
import javax.cache.Cache;
import javax.cache.CacheManagerListener;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicReference;
import java.util.Collections;
import java.util.Collection;
import java.util.EnumSet;
/**
* ReferenceCacheManager
*
* @author Brian Goetz
*/
public abstract class AbstractCacheManager implements CacheManager {
protected final String uri;
protected final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>();
protected final AtomicReference<State> state = new AtomicReference<State>(State.STARTING);
protected final CacheManagerListenerSupport listeners = new CacheManagerListenerSupport();
protected final EnumSet<State> RUNNING_OR_STARTING = EnumSet.of(State.RUNNING, State.STARTING);
protected final EnumSet<State> RUNNING_OR_STOPPING = EnumSet.of(State.RUNNING, State.STOPPING);
protected AbstractCacheManager(String uri) {
this.uri = uri;
}
public String getName() {
return uri;
}
public Cache getCache(String name) {
requireState(State.RUNNING);
return caches.get(name);
}
public void registerCache(String name, Cache cache) {
requireState(RUNNING_OR_STARTING);
Cache c = caches.put(name, cache);
cache.setCacheManager(this);
if (c != null)
c.setCacheManager(null);
listeners.onRegister(name);
}
public void unregisterCache(String name) {
requireState(RUNNING_OR_STOPPING);
Cache cache = caches.remove(name);
if (cache != null)
cache.setCacheManager(null);
listeners.onUnregister(name);
}
public State getState() {
return state.get();
}
public boolean cacheExists(String cacheName) {
requireState(State.RUNNING);
return caches.containsKey(cacheName);
}
public Collection<String> getCacheNames() {
requireState(RUNNING_OR_STOPPING);
return Collections.unmodifiableCollection(caches.keySet());
}
public void addListener(CacheManagerListener cacheManagerListener) {
requireState(State.RUNNING);
listeners.addListener(cacheManagerListener);
}
public void removeListener(CacheManagerListener cacheManagerListener) {
requireState(State.RUNNING);
listeners.removeListener(cacheManagerListener);
}
protected void transitionState(State fromState, State toState) {
if (!state.compareAndSet(fromState, toState))
throw new IllegalStateException("Expecting cache manager " + uri + " to be in state " + fromState + ", found state " + state.get());
if (toState == State.STOPPING)
listeners.stopping();
else if (toState == State.TERMINATED)
listeners.terminated();
}
protected void requireState(State requiredState) {
State curState = state.get();
if (curState != requiredState)
throw new IllegalStateException("Expecting cache manager " + uri + " to be in state " + requiredState + ", found state " + curState);
}
protected void requireState(EnumSet<State> requiredStates) {
State curState = state.get();
if (!requiredStates.contains(curState))
throw new IllegalStateException("Expecting cache manager " + uri + " to be in states " + requiredStates + ", found state " + curState);
}
}
|