001
014
015 package com.liferay.portal.cache.ehcache;
016
017 import com.liferay.portal.cache.transactional.TransactionalPortalCache;
018 import com.liferay.portal.dao.orm.common.EntityCacheImpl;
019 import com.liferay.portal.dao.orm.common.FinderCacheImpl;
020 import com.liferay.portal.kernel.cache.BlockingPortalCache;
021 import com.liferay.portal.kernel.cache.PortalCache;
022 import com.liferay.portal.kernel.cache.PortalCacheManager;
023 import com.liferay.portal.kernel.log.Log;
024 import com.liferay.portal.kernel.log.LogFactoryUtil;
025 import com.liferay.portal.kernel.util.ReflectionUtil;
026 import com.liferay.portal.kernel.util.Validator;
027 import com.liferay.portal.util.PropsUtil;
028 import com.liferay.portal.util.PropsValues;
029
030 import java.io.Serializable;
031
032 import java.lang.reflect.Field;
033
034 import java.net.URL;
035
036 import java.util.HashMap;
037 import java.util.Map;
038
039 import javax.management.MBeanServer;
040
041 import net.sf.ehcache.Cache;
042 import net.sf.ehcache.CacheManager;
043 import net.sf.ehcache.Ehcache;
044 import net.sf.ehcache.config.CacheConfiguration;
045 import net.sf.ehcache.config.Configuration;
046 import net.sf.ehcache.management.ManagementService;
047 import net.sf.ehcache.util.FailSafeTimer;
048
049
056 public class EhcachePortalCacheManager<K extends Serializable, V>
057 implements PortalCacheManager<K, V> {
058
059 public void afterPropertiesSet() {
060 String configurationPath = PropsUtil.get(_configPropertyKey);
061
062 if (Validator.isNull(configurationPath)) {
063 configurationPath = _DEFAULT_CLUSTERED_EHCACHE_CONFIG_FILE;
064 }
065
066 _usingDefault = configurationPath.equals(
067 _DEFAULT_CLUSTERED_EHCACHE_CONFIG_FILE);
068
069 Configuration configuration = EhcacheConfigurationUtil.getConfiguration(
070 configurationPath, _clusterAware, _usingDefault);
071
072 _cacheManager = new CacheManager(configuration);
073
074 FailSafeTimer failSafeTimer = _cacheManager.getTimer();
075
076 failSafeTimer.cancel();
077
078 try {
079 Field cacheManagerTimerField = ReflectionUtil.getDeclaredField(
080 CacheManager.class, "cacheManagerTimer");
081
082 cacheManagerTimerField.set(_cacheManager, null);
083 }
084 catch (Exception e) {
085 throw new RuntimeException(e);
086 }
087
088 if (PropsValues.EHCACHE_PORTAL_CACHE_MANAGER_JMX_ENABLED) {
089 _managementService = new ManagementService(
090 _cacheManager, _mBeanServer, _registerCacheManager,
091 _registerCaches, _registerCacheConfigurations,
092 _registerCacheStatistics);
093
094 _managementService.init();
095 }
096 }
097
098 public void clearAll() {
099 _cacheManager.clearAll();
100 }
101
102 public void destroy() throws Exception {
103 try {
104 _cacheManager.shutdown();
105 }
106 finally {
107 if (_managementService != null) {
108 _managementService.dispose();
109 }
110 }
111 }
112
113 public PortalCache<K, V> getCache(String name) {
114 return getCache(name, false);
115 }
116
117 public PortalCache<K, V> getCache(String name, boolean blocking) {
118 PortalCache<K, V> portalCache = _ehcachePortalCaches.get(name);
119
120 if (portalCache == null) {
121 synchronized (_cacheManager) {
122 portalCache = _ehcachePortalCaches.get(name);
123
124 if (portalCache == null) {
125 portalCache = addCache(name, null);
126 }
127 }
128 }
129
130 if (PropsValues.TRANSACTIONAL_CACHE_ENABLED &&
131 (name.startsWith(EntityCacheImpl.CACHE_NAME) ||
132 name.startsWith(FinderCacheImpl.CACHE_NAME))) {
133
134 portalCache = new TransactionalPortalCache<K, V>(portalCache);
135 }
136
137 if (PropsValues.EHCACHE_BLOCKING_CACHE_ALLOWED && blocking) {
138 portalCache = new BlockingPortalCache<K, V>(portalCache);
139 }
140
141 return portalCache;
142 }
143
144 public CacheManager getEhcacheManager() {
145 return _cacheManager;
146 }
147
148 public void reconfigureCaches(URL configurationURL) {
149 Configuration configuration = EhcacheConfigurationUtil.getConfiguration(
150 configurationURL, _clusterAware, _usingDefault);
151
152 Map<String, CacheConfiguration> cacheConfigurations =
153 configuration.getCacheConfigurations();
154
155 for (CacheConfiguration cacheConfiguration :
156 cacheConfigurations.values()) {
157
158 Cache cache = new Cache(cacheConfiguration);
159
160 PortalCache<K, V> portalCache = addCache(cache.getName(), cache);
161
162 if (portalCache == null) {
163 _log.error(
164 "Failed to override cache " + cacheConfiguration.getName());
165 }
166 }
167 }
168
169 public void removeCache(String name) {
170 _ehcachePortalCaches.remove(name);
171
172 _cacheManager.removeCache(name);
173 }
174
175 public void setClusterAware(boolean clusterAware) {
176 _clusterAware = clusterAware;
177 }
178
179 public void setConfigPropertyKey(String configPropertyKey) {
180 _configPropertyKey = configPropertyKey;
181 }
182
183 public void setMBeanServer(MBeanServer mBeanServer) {
184 _mBeanServer = mBeanServer;
185 }
186
187 public void setRegisterCacheConfigurations(
188 boolean registerCacheConfigurations) {
189
190 _registerCacheConfigurations = registerCacheConfigurations;
191 }
192
193 public void setRegisterCacheManager(boolean registerCacheManager) {
194 _registerCacheManager = registerCacheManager;
195 }
196
197 public void setRegisterCaches(boolean registerCaches) {
198 _registerCaches = registerCaches;
199 }
200
201 public void setRegisterCacheStatistics(boolean registerCacheStatistics) {
202 _registerCacheStatistics = registerCacheStatistics;
203 }
204
205 protected PortalCache<K, V> addCache(String name, Cache cache) {
206 EhcachePortalCache<K, V> ehcachePortalCache = null;
207
208 synchronized (_cacheManager) {
209 if ((cache != null) && _cacheManager.cacheExists(name)) {
210 if (_log.isInfoEnabled()) {
211 _log.info("Overriding existing cache " + name);
212 }
213
214 _cacheManager.removeCache(name);
215 }
216
217 if (cache == null) {
218 if (!_cacheManager.cacheExists(name)) {
219 _cacheManager.addCache(name);
220 }
221 }
222 else {
223 _cacheManager.addCache(cache);
224 }
225
226 Ehcache ehcache = _cacheManager.getEhcache(name);
227
228 if (ehcache == null) {
229 return null;
230 }
231
232 ehcache.setStatisticsEnabled(
233 PropsValues.EHCACHE_STATISTICS_ENABLED);
234
235 ehcachePortalCache = _ehcachePortalCaches.get(name);
236
237 if (ehcachePortalCache == null) {
238 ehcachePortalCache = new EhcachePortalCache<K, V>(ehcache);
239
240 _ehcachePortalCaches.put(name, ehcachePortalCache);
241 }
242 else {
243 ehcachePortalCache.setEhcache(ehcache);
244 }
245
246 }
247
248 return ehcachePortalCache;
249 }
250
251 private static final String _DEFAULT_CLUSTERED_EHCACHE_CONFIG_FILE =
252 "/ehcache/liferay-multi-vm-clustered.xml";
253
254 private static Log _log = LogFactoryUtil.getLog(
255 EhcachePortalCacheManager.class);
256
257 private CacheManager _cacheManager;
258 private boolean _clusterAware;
259 private String _configPropertyKey;
260 private Map<String, EhcachePortalCache<K, V>> _ehcachePortalCaches =
261 new HashMap<String, EhcachePortalCache<K, V>>();
262 private ManagementService _managementService;
263 private MBeanServer _mBeanServer;
264 private boolean _registerCacheConfigurations = true;
265 private boolean _registerCacheManager = true;
266 private boolean _registerCaches = true;
267 private boolean _registerCacheStatistics = true;
268 private boolean _usingDefault;
269
270 }