in src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/impl/PrivilegesHelper.java [651:724]
public static void consolidateAggregates(Session jcrSession, String resourcePath,
Map<Privilege, LocalPrivilege> privilegeToLocalPrivilegesMap,
Map<Privilege, Integer> privilegeLongestDepthMap) throws RepositoryException {
Privilege[] supportedPrivileges = getSupportedOrRegisteredPrivileges(jcrSession, resourcePath);
// sort the aggregates to process the deepest first
Privilege[] supportedAggregatePrivileges = Stream.of(supportedPrivileges)
.filter(Privilege::isAggregate)
.sorted((p1, p2) -> privilegeLongestDepthMap.get(p2).compareTo(privilegeLongestDepthMap.get(p1)))
.toArray(size -> new Privilege[size]);
// loop to consider each aggregate privilege
for (Privilege aggregatePrivilege : supportedAggregatePrivileges) {
// filter the declared aggregate privileges in case some are not a
// direct child. For example, the jcr:all aggregate privileges list
// contains too many for this use case.
int childDepth = privilegeLongestDepthMap.getOrDefault(aggregatePrivilege, -1) + 1;
Privilege[] childPrivileges = Stream.of(aggregatePrivilege.getDeclaredAggregatePrivileges())
.filter(p -> privilegeLongestDepthMap.getOrDefault(p, -1) == childDepth)
.toArray(size -> new Privilege[size]);
// map to LocalPrivileges if we have them
List<LocalPrivilege> childLocalPrivileges = Stream.of(childPrivileges)
.filter(privilegeToLocalPrivilegesMap::containsKey)
.map(privilegeToLocalPrivilegesMap::get)
.collect(Collectors.toList());
if (childPrivileges.length == childLocalPrivileges.size()) {
boolean allAllow = childLocalPrivileges.stream().allMatch(LocalPrivilege::isAllow);
if (allAllow) {
// if the restrictions of all the items is the same then we should copy it up
// and unset the data from each child
Set<LocalRestriction> firstAllowRestrictions = childLocalPrivileges.get(0).getAllowRestrictions();
boolean allRestrictionsSame = childLocalPrivileges.stream().allMatch(lp -> firstAllowRestrictions.equals(lp.getAllowRestrictions()));
if (allRestrictionsSame) {
// all the child privileges are allow so we can mark the parent as allow
LocalPrivilege alp = privilegeToLocalPrivilegesMap.computeIfAbsent(aggregatePrivilege, LocalPrivilege::new);
alp.setAllow(true);
alp.setAllowRestrictions(firstAllowRestrictions);
// each child with the same restrictions can be unset
for (LocalPrivilege lp : childLocalPrivileges) {
if (lp.sameAllowRestrictions(alp.getAllowRestrictions())) {
lp.setAllow(false);
lp.setAllowRestrictions(Collections.emptySet());
}
}
}
}
boolean allDeny = childLocalPrivileges.stream().allMatch(LocalPrivilege::isDeny);
if (allDeny) {
// if the restrictions of all the items is the same then we should copy it up
// and unset the data from each child
Set<LocalRestriction> firstDenyRestrictions = childLocalPrivileges.get(0).getDenyRestrictions();
boolean allRestrictionsSame = childLocalPrivileges.stream().allMatch(lp -> firstDenyRestrictions.equals(lp.getDenyRestrictions()));
if (allRestrictionsSame) {
// all the child privileges are deny so we can mark the parent as deny
LocalPrivilege alp = privilegeToLocalPrivilegesMap.computeIfAbsent(aggregatePrivilege, LocalPrivilege::new);
alp.setDeny(true);
alp.setDenyRestrictions(firstDenyRestrictions);
// each child with the same restrictions can be unset
for (LocalPrivilege lp : childLocalPrivileges) {
if (lp.sameDenyRestrictions(alp.getDenyRestrictions())) {
lp.setDeny(false);
lp.setDenyRestrictions(Collections.emptySet());
}
}
}
}
}
}
// remove any entries that are neither allow nor deny
privilegeToLocalPrivilegesMap.entrySet().removeIf(entry -> entry.getValue().isNone());
}