alfresco-community-repo/source/java/org/alfresco/repo/domain/tenant/AbstractTenantAdminDAOImpl.java
Dave Ward 2e826e9e26 Merged V4.0-BUG-FIX to HEAD
35394: ALF-13394: Allow administrators to gain SiteManager role
   35407: ALF-12740: Updated XHR request processing for IE to ensure no caching (had previously thought IE9 was not affected but apparently it is)
   35408: Fix for ALF-13286 who_can_create_site mention and bad error message
   - explicitly declare public interface on SiteService
   35412: Merged DEV to V4.0-BUG-FIX
      35153: ALF-1834: Renaming folders breaks web form content
             Original solution by Ivan has been reimplemented as per Derek's requirements and against 4.0. 
             [DH: Did some minor legibility changes and fixed LF for AVMDiskDriver]
   35414: Incremented version.revision for 4.0.2
   35417: Merged BRANCHES/DEV/THOR0 to BRANCHES/DEV/V4.0-BUG-FIX: (THOR-6 / ALF-13755)
      29356: THOR-6: MT is configured (but not enabled) by default - will be auto-enabled when first tenant is created
      29455: THOR-6: build test/fix
      29471: THOR-6: build test/fix
   35423: Merged BRANCHES/DEV/THOR0 to BRANCHES/DEV/V4.0-BUG-FIX: (THOR-4 / ALF-13756)
      29500: THOR-4: Replace Tenant attributes with Tenant table (alf_tenant)
      29501: THOR-4: Replace Tenant attributes with Tenant table (alf_tenant)
      29503: THOR-4: Replace Tenant attributes with Tenant table (alf_tenant)
      TODO: ALF-13757 - patch to migrate Tenant attributes to Tenant table (for existing customers)
   35431: Merged V3.4-BUG-FIX to V4.0-BUG-FIX
      35367: ALF-13382: WorkflowService Returning Incorrect Values When Using Native jBPM API to set Local Task Variables
      - Fix by Alex Bykov
      35400: Fix for ALF-13557 - Share forms selectmany.ftl template does not work with Share search query parser; should do a logical OR or AND but does a concatenation
      35416: Incremented version.revision for 3.4.10
      35429: Merged V4.0-BUG-FIX to V3.4-BUG-FIX (partial)
         35328: ALF-13409: Avoid concurrency issues in unit test tear downs by deleting users before sites. User deletion deletes invitations synchronously. Site deletion deletes invitations concurrently to avoid UI timeouts. The potential to access invitations that are being concurrently deleted still exists, but always did!
      35430: ALF-13409: Avoid concurrency issues in unit test tear downs by deleting users before sites - another instance.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@35434 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
2012-04-19 15:43:03 +00:00

232 lines
7.9 KiB
Java

