Skip to content
GroupNameService.java 5.59 KiB
Newer Older
Sonia Zorba's avatar
Sonia Zorba committed
package it.inaf.ia2.gms.service;

import it.inaf.ia2.gms.exception.BadRequestException;
Sonia Zorba's avatar
Sonia Zorba committed
import it.inaf.ia2.gms.persistence.GroupsDAO;
import it.inaf.ia2.gms.persistence.model.GroupEntity;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
Sonia Zorba's avatar
Sonia Zorba committed
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
Sonia Zorba's avatar
Sonia Zorba committed
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Sonia Zorba's avatar
Sonia Zorba committed
import java.util.Set;
import java.util.stream.Collectors;
Sonia Zorba's avatar
Sonia Zorba committed
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * Utility class for retrieving the complete names (including parents) from a
 * set of group paths.
 */
@Service
public class GroupNameService {

    private final GroupsDAO groupsDAO;

Sonia Zorba's avatar
Sonia Zorba committed
    @Autowired
    public GroupNameService(GroupsDAO groupsDAO) {
        this.groupsDAO = groupsDAO;
    }
Sonia Zorba's avatar
Sonia Zorba committed

    public List<String> getGroupsNamesFromIdentifiers(Set<String> groupIdentifiers) {
        return getGroupsNames(groupsDAO.findGroupsByIds(groupIdentifiers));
    }

    public String getGroupCompleteName(GroupEntity group) {
        return getGroupsNames(Collections.singletonList(group)).get(0);
    }

    /**
     * Returns the list of the group complete names, given a list of GroupEntity
     * objects.
     */
    public List<String> getGroupsNames(List<GroupEntity> groups) {

        Set<String> groupIds = groups.stream().map(g -> g.getId()).collect(Collectors.toSet());
        List<String> names = new ArrayList<>(groupsDAO.getGroupCompleteNamesFromId(groupIds).values());
        Collections.sort(names);
    /**
     * @param groups
     * @return map having group id as keys and group names as values
     */
    public Map<String, List<String>> getNames(Set<GroupEntity> groups) {
        Set<String> groupIds = groups.stream()
                .map(g -> g.getId()).collect(Collectors.toSet());
        return getNamesFromIds(groupIds);
    }
    public Map<String, List<String>> getNamesFromIds(Set<String> groupIds) {
        Map<String, List<String>> result = new HashMap<>();
        if (groupIds.contains("ROOT")) {
Sonia Zorba's avatar
Sonia Zorba committed
            result.put("ROOT", Collections.singletonList(getRoot().getName()));
        for (Map.Entry<String, String> entry : groupsDAO.getGroupCompleteNamesFromId(groupIds).entrySet()) {
            List<String> names = splitNames(entry.getValue());
            result.put(entry.getKey(), names);
    private List<String> splitNames(String completeGroupName) {
        return Arrays.asList(completeGroupName.split("(?<!\\\\)\\."));
    }
Sonia Zorba's avatar
Sonia Zorba committed

    public String getShortGroupName(String completeGroupName, Optional<String> groupPrefix) {
Sonia Zorba's avatar
Sonia Zorba committed
        if (groupPrefix.isPresent() && !groupPrefix.get().isBlank()) {
            if (groupPrefix.get().endsWith(".")) {
                // this branch is kept for retro-compatibility with old API, it will be removed in the future
                return completeGroupName.substring(groupPrefix.get().length());
            } else {
                return completeGroupName.substring(groupPrefix.get().length() + 1);
            }
Sonia Zorba's avatar
Sonia Zorba committed
        }
        return completeGroupName;
    }
Sonia Zorba's avatar
Sonia Zorba committed

    public GroupEntity getGroupFromNames(Optional<String> group) {
Sonia Zorba's avatar
Sonia Zorba committed

        List<String> groupNames = extractGroupNames(group);

        if (groupNames.isEmpty()) {
            return getRoot();
Sonia Zorba's avatar
Sonia Zorba committed
        }
        return getGroupFromNamesAndIndex(groupNames, groupNames.size() - 1);
    }
Sonia Zorba's avatar
Sonia Zorba committed

    public GroupEntity getGroupFromNamesAndIndex(Optional<String> group, int index) {
        List<String> groupNames = extractGroupNames(group);
        return getGroupFromNamesAndIndex(groupNames, index);
    private GroupEntity getGroupFromNamesAndIndex(List<String> groupNames, int index) {
        String parentPath = ""; // starting from ROOT
        GroupEntity group = null;
        for (int i = 0; i < index + 1; i++) {
            String groupName = groupNames.get(i);
            group = groupsDAO.findGroupByParentAndName(parentPath, groupName)
                    .orElseThrow(() -> new BadRequestException("Unable to find group " + groupName));
            parentPath = group.getPath();
Sonia Zorba's avatar
Sonia Zorba committed
        }
        if (group == null) {
            throw new IllegalStateException();
        }
        return group;
    }
Sonia Zorba's avatar
Sonia Zorba committed

    private List<String> extractGroupNames(Optional<String> group) {
        return extractGroupNames(group.orElse(null));
    public List<String> extractGroupNames(String groupStr) {

        if (groupStr == null || groupStr.isEmpty()) {
            return new ArrayList<>();
        }

        groupStr = URLDecoder.decode(groupStr, StandardCharsets.UTF_8);

Sonia Zorba's avatar
Sonia Zorba committed
        List<String> names = new ArrayList<>();
        String currentName = "";
        for (int i = 0; i < groupStr.length(); i++) {
            char c = groupStr.charAt(i);
            // dot is the group separator and it must be escaped if used inside
            // group names
            if (c == '.' && groupStr.charAt(i - 1) != '\\') {
                names.add(currentName.replace("\\.", "."));
                currentName = "";
            } else {
                currentName += c;
Sonia Zorba's avatar
Sonia Zorba committed
            }
        }
        names.add(currentName.replace("\\.", "."));
Sonia Zorba's avatar
Sonia Zorba committed
        return names;
    }

Sonia Zorba's avatar
Sonia Zorba committed
    public String getCompleteName(List<String> names) {
        return String.join(".", names.stream()
                .map(n -> n.replace(".", "\\."))
                .collect(Collectors.toList()));
    }

    private GroupEntity getRoot() {
        return groupsDAO.findGroupById("ROOT")
                .orElseThrow(() -> new IllegalStateException("Missing root group"));
Sonia Zorba's avatar
Sonia Zorba committed
    }
}