/** * 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.service.impl; import com.liferay.portal.kernel.dao.db.DB; import com.liferay.portal.kernel.dao.db.DBManagerUtil; import com.liferay.portal.kernel.dao.jdbc.CurrentConnectionUtil; import com.liferay.portal.kernel.dao.orm.ORMException; import com.liferay.portal.kernel.dao.orm.QueryPos; import com.liferay.portal.kernel.dao.orm.SQLQuery; import com.liferay.portal.kernel.dao.orm.Session; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.exception.ResourceBlocksNotSupportedException; import com.liferay.portal.kernel.exception.SystemException; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.model.AuditedModel; import com.liferay.portal.kernel.model.GroupedModel; import com.liferay.portal.kernel.model.PermissionedModel; import com.liferay.portal.kernel.model.PersistedModel; import com.liferay.portal.kernel.model.ResourceAction; import com.liferay.portal.kernel.model.ResourceBlock; import com.liferay.portal.kernel.model.ResourceBlockConstants; import com.liferay.portal.kernel.model.ResourceBlockPermissionsContainer; import com.liferay.portal.kernel.model.ResourceConstants; import com.liferay.portal.kernel.model.ResourceTypePermission; import com.liferay.portal.kernel.model.Role; import com.liferay.portal.kernel.model.RoleConstants; import com.liferay.portal.kernel.security.auth.PrincipalException; import com.liferay.portal.kernel.security.permission.PermissionThreadLocal; import com.liferay.portal.kernel.security.permission.ResourceActionsUtil; import com.liferay.portal.kernel.security.permission.ResourceBlockIdsBag; import com.liferay.portal.kernel.service.PersistedModelLocalService; import com.liferay.portal.kernel.service.PersistedModelLocalServiceRegistryUtil; import com.liferay.portal.kernel.spring.aop.Skip; import com.liferay.portal.kernel.transaction.Isolation; import com.liferay.portal.kernel.transaction.Propagation; import com.liferay.portal.kernel.transaction.TransactionCommitCallbackUtil; import com.liferay.portal.kernel.transaction.Transactional; import com.liferay.portal.kernel.util.ListUtil; import com.liferay.portal.model.impl.ResourceBlockImpl; import com.liferay.portal.security.permission.PermissionCacheUtil; import com.liferay.portal.service.base.ResourceBlockLocalServiceBaseImpl; import com.liferay.portal.util.PropsValues; import com.liferay.util.dao.orm.CustomSQLUtil; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; import javax.sql.DataSource; /** * Provides the local service for accessing, adding, deleting, and updating * resource blocks. * * @author Connor McKay * @author Shuyang Zhou */ public class ResourceBlockLocalServiceImpl extends ResourceBlockLocalServiceBaseImpl { @Override public void addCompanyScopePermission( long companyId, String name, long roleId, String actionId) throws PortalException { updateCompanyScopePermissions( companyId, name, roleId, getActionId(name, actionId), ResourceBlockConstants.OPERATOR_ADD); } @Override public void addCompanyScopePermissions( long companyId, String name, long roleId, long actionIdsLong) { updateCompanyScopePermissions( companyId, name, roleId, actionIdsLong, ResourceBlockConstants.OPERATOR_ADD); } @Override public void addGroupScopePermission( long companyId, long groupId, String name, long roleId, String actionId) throws PortalException { updateGroupScopePermissions( companyId, groupId, name, roleId, getActionId(name, actionId), ResourceBlockConstants.OPERATOR_ADD); } @Override public void addGroupScopePermissions( long companyId, long groupId, String name, long roleId, long actionIdsLong) { updateGroupScopePermissions( companyId, groupId, name, roleId, actionIdsLong, ResourceBlockConstants.OPERATOR_ADD); } @Override public void addIndividualScopePermission( long companyId, long groupId, String name, long primKey, long roleId, String actionId) throws PortalException { PermissionedModel permissionedModel = getPermissionedModel( name, primKey); updateIndividualScopePermissions( companyId, groupId, name, permissionedModel, roleId, getActionId(name, actionId), ResourceBlockConstants.OPERATOR_ADD); } @Override public void addIndividualScopePermission( long companyId, long groupId, String name, PermissionedModel permissionedModel, long roleId, String actionId) throws PortalException { updateIndividualScopePermissions( companyId, groupId, name, permissionedModel, roleId, getActionId(name, actionId), ResourceBlockConstants.OPERATOR_ADD); } @Override public void addIndividualScopePermissions( long companyId, long groupId, String name, long primKey, long roleId, long actionIdsLong) throws PortalException { PermissionedModel permissionedModel = getPermissionedModel( name, primKey); updateIndividualScopePermissions( companyId, groupId, name, permissionedModel, roleId, actionIdsLong, ResourceBlockConstants.OPERATOR_ADD); } @Override public void addIndividualScopePermissions( long companyId, long groupId, String name, PermissionedModel permissionedModel, long roleId, long actionIdsLong) { updateIndividualScopePermissions( companyId, groupId, name, permissionedModel, roleId, actionIdsLong, ResourceBlockConstants.OPERATOR_ADD); } /** * Adds a resource block if necessary and associates the resource block * permissions with it. The resource block will have an initial reference * count of one. * * @param companyId the primary key of the resource block's company * @param groupId the primary key of the resource block's group * @param name the resource block's name * @param permissionsHash the resource block's permission hash * @param resourceBlockPermissionsContainer the resource block's * permissions container * @return the new resource block */ @Override public ResourceBlock addResourceBlock( long companyId, long groupId, String name, String permissionsHash, ResourceBlockPermissionsContainer resourceBlockPermissionsContainer) { long resourceBlockId = counterLocalService.increment( ResourceBlock.class.getName()); ResourceBlock resourceBlock = resourceBlockPersistence.create( resourceBlockId); resourceBlock.setCompanyId(companyId); resourceBlock.setGroupId(groupId); resourceBlock.setName(name); resourceBlock.setPermissionsHash(permissionsHash); resourceBlock.setReferenceCount(1); updateResourceBlock(resourceBlock); resourceBlockPermissionLocalService.addResourceBlockPermissions( resourceBlockId, resourceBlockPermissionsContainer); return resourceBlock; } @Override public ResourceBlock deleteResourceBlock(long resourceBlockId) throws PortalException { ResourceBlock resourceBlock = resourceBlockPersistence.findByPrimaryKey( resourceBlockId); return deleteResourceBlock(resourceBlock); } @Override public ResourceBlock deleteResourceBlock(ResourceBlock resourceBlock) { resourceBlockPermissionLocalService.deleteResourceBlockPermissions( resourceBlock.getPrimaryKey()); resourceBlockPersistence.remove(resourceBlock); return resourceBlock; } @Override public long getActionId(String name, String actionId) throws PortalException { ResourceAction resourcAction = resourceActionLocalService.getResourceAction(name, actionId); return resourcAction.getBitwiseValue(); } @Override public long getActionIds(String name, List<String> actionIds) throws PortalException { long actionIdsLong = 0; for (String actionId : actionIds) { ResourceAction resourceAction = resourceActionLocalService.getResourceAction(name, actionId); actionIdsLong |= resourceAction.getBitwiseValue(); } return actionIdsLong; } @Override public List<String> getActionIds(String name, long actionIdsLong) { List<ResourceAction> resourceActions = resourceActionLocalService.getResourceActions(name); List<String> actionIds = new ArrayList<>(); for (ResourceAction resourceAction : resourceActions) { if ((actionIdsLong & resourceAction.getBitwiseValue()) == resourceAction.getBitwiseValue()) { actionIds.add(resourceAction.getActionId()); } } return actionIds; } @Override public List<String> getCompanyScopePermissions( ResourceBlock resourceBlock, long roleId) { long actionIdsLong = resourceTypePermissionLocalService.getCompanyScopeActionIds( resourceBlock.getCompanyId(), resourceBlock.getName(), roleId); return getActionIds(resourceBlock.getName(), actionIdsLong); } @Override public List<String> getGroupScopePermissions( ResourceBlock resourceBlock, long roleId) { long actionIdsLong = resourceTypePermissionLocalService.getGroupScopeActionIds( resourceBlock.getCompanyId(), resourceBlock.getGroupId(), resourceBlock.getName(), roleId); return getActionIds(resourceBlock.getName(), actionIdsLong); } @Override public PermissionedModel getPermissionedModel(String name, long primKey) throws PortalException { PersistedModelLocalService persistedModelLocalService = PersistedModelLocalServiceRegistryUtil. getPersistedModelLocalService(name); if (persistedModelLocalService == null) { throw new ResourceBlocksNotSupportedException(); } PersistedModel persistedModel = persistedModelLocalService.getPersistedModel(primKey); try { return (PermissionedModel)persistedModel; } catch (ClassCastException cce) { throw new ResourceBlocksNotSupportedException(); } } @Override public List<String> getPermissions( ResourceBlock resourceBlock, long roleId) { ResourceBlockPermissionsContainer resourceBlockPermissionsContainer = resourceBlockPermissionLocalService. getResourceBlockPermissionsContainer( resourceBlock.getPrimaryKey()); long actionIdsLong = resourceBlockPermissionsContainer.getActionIds( roleId); return getActionIds(resourceBlock.getName(), actionIdsLong); } @Override public ResourceBlock getResourceBlock(String name, long primKey) throws PortalException { PermissionedModel permissionedModel = getPermissionedModel( name, primKey); return getResourceBlock(permissionedModel.getResourceBlockId()); } @Override public List<Long> getResourceBlockIds( ResourceBlockIdsBag resourceBlockIdsBag, String name, String actionId) throws PortalException { long actionIdsLong = getActionId(name, actionId); return resourceBlockIdsBag.getResourceBlockIds(actionIdsLong); } @Override public ResourceBlockIdsBag getResourceBlockIdsBag( long companyId, long groupId, String name, long[] roleIds) { return resourceBlockFinder.findByC_G_N_R( companyId, groupId, name, roleIds); } @Override public List<Role> getRoles(String name, long primKey, String actionId) throws PortalException { long actionIdLong = getActionId(name, actionId); ResourceBlock resourceBlock = getResourceBlock(name, primKey); ResourceBlockPermissionsContainer resourceBlockPermissionsContainer = resourceBlockPermissionLocalService. getResourceBlockPermissionsContainer( resourceBlock.getResourceBlockId()); Set<Long> roleIds = resourceBlockPermissionsContainer.getRoleIds(); List<Role> roles = new ArrayList<>(roleIds.size()); for (long roleId : roleIds) { if (resourceBlockPermissionsContainer.hasPermission( roleId, actionIdLong)) { roles.add(roleLocalService.getRole(roleId)); } } return roles; } @Override public boolean hasPermission( String name, long primKey, String actionId, ResourceBlockIdsBag resourceBlockIdsBag) throws PortalException { PermissionedModel permissionedModel = getPermissionedModel( name, primKey); return hasPermission( name, permissionedModel, actionId, resourceBlockIdsBag); } @Override public boolean hasPermission( String name, PermissionedModel permissionedModel, String actionId, ResourceBlockIdsBag resourceBlockIdsBag) throws PortalException { long actionIdsLong = getActionId(name, actionId); return resourceBlockIdsBag.hasResourceBlockId( permissionedModel.getResourceBlockId(), actionIdsLong); } @Override @Skip public boolean isSupported(String name) { return PersistedModelLocalServiceRegistryUtil. isPermissionedModelLocalService(name); } @Override @Transactional( isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW ) public void releasePermissionedModelResourceBlock( PermissionedModel permissionedModel) { releaseResourceBlock(permissionedModel.getResourceBlockId()); } @Override public void releasePermissionedModelResourceBlock(String name, long primKey) throws PortalException { PermissionedModel permissionedModel = getPermissionedModel( name, primKey); releasePermissionedModelResourceBlock(permissionedModel); } /** * Decrements the reference count of the resource block and updates it in * the database or deletes the resource block if the reference count reaches * zero. * * @param resourceBlockId the primary key of the resource block */ @Override @Transactional( isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW ) public void releaseResourceBlock(long resourceBlockId) { Session session = resourceBlockPersistence.openSession(); while (true) { try { String sql = CustomSQLUtil.get(_RELEASE_RESOURCE_BLOCK); SQLQuery sqlQuery = session.createSynchronizedSQLQuery(sql); QueryPos qPos = QueryPos.getInstance(sqlQuery); qPos.add(resourceBlockId); if (sqlQuery.executeUpdate() > 0) { ResourceBlock resourceBlock = (ResourceBlock)session.get( ResourceBlockImpl.class, Long.valueOf(resourceBlockId)); if (resourceBlock.getReferenceCount() == 0) { sql = CustomSQLUtil.get(_DELETE_RESOURCE_BLOCK); sqlQuery = session.createSynchronizedSQLQuery(sql); qPos = QueryPos.getInstance(sqlQuery); qPos.add(resourceBlockId); sqlQuery.executeUpdate(); PermissionCacheUtil.clearResourceBlockCache( resourceBlock.getCompanyId(), resourceBlock.getGroupId(), resourceBlock.getName()); } } resourceBlockPersistence.closeSession(session); break; } catch (ORMException orme) { if (_log.isWarnEnabled()) { _log.warn( "Unable to decrement reference count for resource " + "block " + resourceBlockId + ". Retrying."); } } } } /** * Decrements the reference count of the resource block and updates it in * the database or deletes the resource block if the reference count reaches * zero. * * @param resourceBlock the resource block */ @Override @Transactional( isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW ) public void releaseResourceBlock(ResourceBlock resourceBlock) { releaseResourceBlock(resourceBlock.getResourceBlockId()); } @Override public void removeAllGroupScopePermissions( long companyId, String name, long roleId, long actionIdsLong) { List<ResourceTypePermission> resourceTypePermissions = resourceTypePermissionLocalService. getGroupScopeResourceTypePermissions(companyId, name, roleId); for (ResourceTypePermission resourceTypePermission : resourceTypePermissions) { removeGroupScopePermissions( companyId, resourceTypePermission.getGroupId(), name, roleId, actionIdsLong); } } @Override public void removeAllGroupScopePermissions( long companyId, String name, long roleId, String actionId) throws PortalException { removeAllGroupScopePermissions( companyId, name, roleId, getActionId(name, actionId)); } @Override public void removeCompanyScopePermission( long companyId, String name, long roleId, String actionId) throws PortalException { updateCompanyScopePermissions( companyId, name, roleId, getActionId(name, actionId), ResourceBlockConstants.OPERATOR_REMOVE); } @Override public void removeCompanyScopePermissions( long companyId, String name, long roleId, long actionIdsLong) { updateCompanyScopePermissions( companyId, name, roleId, actionIdsLong, ResourceBlockConstants.OPERATOR_REMOVE); } @Override public void removeGroupScopePermission( long companyId, long groupId, String name, long roleId, String actionId) throws PortalException { updateGroupScopePermissions( companyId, groupId, name, roleId, getActionId(name, actionId), ResourceBlockConstants.OPERATOR_REMOVE); } @Override public void removeGroupScopePermissions( long companyId, long groupId, String name, long roleId, long actionIdsLong) { updateGroupScopePermissions( companyId, groupId, name, roleId, actionIdsLong, ResourceBlockConstants.OPERATOR_REMOVE); } @Override public void removeIndividualScopePermission( long companyId, long groupId, String name, long primKey, long roleId, String actionId) throws PortalException { PermissionedModel permissionedModel = getPermissionedModel( name, primKey); updateIndividualScopePermissions( companyId, groupId, name, permissionedModel, roleId, getActionId(name, actionId), ResourceBlockConstants.OPERATOR_REMOVE); } @Override public void removeIndividualScopePermission( long companyId, long groupId, String name, PermissionedModel permissionedModel, long roleId, String actionId) throws PortalException { updateIndividualScopePermissions( companyId, groupId, name, permissionedModel, roleId, getActionId(name, actionId), ResourceBlockConstants.OPERATOR_REMOVE); } @Override public void removeIndividualScopePermissions( long companyId, long groupId, String name, long primKey, long roleId, long actionIdsLong) throws PortalException { PermissionedModel permissionedModel = getPermissionedModel( name, primKey); updateIndividualScopePermissions( companyId, groupId, name, permissionedModel, roleId, actionIdsLong, ResourceBlockConstants.OPERATOR_REMOVE); } @Override public void removeIndividualScopePermissions( long companyId, long groupId, String name, PermissionedModel permissionedModel, long roleId, long actionIdsLong) { updateIndividualScopePermissions( companyId, groupId, name, permissionedModel, roleId, actionIdsLong, ResourceBlockConstants.OPERATOR_REMOVE); } @Override public void setCompanyScopePermissions( long companyId, String name, long roleId, List<String> actionIds) throws PortalException { checkGuestSupportedPermission(companyId, name, roleId, actionIds); updateCompanyScopePermissions( companyId, name, roleId, getActionIds(name, actionIds), ResourceBlockConstants.OPERATOR_SET); } @Override public void setCompanyScopePermissions( long companyId, String name, long roleId, long actionIdsLong) { updateCompanyScopePermissions( companyId, name, roleId, actionIdsLong, ResourceBlockConstants.OPERATOR_SET); } @Override public void setGroupScopePermissions( long companyId, long groupId, String name, long roleId, List<String> actionIds) throws PortalException { checkGuestSupportedPermission(companyId, name, roleId, actionIds); updateGroupScopePermissions( companyId, groupId, name, roleId, getActionIds(name, actionIds), ResourceBlockConstants.OPERATOR_SET); } @Override public void setGroupScopePermissions( long companyId, long groupId, String name, long roleId, long actionIdsLong) { updateGroupScopePermissions( companyId, groupId, name, roleId, actionIdsLong, ResourceBlockConstants.OPERATOR_SET); } @Override public void setIndividualScopePermissions( long companyId, long groupId, String name, long primKey, long roleId, List<String> actionIds) throws PortalException { PermissionedModel permissionedModel = getPermissionedModel( name, primKey); checkGuestSupportedPermission(companyId, name, roleId, actionIds); updateIndividualScopePermissions( companyId, groupId, name, permissionedModel, roleId, getActionIds(name, actionIds), ResourceBlockConstants.OPERATOR_SET); } @Override public void setIndividualScopePermissions( long companyId, long groupId, String name, long primKey, long roleId, long actionIdsLong) throws PortalException { PermissionedModel permissionedModel = getPermissionedModel( name, primKey); updateIndividualScopePermissions( companyId, groupId, name, permissionedModel, roleId, actionIdsLong, ResourceBlockConstants.OPERATOR_SET); } @Override public void setIndividualScopePermissions( long companyId, long groupId, String name, long primKey, Map<Long, String[]> roleIdsToActionIds) throws PortalException { boolean flushResourceBlockEnabled = PermissionThreadLocal.isFlushResourceBlockEnabled( companyId, groupId, name); PermissionThreadLocal.setFlushResourceBlockEnabled( companyId, groupId, name, false); try { PermissionedModel permissionedModel = getPermissionedModel( name, primKey); for (Map.Entry<Long, String[]> entry : roleIdsToActionIds.entrySet()) { long roleId = entry.getKey(); List<String> actionIds = ListUtil.fromArray(entry.getValue()); checkGuestSupportedPermission( companyId, name, roleId, actionIds); updateIndividualScopePermissions( companyId, groupId, name, permissionedModel, roleId, getActionIds(name, actionIds), ResourceBlockConstants.OPERATOR_SET); } } finally { PermissionThreadLocal.setFlushResourceBlockEnabled( companyId, groupId, name, flushResourceBlockEnabled); PermissionCacheUtil.clearResourceBlockCache( companyId, groupId, name); PermissionCacheUtil.clearResourcePermissionCache( ResourceConstants.SCOPE_INDIVIDUAL, name, String.valueOf(primKey)); } } @Override public void setIndividualScopePermissions( long companyId, long groupId, String name, PermissionedModel permissionedModel, long roleId, List<String> actionIds) throws PortalException { checkGuestSupportedPermission(companyId, name, roleId, actionIds); updateIndividualScopePermissions( companyId, groupId, name, permissionedModel, roleId, getActionIds(name, actionIds), ResourceBlockConstants.OPERATOR_SET); } @Override public void setIndividualScopePermissions( long companyId, long groupId, String name, PermissionedModel permissionedModel, long roleId, long actionIdsLong) { updateIndividualScopePermissions( companyId, groupId, name, permissionedModel, roleId, actionIdsLong, ResourceBlockConstants.OPERATOR_SET); } @Override public void updateCompanyScopePermissions( long companyId, String name, long roleId, long actionIdsLong, int operator) { resourceTypePermissionLocalService. updateCompanyScopeResourceTypePermissions( companyId, name, roleId, actionIdsLong, operator); List<ResourceBlock> resourceBlocks = resourceBlockPersistence.findByC_N( companyId, name); updatePermissions(resourceBlocks, roleId, actionIdsLong, operator); PermissionCacheUtil.clearResourceCache(); } @Override public void updateGroupScopePermissions( long companyId, long groupId, String name, long roleId, long actionIdsLong, int operator) { resourceTypePermissionLocalService. updateGroupScopeResourceTypePermissions( companyId, groupId, name, roleId, actionIdsLong, operator); List<ResourceBlock> resourceBlocks = resourceBlockPersistence.findByC_G_N(companyId, groupId, name); updatePermissions(resourceBlocks, roleId, actionIdsLong, operator); PermissionCacheUtil.clearResourceCache(); } @Override public void updateIndividualScopePermissions( long companyId, long groupId, String name, PermissionedModel permissionedModel, long roleId, long actionIdsLong, int operator) { ResourceBlock resourceBlock = resourceBlockPersistence.fetchByPrimaryKey( permissionedModel.getResourceBlockId()); ResourceBlockPermissionsContainer resourceBlockPermissionsContainer = null; if (resourceBlock == null) { resourceBlockPermissionsContainer = resourceTypePermissionLocalService. getResourceBlockPermissionsContainer( companyId, groupId, name); } else { resourceBlockPermissionsContainer = resourceBlockPermissionLocalService. getResourceBlockPermissionsContainer( resourceBlock.getPrimaryKey()); } long oldActionIdsLong = resourceBlockPermissionsContainer.getActionIds( roleId); if (operator == ResourceBlockConstants.OPERATOR_ADD) { actionIdsLong |= oldActionIdsLong; } else if (operator == ResourceBlockConstants.OPERATOR_REMOVE) { actionIdsLong = oldActionIdsLong & (~actionIdsLong); } if (resourceBlock != null) { if (oldActionIdsLong == actionIdsLong) { return; } resourceBlockLocalService.releaseResourceBlock(resourceBlock); } resourceBlockPermissionsContainer.setPermissions(roleId, actionIdsLong); String permissionsHash = resourceBlockPermissionsContainer.getPermissionsHash(); resourceBlockLocalService.updateResourceBlockId( companyId, groupId, name, permissionedModel, permissionsHash, resourceBlockPermissionsContainer); PermissionCacheUtil.clearResourceBlockCache(companyId, groupId, name); } @Override @Transactional( isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW ) public ResourceBlock updateResourceBlockId( long companyId, long groupId, String name, final PermissionedModel permissionedModel, String permissionsHash, ResourceBlockPermissionsContainer resourceBlockPermissionsContainer) { ResourceBlock resourceBlock = null; while (true) { resourceBlock = resourceBlockPersistence.fetchByC_G_N_P( companyId, groupId, name, permissionsHash, false); if (resourceBlock == null) { try { resourceBlock = addResourceBlock( companyId, groupId, name, permissionsHash, resourceBlockPermissionsContainer); // On success, manually flush to enforce database row lock if (PropsValues.SPRING_HIBERNATE_SESSION_DELEGATED) { resourceBlockPersistence.flush(); } } catch (SystemException se) { if (_log.isWarnEnabled()) { _log.warn( "Unable to add a new resource block. Retrying", se); } // On failure, cancel all pending persistent entities Session session = resourceBlockPersistence.getCurrentSession(); session.clear(); DB db = DBManagerUtil.getDB(); if (!db.isSupportsQueryingAfterException()) { DataSource dataSource = resourceBlockPersistence.getDataSource(); Connection connection = CurrentConnectionUtil.getConnection(dataSource); try { connection.rollback(); connection.setAutoCommit(false); } catch (SQLException sqle) { throw new SystemException(sqle); } } continue; } break; } Session session = resourceBlockPersistence.openSession(); try { String sql = CustomSQLUtil.get(_RETAIN_RESOURCE_BLOCK); SQLQuery sqlQuery = session.createSynchronizedSQLQuery(sql); QueryPos qPos = QueryPos.getInstance(sqlQuery); qPos.add(resourceBlock.getResourceBlockId()); if (sqlQuery.executeUpdate() > 0) { // We currently use an "update set" SQL statement to // increment the reference count in a discontinuous manner. // We can change it to an "update where" SQL statement to // guarantee continuous counts. We are using a SQL statement // that allows for a discontinuous count since it is cheaper // and continuity is not required. resourceBlock.setReferenceCount( resourceBlock.getReferenceCount() + 1); break; } } catch (ORMException orme) { if (_log.isWarnEnabled()) { _log.warn( "Unable to increment reference count for resource " + "block " + resourceBlock.getResourceBlockId() + ". Retrying"); } } finally { // Prevent Hibernate from automatically flushing out the first // level cache since that will lead to a regular update that // will overwrite the previous update causing a lost update. session.evict(resourceBlock); resourceBlockPersistence.closeSession(session); } } permissionedModel.setResourceBlockId( resourceBlock.getResourceBlockId()); Callable<Void> callable = new Callable<Void>() { @Override public Void call() throws Exception { permissionedModel.persist(); return null; } }; TransactionCommitCallbackUtil.registerCallback(callable); return resourceBlock; } @Override public void verifyResourceBlockId(long companyId, String name, long primKey) throws PortalException { PermissionedModel permissionedModel = getPermissionedModel( name, primKey); ResourceBlock resourceBlock = resourceBlockPersistence.fetchByPrimaryKey( permissionedModel.getResourceBlockId()); if (resourceBlock != null) { return; } if (_log.isWarnEnabled()) { _log.warn( "Resource block " + permissionedModel.getResourceBlockId() + " missing for " + name + "#" + primKey); } long groupId = 0; long ownerId = 0; if (permissionedModel instanceof GroupedModel) { GroupedModel groupedModel = (GroupedModel)permissionedModel; groupId = groupedModel.getGroupId(); ownerId = groupedModel.getUserId(); } else if (permissionedModel instanceof AuditedModel) { AuditedModel auditedModel = (AuditedModel)permissionedModel; ownerId = auditedModel.getUserId(); } resourceLocalService.addResources( companyId, groupId, ownerId, name, primKey, false, true, true); } protected void checkGuestSupportedPermission( long companyId, String name, long roleId, List<String> actionIds) throws PortalException { if (!isGuestRole(companyId, roleId)) { return; } List<String> unsupportedActionIds = ResourceActionsUtil.getResourceGuestUnsupportedActions(name, name); for (String actionId : actionIds) { if (unsupportedActionIds.contains(actionId)) { throw new PrincipalException( actionId + "is not supported by role " + roleId); } } } protected boolean isGuestRole(long companyId, long roleId) throws PortalException { Role guestRole = roleLocalService.getRole( companyId, RoleConstants.GUEST); if (roleId == guestRole.getRoleId()) { return true; } return false; } protected void updatePermissions( List<ResourceBlock> resourceBlocks, long roleId, long actionIdsLong, int operator) { for (ResourceBlock resourceBlock : resourceBlocks) { resourceBlockPermissionLocalService.updateResourceBlockPermission( resourceBlock.getPrimaryKey(), roleId, actionIdsLong, operator); updatePermissionsHash(resourceBlock); } } protected void updatePermissionsHash(ResourceBlock resourceBlock) { ResourceBlockPermissionsContainer resourceBlockPermissionsContainer = resourceBlockPermissionLocalService. getResourceBlockPermissionsContainer( resourceBlock.getPrimaryKey()); String permissionsHash = resourceBlockPermissionsContainer.getPermissionsHash(); resourceBlock.setPermissionsHash(permissionsHash); updateResourceBlock(resourceBlock); } private static final String _DELETE_RESOURCE_BLOCK = ResourceBlockLocalServiceImpl.class.getName() + ".deleteResourceBlock"; private static final String _RELEASE_RESOURCE_BLOCK = ResourceBlockLocalServiceImpl.class.getName() + ".releaseResourceBlock"; private static final String _RETAIN_RESOURCE_BLOCK = ResourceBlockLocalServiceImpl.class.getName() + ".retainResourceBlock"; private static final Log _log = LogFactoryUtil.getLog( ResourceBlockLocalServiceImpl.class); }