001    /**
002     * Copyright (c) 2000-present 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.AbstractPortalCacheManager;
018    import com.liferay.portal.kernel.cache.PortalCache;
019    import com.liferay.portal.kernel.cache.configuration.PortalCacheManagerConfiguration;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.util.ObjectValuePair;
023    import com.liferay.portal.kernel.util.ReflectionUtil;
024    import com.liferay.portal.kernel.util.Validator;
025    import com.liferay.portal.util.PropsUtil;
026    import com.liferay.portal.util.PropsValues;
027    
028    import java.io.Serializable;
029    
030    import java.lang.reflect.Field;
031    
032    import java.net.URL;
033    
034    import java.util.Map;
035    
036    import javax.management.MBeanServer;
037    
038    import net.sf.ehcache.Cache;
039    import net.sf.ehcache.CacheManager;
040    import net.sf.ehcache.config.CacheConfiguration;
041    import net.sf.ehcache.config.Configuration;
042    import net.sf.ehcache.event.CacheManagerEventListenerRegistry;
043    import net.sf.ehcache.management.ManagementService;
044    import net.sf.ehcache.util.FailSafeTimer;
045    
046    /**
047     * @author Joseph Shum
048     * @author Raymond Aug??
049     * @author Michael C. Han
050     * @author Shuyang Zhou
051     * @author Edward Han
052     */
053    public class EhcachePortalCacheManager<K extends Serializable, V>
054            extends AbstractPortalCacheManager<K, V> {
055    
056            public CacheManager getEhcacheManager() {
057                    return _cacheManager;
058            }
059    
060            @Override
061            public String getName() {
062                    return _name;
063            }
064    
065            @Override
066            public void reconfigureCaches(URL configurationURL) {
067                    _configurationPair = EhcacheConfigurationHelperUtil.getConfiguration(
068                            configurationURL, clusterAware, _usingDefault);
069    
070                    Configuration ehcacheConfiguration = _configurationPair.getKey();
071    
072                    if (!_name.equals(ehcacheConfiguration.getName())) {
073                            return;
074                    }
075    
076                    reconfigEhcache(ehcacheConfiguration);
077    
078                    reconfigPortalCache(_configurationPair.getValue());
079            }
080    
081            public void setConfigPropertyKey(String configPropertyKey) {
082                    _configPropertyKey = configPropertyKey;
083            }
084    
085            public void setMBeanServer(MBeanServer mBeanServer) {
086                    _mBeanServer = mBeanServer;
087            }
088    
089            public void setRegisterCacheConfigurations(
090                    boolean registerCacheConfigurations) {
091    
092                    _registerCacheConfigurations = registerCacheConfigurations;
093            }
094    
095            public void setRegisterCacheManager(boolean registerCacheManager) {
096                    _registerCacheManager = registerCacheManager;
097            }
098    
099            public void setRegisterCaches(boolean registerCaches) {
100                    _registerCaches = registerCaches;
101            }
102    
103            public void setRegisterCacheStatistics(boolean registerCacheStatistics) {
104                    _registerCacheStatistics = registerCacheStatistics;
105            }
106    
107            @Override
108            protected PortalCache<K, V> createPortalCache(String cacheName) {
109                    synchronized (_cacheManager) {
110                            if (!_cacheManager.cacheExists(cacheName)) {
111                                    _cacheManager.addCache(cacheName);
112                            }
113                    }
114    
115                    Cache cache = _cacheManager.getCache(cacheName);
116    
117                    return new EhcachePortalCache<K, V>(this, cache);
118            }
119    
120            @Override
121            protected void doClearAll() {
122                    _cacheManager.clearAll();
123            }
124    
125            @Override
126            protected void doDestroy() {
127                    try {
128                            _cacheManager.shutdown();
129                    }
130                    finally {
131                            if (_managementService != null) {
132                                    _managementService.dispose();
133                            }
134                    }
135            }
136    
137            @Override
138            protected void doRemoveCache(String cacheName) {
139                    _cacheManager.removeCache(cacheName);
140            }
141    
142            @Override
143            protected PortalCacheManagerConfiguration
144                    getPortalCacheManagerConfiguration() {
145    
146                    return _configurationPair.getValue();
147            }
148    
149            @Override
150            protected void initPortalCacheManager() {
151                    String configurationPath = PropsUtil.get(_configPropertyKey);
152    
153                    if (Validator.isNull(configurationPath)) {
154                            configurationPath = _DEFAULT_CLUSTERED_EHCACHE_CONFIG_FILE;
155                    }
156    
157                    _usingDefault = configurationPath.equals(
158                            _DEFAULT_CLUSTERED_EHCACHE_CONFIG_FILE);
159    
160                    _configurationPair = EhcacheConfigurationHelperUtil.getConfiguration(
161                            configurationPath, clusterAware, _usingDefault);
162    
163                    _cacheManager = CacheManagerUtil.createCacheManager(
164                            _configurationPair.getKey());
165    
166                    _name = _cacheManager.getName();
167    
168                    FailSafeTimer failSafeTimer = _cacheManager.getTimer();
169    
170                    failSafeTimer.cancel();
171    
172                    try {
173                            Field cacheManagerTimerField = ReflectionUtil.getDeclaredField(
174                                    CacheManager.class, "cacheManagerTimer");
175    
176                            cacheManagerTimerField.set(_cacheManager, null);
177                    }
178                    catch (Exception e) {
179                            throw new RuntimeException(e);
180                    }
181    
182                    if (PropsValues.EHCACHE_PORTAL_CACHE_MANAGER_JMX_ENABLED) {
183                            _managementService = new ManagementService(
184                                    _cacheManager, _mBeanServer, _registerCacheManager,
185                                    _registerCaches, _registerCacheConfigurations,
186                                    _registerCacheStatistics);
187    
188                            _managementService.init();
189                    }
190    
191                    CacheManagerEventListenerRegistry cacheManagerEventListenerRegistry =
192                            _cacheManager.getCacheManagerEventListenerRegistry();
193    
194                    cacheManagerEventListenerRegistry.registerListener(
195                            new PortalCacheManagerEventListener(
196                                    aggregatedCacheManagerListener));
197            }
198    
199            protected void reconfigEhcache(Configuration configuration) {
200                    Map<String, CacheConfiguration> cacheConfigurations =
201                            configuration.getCacheConfigurations();
202    
203                    for (CacheConfiguration cacheConfiguration :
204                                    cacheConfigurations.values()) {
205    
206                            String portalCacheName = cacheConfiguration.getName();
207    
208                            synchronized (_cacheManager) {
209                                    if (_cacheManager.cacheExists(portalCacheName)) {
210                                            if (_log.isInfoEnabled()) {
211                                                    _log.info(
212                                                            "Overriding existing cache " + portalCacheName);
213                                            }
214    
215                                            _cacheManager.removeCache(portalCacheName);
216                                    }
217    
218                                    Cache cache = new Cache(cacheConfiguration);
219    
220                                    _cacheManager.addCache(cache);
221                            }
222                    }
223            }
224    
225            private static final String _DEFAULT_CLUSTERED_EHCACHE_CONFIG_FILE =
226                    "/ehcache/liferay-multi-vm-clustered.xml";
227    
228            private static final Log _log = LogFactoryUtil.getLog(
229                    EhcachePortalCacheManager.class);
230    
231            private CacheManager _cacheManager;
232            private String _configPropertyKey;
233            private ObjectValuePair<Configuration, PortalCacheManagerConfiguration>
234                    _configurationPair;
235            private ManagementService _managementService;
236            private MBeanServer _mBeanServer;
237            private String _name;
238            private boolean _registerCacheConfigurations = true;
239            private boolean _registerCacheManager = true;
240            private boolean _registerCaches = true;
241            private boolean _registerCacheStatistics = true;
242            private boolean _usingDefault;
243    
244    }