mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
RM-2072: Concurrency exceptions and deadlocks on Records Management "File to" rule
* unit test provides easy way to reproduce (number of batches and size configurable) * 500 docs now being added via described scenario * extended security props no longer being set up the hierarchy (which was leading to terminal deadlocks) +review RM @taksoy git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.2.1.x@102486 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -211,8 +211,11 @@ public class CreateRecordAction extends AuditableActionExecuterAbstractBase
|
||||
hideRecord = hideRecordValue.booleanValue();
|
||||
}
|
||||
|
||||
// create record from existing document
|
||||
recordService.createRecord(filePlan, actionedUponNodeRef, !hideRecord);
|
||||
synchronized (this)
|
||||
{
|
||||
// create record from existing document
|
||||
recordService.createRecord(filePlan, actionedUponNodeRef, !hideRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -17,7 +17,6 @@ import org.alfresco.service.cmr.action.ParameterDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileNotFoundException;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.DuplicateChildNodeNameException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
@@ -133,7 +132,7 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
|
||||
{
|
||||
targetIsUnfiledRecords = (dictionaryService.isSubClass(actionedUponType, ContentModel.TYPE_CONTENT) && !recordService.isFiled(actionedUponNodeRef))
|
||||
|| TYPE_UNFILED_RECORD_FOLDER.equals(actionedUponType);
|
||||
}
|
||||
}
|
||||
|
||||
// first look to see if the destination record folder has been specified
|
||||
NodeRef recordFolder = (NodeRef)action.getParameterValue(PARAM_DESTINATION_RECORD_FOLDER);
|
||||
@@ -144,15 +143,21 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
|
||||
{
|
||||
public NodeRef execute() throws Throwable
|
||||
{
|
||||
NodeRef result = null;
|
||||
try
|
||||
{
|
||||
// get the reference to the record folder based on the relative path
|
||||
return createOrResolvePath(action, actionedUponNodeRef, finaltargetIsUnfiledRecords);
|
||||
synchronized (this)
|
||||
{
|
||||
// get the reference to the record folder based on the relative path
|
||||
result = createOrResolvePath(action, actionedUponNodeRef, finaltargetIsUnfiledRecords);
|
||||
}
|
||||
}
|
||||
catch (DuplicateChildNodeNameException ex)
|
||||
{
|
||||
{
|
||||
throw new ConcurrencyFailureException("Cannot create or resolve path.", ex);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}, false, true);
|
||||
}
|
||||
@@ -168,18 +173,22 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
|
||||
{
|
||||
try
|
||||
{
|
||||
if(getMode() == CopyMoveLinkFileToActionMode.MOVE)
|
||||
{
|
||||
fileFolderService.move(actionedUponNodeRef, finalRecordFolder, null);
|
||||
}
|
||||
else if(getMode() == CopyMoveLinkFileToActionMode.COPY)
|
||||
{
|
||||
fileFolderService.copy(actionedUponNodeRef, finalRecordFolder, null);
|
||||
}
|
||||
else if(getMode() == CopyMoveLinkFileToActionMode.LINK)
|
||||
{
|
||||
recordService.link(actionedUponNodeRef, finalRecordFolder);
|
||||
}
|
||||
synchronized (this)
|
||||
{
|
||||
if(getMode() == CopyMoveLinkFileToActionMode.MOVE)
|
||||
{
|
||||
fileFolderService.move(actionedUponNodeRef, finalRecordFolder, null);
|
||||
}
|
||||
else if(getMode() == CopyMoveLinkFileToActionMode.COPY)
|
||||
{
|
||||
fileFolderService.copy(actionedUponNodeRef, finalRecordFolder, null);
|
||||
}
|
||||
else if(getMode() == CopyMoveLinkFileToActionMode.LINK)
|
||||
{
|
||||
recordService.link(actionedUponNodeRef, finalRecordFolder);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (FileNotFoundException fileNotFound)
|
||||
{
|
||||
@@ -361,18 +370,7 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
|
||||
*/
|
||||
private NodeRef getChild(NodeRef parent, String childName)
|
||||
{
|
||||
NodeRef child = null;
|
||||
List<ChildAssociationRef> children = nodeService.getChildAssocs(parent);
|
||||
for (ChildAssociationRef childAssoc : children) {
|
||||
NodeRef childNodeRef = childAssoc.getChildRef();
|
||||
String existingChildName = (String)nodeService.getProperty(childNodeRef, ContentModel.PROP_NAME);
|
||||
if(existingChildName.equals(childName))
|
||||
{
|
||||
child = childNodeRef;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return child;
|
||||
return nodeService.getChildByName(parent, ContentModel.ASSOC_CONTAINS, childName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -392,22 +390,31 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
|
||||
@Override
|
||||
public NodeRef doWork()
|
||||
{
|
||||
NodeRef child = null;
|
||||
if(targetisUnfiledRecords)
|
||||
// double check that the child hasn't been created by another thread
|
||||
NodeRef child = getChild(parent, childName);
|
||||
if (child == null)
|
||||
{
|
||||
child = fileFolderService.create(parent, childName, RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER).getNodeRef();
|
||||
}
|
||||
else if(lastAsFolder)
|
||||
{
|
||||
child = recordFolderService.createRecordFolder(parent, childName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(RecordsManagementModel.TYPE_RECORD_FOLDER.equals(nodeService.getType(parent)))
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to execute " + action.getActionDefinitionName() + " action, because the destination path could not be created.");
|
||||
}
|
||||
child = filePlanService.createRecordCategory(parent, childName);
|
||||
if(targetisUnfiledRecords)
|
||||
{
|
||||
// create unfiled folder
|
||||
child = fileFolderService.create(parent, childName, RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER).getNodeRef();
|
||||
}
|
||||
else if(lastAsFolder)
|
||||
{
|
||||
// create record folder
|
||||
child = recordFolderService.createRecordFolder(parent, childName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ensure we are not trying to create a record categtory in a record folder
|
||||
if(RecordsManagementModel.TYPE_RECORD_FOLDER.equals(nodeService.getType(parent)))
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to execute " + action.getActionDefinitionName() + " action, because the destination path has a record category within a record folder.");
|
||||
}
|
||||
|
||||
// create record category
|
||||
child = filePlanService.createRecordCategory(parent, childName);
|
||||
}
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
@@ -329,38 +329,44 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private JSONObject setRmNodeValues(NodeRef nodeRef, boolean useShortQName)
|
||||
{
|
||||
JSONObject rmNodeValues = new JSONObject();
|
||||
|
||||
// UI convenience type
|
||||
rmNodeValues.put("uiType", getUIType(nodeRef));
|
||||
|
||||
// Get the 'kind' of the file plan component
|
||||
FilePlanComponentKind kind = filePlanService.getFilePlanComponentKind(nodeRef);
|
||||
rmNodeValues.put("kind", kind.toString());
|
||||
|
||||
// File plan node reference
|
||||
NodeRef filePlan = filePlanService.getFilePlan(nodeRef);
|
||||
rmNodeValues.put("filePlan", filePlan.toString());
|
||||
|
||||
// Unfiled container node reference
|
||||
NodeRef unfiledRecordContainer = filePlanService.getUnfiledContainer(filePlan);
|
||||
if (unfiledRecordContainer != null)
|
||||
private JSONObject setRmNodeValues(final NodeRef nodeRef, final boolean useShortQName)
|
||||
{
|
||||
return AuthenticationUtil.runAsSystem(new RunAsWork<JSONObject>()
|
||||
{
|
||||
rmNodeValues.put("unfiledRecordContainer", unfiledRecordContainer.toString());
|
||||
rmNodeValues.put("properties", propertiesToJSON(unfiledRecordContainer, nodeService.getProperties(unfiledRecordContainer), useShortQName));
|
||||
QName type = fileFolderService.getFileInfo(unfiledRecordContainer).getType();
|
||||
rmNodeValues.put("type", useShortQName ? type.toPrefixString(namespaceService) : type.toString());
|
||||
}
|
||||
public JSONObject doWork()
|
||||
{
|
||||
JSONObject rmNodeValues = new JSONObject();
|
||||
|
||||
// Set the indicators array
|
||||
setIndicators(rmNodeValues, nodeRef);
|
||||
// UI convenience type
|
||||
rmNodeValues.put("uiType", getUIType(nodeRef));
|
||||
|
||||
// Set the actions array
|
||||
setActions(rmNodeValues, nodeRef);
|
||||
|
||||
return rmNodeValues;
|
||||
// Get the 'kind' of the file plan component
|
||||
FilePlanComponentKind kind = filePlanService.getFilePlanComponentKind(nodeRef);
|
||||
rmNodeValues.put("kind", kind.toString());
|
||||
|
||||
// File plan node reference
|
||||
NodeRef filePlan = filePlanService.getFilePlan(nodeRef);
|
||||
rmNodeValues.put("filePlan", filePlan.toString());
|
||||
|
||||
// Unfiled container node reference
|
||||
NodeRef unfiledRecordContainer = filePlanService.getUnfiledContainer(filePlan);
|
||||
if (unfiledRecordContainer != null)
|
||||
{
|
||||
rmNodeValues.put("unfiledRecordContainer", unfiledRecordContainer.toString());
|
||||
rmNodeValues.put("properties", propertiesToJSON(unfiledRecordContainer, nodeService.getProperties(unfiledRecordContainer), useShortQName));
|
||||
QName type = fileFolderService.getFileInfo(unfiledRecordContainer).getType();
|
||||
rmNodeValues.put("type", useShortQName ? type.toPrefixString(namespaceService) : type.toString());
|
||||
}
|
||||
|
||||
// Set the indicators array
|
||||
setIndicators(rmNodeValues, nodeRef);
|
||||
|
||||
// Set the actions array
|
||||
setActions(rmNodeValues, nodeRef);
|
||||
|
||||
return rmNodeValues;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@@ -46,8 +46,7 @@ import org.alfresco.service.namespace.QName;
|
||||
(
|
||||
defaultType = "rma:extendedSecurity"
|
||||
)
|
||||
public class ExtendedSecurityAspect extends BaseBehaviourBean
|
||||
implements NodeServicePolicies.OnMoveNodePolicy
|
||||
public class ExtendedSecurityAspect extends BaseBehaviourBean
|
||||
{
|
||||
/** extended security service */
|
||||
protected ExtendedSecurityService extendedSecurityService;
|
||||
@@ -74,40 +73,4 @@ public class ExtendedSecurityAspect extends BaseBehaviourBean
|
||||
{
|
||||
return new DoNothingCopyBehaviourCallback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update extended security when moving a node.
|
||||
*
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.OnMoveNodePolicy#onMoveNode(org.alfresco.service.cmr.repository.ChildAssociationRef, org.alfresco.service.cmr.repository.ChildAssociationRef)
|
||||
*/
|
||||
@Override
|
||||
@Behaviour
|
||||
(
|
||||
kind = BehaviourKind.CLASS,
|
||||
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT
|
||||
)
|
||||
public void onMoveNode(final ChildAssociationRef origAssoc, final ChildAssociationRef newAssoc)
|
||||
{
|
||||
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void doWork()
|
||||
{
|
||||
NodeRef record = newAssoc.getChildRef();
|
||||
NodeRef newParent = newAssoc.getParentRef();
|
||||
NodeRef oldParent = origAssoc.getParentRef();
|
||||
|
||||
Set<String> readers = extendedSecurityService.getExtendedReaders(record);
|
||||
Set<String> writers = extendedSecurityService.getExtendedWriters(record);
|
||||
|
||||
extendedSecurityService.addExtendedSecurity(newParent, readers, writers);
|
||||
extendedSecurityService.removeExtendedSecurity(oldParent, readers, writers);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@@ -973,7 +973,7 @@ public class RecordServiceImpl extends BaseBehaviourBean
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.disposableitem.RecordService#isFiled(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
@Override
|
||||
public boolean isFiled(NodeRef nodeRef)
|
||||
public boolean isFiled(final NodeRef nodeRef)
|
||||
{
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
|
||||
@@ -981,15 +981,24 @@ public class RecordServiceImpl extends BaseBehaviourBean
|
||||
|
||||
if (isRecord(nodeRef))
|
||||
{
|
||||
ChildAssociationRef childAssocRef = nodeService.getPrimaryParent(nodeRef);
|
||||
if (childAssocRef != null)
|
||||
{
|
||||
NodeRef parent = childAssocRef.getParentRef();
|
||||
if (parent != null && recordFolderService.isRecordFolder(parent))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
result = AuthenticationUtil.runAsSystem(new RunAsWork<Boolean>()
|
||||
{
|
||||
public Boolean doWork() throws Exception
|
||||
{
|
||||
boolean result = false;
|
||||
ChildAssociationRef childAssocRef = nodeService.getPrimaryParent(nodeRef);
|
||||
if (childAssocRef != null)
|
||||
{
|
||||
NodeRef parent = childAssocRef.getParentRef();
|
||||
if (parent != null && recordFolderService.isRecordFolder(parent))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@@ -40,6 +40,7 @@ import org.alfresco.module.org_alfresco_module_rm.security.ExtendedReaderDynamic
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedWriterDynamicAuthority;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authority.RMAuthority;
|
||||
import org.alfresco.service.cmr.repository.DuplicateChildNodeNameException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
@@ -835,7 +836,14 @@ public class FilePlanRoleServiceImpl implements FilePlanRoleService,
|
||||
if (!getAllAssignedToRole(filePlan, role).contains(authorityName))
|
||||
{
|
||||
String roleAuthority = authorityService.getName(AuthorityType.GROUP, getFullRoleName(role, filePlan));
|
||||
authorityService.addAuthority(roleAuthority, authorityName);
|
||||
try
|
||||
{
|
||||
authorityService.addAuthority(roleAuthority, authorityName);
|
||||
}
|
||||
catch (DuplicateChildNodeNameException exception)
|
||||
{
|
||||
// ignore, because the work has already been performed
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
|
@@ -46,10 +46,6 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
|
||||
implements ExtendedSecurityService,
|
||||
RecordsManagementModel
|
||||
{
|
||||
/** Ad hoc properties used for reference counting */
|
||||
private static final QName PROP_EXTENDED_READER_ROLE = QName.createQName(RM_URI, "extendedReaderRole");
|
||||
private static final QName PROP_EXTENDED_WRITER_ROLE = QName.createQName(RM_URI, "extendedWriterRole");
|
||||
|
||||
/** File plan service */
|
||||
private FilePlanService filePlanService;
|
||||
|
||||
@@ -72,7 +68,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
|
||||
this.filePlanRoleService = filePlanRoleService;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService#hasExtendedSecurity(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
public boolean hasExtendedSecurity(NodeRef nodeRef)
|
||||
@@ -137,6 +133,9 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
|
||||
if (nodeRef != null)
|
||||
{
|
||||
addExtendedSecurityImpl(nodeRef, readers, writers, applyToParents);
|
||||
|
||||
// add to the extended security roles
|
||||
addExtendedSecurityRoles(nodeRef, readers, writers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,37 +148,37 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
|
||||
* @param applyToParents
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private void addExtendedSecurityImpl(NodeRef nodeRef, Set<String> readers, Set<String> writers, boolean applyToParents)
|
||||
private void addExtendedSecurityImpl(final NodeRef nodeRef, Set<String> readers, Set<String> writers, boolean applyToParents)
|
||||
{
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
ParameterCheck.mandatory("applyToParents", applyToParents);
|
||||
|
||||
// add the aspect if missing
|
||||
if (!nodeService.hasAspect(nodeRef, ASPECT_EXTENDED_SECURITY))
|
||||
{
|
||||
nodeService.addAspect(nodeRef, ASPECT_EXTENDED_SECURITY, null);
|
||||
}
|
||||
|
||||
// get the properties
|
||||
final Map<QName, Serializable> properties = nodeService.getProperties(nodeRef);
|
||||
|
||||
// update the readers map
|
||||
if (readers != null && readers.size() != 0)
|
||||
{
|
||||
// get reader map
|
||||
Map<String, Integer> readersMap = (Map<String, Integer>)nodeService.getProperty(nodeRef, PROP_READERS);
|
||||
Map<String, Integer> readersMap = (Map<String, Integer>)properties.get(PROP_READERS);
|
||||
|
||||
// set the readers property (this will in turn apply the aspect if required)
|
||||
nodeService.setProperty(nodeRef, PROP_READERS, (Serializable)addToMap(readersMap, readers));
|
||||
properties.put(PROP_READERS, (Serializable)addToMap(readersMap, readers));
|
||||
}
|
||||
|
||||
|
||||
// update the writers map
|
||||
if (writers != null && writers.size() != 0)
|
||||
{
|
||||
// get writer map
|
||||
Map<String, Integer> writersMap = (Map<String, Integer>)nodeService.getProperty(nodeRef, PROP_WRITERS);
|
||||
|
||||
// set the writers property (this will in turn apply the aspect if required)
|
||||
nodeService.setProperty(nodeRef, PROP_WRITERS, (Serializable)addToMap(writersMap, writers));
|
||||
}
|
||||
if (writers != null && writers.size() != 0)
|
||||
{
|
||||
// get writer map
|
||||
Map<String, Integer> writersMap = (Map<String, Integer>)properties.get(PROP_WRITERS);
|
||||
|
||||
// set the writers property (this will in turn apply the aspect if required)
|
||||
properties.put(PROP_WRITERS, (Serializable)addToMap(writersMap, writers));
|
||||
}
|
||||
|
||||
// set properties
|
||||
nodeService.setProperties(nodeRef, properties);
|
||||
|
||||
// apply the readers to any renditions of the content
|
||||
if (isRecord(nodeRef))
|
||||
{
|
||||
@@ -189,22 +188,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
|
||||
NodeRef child = assoc.getChildRef();
|
||||
addExtendedSecurityImpl(child, readers, writers, false);
|
||||
}
|
||||
}
|
||||
|
||||
// add to the extended security roles
|
||||
addExtendedSecurityRoles(nodeRef, readers, writers);
|
||||
|
||||
if (applyToParents)
|
||||
{
|
||||
// apply the extended readers up the file plan primary hierarchy
|
||||
NodeRef parent = nodeService.getPrimaryParent(nodeRef).getParentRef();
|
||||
if (parent != null &&
|
||||
filePlanService.isFilePlanComponent(parent))
|
||||
{
|
||||
addExtendedSecurityImpl(parent, readers, null, applyToParents);
|
||||
addExtendedSecurityImpl(parent, writers, null, applyToParents);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -217,37 +201,29 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
|
||||
{
|
||||
NodeRef filePlan = filePlanService.getFilePlan(nodeRef);
|
||||
|
||||
addExtendedSecurityRolesImpl(filePlan, readers, PROP_EXTENDED_READER_ROLE, FilePlanRoleService.ROLE_EXTENDED_READERS);
|
||||
addExtendedSecurityRolesImpl(filePlan, writers, PROP_EXTENDED_WRITER_ROLE, FilePlanRoleService.ROLE_EXTENDED_WRITERS);
|
||||
addExtendedSecurityRolesImpl(filePlan, readers, FilePlanRoleService.ROLE_EXTENDED_READERS);
|
||||
addExtendedSecurityRolesImpl(filePlan, writers, FilePlanRoleService.ROLE_EXTENDED_WRITERS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add extended security roles implementation
|
||||
*
|
||||
* @param filePlan
|
||||
* @param authorities
|
||||
* @param propertyName
|
||||
* @param roleName
|
||||
* @param filePlan file plan
|
||||
* @param authorities authorities
|
||||
* @param roleName role name
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private void addExtendedSecurityRolesImpl(NodeRef filePlan, Set<String> authorities, QName propertyName, String roleName)
|
||||
private void addExtendedSecurityRolesImpl(NodeRef filePlan, Set<String> authorities, String roleName)
|
||||
{
|
||||
if (authorities != null)
|
||||
{
|
||||
// get the reference count
|
||||
Map<String, Integer> referenceCountMap = (Map<String, Integer>)nodeService.getProperty(filePlan, propertyName);
|
||||
|
||||
for (String authority : authorities)
|
||||
{
|
||||
if ((!authority.equals(PermissionService.ALL_AUTHORITIES) && !authority.equals(PermissionService.OWNER_AUTHORITY)) &&
|
||||
(referenceCountMap == null || !referenceCountMap.containsKey(authority)))
|
||||
if ((!authority.equals(PermissionService.ALL_AUTHORITIES) && !authority.equals(PermissionService.OWNER_AUTHORITY)))
|
||||
{
|
||||
// add the authority to the role
|
||||
filePlanRoleService.assignRoleToAuthority(filePlan, roleName, authority);
|
||||
}
|
||||
}
|
||||
|
||||
// update the reference count
|
||||
nodeService.setProperty(filePlan, propertyName, (Serializable)addToMap(referenceCountMap, authorities));
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user