Merged BRANCHES/V2.2.1.x to BRANCHES/V2.2:

102241: RM-2072 (Concurrency exceptions and deadlocks on Records Management "File to" rule)
   102242: RM-1100 (Uncaught LockAcquisitionException in RM 2.0.4)
   102267: RM-2072 (Concurrency exceptions and deadlocks on Records Management "File to" rule)
   102269: RM-2072 (Concurrency exceptions and deadlocks on Records Management "File to" rule)
   102279: RM-2072 (Concurrency exceptions and deadlocks on Records Management "File to" rule)
   102486: RM-2072: Concurrency exceptions and deadlocks on Records Management "File to" rule
   102636: RM-2191 ("Create Category" and "Manage Permissions" buttons are enabled for user with read-only permissions)
   102675: RM-2190 (Concurrency exception when upload document to several folders with rules configured to file records)
   102687: RM-2192 (User has no access to the recorded document after it was filed)
   102698: Removed warnings
   102699: .ant-targets-build.xml files added to svn:ignore
   102700: .ant-targets-build.xml files added to svn:ignore
   102701: RM-2190 (Concurrency exception when upload document to several folders with rules configured to file records)
   102756: RM-2192 (User has no access to the recorded document after it was filed)
   102762: Commented out intermittently failing test
   102795: (RECORD ONLY) Deploy RM 2.2.1.1 on Maven Repository
   102807: (RECORD ONLY) Changed the artifact version to 2.2.1.2-SNAPSHOT

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.2@103037 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Tuna Aksoy
2015-04-29 08:35:10 +00:00
parent 8b62190595
commit f695bcab1a
17 changed files with 781 additions and 245 deletions

View File

@@ -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);
}
}
}

View File

