001    /**
002     * Copyright (c) 2000-2013 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.dao.orm.hibernate.region;
016    
017    import com.liferay.portal.cache.ehcache.EhcacheConfigurationUtil;
018    import com.liferay.portal.cache.ehcache.ModifiableEhcacheWrapper;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.util.GetterUtil;
022    import com.liferay.portal.kernel.util.PortalLifecycle;
023    import com.liferay.portal.kernel.util.ReflectionUtil;
024    import com.liferay.portal.kernel.util.SystemProperties;
025    import com.liferay.portal.kernel.util.Validator;
026    
027    import java.lang.reflect.Field;
028    
029    import java.net.URL;
030    
031    import java.util.Map;
032    import java.util.Properties;
033    
034    import net.sf.ehcache.Cache;
035    import net.sf.ehcache.CacheManager;
036    import net.sf.ehcache.Ehcache;
037    import net.sf.ehcache.config.CacheConfiguration;
038    import net.sf.ehcache.config.Configuration;
039    import net.sf.ehcache.config.ConfigurationFactory;
040    import net.sf.ehcache.hibernate.EhCacheRegionFactory;
041    import net.sf.ehcache.hibernate.regions.EhcacheCollectionRegion;
042    import net.sf.ehcache.hibernate.regions.EhcacheEntityRegion;
043    import net.sf.ehcache.hibernate.regions.EhcacheQueryResultsRegion;
044    import net.sf.ehcache.hibernate.regions.EhcacheTimestampsRegion;
045    import net.sf.ehcache.util.FailSafeTimer;
046    
047    import org.hibernate.cache.CacheDataDescription;
048    import org.hibernate.cache.CacheException;
049    import org.hibernate.cache.CollectionRegion;
050    import org.hibernate.cache.EntityRegion;
051    import org.hibernate.cache.QueryResultsRegion;
052    import org.hibernate.cache.TimestampsRegion;
053    import org.hibernate.cfg.Settings;
054    
055    /**
056     * @author Edward Han
057     */
058    public class LiferayEhcacheRegionFactory extends EhCacheRegionFactory {
059    
060            public LiferayEhcacheRegionFactory(Properties properties) {
061                    super(properties);
062            }
063    
064            @Override
065            public CollectionRegion buildCollectionRegion(
066                            String regionName, Properties properties,
067                            CacheDataDescription cacheDataDescription)
068                    throws CacheException {
069    
070                    configureCache(regionName);
071    
072                    EhcacheCollectionRegion ehcacheCollectionRegion =
073                            (EhcacheCollectionRegion)super.buildCollectionRegion(
074                                    regionName, properties, cacheDataDescription);
075    
076                    return new CollectionRegionWrapper(ehcacheCollectionRegion);
077            }
078    
079            @Override
080            public EntityRegion buildEntityRegion(
081                            String regionName, Properties properties,
082                            CacheDataDescription cacheDataDescription)
083                    throws CacheException {
084    
085                    configureCache(regionName);
086    
087                    EhcacheEntityRegion ehcacheEntityRegion =
088                            (EhcacheEntityRegion)super.buildEntityRegion(
089                                    regionName, properties, cacheDataDescription);
090    
091                    return new EntityRegionWrapper(ehcacheEntityRegion);
092            }
093    
094            @Override
095            public QueryResultsRegion buildQueryResultsRegion(
096                            String regionName, Properties properties)
097                    throws CacheException {
098    
099                    configureCache(regionName);
100    
101                    EhcacheQueryResultsRegion ehcacheQueryResultsRegion =
102                            (EhcacheQueryResultsRegion)super.buildQueryResultsRegion(
103                                    regionName, properties);
104    
105                    return new QueryResultsRegionWrapper(ehcacheQueryResultsRegion);
106            }
107    
108            @Override
109            public TimestampsRegion buildTimestampsRegion(
110                            String regionName, Properties properties)
111                    throws CacheException {
112    
113                    configureCache(regionName);
114    
115                    EhcacheTimestampsRegion ehcacheTimestampsRegion =
116                            (EhcacheTimestampsRegion)super.buildTimestampsRegion(
117                                    regionName, properties);
118    
119                    TimestampsRegion timestampsRegion = new TimestampsRegionWrapper(
120                            ehcacheTimestampsRegion);
121    
122                    return timestampsRegion;
123            }
124    
125            public CacheManager getCacheManager() {
126                    return manager;
127            }
128    
129            public void reconfigureCaches(URL cacheConfigFile) {
130                    synchronized (manager) {
131                            Configuration configuration =
132                                    EhcacheConfigurationUtil.getConfiguration(
133                                            cacheConfigFile, true, _usingDefault);
134    
135                            Map<String, CacheConfiguration> cacheConfigurations =
136                                    configuration.getCacheConfigurations();
137    
138                            for (CacheConfiguration cacheConfiguration :
139                                            cacheConfigurations.values()) {
140    
141                                    Ehcache ehcache = new Cache(cacheConfiguration);
142    
143                                    reconfigureCache(ehcache);
144                            }
145                    }
146            }
147    
148            @Override
149            public void start(Settings settings, Properties properties)
150                    throws CacheException {
151    
152                    try {
153                            String configurationPath = null;
154    
155                            if (properties != null) {
156                                    configurationPath = (String)properties.get(
157                                            NET_SF_EHCACHE_CONFIGURATION_RESOURCE_NAME);
158                            }
159    
160                            if (Validator.isNull(configurationPath)) {
161                                    configurationPath = _DEFAULT_CLUSTERED_EHCACHE_CONFIG_FILE;
162                            }
163    
164                            Configuration configuration = null;
165    
166                            if (Validator.isNull(configurationPath)) {
167                                    configuration = ConfigurationFactory.parseConfiguration();
168                            }
169                            else {
170                                    _usingDefault = configurationPath.equals(
171                                            _DEFAULT_CLUSTERED_EHCACHE_CONFIG_FILE);
172    
173                                    configuration = EhcacheConfigurationUtil.getConfiguration(
174                                            configurationPath, true, _usingDefault);
175                            }
176    
177                            /*Object transactionManager =
178                                    getOnePhaseCommitSyncTransactionManager(settings, properties);
179    
180                            configuration.setDefaultTransactionManager(transactionManager);*/
181    
182                            manager = new CacheManager(configuration);
183    
184                            boolean skipUpdateCheck = GetterUtil.getBoolean(
185                                    SystemProperties.get("net.sf.ehcache.skipUpdateCheck"));
186                            boolean tcActive = GetterUtil.getBoolean(
187                                    SystemProperties.get("tc.active"));
188    
189                            if (skipUpdateCheck && !tcActive) {
190                                    FailSafeTimer failSafeTimer = manager.getTimer();
191    
192                                    failSafeTimer.cancel();
193    
194                                    try {
195                                            Field cacheManagerTimerField =
196                                                    ReflectionUtil.getDeclaredField(
197                                                            CacheManager.class, "cacheManagerTimer");
198    
199                                            cacheManagerTimerField.set(manager, null);
200                                    }
201                                    catch (Exception e) {
202                                            throw new RuntimeException(e);
203                                    }
204                            }
205    
206                            mbeanRegistrationHelper.registerMBean(manager, properties);
207    
208                            _mBeanRegisteringPortalLifecycle =
209                                    new MBeanRegisteringPortalLifecycle(manager);
210    
211                            _mBeanRegisteringPortalLifecycle.registerPortalLifecycle(
212                                    PortalLifecycle.METHOD_INIT);
213                    }
214                    catch (net.sf.ehcache.CacheException ce) {
215                            throw new CacheException(ce);
216                    }
217            }
218    
219            protected void configureCache(String regionName) {
220                    synchronized (manager) {
221                            Ehcache ehcache = manager.getEhcache(regionName);
222    
223                            if (ehcache == null) {
224                                    manager.addCache(regionName);
225    
226                                    ehcache = manager.getEhcache(regionName);
227                            }
228    
229                            if (!(ehcache instanceof ModifiableEhcacheWrapper)) {
230                                    Ehcache modifiableEhcacheWrapper = new ModifiableEhcacheWrapper(
231                                            ehcache);
232    
233                                    manager.replaceCacheWithDecoratedCache(
234                                            ehcache, modifiableEhcacheWrapper);
235                            }
236                    }
237            }
238    
239            protected void reconfigureCache(Ehcache replacementCache) {
240                    String cacheName = replacementCache.getName();
241    
242                    Ehcache ehcache = manager.getEhcache(cacheName);
243    
244                    if ((ehcache != null) &&
245                            (ehcache instanceof ModifiableEhcacheWrapper)) {
246    
247                            if (_log.isInfoEnabled()) {
248                                    _log.info("Reconfiguring Hibernate cache " + cacheName);
249                            }
250    
251                            ModifiableEhcacheWrapper modifiableEhcacheWrapper =
252                                    (ModifiableEhcacheWrapper)ehcache;
253    
254                            manager.replaceCacheWithDecoratedCache(
255                                    ehcache, modifiableEhcacheWrapper.getWrappedCache());
256    
257                            manager.removeCache(cacheName);
258    
259                            manager.addCache(replacementCache);
260    
261                            modifiableEhcacheWrapper.setWrappedCache(replacementCache);
262    
263                            manager.replaceCacheWithDecoratedCache(
264                                    replacementCache, modifiableEhcacheWrapper);
265                    }
266                    else {
267                            if (_log.isInfoEnabled()) {
268                                    _log.info("Configuring Hibernate cache " + cacheName);
269                            }
270    
271                            if (ehcache != null) {
272                                    manager.removeCache(cacheName);
273                            }
274    
275                            ehcache = new ModifiableEhcacheWrapper(replacementCache);
276    
277                            manager.addCache(replacementCache);
278    
279                            manager.replaceCacheWithDecoratedCache(replacementCache, ehcache);
280                    }
281            }
282    
283            private static final String _DEFAULT_CLUSTERED_EHCACHE_CONFIG_FILE =
284                    "/ehcache/hibernate-clustered.xml";
285    
286            private static Log _log = LogFactoryUtil.getLog(
287                    LiferayEhcacheRegionFactory.class);
288    
289            private MBeanRegisteringPortalLifecycle _mBeanRegisteringPortalLifecycle;
290            private boolean _usingDefault;
291    
292    }