/**
* 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;
import com.liferay.portal.cache.configuration.PortalCacheConfiguration;
import com.liferay.portal.cache.configuration.PortalCacheManagerConfiguration;
import com.liferay.portal.cache.internal.mvcc.MVCCPortalCache;
import com.liferay.portal.kernel.cache.PortalCache;
import com.liferay.portal.kernel.cache.PortalCacheException;
import com.liferay.portal.kernel.cache.PortalCacheListener;
import com.liferay.portal.kernel.cache.PortalCacheListenerScope;
import com.liferay.portal.kernel.cache.PortalCacheManager;
import com.liferay.portal.kernel.cache.PortalCacheManagerListener;
import com.liferay.portal.kernel.model.MVCCModel;
import com.liferay.portal.kernel.resiliency.spi.SPIUtil;
import com.liferay.portal.kernel.util.CharPool;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import java.io.Serializable;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* @author Tina Tian
*/
public abstract class BasePortalCacheManager<K extends Serializable, V>
implements PortalCacheManager<K, V> {
@Override
public void clearAll() throws PortalCacheException {
doClearAll();
}
@Override
public void destroy() {
portalCaches.clear();
doDestroy();
}
@Override
public PortalCache<K, V> getPortalCache(String portalCacheName)
throws PortalCacheException {
return getPortalCache(portalCacheName, false);
}
@Override
public PortalCache<K, V> getPortalCache(
String portalCacheName, boolean blocking)
throws PortalCacheException {
return getPortalCache(portalCacheName, blocking, false);
}
@Override
public PortalCache<K, V> getPortalCache(
String portalCacheName, boolean blocking, boolean mvcc)
throws PortalCacheException {
PortalCache<K, V> portalCache = portalCaches.get(portalCacheName);
if (portalCache != null) {
return portalCache;
}
PortalCacheConfiguration portalCacheConfiguration =
_portalCacheManagerConfiguration.getPortalCacheConfiguration(
portalCacheName);
if (portalCacheConfiguration == null) {
portalCacheConfiguration =
_defaultPortalCacheConfiguration.newPortalCacheConfiguration(
portalCacheName);
_portalCacheManagerConfiguration.putPortalCacheConfiguration(
portalCacheName, portalCacheConfiguration);
}
portalCache = createPortalCache(portalCacheConfiguration);
_initPortalCacheListeners(portalCache, portalCacheConfiguration);
if (mvcc) {
portalCache = (PortalCache<K, V>)new MVCCPortalCache<>(
(LowLevelCache<K, MVCCModel>)portalCache);
}
if (isTransactionalPortalCacheEnabled() &&
isTransactionalPortalCache(portalCacheName)) {
portalCache = new TransactionalPortalCache<>(portalCache);
}
if (isBlockingPortalCacheAllowed() && blocking) {
portalCache = new BlockingPortalCache<>(portalCache);
}
PortalCache<K, V> previousPortalCache = portalCaches.putIfAbsent(
portalCacheName, portalCache);
if (previousPortalCache != null) {
portalCache = previousPortalCache;
}
else if (portalCacheConfiguration != null) {
Properties portalCacheBootstrapLoaderProperties =
portalCacheConfiguration.
getPortalCacheBootstrapLoaderProperties();
if (portalCacheBootstrapLoaderProperties != null) {
PortalCacheBootstrapLoader portalCacheBootstrapLoader =
portalCacheBootstrapLoaderFactory.create(
portalCacheBootstrapLoaderProperties);
if (portalCacheBootstrapLoader != null) {
portalCacheBootstrapLoader.loadPortalCache(
getPortalCacheManagerName(), portalCacheName);
}
}
}
return portalCache;
}
@Override
public Set<PortalCacheManagerListener> getPortalCacheManagerListeners() {
return aggregatedPortalCacheManagerListener.
getPortalCacheManagerListeners();
}
@Override
public String getPortalCacheManagerName() {
return _portalCacheManagerName;
}
public String[] getTransactionalPortalCacheNames() {
return _transactionalPortalCacheNames;
}
public boolean isBlockingPortalCacheAllowed() {
return _blockingPortalCacheAllowed;
}
@Override
public boolean isClusterAware() {
return _clusterAware;
}
public boolean isTransactionalPortalCacheEnabled() {
return _transactionalPortalCacheEnabled;
}
@Override
public boolean registerPortalCacheManagerListener(
PortalCacheManagerListener portalCacheManagerListener) {
return aggregatedPortalCacheManagerListener.addPortalCacheListener(
portalCacheManagerListener);
}
@Override
public void removePortalCache(String portalCacheName) {
portalCaches.remove(portalCacheName);
doRemovePortalCache(portalCacheName);
}
public void setBlockingPortalCacheAllowed(
boolean blockingPortalCacheAllowed) {
_blockingPortalCacheAllowed = blockingPortalCacheAllowed;
}
public void setClusterAware(boolean clusterAware) {
_clusterAware = clusterAware;
}
public void setMpiOnly(boolean mpiOnly) {
_mpiOnly = mpiOnly;
}
public void setPortalCacheManagerName(String portalCacheManagerName) {
_portalCacheManagerName = portalCacheManagerName;
}
public void setTransactionalPortalCacheEnabled(
boolean transactionalPortalCacheEnabled) {
_transactionalPortalCacheEnabled = transactionalPortalCacheEnabled;
}
public void setTransactionalPortalCacheNames(
String[] transactionalPortalCacheNames) {
_transactionalPortalCacheNames = transactionalPortalCacheNames;
}
@Override
public boolean unregisterPortalCacheManagerListener(
PortalCacheManagerListener portalCacheManagerListener) {
return aggregatedPortalCacheManagerListener.removePortalCacheListener(
portalCacheManagerListener);
}
@Override
public void unregisterPortalCacheManagerListeners() {
aggregatedPortalCacheManagerListener.clearAll();
}
protected abstract PortalCache<K, V> createPortalCache(
PortalCacheConfiguration portalCacheConfiguration);
protected abstract void doClearAll();
protected abstract void doDestroy();
protected abstract void doRemovePortalCache(String portalCacheName);
protected abstract PortalCacheManagerConfiguration
getPortalCacheManagerConfiguration();
protected void initialize() {
if ((_portalCacheManagerConfiguration != null) ||
(_mpiOnly && SPIUtil.isSPI())) {
return;
}
if (Validator.isNull(_portalCacheManagerName)) {
throw new IllegalArgumentException(
"Portal cache manager name is not specified");
}
initPortalCacheManager();
_portalCacheManagerConfiguration = getPortalCacheManagerConfiguration();
_defaultPortalCacheConfiguration =
_portalCacheManagerConfiguration.
getDefaultPortalCacheConfiguration();
for (Properties properties :
_portalCacheManagerConfiguration.
getPortalCacheManagerListenerPropertiesSet()) {
PortalCacheManagerListener portalCacheManagerListener =
portalCacheManagerListenerFactory.create(this, properties);
if (portalCacheManagerListener != null) {
registerPortalCacheManagerListener(portalCacheManagerListener);
}
}
}
protected abstract void initPortalCacheManager();
protected boolean isTransactionalPortalCache(String portalCacheName) {
for (String namePattern : getTransactionalPortalCacheNames()) {
if (StringUtil.wildcardMatches(
portalCacheName, namePattern, CharPool.QUESTION,
CharPool.STAR, CharPool.PERCENT, true)) {
return true;
}
}
return false;
}
protected void reconfigPortalCache(
PortalCacheManagerConfiguration portalCacheManagerConfiguration) {
for (String portalCacheName :
portalCacheManagerConfiguration.getPortalCacheNames()) {
PortalCacheConfiguration portalCacheConfiguration =
portalCacheManagerConfiguration.getPortalCacheConfiguration(
portalCacheName);
_portalCacheManagerConfiguration.putPortalCacheConfiguration(
portalCacheName, portalCacheConfiguration);
PortalCache<K, V> portalCache = portalCaches.get(portalCacheName);
if (portalCache == null) {
continue;
}
removeConfigurableEhcachePortalCacheListeners(portalCache);
_initPortalCacheListeners(portalCache, portalCacheConfiguration);
}
}
protected abstract void removeConfigurableEhcachePortalCacheListeners(
PortalCache<K, V> portalCache);
protected final AggregatedPortalCacheManagerListener
aggregatedPortalCacheManagerListener =
new AggregatedPortalCacheManagerListener();
protected PortalCacheBootstrapLoaderFactory
portalCacheBootstrapLoaderFactory;
protected PortalCacheListenerFactory portalCacheListenerFactory;
protected PortalCacheManagerListenerFactory<PortalCacheManager<K, V>>
portalCacheManagerListenerFactory;
protected final ConcurrentMap<String, PortalCache<K, V>> portalCaches =
new ConcurrentHashMap<>();
private void _initPortalCacheListeners(
PortalCache<K, V> portalCache,
PortalCacheConfiguration portalCacheConfiguration) {
if (portalCacheConfiguration == null) {
return;
}
for (Properties properties :
portalCacheConfiguration.
getPortalCacheListenerPropertiesSet()) {
PortalCacheListener<K, V> portalCacheListener =
portalCacheListenerFactory.create(properties);
if (portalCacheListener == null) {
continue;
}
PortalCacheListenerScope portalCacheListenerScope =
(PortalCacheListenerScope)properties.remove(
PortalCacheConfiguration.PORTAL_CACHE_LISTENER_SCOPE);
if (portalCacheListenerScope == null) {
portalCacheListenerScope = PortalCacheListenerScope.ALL;
}
portalCache.registerPortalCacheListener(
portalCacheListener, portalCacheListenerScope);
}
}
private boolean _blockingPortalCacheAllowed;
private boolean _clusterAware;
private PortalCacheConfiguration _defaultPortalCacheConfiguration;
private boolean _mpiOnly;
private PortalCacheManagerConfiguration _portalCacheManagerConfiguration;
private String _portalCacheManagerName;
private boolean _transactionalPortalCacheEnabled;
private String[] _transactionalPortalCacheNames = StringPool.EMPTY_ARRAY;
}