public Collection getPrivileges()

in src/main/java/org/apache/sling/starter/access/models/Ace.java [155:316]


    public Collection<PrivilegeItem> getPrivileges() throws RepositoryException {
        Map<Privilege, PrivilegeItem> privilegesMap = getPersistedPrivilegesMap(); 
        if (privilegesMap == null || privilegesMap.isEmpty()) {
            return Collections.emptyList();
        }

        //make a temp map for quick lookup below
        Set<RestrictionDefinition> supportedRestrictions = getSupportedRestrictions();
        Map<String, RestrictionDefinition> srMap = toSrMap(supportedRestrictions);

        Map<String, List<RestrictionItem>> postedAllowRestrictionsMap = new HashMap<>(); 
        Map<String, List<RestrictionItem>> postedDenyRestrictionsMap = new HashMap<>(); 
        Map<String, String[]> fieldValues = populateEntriesFromPreviousFailedPost(postedAllowRestrictionsMap, postedDenyRestrictionsMap, srMap);
        Map<String, String[]> toDeleteFieldValues = getFieldValuesForPattern(RESTRICTION_PATTERN_DELETE);
        //entries from the previous failed POST.
        for (PrivilegeItem entry : privilegesMap.values()) {
            String privilegeName = entry.getName();
            // check for any submitted form fields in case of error and redisplay of the page
            String paramValue = request.getParameter(String.format("privilege@%s", privilegeName));
            if (paramValue != null) {
                //req param was here from a failed post?
                if ("granted".equals(paramValue)) {
                    entry.setGranted(true);
                } else if ("denied".equals(paramValue)) {
                    entry.setDenied(true);
                }
            } else {
                // check for delete existing param
                String paramDeleteValue = request.getParameter(String.format("privilege@%s@Delete", privilegeName));
                if (paramDeleteValue != null) {
                    //req param was here from a failed post?
                    if ("granted".equals(paramDeleteValue)) {
                        entry.setGranted(false);
                    } else if ("denied".equals(paramDeleteValue)) {
                        entry.setDenied(false);
                    }
                }
            }

            for (boolean forAllow : new boolean [] {true, false}) {
                // first add items for any posted fields
                Map<String, List<RestrictionItem>> postedRestrictionsMap = forAllow ? postedAllowRestrictionsMap : postedDenyRestrictionsMap;
                List<RestrictionItem> newRestrictionsList = postedRestrictionsMap.computeIfAbsent(privilegeName, pn -> new ArrayList<>());
                //now merge in any declared restrictions that were not posted
                List<RestrictionItem> declaredRestrictions = forAllow ? entry.getAllowRestrictions() : entry.getDenyRestrictions();
                if (declaredRestrictions != null && !declaredRestrictions.isEmpty()) {
                    for (RestrictionItem ri : declaredRestrictions) {
                        String restrictionName = ri.getName();

                        boolean addIt = true;
                        String fieldKeyPrefix = String.format("restriction@%s@%s", privilegeName, restrictionName);
                        String fieldKey = String.format("%s@%s", fieldKeyPrefix, (forAllow ? "Allow" : "Deny"));
                        // skip it if it was requested to be deleted in the previous POST attempt
                        // or already handled above
                        if (toDeleteFieldValues.containsKey(String.format("%s%s", fieldKeyPrefix, SlingPostConstants.SUFFIX_DELETE))) {
                            addIt = false;
                        } else if (fieldValues.containsKey(fieldKey)) {
                            // mark the form posted item as exists since it also
                            //  had a persisted value
                            newRestrictionsList.stream()
                                .filter(list -> list.getName().equals(restrictionName))
                                .forEach(item -> item.setExists(true));
                            addIt = false;
                        }

                        if (addIt) {
                            newRestrictionsList.add(ri);
                        }
                    }
                }

                // check if we are missing an item for any mandatory restrictions
                populateEntriesForMissingMandatoryRestrictions(newRestrictionsList, supportedRestrictions);

                // and apply it
                if (forAllow) {
                    entry.setAllowRestrictions(newRestrictionsList);
                } else {
                    entry.setDenyRestrictions(newRestrictionsList);
                }

                // populate restrictions to delete here.
                toDeleteFieldValues.keySet().stream()
                    .filter(key -> RESTRICTION_PATTERN_DELETE.matcher(key).matches())
                    .forEach(key -> {
                        Matcher matcher = RESTRICTION_PATTERN_DELETE.matcher(key);
                        if (matcher.matches()) {
                            String restrictionName = matcher.group(2);
                            if (forAllow) {
                                entry.addAllowRestrictionToDelete(restrictionName);
                            } else {
                                entry.addDenyRestrictionToDelete(restrictionName);
                            }
                        }
                    });
            }
        }

        List<PrivilegeItem> list = new ArrayList<>(privilegesMap.values());
        list.sort((p1, p2) -> {
            String longestPath1 = p1.getLongestPath();
            String[] segments1 = longestPath1.split("/");
            String longestPath2 = p2.getLongestPath();
            String[] segments2 = longestPath2.split("/");

            for (int i = 0; i < segments1.length; i++) {
                Integer priority1 = privilegesPriority.getOrDefault(segments1[i], 1000);
                if (segments2.length <= i) {
                    return longestPath1.compareTo(longestPath2);
                }
                Integer priority2 = privilegesPriority.getOrDefault(segments2[i], 1000);
                int cmp = priority1.compareTo(priority2);
                if (cmp != 0) {
                    return cmp;
                }
            }
            if (segments1.length == segments2.length) {
                // natural sort of the namespace-free last segment of each path
                String lastSegment1 = segments1[segments1.length - 1];
                String lastSegment2 = segments2[segments2.length - 1];
                lastSegment1 = lastSegment1.substring(lastSegment1.indexOf(':'));
                lastSegment2 = lastSegment2.substring(lastSegment2.indexOf(':'));
                return lastSegment1.compareTo(lastSegment2);
            }
            return longestPath1.compareTo(longestPath2);
        });

        // loop through one more time to annotate the items with
        //   extra css markers to help render a tree-ish view
        boolean lastBranch = true;
        for (int i = list.size() - 1; i > 0; i--) {
            PrivilegeItem item = list.get(i);
            if (lastBranch) {
                item.addExtraCssClass("lastBranch");
            }
            if (lastBranch && item.getDepth() == 1) {
                lastBranch = false;
            }
            if (i == list.size() - 1) {
                item.addExtraCssClass("lastSibling");
            } else {
                boolean lastSibling = true;
                // if the there remains another item that has the same depth as this
                //  then this is not the last sibling
                for (int j = i + 1; j < list.size(); j++) {
                    PrivilegeItem nextItem = list.get(j);
                    if (nextItem.getDepth() == item.getDepth()) {
                        String nextItemParentPath = ResourceUtil.getParent(nextItem.getLongestPath());
                        String itemParentPath = ResourceUtil.getParent(item.getLongestPath());
                        if (nextItemParentPath != null && nextItemParentPath.equals(itemParentPath)) {
                            lastSibling = false;
                            break;
                        }
                    }
                }
                if (lastSibling) {
                    item.addExtraCssClass("lastSibling");
                }
            }
        }
        return list;
    }