001: package ri.cache;
002:
003: import ri.cache.util.CacheManagerListenerSupport;
004:
005: import javax.cache.CacheManager;
006: import javax.cache.Cache;
007: import javax.cache.CacheManagerListener;
008: import java.util.concurrent.ConcurrentHashMap;
009: import java.util.concurrent.ConcurrentMap;
010: import java.util.concurrent.atomic.AtomicReference;
011: import java.util.Collections;
012: import java.util.Collection;
013: import java.util.EnumSet;
014:
015: /**
016: * ReferenceCacheManager
017: *
018: * @author Brian Goetz
019: */
020: public abstract class AbstractCacheManager implements CacheManager {
021:
022: protected final String uri;
023: protected final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>();
024: protected final AtomicReference<State> state = new AtomicReference<State>(
025: State.STARTING);
026: protected final CacheManagerListenerSupport listeners = new CacheManagerListenerSupport();
027: protected final EnumSet<State> RUNNING_OR_STARTING = EnumSet.of(
028: State.RUNNING, State.STARTING);
029: protected final EnumSet<State> RUNNING_OR_STOPPING = EnumSet.of(
030: State.RUNNING, State.STOPPING);
031:
032: protected AbstractCacheManager(String uri) {
033: this .uri = uri;
034: }
035:
036: public String getName() {
037: return uri;
038: }
039:
040: public Cache getCache(String name) {
041: requireState(State.RUNNING);
042: return caches.get(name);
043: }
044:
045: public void registerCache(String name, Cache cache) {
046: requireState(RUNNING_OR_STARTING);
047: Cache c = caches.put(name, cache);
048: cache.setCacheManager(this );
049: if (c != null)
050: c.setCacheManager(null);
051: listeners.onRegister(name);
052: }
053:
054: public void unregisterCache(String name) {
055: requireState(RUNNING_OR_STOPPING);
056: Cache cache = caches.remove(name);
057: if (cache != null)
058: cache.setCacheManager(null);
059: listeners.onUnregister(name);
060: }
061:
062: public State getState() {
063: return state.get();
064: }
065:
066: public boolean cacheExists(String cacheName) {
067: requireState(State.RUNNING);
068: return caches.containsKey(cacheName);
069: }
070:
071: public Collection<String> getCacheNames() {
072: requireState(RUNNING_OR_STOPPING);
073: return Collections.unmodifiableCollection(caches.keySet());
074: }
075:
076: public void addListener(CacheManagerListener cacheManagerListener) {
077: requireState(State.RUNNING);
078: listeners.addListener(cacheManagerListener);
079: }
080:
081: public void removeListener(CacheManagerListener cacheManagerListener) {
082: requireState(State.RUNNING);
083: listeners.removeListener(cacheManagerListener);
084: }
085:
086: protected void transitionState(State fromState, State toState) {
087: if (!state.compareAndSet(fromState, toState))
088: throw new IllegalStateException("Expecting cache manager "
089: + uri + " to be in state " + fromState
090: + ", found state " + state.get());
091: if (toState == State.STOPPING)
092: listeners.stopping();
093: else if (toState == State.TERMINATED)
094: listeners.terminated();
095: }
096:
097: protected void requireState(State requiredState) {
098: State curState = state.get();
099: if (curState != requiredState)
100: throw new IllegalStateException("Expecting cache manager "
101: + uri + " to be in state " + requiredState
102: + ", found state " + curState);
103: }
104:
105: protected void requireState(EnumSet<State> requiredStates) {
106: State curState = state.get();
107: if (!requiredStates.contains(curState))
108: throw new IllegalStateException("Expecting cache manager "
109: + uri + " to be in states " + requiredStates
110: + ", found state " + curState);
111: }
112: }
|