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 = EhcacheConfigurationUtil.
132                                    getConfiguration(cacheConfigFile, true, _usingDefault);
133    
134                            Map<String, CacheConfiguration> cacheConfigurations =
135                                    configuration.getCacheConfigurations();
136    
137                            for (CacheConfiguration cacheConfiguration :
138                                            cacheConfigurations.values()) {
139    
140                                    Ehcache ehcache = new Cache(cacheConfiguration);
141    
142                                    reconfigureCache(ehcache);
143                            }
144                    }
145            }
146    
147            @Override
148            public void start(Settings settings, Properties properties)
149                    throws CacheException {
150    
151                    try {
152                            String configurationPath = null;
153    
154                            if (properties != null) {
155                                    configurationPath = (String)properties.get(
156                                            NET_SF_EHCACHE_CONFIGURATION_RESOURCE_NAME);
157                            }
158    
159                            if (Validator.isNull(configurationPath)) {
160                                    configurationPath = _DEFAULT_CLUSTERED_EHCACHE_CONFIG_FILE;
161                            }
162    
163                            Configuration configuration = null;
164    
165                            if (Validator.isNull(configurationPath)) {
166                                    configuration = ConfigurationFactory.parseConfiguration();
167                            }
168                            else {
169                                    _usingDefault = configurationPath.equals(
170                                            _DEFAULT_CLUSTERED_EHCACHE_CONFIG_FILE);
171    
172                                    configuration = EhcacheConfigurationUtil.getConfiguration(
173                                            configurationPath, true, _usingDefault);
174                            }
175    
176                            /*Object transactionManager =
177                                    getOnePhaseCommitSyncTransactionManager(settings, properties);
178    
179                            configuration.setDefaultTransactionManager(transactionManager);*/
180    
181                            manager = new CacheManager(configuration);
182    
183                            boolean skipUpdateCheck = GetterUtil.getBoolean(
184                                    SystemProperties.get("net.sf.ehcache.skipUpdateCheck"));
185                            boolean tcActive = GetterUtil.getBoolean(
186                                    SystemProperties.get("tc.active"));
187    
188                            if (skipUpdateCheck && !tcActive) {
189                                    FailSafeTimer failSafeTimer = manager.getTimer();
190    
191                                    failSafeTimer.cancel();
192    
193                                    try {
194                                            Field cacheManagerTimerField =
195                                                    ReflectionUtil.getDeclaredField(
196                                                            CacheManager.class, "cacheManagerTimer");
197    
198                                            cacheManagerTimerField.set(manager, null);
199                                    }
200                                    catch (Exception e) {
201                                            throw new RuntimeException(e);
202                                    }
203                            }
204    
205                            mbeanRegistrationHelper.registerMBean(manager, properties);
206    
207                            _mBeanRegisteringPortalLifecycle =
208                                    new MBeanRegisteringPortalLifecycle(manager);
209    
210                            _mBeanRegisteringPortalLifecycle.registerPortalLifecycle(
211                                    PortalLifecycle.METHOD_INIT);
212                    }
213                    catch (net.sf.ehcache.CacheException ce) {
214                            throw new CacheException(ce);
215                    }
216            }
217    
218            protected void configureCache(String regionName) {
219                    synchronized (manager) {
220                            Ehcache ehcache = manager.getEhcache(regionName);
221    
222                            if (ehcache == null) {
223                                    manager.addCache(regionName);
224    
225                                    ehcache = manager.getEhcache(regionName);
226                            }
227    
228                            if (!(ehcache instanceof ModifiableEhcacheWrapper)) {
229                                    Ehcache modifiableEhcacheWrapper = new ModifiableEhcacheWrapper(
230                                            ehcache);
231    
232                                    manager.replaceCacheWithDecoratedCache(
233                                            ehcache, modifiableEhcacheWrapper);
234                            }
235                    }
236            }
237    
238            protected void reconfigureCache(Ehcache replacementCache) {
239                    String cacheName = replacementCache.getName();
240    
241                    Ehcache ehcache = manager.getEhcache(cacheName);
242    
243                    if ((ehcache != null) &&
244                            (ehcache instanceof ModifiableEhcacheWrapper)) {
245    
246                            if (_log.isInfoEnabled()) {
247                                    _log.info("Reconfiguring Hibernate cache " + cacheName);
248                            }
249    
250                            ModifiableEhcacheWrapper modifiableEhcacheWrapper =
251                                    (ModifiableEhcacheWrapper)ehcache;
252    
253                            manager.replaceCacheWithDecoratedCache(
254                                    ehcache, modifiableEhcacheWrapper.getWrappedCache());
255    
256                            manager.removeCache(cacheName);
257    
258                            manager.addCache(replacementCache);
259    
260                            modifiableEhcacheWrapper.setWrappedCache(replacementCache);
261    
262                            manager.replaceCacheWithDecoratedCache(
263                                    replacementCache, modifiableEhcacheWrapper);
264                    }
265                    else {
266                            if (_log.isInfoEnabled()) {
267                                    _log.info("Configuring Hibernate cache " + cacheName);
268                            }
269    
270                            if (ehcache != null) {
271                                    manager.removeCache(cacheName);
272                            }
273    
274                            ehcache = new ModifiableEhcacheWrapper(replacementCache);
275    
276                            manager.addCache(replacementCache);
277    
278                            manager.replaceCacheWithDecoratedCache(replacementCache, ehcache);
279                    }
280            }
281    
282            private static final String _DEFAULT_CLUSTERED_EHCACHE_CONFIG_FILE =
283                    "/ehcache/hibernate-clustered.xml";
284    
285            private static Log _log = LogFactoryUtil.getLog(
286                    LiferayEhcacheRegionFactory.class);
287    
288            private MBeanRegisteringPortalLifecycle _mBeanRegisteringPortalLifecycle;
289            private boolean _usingDefault;
290    
291    }