Set<String> newGrantedPrivilegeNames = disaggregateToPrivilegeNames(accessControlManager, grantedPrivilegeNames, specifiedPrivilegeNames);
Set<String> newDeniedPrivilegeNames = disaggregateToPrivilegeNames(accessControlManager, deniedPrivilegeNames, specifiedPrivilegeNames);
disaggregateToPrivilegeNames(accessControlManager, removedPrivilegeNames, specifiedPrivilegeNames);
// Get or create the ACL for the node.
AccessControlList acl = null;
AccessControlPolicy[] policies = accessControlManager.getPolicies(resourcePath);
for (AccessControlPolicy policy : policies) {
if (policy instanceof AccessControlList) {
acl = (AccessControlList) policy;
break;
}
}
if (acl == null) {
AccessControlPolicyIterator applicablePolicies = accessControlManager.getApplicablePolicies(resourcePath);
while (applicablePolicies.hasNext()) {
AccessControlPolicy policy = applicablePolicies.nextAccessControlPolicy();
if (policy instanceof AccessControlList) {
acl = (AccessControlList) policy;
break;
}
}
}
if (acl == null) {
throw new RepositoryException("Could not obtain ACL for resource " + resourcePath);
}
// Used only for logging.
Set<Privilege> oldGrants = null;
Set<Privilege> oldDenies = null;
if (log.isDebugEnabled()) {
oldGrants = new HashSet<Privilege>();
oldDenies = new HashSet<Privilege>();
}
// Combine all existing ACEs for the target principal.
AccessControlEntry[] accessControlEntries = acl.getAccessControlEntries();
for (int i=0; i < accessControlEntries.length; i++) {
AccessControlEntry ace = accessControlEntries[i];
if (principal.equals(ace.getPrincipal())) {
if (log.isDebugEnabled()) {
log.debug("Found Existing ACE for principal {} on resource {}", new Object[] {principal.getName(), resourcePath});
}
if (order == null || order.length() == 0) {
//order not specified, so keep track of the original ACE position.
order = String.valueOf(i);
}
boolean isAllow = isAllow(ace);
Privilege[] privileges = ace.getPrivileges();
if (log.isDebugEnabled()) {
if (isAllow) {
oldGrants.addAll(Arrays.asList(privileges));
} else {
oldDenies.addAll(Arrays.asList(privileges));
}
}
for (Privilege privilege : privileges) {
Set<String> maintainedPrivileges = disaggregateToPrivilegeNames(privilege);
// If there is any overlap with the newly specified privileges, then
// break the existing privilege down; otherwise, maintain as is.
if (!maintainedPrivileges.removeAll(specifiedPrivilegeNames)) {
// No conflicts, so preserve the original.
maintainedPrivileges.clear();
maintainedPrivileges.add(privilege.getName());
}
if (!maintainedPrivileges.isEmpty()) {
if (isAllow) {
newGrantedPrivilegeNames.addAll(maintainedPrivileges);
} else {
newDeniedPrivilegeNames.addAll(maintainedPrivileges);
}
}
}
// Remove the old ACE.
acl.removeAccessControlEntry(ace);
}
}
//add a fresh ACE with the granted privileges
List<Privilege> grantedPrivilegeList = new ArrayList<Privilege>();
for (String name : newGrantedPrivilegeNames) {
Privilege privilege = accessControlManager.privilegeFromName(name);
grantedPrivilegeList.add(privilege);
}
if (grantedPrivilegeList.size() > 0) {
acl.addAccessControlEntry(principal, grantedPrivilegeList.toArray(new Privilege[grantedPrivilegeList.size()]));
}
//add a fresh ACE with the denied privileges
List<Privilege> deniedPrivilegeList = new ArrayList<Privilege>();
for (String name : newDeniedPrivilegeNames) {