/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.cache.ehcache.internal;
import com.liferay.portal.cache.BasePortalCacheManager;
import com.liferay.portal.cache.configuration.PortalCacheConfiguration;
import com.liferay.portal.cache.configuration.PortalCacheManagerConfiguration;
import com.liferay.portal.cache.ehcache.EhcacheUnwrapUtil;
import com.liferay.portal.cache.ehcache.internal.configurator.BaseEhcachePortalCacheManagerConfigurator;
import com.liferay.portal.cache.ehcache.internal.event.ConfigurableEhcachePortalCacheListener;
import com.liferay.portal.cache.ehcache.internal.event.PortalCacheManagerEventListener;
import com.liferay.portal.kernel.cache.PortalCache;
import com.liferay.portal.kernel.cache.PortalCacheListener;
import com.liferay.portal.kernel.cache.PortalCacheListenerScope;
import com.liferay.portal.kernel.cache.configurator.PortalCacheConfiguratorSettings;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.AggregateClassLoader;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.ObjectValuePair;
import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
import com.liferay.portal.kernel.util.Props;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.ReflectionUtil;
import com.liferay.portal.kernel.util.Validator;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.Map;
import javax.management.MBeanServer;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.config.Configuration;
import net.sf.ehcache.event.CacheManagerEventListenerRegistry;
import net.sf.ehcache.management.ManagementService;
import net.sf.ehcache.util.FailSafeTimer;
/**
* @author Joseph Shum
* @author Raymond Augé
* @author Michael C. Han
* @author Shuyang Zhou
* @author Edward Han
*/
public class EhcachePortalCacheManager<K extends Serializable, V>
extends BasePortalCacheManager<K, V> {
public CacheManager getEhcacheManager() {
return _cacheManager;
}
@Override
public void reconfigurePortalCaches(URL configurationURL) {
ObjectValuePair<Configuration, PortalCacheManagerConfiguration>
configurationObjectValuePair =
baseEhcachePortalCacheManagerConfigurator.
getConfigurationObjectValuePair(
getPortalCacheManagerName(), configurationURL,
_usingDefault);
reconfigEhcache(configurationObjectValuePair.getKey());
reconfigPortalCache(configurationObjectValuePair.getValue());
}
public void setConfigFile(String configFile) {
_configFile = configFile;
}
public void setDefaultConfigFile(String defaultConfigFile) {
_defaultConfigFile = defaultConfigFile;
}
public void setRegisterCacheConfigurations(
boolean registerCacheConfigurations) {
_registerCacheConfigurations = registerCacheConfigurations;
}
public void setRegisterCacheManager(boolean registerCacheManager) {
_registerCacheManager = registerCacheManager;
}
public void setRegisterCaches(boolean registerCaches) {
_registerCaches = registerCaches;
}
public void setRegisterCacheStatistics(boolean registerCacheStatistics) {
_registerCacheStatistics = registerCacheStatistics;
}
public void setStopCacheManagerTimer(boolean stopCacheManagerTimer) {
_stopCacheManagerTimer = stopCacheManagerTimer;
}
protected Ehcache createEhcache(
String portalCacheName, CacheConfiguration cacheConfiguration) {
if (_cacheManager.cacheExists(portalCacheName)) {
if (_log.isInfoEnabled()) {
_log.info("Overriding existing cache " + portalCacheName);
}
_cacheManager.removeCache(portalCacheName);
}
Cache cache = new Cache(cacheConfiguration);
_cacheManager.addCache(cache);
return cache;
}
@Override
protected PortalCache<K, V> createPortalCache(
PortalCacheConfiguration portalCacheConfiguration) {
String portalCacheName = portalCacheConfiguration.getPortalCacheName();
synchronized (_cacheManager) {
if (!_cacheManager.cacheExists(portalCacheName)) {
_cacheManager.addCache(portalCacheName);
}
}
Cache cache = _cacheManager.getCache(portalCacheName);
EhcachePortalCacheConfiguration ehcachePortalCacheConfiguration =
(EhcachePortalCacheConfiguration)portalCacheConfiguration;
if (ehcachePortalCacheConfiguration.isRequireSerialization()) {
return new SerializableEhcachePortalCache<>(this, cache);
}
return new EhcachePortalCache<>(this, cache);
}
@Override
protected void doClearAll() {
for (String cacheName : _cacheManager.getCacheNames()) {
Cache cache = _cacheManager.getCache(cacheName);
if (cache != null) {
cache.removeAll();
}
}
}
@Override
protected void doDestroy() {
_cacheManager.shutdown();
if (_managementService != null) {
_managementService.dispose();
}
}
@Override
protected void doRemovePortalCache(String portalCacheName) {
_cacheManager.removeCache(portalCacheName);
}
@Override
protected PortalCacheManagerConfiguration
getPortalCacheManagerConfiguration() {
return _portalCacheManagerConfiguration;
}
@Override
protected void initPortalCacheManager() {
setBlockingPortalCacheAllowed(
GetterUtil.getBoolean(
props.get(PropsKeys.EHCACHE_BLOCKING_CACHE_ALLOWED)));
setTransactionalPortalCacheEnabled(
GetterUtil.getBoolean(
props.get(PropsKeys.TRANSACTIONAL_CACHE_ENABLED)));
setTransactionalPortalCacheNames(
GetterUtil.getStringValues(
props.getArray(PropsKeys.TRANSACTIONAL_CACHE_NAMES)));
if (Validator.isNull(_configFile)) {
_configFile = _defaultConfigFile;
}
URL configFileURL =
BaseEhcachePortalCacheManagerConfigurator.class.getResource(
_configFile);
if (configFileURL == null) {
ClassLoader classLoader = PortalClassLoaderUtil.getClassLoader();
configFileURL = classLoader.getResource(_configFile);
}
_usingDefault = _configFile.equals(_defaultConfigFile);
ObjectValuePair<Configuration, PortalCacheManagerConfiguration>
configurationObjectValuePair =
baseEhcachePortalCacheManagerConfigurator.
getConfigurationObjectValuePair(
getPortalCacheManagerName(), configFileURL,
_usingDefault);
_cacheManager = new CacheManager(configurationObjectValuePair.getKey());
_portalCacheManagerConfiguration =
configurationObjectValuePair.getValue();
if (_stopCacheManagerTimer) {
FailSafeTimer failSafeTimer = _cacheManager.getTimer();
failSafeTimer.cancel();
try {
Field cacheManagerTimerField = ReflectionUtil.getDeclaredField(
CacheManager.class, "cacheManagerTimer");
cacheManagerTimerField.set(_cacheManager, null);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
CacheManagerEventListenerRegistry cacheManagerEventListenerRegistry =
_cacheManager.getCacheManagerEventListenerRegistry();
cacheManagerEventListenerRegistry.registerListener(
new PortalCacheManagerEventListener(
aggregatedPortalCacheManagerListener));
if (GetterUtil.getBoolean(
props.get(
PropsKeys.EHCACHE_PORTAL_CACHE_MANAGER_JMX_ENABLED))) {
_managementService = new ManagementService(
_cacheManager, mBeanServer, _registerCacheManager,
_registerCaches, _registerCacheConfigurations,
_registerCacheStatistics);
_managementService.init();
}
}
protected void reconfigEhcache(Configuration configuration) {
Map<String, CacheConfiguration> cacheConfigurations =
configuration.getCacheConfigurations();
for (CacheConfiguration cacheConfiguration :
cacheConfigurations.values()) {
String portalCacheName = cacheConfiguration.getName();
synchronized (_cacheManager) {
Ehcache ehcache = createEhcache(
portalCacheName, cacheConfiguration);
PortalCache<K, V> portalCache = portalCaches.get(
portalCacheName);
if (portalCache != null) {
EhcachePortalCache<K, V> ehcachePortalCache =
(EhcachePortalCache<K, V>)
EhcacheUnwrapUtil.getWrappedPortalCache(
portalCache);
if (ehcachePortalCache != null) {
ehcachePortalCache.reconfigEhcache(ehcache);
}
else {
_log.error(
"Unable to reconfigure cache with name " +
portalCacheName);
}
}
}
}
}
protected boolean reconfigure(
PortalCacheConfiguratorSettings portalCacheConfiguratorSettings) {
String portalCacheConfigurationLocation =
portalCacheConfiguratorSettings.
getPortalCacheConfigrationLocation();
if (Validator.isNull(portalCacheConfigurationLocation)) {
return false;
}
ClassLoader classLoader =
portalCacheConfiguratorSettings.getClassLoader();
URL url = classLoader.getResource(portalCacheConfigurationLocation);
if (url == null) {
return false;
}
Thread currentThread = Thread.currentThread();
ClassLoader contextClassLoader = currentThread.getContextClassLoader();
currentThread.setContextClassLoader(
AggregateClassLoader.getAggregateClassLoader(
PortalClassLoaderUtil.getClassLoader(),
portalCacheConfiguratorSettings.getClassLoader()));
try {
if (_log.isInfoEnabled()) {
_log.info(
"Reconfiguring caches in cache manager " +
getPortalCacheManagerName() + " using " + url);
}
reconfigurePortalCaches(url);
}
finally {
currentThread.setContextClassLoader(contextClassLoader);
}
return true;
}
@Override
protected void removeConfigurableEhcachePortalCacheListeners(
PortalCache<K, V> portalCache) {
EhcachePortalCache<K, V> ehcachePortalCache =
(EhcachePortalCache<K, V>)
EhcacheUnwrapUtil.getWrappedPortalCache(portalCache);
Map<PortalCacheListener<K, V>, PortalCacheListenerScope>
portalCacheListeners = ehcachePortalCache.getPortalCacheListeners();
for (PortalCacheListener<K, V> portalCacheListener :
portalCacheListeners.keySet()) {
if (portalCacheListener instanceof
ConfigurableEhcachePortalCacheListener) {
portalCache.unregisterPortalCacheListener(portalCacheListener);
}
}
}
protected BaseEhcachePortalCacheManagerConfigurator
baseEhcachePortalCacheManagerConfigurator;
protected MBeanServer mBeanServer;
protected volatile Props props;
private static final Log _log = LogFactoryUtil.getLog(
EhcachePortalCacheManager.class);
private CacheManager _cacheManager;
private String _configFile;
private String _defaultConfigFile;
private ManagementService _managementService;
private PortalCacheManagerConfiguration _portalCacheManagerConfiguration;
private boolean _registerCacheConfigurations = true;
private boolean _registerCacheManager = true;
private boolean _registerCaches = true;
private boolean _registerCacheStatistics = true;
private boolean _stopCacheManagerTimer = true;
private boolean _usingDefault;
}