mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged HEAD-QA to HEAD (4.2) (including moving test classes into separate folders)
51903 to 54309 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@54310 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Alfresco Software Limited.
|
||||
/*
|
||||
* Copyright (C) 2005-2013 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
@@ -14,493 +14,318 @@
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.config.xml;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.cache.SimpleCache;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationContext;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.repo.tenant.TenantAdminService;
|
||||
import org.alfresco.repo.tenant.TenantDeployer;
|
||||
import org.alfresco.repo.tenant.TenantUtil;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.extensions.config.ConfigDeployment;
|
||||
import org.springframework.extensions.config.ConfigImpl;
|
||||
import org.springframework.extensions.config.ConfigSection;
|
||||
import org.springframework.extensions.config.ConfigSource;
|
||||
import org.springframework.extensions.config.evaluator.Evaluator;
|
||||
import org.springframework.extensions.config.xml.XMLConfigService;
|
||||
import org.springframework.extensions.config.xml.elementreader.ConfigElementReader;
|
||||
|
||||
/**
|
||||
* XML-based configuration service which can optionally read config from the Repository
|
||||
*
|
||||
*/
|
||||
public class RepoXMLConfigService extends XMLConfigService implements TenantDeployer
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(RepoXMLConfigService.class);
|
||||
|
||||
/**
|
||||
* Lock objects
|
||||
*/
|
||||
private ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
private Lock readLock = lock.readLock();
|
||||
private Lock writeLock = lock.writeLock();
|
||||
|
||||
// Dependencies
|
||||
private TransactionService transactionService;
|
||||
private AuthenticationContext authenticationContext;
|
||||
private TenantAdminService tenantAdminService;
|
||||
|
||||
// Internal cache (clusterable)
|
||||
private SimpleCache<String, ConfigData> configDataCache;
|
||||
|
||||
// used to reset the cache
|
||||
private ThreadLocal<ConfigData> configDataThreadLocal = new ThreadLocal<ConfigData>();
|
||||
|
||||
public void setTransactionService(TransactionService transactionService)
|
||||
{
|
||||
this.transactionService = transactionService;
|
||||
}
|
||||
|
||||
public void setAuthenticationContext(AuthenticationContext authenticationContext)
|
||||
{
|
||||
this.authenticationContext = authenticationContext;
|
||||
}
|
||||
|
||||
public void setTenantAdminService(TenantAdminService tenantAdminService)
|
||||
{
|
||||
this.tenantAdminService = tenantAdminService;
|
||||
}
|
||||
|
||||
public void setConfigDataCache(SimpleCache<String, ConfigData> configDataCache)
|
||||
{
|
||||
this.configDataCache = configDataCache;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs an XMLConfigService using the given config source
|
||||
*
|
||||
* @param configSource
|
||||
* A ConfigSource
|
||||
*/
|
||||
public RepoXMLConfigService(ConfigSource configSource)
|
||||
{
|
||||
super(configSource);
|
||||
}
|
||||
|
||||
public List<ConfigDeployment> initConfig()
|
||||
{
|
||||
return resetRepoConfig().getConfigDeployments();
|
||||
}
|
||||
|
||||
private ConfigData initRepoConfig(final String tenantDomain)
|
||||
{
|
||||
ConfigData configData;
|
||||
|
||||
// can be null e.g. initial login, after fresh bootstrap
|
||||
String currentUser = authenticationContext.getCurrentUserName();
|
||||
if (currentUser == null)
|
||||
{
|
||||
authenticationContext.setSystemUserAsCurrentUser();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
configData = transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<ConfigData>()
|
||||
{
|
||||
|
||||
@Override
|
||||
public ConfigData execute() throws Throwable
|
||||
{
|
||||
// parse config
|
||||
List<ConfigDeployment> configDeployments = RepoXMLConfigService.super.initConfig();
|
||||
|
||||
ConfigData configData = getConfigDataLocal(tenantDomain);
|
||||
if (configData != null)
|
||||
{
|
||||
configData.setConfigDeployments(configDeployments);
|
||||
}
|
||||
return configData;
|
||||
}
|
||||
}, transactionService.isReadOnly());
|
||||
|
||||
logger.info("Config initialised");
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (currentUser == null)
|
||||
{
|
||||
authenticationContext.clearCurrentSecurityContext();
|
||||
}
|
||||
}
|
||||
|
||||
return configData;
|
||||
}
|
||||
|
||||
public void destroy()
|
||||
{
|
||||
super.destroy();
|
||||
|
||||
logger.info("Config destroyed");
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the config service
|
||||
*/
|
||||
public void reset()
|
||||
{
|
||||
resetRepoConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the config service
|
||||
*/
|
||||
private ConfigData resetRepoConfig()
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Resetting repo config service");
|
||||
}
|
||||
|
||||
String tenantDomain = getTenantDomain();
|
||||
try
|
||||
{
|
||||
destroy();
|
||||
|
||||
// create threadlocal, if needed
|
||||
ConfigData configData = getConfigDataLocal(tenantDomain);
|
||||
if (configData == null)
|
||||
{
|
||||
configData = new ConfigData(tenantDomain);
|
||||
this.configDataThreadLocal.set(configData);
|
||||
}
|
||||
|
||||
configData = initRepoConfig(tenantDomain);
|
||||
|
||||
if (configData == null)
|
||||
{
|
||||
// unexpected
|
||||
throw new AlfrescoRuntimeException("Failed to reset configData " + tenantDomain);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
writeLock.lock();
|
||||
configDataCache.put(tenantDomain, configData);
|
||||
}
|
||||
finally
|
||||
{
|
||||
writeLock.unlock();
|
||||
}
|
||||
|
||||
return configData;
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
readLock.lock();
|
||||
if (configDataCache.get(tenantDomain) != null)
|
||||
{
|
||||
this.configDataThreadLocal.set(null); // it's in the cache, clear the threadlocal
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent event)
|
||||
{
|
||||
// run as System on bootstrap
|
||||
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||
{
|
||||
public Object doWork()
|
||||
{
|
||||
initConfig();
|
||||
return null;
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
|
||||
if ((tenantAdminService != null) && (tenantAdminService.isEnabled()))
|
||||
{
|
||||
tenantAdminService.deployTenants(this, logger);
|
||||
tenantAdminService.register(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event)
|
||||
{
|
||||
// NOOP
|
||||
}
|
||||
|
||||
public void onEnableTenant()
|
||||
{
|
||||
initConfig(); // will be called in context of tenant
|
||||
}
|
||||
|
||||
public void onDisableTenant()
|
||||
{
|
||||
destroy(); // will be called in context of tenant
|
||||
}
|
||||
|
||||
// re-entrant (eg. via reset)
|
||||
private ConfigData getConfigData()
|
||||
{
|
||||
String tenantDomain = getTenantDomain();
|
||||
|
||||
// check threadlocal first - return if set
|
||||
ConfigData configData = getConfigDataLocal(tenantDomain);
|
||||
if (configData != null)
|
||||
{
|
||||
return configData; // return local config
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// check cache second - return if set
|
||||
readLock.lock();
|
||||
configData = configDataCache.get(tenantDomain);
|
||||
|
||||
if (configData != null)
|
||||
{
|
||||
return configData; // return cached config
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
readLock.unlock();
|
||||
}
|
||||
|
||||
// reset caches - may have been invalidated (e.g. in a cluster)
|
||||
configData = resetRepoConfig();
|
||||
|
||||
if (configData == null)
|
||||
{
|
||||
// unexpected
|
||||
throw new AlfrescoRuntimeException("Failed to get configData " + tenantDomain);
|
||||
}
|
||||
|
||||
return configData;
|
||||
}
|
||||
|
||||
// get threadlocal
|
||||
private ConfigData getConfigDataLocal(String tenantDomain)
|
||||
{
|
||||
ConfigData configData = this.configDataThreadLocal.get();
|
||||
|
||||
// check to see if domain switched (eg. during login)
|
||||
if ((configData != null) && (tenantDomain.equals(configData.getTenantDomain())))
|
||||
{
|
||||
return configData; // return threadlocal, if set
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void removeConfigData()
|
||||
{
|
||||
try
|
||||
{
|
||||
writeLock.lock();
|
||||
String tenantDomain = getTenantDomain();
|
||||
if (configDataCache.get(tenantDomain) != null)
|
||||
{
|
||||
configDataCache.remove(tenantDomain);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConfigImpl getGlobalConfigImpl()
|
||||
{
|
||||
return getConfigData().getGlobalConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void putGlobalConfig(ConfigImpl globalConfig)
|
||||
{
|
||||
getConfigData().setGlobalConfig(globalConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeGlobalConfig()
|
||||
{
|
||||
removeConfigData();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Evaluator> getEvaluators()
|
||||
{
|
||||
return getConfigData().getEvaluators();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void putEvaluators(Map<String, Evaluator> evaluators)
|
||||
{
|
||||
getConfigData().setEvaluators(evaluators);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeEvaluators()
|
||||
{
|
||||
removeConfigData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<ConfigSection>> getSectionsByArea()
|
||||
{
|
||||
return getConfigData().getSectionsByArea();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void putSectionsByArea(Map<String, List<ConfigSection>> sectionsByArea)
|
||||
{
|
||||
getConfigData().setSectionsByArea(sectionsByArea);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeSectionsByArea()
|
||||
{
|
||||
removeConfigData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ConfigSection> getSections()
|
||||
{
|
||||
return getConfigData().getSections();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void putSections(List<ConfigSection> sections)
|
||||
{
|
||||
getConfigData().setSections(sections);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeSections()
|
||||
{
|
||||
removeConfigData();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, ConfigElementReader> getElementReaders()
|
||||
{
|
||||
return getConfigData().getElementReaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void putElementReaders(Map<String, ConfigElementReader> elementReaders)
|
||||
{
|
||||
getConfigData().setElementReaders(elementReaders);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeElementReaders()
|
||||
{
|
||||
removeConfigData();
|
||||
}
|
||||
|
||||
// local helper - returns tenant domain (or empty string if default non-tenant)
|
||||
private String getTenantDomain()
|
||||
{
|
||||
return TenantUtil.getCurrentDomain();
|
||||
}
|
||||
|
||||
private static class ConfigData
|
||||
{
|
||||
private ConfigImpl globalConfig;
|
||||
private Map<String, Evaluator> evaluators;
|
||||
private Map<String, List<ConfigSection>> sectionsByArea;
|
||||
private List<ConfigSection> sections;
|
||||
private Map<String, ConfigElementReader> elementReaders;
|
||||
|
||||
private List<ConfigDeployment> configDeployments;
|
||||
|
||||
private String tenantDomain;
|
||||
|
||||
public ConfigData(String tenantDomain)
|
||||
{
|
||||
this.tenantDomain = tenantDomain;
|
||||
}
|
||||
|
||||
public String getTenantDomain()
|
||||
{
|
||||
return tenantDomain;
|
||||
}
|
||||
|
||||
public ConfigImpl getGlobalConfig()
|
||||
{
|
||||
return globalConfig;
|
||||
}
|
||||
public void setGlobalConfig(ConfigImpl globalConfig)
|
||||
{
|
||||
this.globalConfig = globalConfig;
|
||||
}
|
||||
public Map<String, Evaluator> getEvaluators()
|
||||
{
|
||||
return evaluators;
|
||||
}
|
||||
public void setEvaluators(Map<String, Evaluator> evaluators)
|
||||
{
|
||||
this.evaluators = evaluators;
|
||||
}
|
||||
public Map<String, List<ConfigSection>> getSectionsByArea()
|
||||
{
|
||||
return sectionsByArea;
|
||||
}
|
||||
public void setSectionsByArea(Map<String, List<ConfigSection>> sectionsByArea)
|
||||
{
|
||||
this.sectionsByArea = sectionsByArea;
|
||||
}
|
||||
public List<ConfigSection> getSections()
|
||||
{
|
||||
return sections;
|
||||
}
|
||||
public void setSections(List<ConfigSection> sections)
|
||||
{
|
||||
this.sections = sections;
|
||||
}
|
||||
public Map<String, ConfigElementReader> getElementReaders()
|
||||
{
|
||||
return elementReaders;
|
||||
}
|
||||
public void setElementReaders(Map<String, ConfigElementReader> elementReaders)
|
||||
{
|
||||
this.elementReaders = elementReaders;
|
||||
}
|
||||
public List<ConfigDeployment> getConfigDeployments()
|
||||
{
|
||||
return configDeployments;
|
||||
}
|
||||
public void setConfigDeployments(List<ConfigDeployment> configDeployments)
|
||||
{
|
||||
this.configDeployments = configDeployments;
|
||||
}
|
||||
}
|
||||
}
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.config.xml;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.config.ConfigDataCache;
|
||||
import org.alfresco.repo.config.ConfigDataCache.ConfigData;
|
||||
import org.alfresco.repo.config.ConfigDataCache.ImmutableConfigData;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.repo.tenant.TenantAdminService;
|
||||
import org.alfresco.repo.tenant.TenantDeployer;
|
||||
import org.alfresco.repo.tenant.TenantUtil;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.extensions.config.ConfigDeployment;
|
||||
import org.springframework.extensions.config.ConfigImpl;
|
||||
import org.springframework.extensions.config.ConfigSection;
|
||||
import org.springframework.extensions.config.ConfigSource;
|
||||
import org.springframework.extensions.config.evaluator.Evaluator;
|
||||
import org.springframework.extensions.config.xml.XMLConfigService;
|
||||
import org.springframework.extensions.config.xml.elementreader.ConfigElementReader;
|
||||
|
||||
/**
|
||||
* XML-based configuration service which can optionally read config from the Repository
|
||||
*/
|
||||
public class RepoXMLConfigService extends XMLConfigService implements TenantDeployer
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(RepoXMLConfigService.class);
|
||||
|
||||
/**
|
||||
* Configuration that is manipulated by the current thread.<br/>
|
||||
* This is required because the super classes call back into this mechanism after
|
||||
* receiving the initial object, etc.
|
||||
*/
|
||||
private final ThreadLocal<ConfigData> configUnderConstruction = new ThreadLocal<ConfigData>();
|
||||
|
||||
// Dependencies
|
||||
private TransactionService transactionService;
|
||||
private TenantAdminService tenantAdminService;
|
||||
private ConfigDataCache configDataCache;
|
||||
|
||||
public void setTransactionService(TransactionService transactionService)
|
||||
{
|
||||
this.transactionService = transactionService;
|
||||
}
|
||||
|
||||
public void setTenantAdminService(TenantAdminService tenantAdminService)
|
||||
{
|
||||
this.tenantAdminService = tenantAdminService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the asynchronously-controlled cache.
|
||||
*/
|
||||
public void setConfigDataCache(ConfigDataCache configDataCache)
|
||||
{
|
||||
this.configDataCache = configDataCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an XMLConfigService using the given config source
|
||||
*/
|
||||
public RepoXMLConfigService(ConfigSource configSource)
|
||||
{
|
||||
super(configSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ConfigDeployment> initConfig()
|
||||
{
|
||||
configDataCache.refresh();
|
||||
// Just return whatever is there (no-one uses it)
|
||||
ConfigData configData = configDataCache.get();
|
||||
return configData.getConfigDeployments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the repository configuration data for a given tenant.
|
||||
* This does the low-level initialization of the configuration and does not do any
|
||||
* caching.
|
||||
*
|
||||
* @param tenantDomain the current tenant domain
|
||||
* @return return the repository configuration for the given tenant (never <tt>null</tt>)
|
||||
*/
|
||||
public ConfigData getRepoConfig(final String tenantDomain)
|
||||
{
|
||||
final RetryingTransactionCallback<Void> getConfigWork = new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
// parse config
|
||||
RepoXMLConfigService.super.initConfig();
|
||||
return null;
|
||||
}
|
||||
};
|
||||
RunAsWork<Void> getConfigRunAs = new RunAsWork<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void doWork() throws Exception
|
||||
{
|
||||
transactionService.getRetryingTransactionHelper().doInTransaction(getConfigWork, true);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug(
|
||||
"Fetching repository config data for tenant: \n" +
|
||||
" Tenant Domain: " + tenantDomain);
|
||||
}
|
||||
// Put some mutable config onto the current thread and have the superclasses mess with that.
|
||||
ConfigData configData = new ConfigData();
|
||||
configUnderConstruction.set(configData);
|
||||
// Do the work
|
||||
AuthenticationUtil.runAsSystem(getConfigRunAs);
|
||||
// Now wrap the config so that it cannot be changed
|
||||
configData = new ImmutableConfigData(configData);
|
||||
// Done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug(
|
||||
"Fetched repository config data for tenant: \n" +
|
||||
" Tenant Domain: " + tenantDomain + "\n" +
|
||||
" Config: " + configData);
|
||||
}
|
||||
return configData;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException(
|
||||
"Failed to fetch repository config data for tenant \n" +
|
||||
" Tenant Domain: " + tenantDomain,
|
||||
e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
configUnderConstruction.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the config values for the current tenant
|
||||
*/
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
configDataCache.refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent event)
|
||||
{
|
||||
// run as System on bootstrap
|
||||
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||
{
|
||||
public Object doWork()
|
||||
{
|
||||
initConfig();
|
||||
return null;
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
|
||||
if ((tenantAdminService != null) && (tenantAdminService.isEnabled()))
|
||||
{
|
||||
tenantAdminService.deployTenants(this, logger);
|
||||
tenantAdminService.register(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event)
|
||||
{
|
||||
// NOOP
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnableTenant()
|
||||
{
|
||||
initConfig(); // will be called in context of tenant
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisableTenant()
|
||||
{
|
||||
destroy(); // will be called in context of tenant
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the tenant-specific config data from the cache. If nothing is
|
||||
* available then the config will be created.
|
||||
* <p/>
|
||||
* Note that this method is used during construction of the config as well.
|
||||
* When this occurs, a thread local value is used in place of the cached
|
||||
* value. It's not pretty.
|
||||
*
|
||||
* @return the tenant-specific configuration (never <tt>null</tt>)
|
||||
*/
|
||||
private ConfigData getConfigData()
|
||||
{
|
||||
if (configUnderConstruction.get() != null)
|
||||
{
|
||||
// We are busy building some config so we can return it
|
||||
return configUnderConstruction.get();
|
||||
}
|
||||
// Go to the backing cache
|
||||
return configDataCache.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConfigImpl getGlobalConfigImpl()
|
||||
{
|
||||
return getConfigData().getGlobalConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void putGlobalConfig(ConfigImpl globalConfig)
|
||||
{
|
||||
getConfigData().setGlobalConfig(globalConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeGlobalConfig()
|
||||
{
|
||||
throw new UnsupportedOperationException("'destroy' method must destroy all config. Piecemeal destruction is not supported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Evaluator> getEvaluators()
|
||||
{
|
||||
return getConfigData().getEvaluators();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void putEvaluators(Map<String, Evaluator> evaluators)
|
||||
{
|
||||
getConfigData().setEvaluators(evaluators);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeEvaluators()
|
||||
{
|
||||
throw new UnsupportedOperationException("'destroy' method must destroy all config. Piecemeal destruction is not supported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<ConfigSection>> getSectionsByArea()
|
||||
{
|
||||
return getConfigData().getSectionsByArea();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void putSectionsByArea(Map<String, List<ConfigSection>> sectionsByArea)
|
||||
{
|
||||
getConfigData().setSectionsByArea(sectionsByArea);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeSectionsByArea()
|
||||
{
|
||||
throw new UnsupportedOperationException("'destroy' method must destroy all config. Piecemeal destruction is not supported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ConfigSection> getSections()
|
||||
{
|
||||
return getConfigData().getSections();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void putSections(List<ConfigSection> sections)
|
||||
{
|
||||
getConfigData().setSections(sections);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeSections()
|
||||
{
|
||||
throw new UnsupportedOperationException("'destroy' method must destroy all config. Piecemeal destruction is not supported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, ConfigElementReader> getElementReaders()
|
||||
{
|
||||
return getConfigData().getElementReaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void putElementReaders(Map<String, ConfigElementReader> elementReaders)
|
||||
{
|
||||
getConfigData().setElementReaders(elementReaders);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeElementReaders()
|
||||
{
|
||||
throw new UnsupportedOperationException("'destroy' method must destroy all config. Piecemeal destruction is not supported.");
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user