Skip to content
GroupsService.java 5.4 KiB
Newer Older
package it.inaf.ia2.gms.service;

import it.inaf.ia2.gms.exception.BadRequestException;
import it.inaf.ia2.gms.exception.UnauthorizedException;
import it.inaf.ia2.gms.model.GroupBreadcrumb;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import it.inaf.ia2.gms.persistence.GroupsDAO;
import it.inaf.ia2.gms.persistence.MembershipsDAO;
import it.inaf.ia2.gms.persistence.PermissionsDAO;
import it.inaf.ia2.gms.persistence.model.GroupEntity;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class GroupsService {

    public static final String ROOT = "ROOT";

    private final GroupsDAO groupsDAO;
    private final PermissionsDAO permissionsDAO;
    private final MembershipsDAO membershipsDAO;
    public GroupsService(GroupsDAO groupsDAO,
            PermissionsDAO permissionsDAO, MembershipsDAO membershipsDAO) {
        this.groupsDAO = groupsDAO;
        this.permissionsDAO = permissionsDAO;
        this.membershipsDAO = membershipsDAO;
        createRootIfNecessary();
    }

    private void createRootIfNecessary() {
        if (groupsDAO.count() == 0) {
            GroupEntity root = new GroupEntity();
            root.setId(ROOT);
            root.setName(ROOT);
            root.setPath("");
            groupsDAO.createGroup(root);
    public GroupEntity addGroup(GroupEntity parent, String groupName) {
        if (groupsDAO.getDirectSubGroups(parent.getPath()).stream()
                .anyMatch(g -> g.getName().equals(groupName))) {
            throw new BadRequestException("There is already a group named " + groupName);
        }

        String newGroupId = UUID.randomUUID().toString().replaceAll("-", "");

        String path = parent.getPath();
        if (!path.isEmpty()) {
            path += ".";
        }
        path += newGroupId;

        GroupEntity group = new GroupEntity();
        group.setId(newGroupId);
        group.setName(groupName);
        group.setPath(path);

        groupsDAO.createGroup(group);

    public GroupEntity renameGroup(GroupEntity group, String newGroupName) {
        if (groupsDAO.getDirectSubGroups(group.getPath()).stream()
                .anyMatch(g -> g.getName().equals(newGroupName))) {
            throw new BadRequestException("There is already a group named " + newGroupName);
        }

        group.setName(newGroupName);

        return groupsDAO.updateGroup(group);
    public GroupEntity deleteGroup(GroupEntity group) {

        if (ROOT.equals(group.getId())) {
            throw new UnauthorizedException("It is not possible to remove the ROOT");
        }

        String parentPath = group.getParentPath();
        GroupEntity parent = groupsDAO.findGroupByPath(parentPath)
                .orElseThrow(() -> new BadRequestException("No group found at path " + parentPath));
        List<GroupEntity> groupsToDelete = groupsDAO.getAllChildren(group.getPath());
        groupsToDelete.add(group);

        List<String> groupsToDeleteIds = groupsToDelete.stream()
                .map(g -> g.getId()).collect(Collectors.toList());

        membershipsDAO.deleteAllGroupsMembership(groupsToDeleteIds);
        permissionsDAO.deleteAllGroupsPermissions(groupsToDeleteIds);

        for (String groupId : groupsToDeleteIds) {
            groupsDAO.deleteGroupById(groupId);
        }
    public GroupEntity getRoot() {
        return getGroupById(ROOT);
    }

    public GroupEntity getGroupById(String groupId) {
        return groupsDAO.findGroupById(groupId)
                .orElseThrow(() -> new BadRequestException("Group " + groupId + " not found"));
    public GroupEntity getGroupByPath(String path) {
        return groupsDAO.findGroupByPath(path)
                .orElseThrow(() -> new BadRequestException("Group not found at path " + path));
    public List<GroupBreadcrumb> getBreadcrumbs(String path) {
        return groupsDAO.getBreadcrumbs(path);

    public Optional<GroupEntity> findGroupByParentAndName(GroupEntity parent, String childName) {
        return groupsDAO.findGroupByParentAndName(parent.getPath(), childName);
    }

    /**
     * Retrieves a group given the sequence of group names corresponding to its
     * path.
     */
    public Optional<GroupEntity> findGroupByNames(List<String> names) {

        // There can be groups with the same name under different parents, so
        // after retrieving this list it is necessary to match for the correct
        // group
        List<GroupEntity> groups = groupsDAO.findGroupsByNames(names);

        String parentPath = "";
        GroupEntity group = null;
        for (String name : names) {
            group = findGroup(groups, parentPath, name);
            if (group == null) {
                break;
            } else {
                parentPath = group.getPath();
            }
        }

        return Optional.ofNullable(group);
    }

    private GroupEntity findGroup(List<GroupEntity> groups, String parentPath, String groupName) {
        for (GroupEntity group : groups) {
            if (parentPath.equals(group.getParentPath()) && groupName.equals(group.getName())) {
                return group;
            }
        }
        return null;
    }

    public List<GroupEntity> searchGroups(String searchText) {
        return groupsDAO.searchGroups(searchText);
    }