protected void processPostedPrivilegeAndRestrictionParams()

in src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/ModifyAceServlet.java [579:680]


    protected void processPostedPrivilegeAndRestrictionParams(@NotNull AccessControlManager acm,
            @NotNull SlingHttpServletRequest request,
            @NotNull Map<String, RestrictionDefinition> srMap,
            @NotNull Map<Privilege, LocalPrivilege> privilegeToLocalPrivilegesMap,
            @NotNull Map<Privilege, Integer> privilegeLongestDepthMap) throws RepositoryException {
        @NotNull
        Map<String, Matcher> postedPrivilegeNameKeys = getMatchedRequestParameterNames(request, PRIVILEGE_PATTERN);

        // collect all the privileges so we can process them in the right order
        Map<Privilege, Set<String>> privilegeToParamValuesMap = new HashMap<>();
        for (Entry<String, Matcher> entry : postedPrivilegeNameKeys.entrySet()) {
            String paramName = entry.getKey();
            Matcher matcher = entry.getValue();
            String privilegeName = matcher.group(1);
            Privilege privilege = acm.privilegeFromName(privilegeName);
            Set<String> paramValues = privilegeToParamValuesMap.computeIfAbsent(privilege, p -> new HashSet<>());
            paramValues.addAll(Arrays.asList(request.getParameterValues(paramName)));
        }

        //also check for any restriction params
        Set<LocalRestriction> generalRestrictions = new HashSet<>();
        Map<String, Matcher> postedRestrictionParams = getMatchedRequestParameterNames(request, RESTRICTION_PATTERN);
        for (Entry<String, Matcher> entry : postedRestrictionParams.entrySet()) {
            Matcher matcher = entry.getValue();
            if (matcher.group(2) != null) {
                PrivilegeValues allowOrDeny = PrivilegeValues.valueOfParam(matcher.group(4));
                if (PrivilegeValues.ALLOW.equals(allowOrDeny) ||
                        PrivilegeValues.DENY.equals(allowOrDeny)) {
                    String privilegeName = matcher.group(1);
                    Privilege privilege = acm.privilegeFromName(privilegeName);
                    Set<String> paramValues = privilegeToParamValuesMap.computeIfAbsent(privilege, p -> new HashSet<>());
                    paramValues.add(allowOrDeny.getParamValue());
                }
            } else {
                // restriction but not for a specific privilege
                String restrictionName = matcher.group(1);
                String paramName = entry.getKey();
                LocalRestriction localRestriction = toLocalRestriction(request, srMap, restrictionName, paramName);
                generalRestrictions.removeIf(r -> r.getName().equals(localRestriction.getName()));
                generalRestrictions.add(localRestriction);
            }
        }

        // apply the general restrictions to any already existing privilege that was not posted
        //   with new state
        if (!generalRestrictions.isEmpty()) {
            for (Entry<Privilege, LocalPrivilege> entry : privilegeToLocalPrivilegesMap.entrySet()) {
                Privilege p = entry.getKey();
                if (!privilegeToParamValuesMap.containsKey(p)) {
                    LocalPrivilege lp = entry.getValue();
                    applyPrivilegeAndRestrictions(privilegeToLocalPrivilegesMap, p, 
                            lp.isAllow(), generalRestrictions, 
                            lp.isDeny(), generalRestrictions);
                }
            }
        }

        List<Entry<Privilege, Set<String>>> sortedEntries = new ArrayList<>(privilegeToParamValuesMap.entrySet());
        // sort the entries to process the most shallow last
        Collections.sort(sortedEntries, (e1, e2) -> privilegeLongestDepthMap.get(e1.getKey()).compareTo(privilegeLongestDepthMap.get(e2.getKey())));
        for (Entry<Privilege, Set<String>> entry : sortedEntries) {
            Set<String> paramValues = entry.getValue();
            Privilege privilege = entry.getKey();

            // convert and sort the values to ensure that allow goes after
            //  deny or none when there is a conflict
            List<PrivilegeValues> privilegeValues = paramValues.stream()
                .map(PrivilegeValues::valueOfParam)
                .sorted((v1, v2) -> Integer.compare(v2.ordinal(), v1.ordinal()))
                .collect(Collectors.toList());
            boolean none = false;
            boolean allow = false;
            Set<LocalRestriction> allowRestrictions = Collections.emptySet();
            boolean deny = false;
            Set<LocalRestriction> denyRestrictions = Collections.emptySet();
            for (PrivilegeValues value : privilegeValues) {
                switch (value) {
                case DENY:
                case DENIED:
                    deny = true;
                    denyRestrictions = postedRestrictionsForPrivilege(request, srMap, privilege, value, generalRestrictions);
                    break;
                case ALLOW:
                case GRANTED:
                    allow = true;
                    allowRestrictions = postedRestrictionsForPrivilege(request, srMap, privilege, value, generalRestrictions);
                    break;
                case NONE:
                    none = true;
                    break;
                default:
                    break;
                }
            }
            if (none) {
                PrivilegesHelper.none(privilegeToLocalPrivilegesMap, Collections.singleton(privilege));
            }
            applyPrivilegeAndRestrictions(privilegeToLocalPrivilegesMap, privilege,
                    allow, allowRestrictions, 
                    deny, denyRestrictions);
        }
    }