@@ -11,16 +11,18 @@ import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.action.ParameterDefinitionImpl;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.service.cmr.action.Action;
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;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.util.StringUtils;
/**
@@ -33,6 +35,9 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
{
private static Log logger = LogFactory.getLog(CopyMoveLinkFileToBaseAction.class);
/** Retrying transaction helper */
private RetryingTransactionHelper retryingTransactionHelper;
/** action parameters */
public static final String PARAM_DESTINATION_RECORD_FOLDER = "destinationRecordFolder";
public static final String PARAM_PATH = "path";
@@ -89,6 +94,14 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
this.filePlanService = filePlanService;
}
/**
* @param retryingTransactionHelper retrying transaction helper
*/
public void setRetryingTransactionHelper(RetryingTransactionHelper retryingTransactionHelper)
{
this.retryingTransactionHelper = retryingTransactionHelper;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#addParameterDefinitions(java.util.List)
*/
@@ -103,7 +116,7 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
* @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
protected void executeImpl(final Action action, final NodeRef actionedUponNodeRef)
protected synchronized void executeImpl(final Action action, final NodeRef actionedUponNodeRef)
{
String actionName = action.getActionDefinitionName();
if (isOkToProceedWithAction(actionedUponNodeRef, actionName))
@@ -125,8 +138,25 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
NodeRef recordFolder = (NodeRef)action.getParameterValue(PARAM_DESTINATION_RECORD_FOLDER);
if (recordFolder == null)
{
// get the reference to the record folder based on the relative path
recordFolder = createOrResolvePath(action, actionedUponNodeRef, targetIsUnfiledRecords);
final boolean finaltargetIsUnfiledRecords = targetIsUnfiledRecords;
recordFolder = retryingTransactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<NodeRef>()
{
public NodeRef execute() throws Throwable
{
NodeRef result = null;
try
{
// 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);
}
// now we have the reference to the target folder we can do some final checks to see if the action is valid
@@ -140,18 +170,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)
{
@@ -333,18 +367,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);
}
/**
@@ -364,22 +387,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;
}

View File

@@ -25,6 +25,8 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
@@ -39,6 +41,8 @@ import org.quartz.JobExecutionException;
*/
public class RecordsManagementJob implements Job
{
private static Log logger = LogFactory.getLog(RecordsManagementJob.class);
private static final long DEFAULT_TIME = 30000L;
private JobLockService jobLockService;
@@ -108,7 +112,18 @@ public class RecordsManagementJob implements Job
}
finally
{
jobLockService.releaseLock(lockToken, getLockQName());
try
{
jobLockService.releaseLock(lockToken, getLockQName());
}
catch (LockAcquisitionException e)
{
// Ignore
if (logger.isDebugEnabled())
{
logger.debug("Lock release failed: " + getLockQName() + ": " + lockToken + "(" + e.getMessage() + ")");
}
}
}
}

View File

@@ -18,6 +18,10 @@
*/
package org.alfresco.module.org_alfresco_module_rm.jscript.app;
import static org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel.READ_RECORDS;
import static org.alfresco.repo.security.authentication.AuthenticationUtil.runAsSystem;
import static org.alfresco.service.cmr.security.AccessStatus.ALLOWED;
import java.util.ArrayList;
import java.util.List;
@@ -305,10 +309,10 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC
rootJSONObject.put("originatingLocationPath", originatingLocationPath.toString());
}
}
/**
* Helper method to get the display path.
*
*
* @param nodeRef node reference
* @return String display path
*/
@@ -329,9 +333,9 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC
* @return
*/
@SuppressWarnings("unchecked")
private JSONObject setRmNodeValues(NodeRef nodeRef, boolean useShortQName)
private JSONObject setRmNodeValues(final NodeRef nodeRef, final boolean useShortQName)
{
JSONObject rmNodeValues = new JSONObject();
JSONObject rmNodeValues = new JSONObject();
// UI convenience type
rmNodeValues.put("uiType", getUIType(nodeRef));
@@ -341,17 +345,20 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC
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)
NodeRef filePlan = getFilePlan(nodeRef);
if (permissionService.hasPermission(filePlan, READ_RECORDS).equals(ALLOWED))
{
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());
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
@@ -363,6 +370,23 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC
return rmNodeValues;
}
/**
* Helper method to get the file plan as a system user for the given node
*
* @param nodeRef The node reference
* @return The file plan where the node is in
*/
private NodeRef getFilePlan(final NodeRef nodeRef)
{
return runAsSystem(new RunAsWork<NodeRef>()
{
public NodeRef doWork()
{
return filePlanService.getFilePlan(nodeRef);
}
});
}
@SuppressWarnings("unchecked")
private void setIndicators(JSONObject rmNodeValues, NodeRef nodeRef)
{

View File

@@ -18,22 +18,14 @@
*/
package org.alfresco.module.org_alfresco_module_rm.model.rma.aspect;
import java.util.Set;
import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean;
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService;
import org.alfresco.repo.copy.CopyBehaviourCallback;
import org.alfresco.repo.copy.CopyDetails;
import org.alfresco.repo.copy.DoNothingCopyBehaviourCallback;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
import org.alfresco.repo.policy.annotation.Behaviour;
import org.alfresco.repo.policy.annotation.BehaviourBean;
import org.alfresco.repo.policy.annotation.BehaviourKind;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
/**
@@ -46,8 +38,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 +65,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;
}
});
}
}

View File

@@ -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;

View File

@@ -32,6 +32,8 @@ import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.NamespaceService;
@@ -146,7 +148,7 @@ public class RecordFolderServiceImpl extends ServiceBaseImpl
* @see org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService#isRecordFolderClosed(NodeRef)
*/
@Override
public boolean isRecordFolderClosed(NodeRef nodeRef)
public boolean isRecordFolderClosed(final NodeRef nodeRef)
{
ParameterCheck.mandatory("nodeRef", nodeRef);
@@ -156,7 +158,13 @@ public class RecordFolderServiceImpl extends ServiceBaseImpl
throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_RECORD_FOLDER_EXPECTED));
}
return ((Boolean) nodeService.getProperty(nodeRef, PROP_IS_CLOSED)).booleanValue();
return AuthenticationUtil.runAsSystem(new RunAsWork<Boolean>()
{
public Boolean doWork() throws Exception
{
return ((Boolean) nodeService.getProperty(nodeRef, PROP_IS_CLOSED));
}
});
}
@Override

View File

@@ -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;

View File

@@ -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));
}
}