001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
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.lang.reflect.Field;
031    
032    import java.net.URL;
033    
034    import java.util.HashMap;
035    import java.util.Map;
036    
037    import javax.management.MBeanServer;
038    
039    import net.sf.ehcache.Cache;
040    import net.sf.ehcache.CacheManager;
041    import net.sf.ehcache.Ehcache;
042    import net.sf.ehcache.config.CacheConfiguration;
043    import net.sf.ehcache.config.Configuration;
044    import net.sf.ehcache.management.ManagementService;
045    import net.sf.ehcache.util.FailSafeTimer;
046    
047    /**
048     * @author Joseph Shum
049     * @author Raymond Augé
050     * @author Michael C. Han
051     * @author Shuyang Zhou
052     * @author Edward Han
053     */
054    public class EhcachePortalCacheManager implements PortalCacheManager {
055    
056            public void afterPropertiesSet() {
057                    String configurationPath = PropsUtil.get(_configPropertyKey);
058    
059                    if (Validator.isNull(configurationPath)) {
060                            configurationPath = _DEFAULT_CLUSTERED_EHCACHE_CONFIG_FILE;
061                    }
062    
063                    boolean usingDefault = configurationPath.equals(
064                            _DEFAULT_CLUSTERED_EHCACHE_CONFIG_FILE);
065    
066                    Configuration configuration = EhcacheConfigurationUtil.getConfiguration(
067                            configurationPath, _clusterAware, usingDefault);
068    
069                    _cacheManager = new CacheManager(configuration);
070    
071                    FailSafeTimer failSafeTimer = _cacheManager.getTimer();
072    
073                    failSafeTimer.cancel();
074    
075                    try {
076                            Field cacheManagerTimerField = ReflectionUtil.getDeclaredField(
077                                    CacheManager.class, "cacheManagerTimer");
078    
079                            cacheManagerTimerField.set(_cacheManager, null);
080                    }
081                    catch (Exception e) {
082                            throw new RuntimeException(e);
083                    }
084    
085                    if (PropsValues.EHCACHE_PORTAL_CACHE_MANAGER_JMX_ENABLED) {
086                            _managementService = new ManagementService(
087                                    _cacheManager, _mBeanServer, _registerCacheManager,
088                                    _registerCaches, _registerCacheConfigurations,
089                                    _registerCacheStatistics);
090    
091                            _managementService.init();
092                    }
093            }
094    
095            public void clearAll() {
096                    _cacheManager.clearAll();
097            }
098    
099            public void destroy() throws Exception {
100                    try {
101                            _cacheManager.shutdown();
102                    }
103                    finally {
104                            if (_managementService != null) {
105                                    _managementService.dispose();
106                            }
107                    }
108            }
109    
110            public PortalCache getCache(String name) {
111                    return getCache(name, false);
112            }
113    
114            public PortalCache getCache(String name, boolean blocking) {
115                    PortalCache portalCache = _ehcachePortalCaches.get(name);
116    
117                    if (portalCache == null) {
118                            synchronized (_cacheManager) {
119                                    portalCache = _ehcachePortalCaches.get(name);
120    
121                                    if (portalCache == null) {
122                                            portalCache = addCache(name, null);
123                                    }
124                            }
125                    }
126    
127                    if (PropsValues.TRANSACTIONAL_CACHE_ENABLED &&
128                            (name.startsWith(EntityCacheImpl.CACHE_NAME) ||
129                             name.startsWith(FinderCacheImpl.CACHE_NAME))) {
130    
131                            portalCache = new TransactionalPortalCache(portalCache);
132                    }
133    
134                    if (PropsValues.EHCACHE_BLOCKING_CACHE_ALLOWED && blocking) {
135                            portalCache = new BlockingPortalCache(portalCache);
136                    }
137    
138                    return portalCache;
139            }
140    
141            public CacheManager getEhcacheManager() {
142                    return _cacheManager;
143            }
144    
145            public void reconfigureCaches(URL configurationURL) {
146                    Configuration configuration = EhcacheConfigurationUtil.getConfiguration(
147                            configurationURL, _clusterAware);
148    
149                    Map<String, CacheConfiguration> cacheConfigurations =
150                            configuration.getCacheConfigurations();
151    
152                    for (CacheConfiguration cacheConfiguration :
153                                    cacheConfigurations.values()) {
154    
155                            Cache cache = new Cache(cacheConfiguration);
156    
157                            PortalCache portalCache = addCache(cache.getName(), cache);
158    
159                            if (portalCache == null) {
160                                    _log.error(
161                                            "Failed to override cache " + cacheConfiguration.getName());
162                            }
163                    }
164            }
165    
166            public void removeCache(String name) {
167                    _ehcachePortalCaches.remove(name);
168    
169                    _cacheManager.removeCache(name);
170            }
171    
172            public void setClusterAware(boolean clusterAware) {
173                    _clusterAware = clusterAware;
174            }
175    
176            public void setConfigPropertyKey(String configPropertyKey) {
177                    _configPropertyKey = configPropertyKey;
178            }
179    
180            public void setMBeanServer(MBeanServer mBeanServer) {
181                    _mBeanServer = mBeanServer;
182            }
183    
184            public void setRegisterCacheConfigurations(
185                    boolean registerCacheConfigurations) {
186    
187                    _registerCacheConfigurations = registerCacheConfigurations;
188            }
189    
190            public void setRegisterCacheManager(boolean registerCacheManager) {
191                    _registerCacheManager = registerCacheManager;
192            }
193    
194            public void setRegisterCaches(boolean registerCaches) {
195                    _registerCaches = registerCaches;
196            }
197    
198            public void setRegisterCacheStatistics(boolean registerCacheStatistics) {
199                    _registerCacheStatistics = registerCacheStatistics;
200            }
201    
202            protected PortalCache addCache(String name, Cache cache) {
203                    EhcachePortalCache ehcachePortalCache = null;
204    
205                    synchronized (_cacheManager) {
206                            if ((cache != null) && _cacheManager.cacheExists(name)) {
207                                    if (_log.isInfoEnabled()) {
208                                            _log.info("Overriding existing cache " + name);
209                                    }
210    
211                                    _cacheManager.removeCache(name);
212                            }
213    
214                            if (cache == null) {
215                                    if (!_cacheManager.cacheExists(name)) {
216                                            _cacheManager.addCache(name);
217                                    }
218                            }
219                            else {
220                                    _cacheManager.addCache(cache);
221                            }
222    
223                            Ehcache ehcache = _cacheManager.getEhcache(name);
224    
225                            if (ehcache == null) {
226                                    return null;
227                            }
228    
229                            ehcache.setStatisticsEnabled(
230                                    PropsValues.EHCACHE_STATISTICS_ENABLED);
231    
232                            ehcachePortalCache = _ehcachePortalCaches.get(name);
233    
234                            if (ehcachePortalCache == null) {
235                                    ehcachePortalCache = new EhcachePortalCache(ehcache);
236    
237                                    _ehcachePortalCaches.put(name, ehcachePortalCache);
238                            }
239                            else {
240                                    ehcachePortalCache.setEhcache(ehcache);
241                            }
242    
243                    }
244    
245                    return ehcachePortalCache;
246            }
247    
248            private static final String _DEFAULT_CLUSTERED_EHCACHE_CONFIG_FILE =
249                    "/ehcache/liferay-multi-vm-clustered.xml";
250    
251            private static Log _log = LogFactoryUtil.getLog(
252                    EhcachePortalCacheManager.class);
253    
254            private CacheManager _cacheManager;
255            private boolean _clusterAware;
256            private String _configPropertyKey;
257            private Map<String, EhcachePortalCache> _ehcachePortalCaches =
258                    new HashMap<String, EhcachePortalCache>();
259            private ManagementService _managementService;
260            private MBeanServer _mBeanServer;
261            private boolean _registerCacheConfigurations = true;
262            private boolean _registerCacheManager = true;
263            private boolean _registerCaches = true;
264            private boolean _registerCacheStatistics = true;
265    
266    }