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