View Javadoc

1   package com.atlassian.cache.impl;
2   
3   import com.atlassian.cache.Cache;
4   import com.atlassian.cache.CacheLoader;
5   import com.atlassian.cache.CacheManager;
6   import com.atlassian.cache.CacheSettings;
7   import com.atlassian.cache.CacheSettingsBuilder;
8   import com.atlassian.cache.CachedReference;
9   import com.atlassian.cache.ManagedCache;
10  import com.atlassian.util.concurrent.Function;
11  import com.atlassian.util.concurrent.ManagedLock;
12  import com.atlassian.util.concurrent.ManagedLocks;
13  import com.atlassian.util.concurrent.NotNull;
14  import com.atlassian.util.concurrent.Nullable;
15  import com.atlassian.util.concurrent.Supplier;
16  
17  import java.util.ArrayList;
18  import java.util.Collection;
19  import java.util.List;
20  import java.util.concurrent.ConcurrentHashMap;
21  import java.util.concurrent.ConcurrentMap;
22  
23  import javax.management.MBeanServer;
24  
25  import static com.google.common.base.Preconditions.checkNotNull;
26  
27  /**
28   * A partial implementation of {@link CacheManager}.
29   *
30   * @since 2.0.6
31   */
32  public abstract class AbstractCacheManager implements CacheManager
33  {
34  
35      /**
36       * Map of all the caches.
37       * Before creating a cache to put into the map, acquire a lock using {@link #cacheCreationLocks}
38       * to ensure that a cache is created only once.
39       */
40      protected final ConcurrentMap<String, Supplier<ManagedCache>> caches = new ConcurrentHashMap<String, Supplier<ManagedCache>>();
41      /** Used to synchronize the creation of caches. */
42      protected final Function<String, ManagedLock> cacheCreationLocks = ManagedLocks.weakManagedLockFactory();
43  
44  
45  
46      @SuppressWarnings("unchecked")
47      @Override
48      public Collection<Cache<?, ?>> getCaches()
49      {
50          List<Cache<?, ?>> managedCaches = new ArrayList<Cache<?, ?>>();
51  
52          for (final com.atlassian.util.concurrent.Supplier<ManagedCache> cacheRef : caches.values())
53          {
54              final ManagedCache managedCache = cacheRef.get();
55              if (managedCache != null)
56              {
57                  managedCaches.add((Cache) managedCache);
58              }
59          }
60          return managedCaches;
61      }
62  
63      @Override
64      public Collection<ManagedCache> getManagedCaches()
65      {
66          List<ManagedCache> managedCaches = new ArrayList<ManagedCache>();
67  
68          for (final com.atlassian.util.concurrent.Supplier<ManagedCache> cacheRef : caches.values())
69          {
70              final ManagedCache managedCache = cacheRef.get();
71              if (managedCache != null)
72              {
73                  managedCaches.add(managedCache);
74              }
75          }
76          return managedCaches;
77      }
78  
79      @Override
80      public void flushCaches()
81      {
82          for (final com.atlassian.util.concurrent.Supplier<ManagedCache> cacheRef : caches.values())
83          {
84              final ManagedCache managedCache = cacheRef.get();
85              if (managedCache != null && managedCache.isFlushable())
86              {
87                  managedCache.clear();
88              }
89          }
90      }
91  
92      @Override
93      public <K, V> Cache<K, V> getCache(@NotNull final String name)
94      {
95          return getCache(name, null);
96      }
97  
98      @Override
99      public <K, V> Cache<K, V> getCache(Class<?> owningClass, String name)
100     {
101         return getCache(cacheName(owningClass, name));
102     }
103 
104     @Override
105     public <K, V> Cache<K, V> getCache(final String name, final Class<K> keyType, final Class<V> valueType)
106     {
107         return getCache(name);
108     }
109 
110     @Override
111     public <K, V> Cache<K, V> getCache(String name, CacheLoader<K, V> loader)
112     {
113         return getCache(name, loader, new CacheSettingsBuilder().build());
114     }
115 
116     @Override
117     public <V> CachedReference<V> getCachedReference(String name, com.atlassian.cache.Supplier<V> supplier)
118     {
119         return getCachedReference(name, supplier, new CacheSettingsBuilder().build());
120     }
121 
122     @Override
123     public <V> CachedReference<V> getCachedReference(Class<?> owningClass,
124                                                      String name,
125                                                      com.atlassian.cache.Supplier<V> supplier)
126     {
127         return getCachedReference(owningClass, name, supplier, new CacheSettingsBuilder().build());
128     }
129 
130     @Override
131     public <V> CachedReference<V> getCachedReference(Class<?> owningClass,
132                                                      String name,
133                                                      com.atlassian.cache.Supplier<V> supplier,
134                                                      CacheSettings settings)
135     {
136         return getCachedReference(cacheName(owningClass, name), supplier, settings);
137     }
138 
139     private static String cacheName(Class<?> owningClass, String name)
140     {
141         checkNotNull(name, "name cannot be null");
142         return owningClass.getName() + "." + name;
143     }
144 
145     @SuppressWarnings("unchecked")
146     @Override
147     public <K, V> Cache<K, V> getCache(String name, CacheLoader<K, V> loader, CacheSettings settings)
148     {
149         if (null == loader)
150         {
151             return (Cache<K, V>) createSimpleCache(name, settings);
152         }
153         else
154         {
155             return (Cache<K, V>) createComputingCache(name, settings, loader);
156         }
157     }
158 
159     /**
160      * Creates a cache that upon a miss is able to populate itself using the loader.
161      *
162      * @return a non-null cache
163      */
164     protected abstract <K, V> ManagedCache createComputingCache(String name, CacheSettings settings, CacheLoader<K, V> loader);
165 
166     /**
167      * Creates a cache with no loader, i.e. one populated via explicit puts.
168      *
169      * @param name the name to give the cache (required)
170      * @return a non-null cache
171      */
172     protected abstract ManagedCache createSimpleCache(String name, CacheSettings settings);
173 }