001
014
015 package com.liferay.portal.cache;
016
017 import com.liferay.portal.cache.transactional.TransactionalPortalCache;
018 import com.liferay.portal.kernel.cache.AggregatedCacheManagerListener;
019 import com.liferay.portal.kernel.cache.BlockingPortalCache;
020 import com.liferay.portal.kernel.cache.BootstrapLoader;
021 import com.liferay.portal.kernel.cache.CacheListener;
022 import com.liferay.portal.kernel.cache.CacheListenerScope;
023 import com.liferay.portal.kernel.cache.CacheManagerListener;
024 import com.liferay.portal.kernel.cache.CallbackFactory;
025 import com.liferay.portal.kernel.cache.PortalCache;
026 import com.liferay.portal.kernel.cache.PortalCacheException;
027 import com.liferay.portal.kernel.cache.PortalCacheManager;
028 import com.liferay.portal.kernel.cache.PortalCacheProvider;
029 import com.liferay.portal.kernel.cache.configuration.CallbackConfiguration;
030 import com.liferay.portal.kernel.cache.configuration.PortalCacheConfiguration;
031 import com.liferay.portal.kernel.cache.configuration.PortalCacheManagerConfiguration;
032 import com.liferay.portal.kernel.resiliency.spi.SPIUtil;
033 import com.liferay.portal.kernel.util.CharPool;
034 import com.liferay.portal.kernel.util.StringUtil;
035 import com.liferay.portal.util.PropsValues;
036
037 import java.io.Serializable;
038
039 import java.util.Map;
040 import java.util.Set;
041 import java.util.concurrent.ConcurrentHashMap;
042 import java.util.concurrent.ConcurrentMap;
043
044
047 public abstract class AbstractPortalCacheManager<K extends Serializable, V>
048 implements PortalCacheManager<K, V> {
049
050 public void afterPropertiesSet() {
051 if ((_portalCacheManagerConfiguration != null) ||
052 (_mpiOnly && SPIUtil.isSPI())) {
053
054 return;
055 }
056
057 initPortalCacheManager();
058
059 _portalCacheManagerConfiguration = getPortalCacheManagerConfiguration();
060
061 for (CallbackConfiguration callbackConfiguration :
062 _portalCacheManagerConfiguration.
063 getCacheManagerListenerConfigurations()) {
064
065 CallbackFactory callbackFactory =
066 callbackConfiguration.getCallbackFactory();
067
068 CacheManagerListener cacheManagerListener =
069 callbackFactory.createCacheManagerListener(
070 callbackConfiguration.getProperties());
071
072 if (cacheManagerListener != null) {
073 registerCacheManagerListener(cacheManagerListener);
074 }
075 }
076
077 PortalCacheProvider.registerPortalCacheManager(this);
078 }
079
080 @Override
081 public void clearAll() throws PortalCacheException {
082 _portalCaches.clear();
083
084 doClearAll();
085 }
086
087 @Override
088 public void destroy() {
089 PortalCacheProvider.unregisterPortalCacheManager(getName());
090
091 _portalCaches.clear();
092
093 doDestroy();
094 }
095
096 @Override
097 public PortalCache<K, V> getCache(String name) throws PortalCacheException {
098 return getCache(name, false);
099 }
100
101 @Override
102 public PortalCache<K, V> getCache(String name, boolean blocking)
103 throws PortalCacheException {
104
105 PortalCache<K, V> portalCache = _portalCaches.get(name);
106
107 if (portalCache != null) {
108 return portalCache;
109 }
110
111 portalCache = createPortalCache(name);
112
113 PortalCacheConfiguration portalCacheConfiguration =
114 _portalCacheManagerConfiguration.getPortalCacheConfiguration(
115 portalCache.getName());
116
117 if (portalCacheConfiguration == null) {
118 portalCacheConfiguration =
119 _portalCacheManagerConfiguration.
120 getDefaultPortalCacheConfiguration();
121 }
122
123 _initPortalCacheListeners(portalCache, portalCacheConfiguration);
124
125 if (PropsValues.TRANSACTIONAL_CACHE_ENABLED &&
126 isTransactionalPortalCache(name)) {
127
128 portalCache = new TransactionalPortalCache<K, V>(portalCache);
129 }
130
131 if (PropsValues.EHCACHE_BLOCKING_CACHE_ALLOWED && blocking) {
132 portalCache = new BlockingPortalCache<K, V>(portalCache);
133 }
134
135 PortalCache<K, V> previousPortalCache = _portalCaches.putIfAbsent(
136 name, portalCache);
137
138 if (previousPortalCache != null) {
139 portalCache = previousPortalCache;
140 }
141 else if (PropsValues.EHCACHE_BOOTSTRAP_CACHE_LOADER_ENABLED &&
142 (portalCacheConfiguration != null)) {
143
144 CallbackConfiguration bootstrapLoaderConfiguration =
145 portalCacheConfiguration.getBootstrapLoaderConfiguration();
146
147 if (bootstrapLoaderConfiguration != null) {
148 CallbackFactory callbackFactory =
149 bootstrapLoaderConfiguration.getCallbackFactory();
150
151 BootstrapLoader bootstrapLoader =
152 callbackFactory.createBootstrapLoader(
153 bootstrapLoaderConfiguration.getProperties());
154
155 if (bootstrapLoader != null) {
156 bootstrapLoader.load(getName(), name);
157 }
158 }
159 }
160
161 return portalCache;
162 }
163
164 @Override
165 public Set<CacheManagerListener> getCacheManagerListeners() {
166 return aggregatedCacheManagerListener.getCacheManagerListeners();
167 }
168
169 @Override
170 public boolean isClusterAware() {
171 return clusterAware;
172 }
173
174 @Override
175 public boolean registerCacheManagerListener(
176 CacheManagerListener cacheManagerListener) {
177
178 return aggregatedCacheManagerListener.addCacheListener(
179 cacheManagerListener);
180 }
181
182 @Override
183 public void removeCache(String name) {
184 _portalCaches.remove(name);
185
186 doRemoveCache(name);
187 }
188
189 public void setClusterAware(boolean clusterAware) {
190 this.clusterAware = clusterAware;
191 }
192
193 public void setMpiOnly(boolean mpiOnly) {
194 _mpiOnly = mpiOnly;
195 }
196
197 @Override
198 public boolean unregisterCacheManagerListener(
199 CacheManagerListener cacheManagerListener) {
200
201 return aggregatedCacheManagerListener.removeCacheListener(
202 cacheManagerListener);
203 }
204
205 @Override
206 public void unregisterCacheManagerListeners() {
207 aggregatedCacheManagerListener.clearAll();
208 }
209
210 protected abstract PortalCache<K, V> createPortalCache(String cacheName);
211
212 protected abstract void doClearAll();
213
214 protected abstract void doDestroy();
215
216 protected abstract void doRemoveCache(String cacheName);
217
218 protected abstract PortalCacheManagerConfiguration
219 getPortalCacheManagerConfiguration();
220
221 protected abstract void initPortalCacheManager();
222
223 protected boolean isTransactionalPortalCache(String name) {
224 for (String namePattern : PropsValues.TRANSACTIONAL_CACHE_NAMES) {
225 if (StringUtil.wildcardMatches(
226 name, namePattern, CharPool.QUESTION, CharPool.STAR,
227 CharPool.PERCENT, true)) {
228
229 return true;
230 }
231 }
232
233 return false;
234 }
235
236 protected void reconfigPortalCache(
237 PortalCacheManagerConfiguration portalCacheManagerConfiguration) {
238
239 for (String portalCacheName :
240 portalCacheManagerConfiguration.getPortalCacheNames()) {
241
242 PortalCache<K, V> portalCache = _portalCaches.get(portalCacheName);
243
244 if (portalCache == null) {
245 continue;
246 }
247
248 portalCache.unregisterCacheListeners();
249
250 _initPortalCacheListeners(
251 portalCache,
252 portalCacheManagerConfiguration.getPortalCacheConfiguration(
253 portalCacheName));
254 }
255 }
256
257 protected final AggregatedCacheManagerListener
258 aggregatedCacheManagerListener = new AggregatedCacheManagerListener();
259 protected boolean clusterAware;
260
261 private void _initPortalCacheListeners(
262 PortalCache<K, V> portalCache,
263 PortalCacheConfiguration portalCacheConfiguration) {
264
265 if (portalCacheConfiguration == null) {
266 return;
267 }
268
269 Map<CallbackConfiguration, CacheListenerScope>
270 cacheListenerConfigurations =
271 portalCacheConfiguration.getCacheListenerConfigurations();
272
273 for (Map.Entry<CallbackConfiguration, CacheListenerScope> entry :
274 cacheListenerConfigurations.entrySet()) {
275
276 CallbackConfiguration callbackConfiguration = entry.getKey();
277
278 CallbackFactory callbackFactory =
279 callbackConfiguration.getCallbackFactory();
280
281 CacheListener<K, V> cacheListener =
282 (CacheListener<K, V>)callbackFactory.createCacheListener(
283 callbackConfiguration.getProperties());
284
285 portalCache.registerCacheListener(cacheListener, entry.getValue());
286 }
287 }
288
289 private boolean _mpiOnly;
290 private PortalCacheManagerConfiguration _portalCacheManagerConfiguration;
291 private final ConcurrentMap<String, PortalCache<K, V>> _portalCaches =
292 new ConcurrentHashMap<String, PortalCache<K, V>>();
293
294 }