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