/* * Copyright (C) 2005-2010 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 . */ package org.alfresco.repo.domain.permissions; import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; 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.repo.domain.CrcHelper; import org.alfresco.repo.domain.qname.QNameDAO; import org.alfresco.repo.security.permissions.ACEType; import org.alfresco.repo.security.permissions.PermissionReference; import org.alfresco.repo.security.permissions.impl.SimplePermissionReference; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.namespace.QName; import org.alfresco.util.Pair; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.extensions.surf.util.ParameterCheck; /** * Abstract implementation for ACL crud DAO. *

* This provides basic services such as caching, but defers to the underlying implementation * for CRUD operations for: * * alf_access_control_list * alf_acl_member * alf_acl_change_set * alf_access_control_entry * alf_permission * alf_authority * * Also, following are currently unused: * * alf_ace_context * alf_authority_alias * * * * @author janv * @since 3.4 */ public abstract class AbstractAclCrudDAOImpl implements AclCrudDAO { private static final String CACHE_REGION_ACL = "Acl"; private static final String CACHE_REGION_AUTHORITY = "Authority"; private static final String CACHE_REGION_PERMISSION = "Permission"; private final AclEntityCallbackDAO aclEntityDaoCallback; private final AuthorityEntityCallbackDAO authorityEntityDaoCallback; private final PermissionEntityCallbackDAO permissionEntityDaoCallback; private QNameDAO qnameDAO; private static int batchSize = 500; public void setQnameDAO(QNameDAO qnameDAO) { this.qnameDAO = qnameDAO; } public void setBatchSize(int batchSizeOverride) { batchSize = batchSizeOverride; } /** * Cache for the ACL entity:
* KEY: ID (ACL)
* VALUE: AclEntity
* VALUE KEY: None
*/ private EntityLookupCache aclEntityCache; /** * Cache for the Authority entity:
* KEY: ID (Authority)
* VALUE: AuthorityEntity
* VALUE KEY: Name
*/ private EntityLookupCache authorityEntityCache; /** * Cache for the Permission entity:
* KEY: ID (Permission)
* VALUE: PermissionEntity
* VALUE KEY: PermissionEntity (compound key: qnameId + name)
*/ private EntityLookupCache permissionEntityCache; /** * Set the cache to use for alf_access_control_list lookups (optional). * * @param aclEntityCache the cache of IDs to AclEntities */ public void setAclEntityCache(SimpleCache aclEntityCache) { this.aclEntityCache = new EntityLookupCache( aclEntityCache, CACHE_REGION_ACL, aclEntityDaoCallback); } /** * Set the cache to use for alf_authority lookups (optional). * * @param authorityEntityCache the cache of IDs to AclEntities */ public void setAuthorityEntityCache(SimpleCache authorityEntityCache) { this.authorityEntityCache = new EntityLookupCache( authorityEntityCache, CACHE_REGION_AUTHORITY, authorityEntityDaoCallback); } /** * Set the cache to use for alf_permission lookups (optional). * * @param permissionEntityCache the cache of IDs to PermissionEntities */ public void setPermissionEntityCache(SimpleCache permissionEntityCache) { this.permissionEntityCache = new EntityLookupCache( permissionEntityCache, CACHE_REGION_PERMISSION, permissionEntityDaoCallback); } /** * Default constructor. *

* This sets up the DAO accessors to bypass any caching to handle the case where the caches are not * supplied in the setters. */ public AbstractAclCrudDAOImpl() { this.aclEntityDaoCallback = new AclEntityCallbackDAO(); this.aclEntityCache = new EntityLookupCache(aclEntityDaoCallback); this.authorityEntityDaoCallback = new AuthorityEntityCallbackDAO(); this.authorityEntityCache = new EntityLookupCache(authorityEntityDaoCallback); this.permissionEntityDaoCallback = new PermissionEntityCallbackDAO(); this.permissionEntityCache = new EntityLookupCache(permissionEntityDaoCallback); } // // Access Control List (ACL) // public AclEntity createAcl(AclEntity entity) { ParameterCheck.mandatory("entity", entity); ParameterCheck.mandatory("entity.aclId", entity.getAclId()); ParameterCheck.mandatory("entity.aclVersion", entity.getAclVersion()); entity.setVersion(0L); Pair entityPair = aclEntityCache.getOrCreateByValue(entity); return entityPair.getSecond(); } public Acl getAcl(long id) { return getAclImpl(id); } private AclEntity getAclImpl(long id) { Pair entityPair = aclEntityCache.getByKey(id); if (entityPair == null) { return null; } return entityPair.getSecond(); } public AclUpdateEntity getAclForUpdate(long id) { AclEntity acl = getAclImpl(id); if (acl == null) { return null; } // copy for update AclUpdateEntity aclEntity = new AclUpdateEntity(); aclEntity.setId(acl.getId()); aclEntity.setVersion(acl.getVersion()); aclEntity.setAclChangeSetId(acl.getAclChangeSetId()); aclEntity.setAclId(acl.getAclId()); aclEntity.setAclType(acl.getAclType()); aclEntity.setAclVersion(acl.getAclVersion()); aclEntity.setInheritedAcl(acl.getInheritedAcl()); aclEntity.setInherits(acl.getInherits()); aclEntity.setInheritsFrom(acl.getInheritsFrom()); aclEntity.setLatest(acl.isLatest()); aclEntity.setVersioned(acl.isVersioned()); aclEntity.setRequiresVersion(acl.getRequiresVersion()); return aclEntity; } public List getAclsThatInheritFromAcl(long aclEntityId) { // not cached return getAclEntitiesThatInheritFromAcl(aclEntityId); } public Long getLatestAclByGuid(String aclGuid) { // not cached return getLatestAclEntityByGuid(aclGuid); } public List getADMNodesByAcl(long aclEntityId, int maxResults) { return getADMNodeEntityIdsByAcl(aclEntityId, maxResults); } public List getAVMNodesByAcl(long aclEntityId, int maxResults) { return getAVMNodeEntityIdsByAcl(aclEntityId, maxResults); } public void updateAcl(AclUpdateEntity entity) { ParameterCheck.mandatory("entity", entity); ParameterCheck.mandatory("entity.id", entity.getId()); ParameterCheck.mandatory("entity.aclVersion", entity.getAclVersion()); ParameterCheck.mandatory("entity.version", entity.getVersion()); int updated = aclEntityCache.updateValue(entity.getId(), entity); if (updated < 1) { throw new ConcurrencyFailureException("AclEntity with ID (" + entity.getId() + ") no longer exists or has been updated concurrently"); } } public void deleteAcl(long id) { Pair entityPair = aclEntityCache.getByKey(id); if (entityPair == null) { return; } int deleted = aclEntityCache.deleteByKey(id); if (deleted < 1) { throw new ConcurrencyFailureException("AclEntity with ID " + id + " no longer exists"); } } /** * Callback for alf_access_control_list DAO */ private class AclEntityCallbackDAO implements EntityLookupCallbackDAO { private final Pair convertEntityToPair(AclEntity entity) { if (entity == null) { return null; } else { return new Pair(entity.getId(), entity); } } public Serializable getValueKey(AclEntity value) { return null; } public Pair createValue(AclEntity value) { AclEntity entity = createAclEntity(value); return convertEntityToPair(entity); } public Pair findByKey(Long key) { AclEntity entity = getAclEntity(key); return convertEntityToPair(entity); } public Pair findByValue(AclEntity value) { if ((value != null) && (value.getId() != null)) { return findByKey(value.getId()); } return null; } public int updateValue(Long key, AclEntity value) { return updateAclEntity(value); } public int deleteByKey(Long key) { return deleteAclEntity(key); } public int deleteByValue(AclEntity value) { throw new UnsupportedOperationException("deleteByValue"); } } protected abstract AclEntity createAclEntity(AclEntity entity); protected abstract AclEntity getAclEntity(long id); protected abstract List getAclEntitiesThatInheritFromAcl(long idOfAcl); protected abstract Long getLatestAclEntityByGuid(String aclGuid); protected abstract int updateAclEntity(AclEntity entity); protected abstract int deleteAclEntity(long id); protected abstract List getADMNodeEntityIdsByAcl(long aclEntityId, int maxResults); protected abstract List getAVMNodeEntityIdsByAcl(long aclEntityId, int maxResults); // // ACL Member // public void addAclMembersToAcl(long aclId, List aceIds, int depth) { ParameterCheck.mandatory("aceIds", aceIds); List newMembers = new ArrayList(aceIds.size()); for (Long aceId : aceIds) { AclMemberEntity newMember = new AclMemberEntity(); newMember.setAclId(aclId); newMember.setAceId(aceId); newMember.setPos(depth); AclMemberEntity result = createAclMemberEntity(newMember); newMembers.add(result); } } public void addAclMembersToAcl(long aclId, List> aceIdsWithDepths) { ParameterCheck.mandatory("aceIdsWithDepths", aceIdsWithDepths); List newMembers = new ArrayList(aceIdsWithDepths.size()); for (Pair aceIdWithDepth : aceIdsWithDepths) { AclMemberEntity newMember = new AclMemberEntity(); newMember.setAclId(aclId); newMember.setAceId(aceIdWithDepth.getFirst()); newMember.setPos(aceIdWithDepth.getSecond()); AclMemberEntity result = createAclMemberEntity(newMember); newMembers.add(result); } } public List getAclMembersByAcl(long idOfAcl) { List entities = getAclMemberEntitiesByAcl(idOfAcl); List result = new ArrayList(entities.size()); result.addAll(entities); return result; } public List getAclMembersByAclForUpdate(long idOfAcl) { List members = getAclMemberEntitiesByAcl(idOfAcl); List membersForUpdate = new ArrayList(members.size()); for (AclMemberEntity member : members) { AclMemberEntity newMember = new AclMemberEntity(); newMember.setId(member.getId()); newMember.setVersion(member.getVersion()); newMember.setAceId(member.getAceId()); newMember.setAclId(member.getAclId()); newMember.setPos(member.getPos()); membersForUpdate.add(newMember); } return membersForUpdate; } public List getAclMembersByAuthority(String authorityName) { List entities = getAclMemberEntitiesByAuthority(authorityName); List result = new ArrayList(entities.size()); result.addAll(entities); return result; } public void updateAclMember(AclMemberEntity entity) { ParameterCheck.mandatory("entity", entity); ParameterCheck.mandatory("entity.id", entity.getId()); ParameterCheck.mandatory("entity.version", entity.getVersion()); ParameterCheck.mandatory("entity.aceId", entity.getAceId()); ParameterCheck.mandatory("entity.aclId", entity.getAclId()); ParameterCheck.mandatory("entity.pos", entity.getPos()); int updated = updateAclMemberEntity(entity); if (updated < 1) { throw new ConcurrencyFailureException("AclMemberEntity with ID (" + entity.getId() + ") no longer exists or has been updated concurrently"); } } public int deleteAclMembers(List aclMemberIds) { int totalDeletedCount = 0; if (aclMemberIds.size() == 0) { return 0; } else if (aclMemberIds.size() <= batchSize) { totalDeletedCount = deleteAclMemberEntities(aclMemberIds); } else { Iterator idIterator = aclMemberIds.iterator(); List batchIds = new ArrayList(batchSize); while (idIterator.hasNext()) { Long id = idIterator.next(); batchIds.add(id); if (batchIds.size() == batchSize || (! idIterator.hasNext())) { int batchDeletedCount = deleteAclMemberEntities(batchIds); totalDeletedCount = totalDeletedCount + batchDeletedCount; batchIds.clear(); } } } // TODO manually update the cache return totalDeletedCount; } public int deleteAclMembersByAcl(long idOfAcl) { return deleteAclMemberEntitiesByAcl(idOfAcl); } protected abstract AclMemberEntity createAclMemberEntity(AclMemberEntity entity); protected abstract List getAclMemberEntitiesByAcl(long idOfAcl); protected abstract List getAclMemberEntitiesByAuthority(String authorityName); protected abstract int updateAclMemberEntity(AclMemberEntity entity); protected abstract int deleteAclMemberEntities(List aclMemberIds); protected abstract int deleteAclMemberEntitiesByAcl(long idOfAcl); // // ACL Change Set // public Long createAclChangeSet() { return createAclChangeSetEntity(); } @Override public void updateAclChangeSet(Long aclChangeSetEntityId, long commitTimeMs) { int updated = updateChangeSetEntity(aclChangeSetEntityId, commitTimeMs); if (updated != 1) { throw new ConcurrencyFailureException("Update by ID should delete exactly 1: " + aclChangeSetEntityId); } } public AclChangeSetEntity getAclChangeSet(Long changeSetId) { return getAclChangeSetEntity(changeSetId); } public void deleteAclChangeSet(Long changeSetId) { int deleted = deleteAclChangeSetEntity(changeSetId); if (deleted != 1) { throw new ConcurrencyFailureException("Deleted by ID should delete exactly 1: " + changeSetId); } } protected abstract Long createAclChangeSetEntity(); protected abstract AclChangeSetEntity getAclChangeSetEntity(Long changeSetId); protected abstract int deleteAclChangeSetEntity(Long id); protected abstract int updateChangeSetEntity(Long id, long commitTimeMs); // // Access Control Entry (ACE) // public Ace createAce(Permission permission, Authority authority, ACEType type, AccessStatus accessStatus) { ParameterCheck.mandatory("permission", permission); ParameterCheck.mandatory("authority", authority); ParameterCheck.mandatory("type", type); ParameterCheck.mandatory("accessStatus", accessStatus); AceEntity entity = new AceEntity(); entity.setApplies(type.getId()); // note: 'applies' stores the ACE type entity.setAllowed((accessStatus == AccessStatus.ALLOWED) ? true : false); entity.setAuthorityId(authority.getId()); entity.setPermissionId(permission.getId()); long aceId = createAceEntity(entity); entity.setVersion(0L); entity.setId(aceId); return entity; } public Ace getAce(Permission permission, Authority authority, ACEType type, AccessStatus accessStatus) { ParameterCheck.mandatory("permission", permission); ParameterCheck.mandatory("authority", authority); ParameterCheck.mandatory("type", type); ParameterCheck.mandatory("accessStatus", accessStatus); return getAceEntity(permission.getId(), authority.getId(), ((accessStatus == AccessStatus.ALLOWED) ? true : false), type); } public Ace getAce(long aceEntityId) { return getAceEntity(aceEntityId); } public Ace getOrCreateAce(Permission permission, Authority authority, ACEType type, AccessStatus accessStatus) { Ace entity = getAce(permission, authority, type, accessStatus); if (entity == null) { entity = createAce(permission, authority, type, accessStatus); } return entity; } public List getAcesByAuthority(long authorityId) { return (List)getAceEntitiesByAuthority(authorityId); } public List> getAcesAndAuthoritiesByAcl(long idOfAcl) { return getAceAndAuthorityEntitiesByAcl(idOfAcl); } public int deleteAces(List aceIds) { int totalDeletedCount = 0; if (aceIds.size() == 0) { return 0; } else if (aceIds.size() <= batchSize) { totalDeletedCount = deleteAceEntities(aceIds); } else { Iterator idIterator = aceIds.iterator(); List batchIds = new ArrayList(batchSize); while (idIterator.hasNext()) { Long id = idIterator.next(); batchIds.add(id); if (batchIds.size() == batchSize || (! idIterator.hasNext())) { int batchDeletedCount = deleteAceEntities(batchIds); totalDeletedCount = totalDeletedCount + batchDeletedCount; batchIds.clear(); } } } return totalDeletedCount; } protected abstract long createAceEntity(AceEntity entity); protected abstract AceEntity getAceEntity(long aceEntityId); protected abstract AceEntity getAceEntity(long permissionId, long authorityId, boolean allowed, ACEType type); protected abstract List getAceEntitiesByAuthority(long authorityId); protected abstract List> getAceAndAuthorityEntitiesByAcl(long idOfAcl); protected abstract int deleteAceEntities(List aceIds); // // Permission // public Permission createPermission(PermissionReference permissionReference) { ParameterCheck.mandatory("permissionReference", permissionReference); PermissionEntity entity = null; // Get the persistent ID for the QName Pair qnamePair = qnameDAO.getOrCreateQName(permissionReference.getQName()); if (qnamePair != null) { Long qnameId = qnamePair.getFirst(); entity = new PermissionEntity(qnameId, permissionReference.getName()); entity.setVersion(0L); Pair entityPair = permissionEntityCache.getOrCreateByValue(entity); entity = entityPair.getSecond(); } return entity; } public Permission getPermission(long id) { Pair entityPair = permissionEntityCache.getByKey(id); if (entityPair == null) { return null; } return entityPair.getSecond(); } public Permission getPermission(PermissionReference permissionReference) { return getPermissionImpl(permissionReference); } private PermissionEntity getPermissionImpl(PermissionReference permissionReference) { ParameterCheck.mandatory("permissionReference", permissionReference); PermissionEntity entity = null; // Get the persistent ID for the QName Pair qnamePair = qnameDAO.getOrCreateQName(permissionReference.getQName()); if (qnamePair != null) { Long qnameId = qnamePair.getFirst(); PermissionEntity permission = new PermissionEntity(qnameId, permissionReference.getName()); Pair entityPair = permissionEntityCache.getByValue(permission); if (entityPair != null) { entity = entityPair.getSecond(); } } return entity; } private PermissionEntity getPermissionForUpdate(PermissionReference permissionReference) { PermissionEntity perm = getPermissionImpl(permissionReference); PermissionEntity newPerm = new PermissionEntity(); newPerm.setId(perm.getId()); newPerm.setVersion(perm.getVersion()); newPerm.setTypeQNameId(perm.getTypeQNameId()); newPerm.setName(perm.getName()); return newPerm; } public Permission getOrCreatePermission(PermissionReference permissionReference) { Permission entity = getPermission(permissionReference); if (entity == null) { entity = createPermission(permissionReference); } return entity; } public void renamePermission(QName oldTypeQName, String oldName, QName newTypeQName, String newName) { ParameterCheck.mandatory("oldTypeQName", oldTypeQName); ParameterCheck.mandatory("oldName", oldName); ParameterCheck.mandatory("newTypeQName", newTypeQName); ParameterCheck.mandatory("newName", newName); if (oldTypeQName.equals(newTypeQName) && oldName.equals(newName)) { throw new IllegalArgumentException("Cannot move permission to itself: " + oldTypeQName + "-" + oldName); } SimplePermissionReference oldPermRef = SimplePermissionReference.getPermissionReference(oldTypeQName, oldName); PermissionEntity permission = getPermissionForUpdate(oldPermRef); if (permission != null) { Long newTypeQNameId = qnameDAO.getOrCreateQName(newTypeQName).getFirst(); permission.setTypeQNameId(newTypeQNameId); permission.setName(newName); int updated = permissionEntityCache.updateValue(permission.getId(), permission); if (updated < 1) { throw new ConcurrencyFailureException("PermissionEntity with ID (" + permission.getId() + ") no longer exists or has been updated concurrently"); } } } public void deletePermission(long id) { Pair entityPair = permissionEntityCache.getByKey(id); if (entityPair == null) { return; } int deleted = permissionEntityCache.deleteByKey(id); if (deleted < 1) { throw new ConcurrencyFailureException("PermissionEntity with ID " + id + " no longer exists"); } } /** * Callback for alf_permission DAO */ private class PermissionEntityCallbackDAO implements EntityLookupCallbackDAO { private final Pair convertEntityToPair(PermissionEntity entity) { if (entity == null) { return null; } else { return new Pair(entity.getId(), entity); } } public PermissionEntity getValueKey(PermissionEntity value) { return value; } public Pair createValue(PermissionEntity value) { PermissionEntity entity = createPermissionEntity(value); return convertEntityToPair(entity); } public Pair findByKey(Long key) { PermissionEntity entity = getPermissionEntity(key); return convertEntityToPair(entity); } public Pair findByValue(PermissionEntity value) { if ((value == null) || (value.getName() == null) || (value.getTypeQNameId() == null)) { throw new AlfrescoRuntimeException("Unexpected: PermissionEntity / name / qnameId must not be null"); } return convertEntityToPair(getPermissionEntity(value.getTypeQNameId(), value.getName())); } public int updateValue(Long key, PermissionEntity value) { return updatePermissionEntity(value); } public int deleteByKey(Long key) { return deletePermissionEntity(key); } public int deleteByValue(PermissionEntity value) { throw new UnsupportedOperationException("deleteByValue"); } } protected abstract PermissionEntity createPermissionEntity(PermissionEntity entity); protected abstract PermissionEntity getPermissionEntity(long id); protected abstract PermissionEntity getPermissionEntity(long qnameId, String name); protected abstract int updatePermissionEntity(PermissionEntity updateEntity); protected abstract int deletePermissionEntity(long id); // // Authority // public Authority createAuthority(String authorityName) { ParameterCheck.mandatory("authorityName", authorityName); AuthorityEntity entity = new AuthorityEntity(); entity.setAuthority(authorityName); entity.setCrc(CrcHelper.getStringCrcPair(authorityName, 32, true, true).getSecond()); entity.setVersion(0L); Pair entityPair = authorityEntityCache.getOrCreateByValue(entity); return entityPair.getSecond(); } public Authority getAuthority(long id) { Pair entityPair = authorityEntityCache.getByKey(id); if (entityPair == null) { return null; } return entityPair.getSecond(); } public Authority getAuthority(String authorityName) { return getAuthorityImpl(authorityName); } private AuthorityEntity getAuthorityImpl(String authorityName) { ParameterCheck.mandatory("authorityName", authorityName); AuthorityEntity authority = new AuthorityEntity(); authority.setAuthority(authorityName); Pair entityPair = authorityEntityCache.getByValue(authority); if (entityPair == null) { return null; } return entityPair.getSecond(); } private AuthorityEntity getAuthorityForUpdate(String authorityName) { AuthorityEntity auth = getAuthorityImpl(authorityName); if (auth == null) { return null; } AuthorityEntity newAuth = new AuthorityEntity(); newAuth.setId(auth.getId()); newAuth.setVersion(auth.getVersion()); newAuth.setAuthority(auth.getAuthority()); newAuth.setCrc(auth.getCrc()); return newAuth; } public Authority getOrCreateAuthority(String name) { Authority entity = getAuthority(name); if (entity == null) { entity = createAuthority(name); } return entity; } public void renameAuthority(String before, String after) { ParameterCheck.mandatory("before", before); ParameterCheck.mandatory("after", after); AuthorityEntity entity = getAuthorityForUpdate(before); if (entity != null) { entity.setAuthority(after); entity.setCrc(CrcHelper.getStringCrcPair(after, 32, true, true).getSecond()); int updated = authorityEntityCache.updateValue(entity.getId(), entity); if (updated < 1) { throw new ConcurrencyFailureException("AuthorityEntity with ID (" + entity.getId() + ") no longer exists or has been updated concurrently"); } } } public void deleteAuthority(long id) { Pair entityPair = authorityEntityCache.getByKey(id); if (entityPair == null) { return; } int deleted = authorityEntityCache.deleteByKey(id); if (deleted < 1) { throw new ConcurrencyFailureException("AuthorityEntity with ID " + id + " no longer exists"); } } /** * Callback for alf_authority DAO */ private class AuthorityEntityCallbackDAO implements EntityLookupCallbackDAO { private final Pair convertEntityToPair(AuthorityEntity entity) { if (entity == null) { return null; } else { return new Pair(entity.getId(), entity); } } public String getValueKey(AuthorityEntity value) { return value.getAuthority(); } public Pair createValue(AuthorityEntity value) { AuthorityEntity entity = createAuthorityEntity(value); return convertEntityToPair(entity); } public Pair findByKey(Long key) { AuthorityEntity entity = getAuthorityEntity(key); return convertEntityToPair(entity); } public Pair findByValue(AuthorityEntity value) { if ((value == null) || (value.getAuthority() == null)) { throw new AlfrescoRuntimeException("Unexpected: AuthorityEntity / name must not be null"); } return convertEntityToPair(getAuthorityEntity(value.getAuthority())); } public int updateValue(Long key, AuthorityEntity value) { return updateAuthorityEntity(value); } public int deleteByKey(Long key) { return deleteAuthorityEntity(key); } public int deleteByValue(AuthorityEntity value) { throw new UnsupportedOperationException("deleteByValue"); } } protected abstract AuthorityEntity createAuthorityEntity(AuthorityEntity entity); protected abstract AuthorityEntity getAuthorityEntity(long id); protected abstract AuthorityEntity getAuthorityEntity(String authorityName); protected abstract int updateAuthorityEntity(AuthorityEntity updateEntity); protected abstract int deleteAuthorityEntity(long id); // ACE Context (NOTE: currently unused - intended for possible future enhancement) protected abstract long createAceContextEntity(AceContextEntity entity); protected abstract AceContextEntity getAceContextEntity(long aceContextId); protected abstract int deleteAceContextEntity(long aceContextId); // // Authority Alias (NOTE: currently unused - intended for possible future enhancement) // protected abstract long createAuthorityAliasEntity(AuthorityAliasEntity entity); protected abstract int deleteAuthorityAliasEntity(long id); }