All Downloads are FREE. Search and download functionalities are using the official Maven repository.

graphql.DirectivesUtil Maven / Gradle / Ivy

package graphql;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import graphql.language.Directive;
import graphql.language.DirectiveDefinition;
import graphql.schema.GraphQLArgument;
import graphql.schema.GraphQLDirective;
import graphql.util.FpKit;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import static graphql.Assert.assertNotNull;
import static graphql.collect.ImmutableKit.emptyList;
import static java.util.stream.Collectors.toList;

@Internal
public class DirectivesUtil {


    public static Map nonRepeatableDirectivesByName(List directives) {
        // filter the repeatable directives
        List singletonDirectives = directives.stream()
                .filter(d -> !d.isRepeatable()).collect(Collectors.toList());

        return FpKit.getByName(singletonDirectives, GraphQLDirective::getName);
    }

    public static Map> allDirectivesByName(List directives) {

        return ImmutableMap.copyOf(FpKit.groupingBy(directives, GraphQLDirective::getName));
    }

    public static GraphQLDirective nonRepeatedDirectiveByNameWithAssert(Map> directives, String directiveName) {
        List directiveList = directives.get(directiveName);
        if (directiveList == null || directiveList.isEmpty()) {
            return null;
        }
        Assert.assertTrue(isAllNonRepeatable(directiveList), () -> String.format("'%s' is a repeatable directive and you have used a non repeatable access method", directiveName));
        return directiveList.get(0);
    }

    public static Optional directiveWithArg(List directives, String directiveName, String argumentName) {
        GraphQLDirective directive = nonRepeatableDirectivesByName(directives).get(directiveName);
        GraphQLArgument argument = null;
        if (directive != null) {
            argument = directive.getArgument(argumentName);
        }
        return Optional.ofNullable(argument);
    }


    public static boolean isAllNonRepeatable(List directives) {
        if (directives == null || directives.isEmpty()) {
            return false;
        }
        for (GraphQLDirective graphQLDirective : directives) {
            if (graphQLDirective.isRepeatable()) {
                return false;
            }
        }
        return true;
    }

    public static List enforceAdd(List targetList, GraphQLDirective newDirective) {
        assertNotNull(targetList, () -> "directive list can't be null");
        assertNotNull(newDirective, () -> "directive can't be null");

        // check whether the newDirective is repeatable in advance, to avoid needless operations
        if (newDirective.isNonRepeatable()) {
            Map> map = allDirectivesByName(targetList);
            assertNonRepeatable(newDirective, map);
        }
        targetList.add(newDirective);
        return targetList;
    }

    public static List enforceAddAll(List targetList, List newDirectives) {
        assertNotNull(targetList, () -> "directive list can't be null");
        assertNotNull(newDirectives, () -> "directive list can't be null");
        Map> map = allDirectivesByName(targetList);
        for (GraphQLDirective newDirective : newDirectives) {
            assertNonRepeatable(newDirective, map);
            targetList.add(newDirective);
        }
        return targetList;
    }

    private static void assertNonRepeatable(GraphQLDirective directive, Map> mapOfDirectives) {
        if (directive.isNonRepeatable()) {
            List currentDirectives = mapOfDirectives.getOrDefault(directive.getName(), emptyList());
            int currentSize = currentDirectives.size();
            if (currentSize > 0) {
                Assert.assertShouldNeverHappen("%s is a non repeatable directive but there is already one present in this list", directive.getName());
            }
        }
    }

    public static GraphQLDirective getFirstDirective(String name, Map> allDirectivesByName) {
        List directives = allDirectivesByName.getOrDefault(name, emptyList());
        if (directives.isEmpty()) {
            return null;
        }
        return directives.get(0);
    }

    /**
     * A holder class that breaks a list of directives into maps to be more easily accessible in using classes
     */
    public static class DirectivesHolder {

        private final ImmutableMap> allDirectivesByName;
        private final ImmutableMap nonRepeatableDirectivesByName;
        private final List allDirectives;

        public DirectivesHolder(Collection allDirectives) {
            this.allDirectives = ImmutableList.copyOf(allDirectives);
            this.allDirectivesByName = ImmutableMap.copyOf(FpKit.groupingBy(allDirectives, GraphQLDirective::getName));
            // filter out the repeatable directives
            List nonRepeatableDirectives = allDirectives.stream()
                    .filter(d -> !d.isRepeatable()).collect(Collectors.toList());
            this.nonRepeatableDirectivesByName = ImmutableMap.copyOf(FpKit.getByName(nonRepeatableDirectives, GraphQLDirective::getName));
        }

        public ImmutableMap> getAllDirectivesByName() {
            return allDirectivesByName;
        }

        public ImmutableMap getDirectivesByName() {
            return nonRepeatableDirectivesByName;
        }

        public List getDirectives() {
            return allDirectives;
        }

        public GraphQLDirective getDirective(String directiveName) {
            List directiveList = allDirectivesByName.get(directiveName);
            if (directiveList == null || directiveList.isEmpty()) {
                return null;
            }
            Assert.assertTrue(isAllNonRepeatable(directiveList), () -> String.format("'%s' is a repeatable directive and you have used a non repeatable access method", directiveName));
            return directiveList.get(0);

        }

        public List getDirectives(String directiveName) {
            return allDirectivesByName.getOrDefault(directiveName, emptyList());
        }
    }

    public static List nonRepeatableDirectivesOnly(Map directiveDefinitionMap, List directives) {
        return directives.stream().filter(directive -> {
            String directiveName = directive.getName();
            DirectiveDefinition directiveDefinition = directiveDefinitionMap.get(directiveName);
            return directiveDefinition == null || !directiveDefinition.isRepeatable();
        }).collect(toList());
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy