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