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