/*
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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.
*
* 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.domain.tenant;
import java.io.Serializable;
import java.util.List;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.cache.lookup.EntityLookupCache;
import org.alfresco.repo.cache.lookup.EntityLookupCache.EntityLookupCallbackDAO;
import org.alfresco.util.Pair;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.extensions.surf.util.ParameterCheck;
/**
* Abstract implementation for TenantAdmin DAO.
* <p>
* This provides basic services such as caching, but defers to the underlying implementation
* for CRUD operations for:
*
* <b>alf_tenant</b>
*
* @author janv
* @since 4.0 (thor)
*/
public abstract class AbstractTenantAdminDAOImpl implements TenantAdminDAO
{
private final TenantEntityCallbackDAO tenantEntityDaoCallback;
/**
* Cache for the Tenant entity:<br/>
* KEY: TenantDomain (String)<br/>
* VALUE: TenantEntity<br/>
* VALUE KEY: None<br/>
*/
private EntityLookupCache<String, TenantEntity, Serializable> tenantEntityCache;
/**
* Set the cache to use for <b>alf_tenant</b> lookups (optional).
*
* @param tenantEntityCache the cache of tenantDomains to TenantEntities
*/
public void setTenantEntityCache(SimpleCache<Serializable, Object> tenantEntityCache)
{
this.tenantEntityCache = new EntityLookupCache<String, TenantEntity, Serializable>(
tenantEntityCache,
tenantEntityDaoCallback);
}
/**
* Default constructor.
* <p>
* This sets up the DAO accessor to bypass any caching to handle the case where the caches are not
* supplied in the setters.
*/
public AbstractTenantAdminDAOImpl()
{
this.tenantEntityDaoCallback = new TenantEntityCallbackDAO();
this.tenantEntityCache = new EntityLookupCache<String, TenantEntity, Serializable>(tenantEntityDaoCallback);
}
public TenantEntity createTenant(TenantEntity entity)
{
ParameterCheck.mandatory("entity", entity);
ParameterCheck.mandatoryString("entity.tenantDomain", entity.getTenantDomain());
if (entity.getEnabled() == null)
{
entity.setEnabled(true);
}
// force lower-case on create
entity.setTenantDomain(entity.getTenantDomain().toLowerCase());
entity.setVersion(0L);
Pair<String, TenantEntity> entityPair = tenantEntityCache.getOrCreateByValue(entity);
return entityPair.getSecond();
}
public TenantEntity getTenant(String tenantDomain)
{
return getTenantImpl(tenantDomain);
}
private TenantEntity getTenantImpl(String tenantDomain)
{
Pair<String, TenantEntity> entityPair = tenantEntityCache.getByKey(tenantDomain);
if (entityPair == null)
{
// try lower-case to make sure
entityPair = tenantEntityCache.getByKey(tenantDomain.toLowerCase());
if (entityPair == null)
{
return null;
}
}
return entityPair.getSecond();
}
public List<TenantEntity> listTenants()
{
return getTenantEntities();
}
public TenantUpdateEntity getTenantForUpdate(String tenantDomain)
{
TenantEntity entity = getTenantImpl(tenantDomain);
if (entity == null)
{
return null;
}
// copy for update
TenantUpdateEntity updateEntity = new TenantUpdateEntity(entity.getTenantDomain());
updateEntity.setVersion(entity.getVersion());
updateEntity.setEnabled(entity.getEnabled());
return updateEntity;
}
public void updateTenant(TenantUpdateEntity entity)
{
ParameterCheck.mandatory("entity", entity);
ParameterCheck.mandatory("entity.version", entity.getVersion());
ParameterCheck.mandatoryString("entity.tenantDomain", entity.getTenantDomain());
int updated = tenantEntityCache.updateValue(entity.getTenantDomain(), entity);
if (updated < 1)
{
throw new ConcurrencyFailureException("TenantEntity " + entity.getTenantDomain() + " no longer exists or has been updated concurrently");
}
}
public void deleteTenant(String tenantDomain)
{
ParameterCheck.mandatoryString("tenantDomain", tenantDomain);
// force lower-case on delete
tenantDomain = tenantDomain.toLowerCase();
int deleted = tenantEntityCache.deleteByKey(tenantDomain);
if (deleted < 1)
{
throw new ConcurrencyFailureException("TenantEntity " + tenantDomain + " no longer exists");
}
}
/**
* Callback for <b>alf_tenant</b> DAO
*/
private class TenantEntityCallbackDAO implements EntityLookupCallbackDAO<String, TenantEntity, Serializable>
{
private final Pair<String, TenantEntity> convertEntityToPair(TenantEntity entity)
{
if (entity == null)
{
return null;
}
else
{
return new Pair<String, TenantEntity>(entity.getTenantDomain(), entity);
}
}
public Serializable getValueKey(TenantEntity value)
{
return null;
}
public Pair<String, TenantEntity> createValue(TenantEntity value)
{
TenantEntity entity = createTenantEntity(value);
return convertEntityToPair(entity);
}
public Pair<String, TenantEntity> findByKey(String key)
{
TenantEntity entity = getTenantEntity(key);
return convertEntityToPair(entity);
}
public Pair<String, TenantEntity> findByValue(TenantEntity value)
{
if ((value == null) || (value.getTenantDomain() == null))
{
throw new AlfrescoRuntimeException("Unexpected: TenantEntity / tenantDomain must not be null");
}
return convertEntityToPair(getTenantEntity(value.getTenantDomain()));
}
public int updateValue(String tenantDomain, TenantEntity value)
{
return updateTenantEntity(value);
}
public int deleteByKey(String tenantDomain)
{
return deleteTenantEntity(tenantDomain);
}
public int deleteByValue(TenantEntity value)
{
throw new UnsupportedOperationException("deleteByValue");
}
}
protected abstract TenantEntity createTenantEntity(TenantEntity tenantEntity);
protected abstract TenantEntity getTenantEntity(String tenantDomain);
protected abstract List<TenantEntity> getTenantEntities();
protected abstract int updateTenantEntity(TenantEntity tenantEntity);
protected abstract int deleteTenantEntity(String tenantDomain);
}