@@ -0,0 +1,3630 @@
+/*%0A * This file is part of Orbit, licenced under the MIT Licence (MIT)%0A *%0A * Copyright (c) Vayzd Network %3Chttps://www.vayzd.net/%3E%0A * Copyright (c) contributors%0A *%0A * Permission is hereby granted, free of charge, to any person obtaining a copy%0A * of this software and associated documentation files (the %22Software%22), to deal%0A * in the Software without restriction, including without limitation the rights%0A * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell%0A * copies of the Software, and to permit persons to whom the Software is%0A * furnished to do so, subject to the following conditions:%0A *%0A * The above copyright notice and this permission notice shall be included in all%0A * copies or substantial portions of the Software.%0A *%0A * THE SOFTWARE IS PROVIDED %22AS IS%22, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR%0A * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,%0A * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE%0A * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER%0A * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,%0A * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE%0A * SOFTWARE.%0A */%0Apackage net.vayzd.orbit.datastore.group;%0A%0Aimport com.google.common.collect.*;%0Aimport lombok.*;%0Aimport net.vayzd.orbit.datastore.*;%0A%0Aimport java.util.*;%0A%0A@RequiredArgsConstructor(access = AccessLevel.PRIVATE)%0A@Getter(AccessLevel.PRIVATE)%0Apublic class PermissionCalculator %7B%0A%0A    @NonNull%0A    private final DatastoreGroup group;%0A    @NonNull%0A    private final Datastore datastore;%0A%0A    public static PermissionCalculator of(DatastoreGroup group, Datastore datastore) %7B%0A        return new PermissionCalculator(group, datastore);%0A    %7D%0A%0A    public ImmutableSet%3CString%3E computeEffectivePermissions() %7B%0A        List%3CString%3E permissions = new LinkedList%3C%3E();%0A        for (String ancestor : calculateGroupTree()) %7B%0A            for (String permission : getGroupFor(ancestor).getPermissionSet()) %7B%0A                if (permissions.contains(permission)) %7B%0A                    continue;%0A                %7D%0A                permissions.add(permission);%0A            %7D%0A        %7D%0A        return squash(permissions);%0A    %7D%0A%0A    private ImmutableSet%3CString%3E calculateGroupTree() %7B%0A        List%3CString%3E tree = new ArrayList%3C%3E();%0A        for (String next : group.getParentSet()) %7B%0A            if (next.equals(group.getName())) %7B%0A                continue;%0A            %7D%0A            for (String trunk : calculateBackwardGroupTree(next)) %7B%0A                tree.add(0, trunk);%0A            %7D%0A        %7D%0A        return squash(tree);%0A    %7D%0A%0A    private ImmutableSet%3CString%3E calculateBackwardGroupTree(String group) %7B%0A        List%3CString%3E tree = new ArrayList%3C%3E();%0A        tree.add(group);%0A        for (String next : getGroupFor(group).getParentSet()) %7B%0A            try %7B%0A                if (next.equals(group)) %7B%0A                    continue;%0A                %7D%0A                if (getGroupFor(next).getParentSet().contains(group)) %7B%0A                    continue;%0A                %7D%0A                tree.addAll(new ArrayList%3C%3E(calculateBackwardGroupTree(next)));%0A            %7D catch (StackOverflowError error) %7B%0A                return squash(getGroupFor(group).getParentSet());%0A            %7D%0A        %7D%0A        return squash(tree);%0A    %7D%0A%0A    private DatastoreGroup getGroupFor(String name) %7B%0A        Optional%3CDatastoreGroup%3E group = datastore.getGroup(name);%0A        return group.orElseGet(this::getGroup);%0A    %7D%0A%0A    private %3CT%3E ImmutableSet%3CT%3E squash(Collection%3CT%3E list) %7B%0A        return ImmutableSet.copyOf(list);%0A    %7D%0A%7D

Add PermissionCalculator class