Search in sources :

Example 1 with CONTINUE

use of graphql.util.TraversalControl.CONTINUE in project graphql-java by graphql-java.

the class SchemaTransformer method traverseAndTransform.

private boolean traverseAndTransform(DummyRoot dummyRoot, Map<String, GraphQLNamedType> changedTypes, Map<String, GraphQLTypeReference> typeReferences, GraphQLTypeVisitor visitor, GraphQLCodeRegistry.Builder codeRegistry) {
    List<NodeZipper<GraphQLSchemaElement>> zippers = new LinkedList<>();
    Map<GraphQLSchemaElement, NodeZipper<GraphQLSchemaElement>> zipperByNodeAfterTraversing = new LinkedHashMap<>();
    Map<GraphQLSchemaElement, NodeZipper<GraphQLSchemaElement>> zipperByOriginalNode = new LinkedHashMap<>();
    Map<NodeZipper<GraphQLSchemaElement>, List<List<Breadcrumb<GraphQLSchemaElement>>>> breadcrumbsByZipper = new LinkedHashMap<>();
    Map<GraphQLSchemaElement, List<GraphQLSchemaElement>> reverseDependencies = new LinkedHashMap<>();
    Map<String, List<GraphQLSchemaElement>> typeRefReverseDependencies = new LinkedHashMap<>();
    TraverserVisitor<GraphQLSchemaElement> nodeTraverserVisitor = new TraverserVisitor<GraphQLSchemaElement>() {

        @Override
        public TraversalControl enter(TraverserContext<GraphQLSchemaElement> context) {
            GraphQLSchemaElement currentSchemaElement = context.thisNode();
            if (currentSchemaElement == dummyRoot) {
                return TraversalControl.CONTINUE;
            }
            if (currentSchemaElement instanceof GraphQLTypeReference) {
                GraphQLTypeReference typeRef = (GraphQLTypeReference) currentSchemaElement;
                typeReferences.put(typeRef.getName(), typeRef);
            }
            NodeZipper<GraphQLSchemaElement> nodeZipper = new NodeZipper<>(currentSchemaElement, context.getBreadcrumbs(), SCHEMA_ELEMENT_ADAPTER);
            context.setVar(NodeZipper.class, nodeZipper);
            context.setVar(NodeAdapter.class, SCHEMA_ELEMENT_ADAPTER);
            int zippersBefore = zippers.size();
            TraversalControl result = currentSchemaElement.accept(context, visitor);
            // detection if the node was changed
            if (zippersBefore + 1 == zippers.size()) {
                nodeZipper = zippers.get(zippers.size() - 1);
                if (context.originalThisNode() instanceof GraphQLNamedType && context.isChanged()) {
                    GraphQLNamedType originalNamedType = (GraphQLNamedType) context.originalThisNode();
                    GraphQLNamedType changedNamedType = (GraphQLNamedType) context.thisNode();
                    if (!originalNamedType.getName().equals(changedNamedType.getName())) {
                        changedTypes.put(originalNamedType.getName(), changedNamedType);
                    }
                }
            }
            zipperByOriginalNode.put(context.originalThisNode(), nodeZipper);
            if (context.isDeleted()) {
                zipperByNodeAfterTraversing.put(context.originalThisNode(), nodeZipper);
            } else {
                zipperByNodeAfterTraversing.put(context.thisNode(), nodeZipper);
            }
            breadcrumbsByZipper.put(nodeZipper, new ArrayList<>());
            breadcrumbsByZipper.get(nodeZipper).add(context.getBreadcrumbs());
            if (nodeZipper.getModificationType() != NodeZipper.ModificationType.DELETE) {
                reverseDependencies.computeIfAbsent(context.thisNode(), ign -> new ArrayList<>()).add(context.getParentNode());
                if (context.originalThisNode() instanceof GraphQLTypeReference) {
                    String typeName = ((GraphQLTypeReference) context.originalThisNode()).getName();
                    typeRefReverseDependencies.computeIfAbsent(typeName, ign -> new ArrayList<>()).add(context.getParentNode());
                }
            }
            return result;
        }

        @Override
        public TraversalControl leave(TraverserContext<GraphQLSchemaElement> context) {
            return TraversalControl.CONTINUE;
        }

        @Override
        public TraversalControl backRef(TraverserContext<GraphQLSchemaElement> context) {
            NodeZipper<GraphQLSchemaElement> zipper = zipperByOriginalNode.get(context.thisNode());
            breadcrumbsByZipper.get(zipper).add(context.getBreadcrumbs());
            if (zipper.getModificationType() == DELETE) {
                return CONTINUE;
            }
            visitor.visitBackRef(context);
            List<GraphQLSchemaElement> reverseDependenciesForCurNode = reverseDependencies.get(zipper.getCurNode());
            assertNotNull(reverseDependenciesForCurNode);
            reverseDependenciesForCurNode.add(context.getParentNode());
            return TraversalControl.CONTINUE;
        }
    };
    Traverser<GraphQLSchemaElement> traverser = Traverser.depthFirstWithNamedChildren(SCHEMA_ELEMENT_ADAPTER::getNamedChildren, zippers, null);
    if (codeRegistry != null) {
        traverser.rootVar(GraphQLCodeRegistry.Builder.class, codeRegistry);
    }
    traverser.traverse(dummyRoot, nodeTraverserVisitor);
    List<List<GraphQLSchemaElement>> stronglyConnectedTopologicallySorted = getStronglyConnectedComponentsTopologicallySorted(reverseDependencies, typeRefReverseDependencies);
    return zipUpToDummyRoot(zippers, stronglyConnectedTopologicallySorted, breadcrumbsByZipper, zipperByNodeAfterTraversing);
}
Also used : TraversalControl(graphql.util.TraversalControl) Traverser(graphql.util.Traverser) SCHEMA_ELEMENT_ADAPTER(graphql.schema.GraphQLSchemaElementAdapter.SCHEMA_ELEMENT_ADAPTER) HashMap(java.util.HashMap) Multimap(com.google.common.collect.Multimap) NodeLocation(graphql.util.NodeLocation) StronglyConnectedComponentsTopologicallySorted.getStronglyConnectedComponentsTopologicallySorted(graphql.schema.impl.StronglyConnectedComponentsTopologicallySorted.getStronglyConnectedComponentsTopologicallySorted) TraverserContext(graphql.util.TraverserContext) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Breadcrumb(graphql.util.Breadcrumb) Assert.assertShouldNeverHappen(graphql.Assert.assertShouldNeverHappen) NodeAdapter(graphql.util.NodeAdapter) Map(java.util.Map) SchemaElementChildrenContainer.newSchemaElementChildrenContainer(graphql.schema.SchemaElementChildrenContainer.newSchemaElementChildrenContainer) LinkedList(java.util.LinkedList) LinkedHashMultimap(com.google.common.collect.LinkedHashMultimap) LinkedHashSet(java.util.LinkedHashSet) REPLACE(graphql.util.NodeZipper.ModificationType.REPLACE) TraverserVisitor(graphql.util.TraverserVisitor) Iterator(java.util.Iterator) CONTINUE(graphql.util.TraversalControl.CONTINUE) Collection(java.util.Collection) Set(java.util.Set) DELETE(graphql.util.NodeZipper.ModificationType.DELETE) String.format(java.lang.String.format) Consumer(java.util.function.Consumer) NodeZipper(graphql.util.NodeZipper) List(java.util.List) PublicApi(graphql.PublicApi) Assert.assertNotNull(graphql.Assert.assertNotNull) Assert.assertNotEmpty(graphql.Assert.assertNotEmpty) Collections(java.util.Collections) ArrayList(java.util.ArrayList) TraverserContext(graphql.util.TraverserContext) LinkedHashMap(java.util.LinkedHashMap) TraverserVisitor(graphql.util.TraverserVisitor) TraversalControl(graphql.util.TraversalControl) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) SCHEMA_ELEMENT_ADAPTER(graphql.schema.GraphQLSchemaElementAdapter.SCHEMA_ELEMENT_ADAPTER) Breadcrumb(graphql.util.Breadcrumb) LinkedList(java.util.LinkedList) NodeZipper(graphql.util.NodeZipper)

Example 2 with CONTINUE

use of graphql.util.TraversalControl.CONTINUE in project graphql-java by graphql-java.

the class Anonymizer method rewriteQuery.

private static String rewriteQuery(String query, GraphQLSchema schema, Map<GraphQLNamedSchemaElement, String> newNames, Map<String, Object> variables) {
    AtomicInteger fragmentCounter = new AtomicInteger(1);
    AtomicInteger variableCounter = new AtomicInteger(1);
    Map<Node, String> astNodeToNewName = new LinkedHashMap<>();
    Map<String, String> variableNames = new LinkedHashMap<>();
    Map<Field, GraphQLFieldDefinition> fieldToFieldDefinition = new LinkedHashMap<>();
    Document document = new Parser().parseDocument(query);
    assertUniqueOperation(document);
    QueryTraverser queryTraverser = QueryTraverser.newQueryTraverser().document(document).schema(schema).variables(variables).build();
    queryTraverser.visitDepthFirst(new QueryVisitor() {

        @Override
        public void visitField(QueryVisitorFieldEnvironment env) {
            if (env.isTypeNameIntrospectionField()) {
                return;
            }
            fieldToFieldDefinition.put(env.getField(), env.getFieldDefinition());
            String newName = assertNotNull(newNames.get(env.getFieldDefinition()));
            Field field = env.getField();
            astNodeToNewName.put(field, newName);
            List<Directive> directives = field.getDirectives();
            for (Directive directive : directives) {
                // this is a directive definition
                GraphQLDirective directiveDefinition = assertNotNull(schema.getDirective(directive.getName()), () -> format("%s directive definition not found ", directive.getName()));
                String directiveName = directiveDefinition.getName();
                String newDirectiveName = assertNotNull(newNames.get(directiveDefinition), () -> format("No new name found for directive %s", directiveName));
                astNodeToNewName.put(directive, newDirectiveName);
                for (Argument argument : directive.getArguments()) {
                    GraphQLArgument argumentDefinition = directiveDefinition.getArgument(argument.getName());
                    String newArgumentName = assertNotNull(newNames.get(argumentDefinition), () -> format("%s no new name found for directive argument %s %s", directiveName, argument.getName()));
                    astNodeToNewName.put(argument, newArgumentName);
                    visitDirectiveArgumentValues(directive, argument.getValue());
                }
            }
        }

        private void visitDirectiveArgumentValues(Directive directive, Value value) {
            if (value instanceof VariableReference) {
                String name = ((VariableReference) value).getName();
                if (!variableNames.containsKey(name)) {
                    String newName = "var" + variableCounter.getAndIncrement();
                    variableNames.put(name, newName);
                }
            }
        }

        @Override
        public void visitInlineFragment(QueryVisitorInlineFragmentEnvironment queryVisitorInlineFragmentEnvironment) {
        }

        @Override
        public TraversalControl visitArgumentValue(QueryVisitorFieldArgumentValueEnvironment environment) {
            QueryVisitorFieldArgumentInputValue argumentInputValue = environment.getArgumentInputValue();
            if (argumentInputValue.getValue() instanceof VariableReference) {
                String name = ((VariableReference) argumentInputValue.getValue()).getName();
                if (!variableNames.containsKey(name)) {
                    String newName = "var" + variableCounter.getAndIncrement();
                    variableNames.put(name, newName);
                }
            }
            return CONTINUE;
        }

        @Override
        public void visitFragmentSpread(QueryVisitorFragmentSpreadEnvironment queryVisitorFragmentSpreadEnvironment) {
            FragmentDefinition fragmentDefinition = queryVisitorFragmentSpreadEnvironment.getFragmentDefinition();
            String newName;
            if (!astNodeToNewName.containsKey(fragmentDefinition)) {
                newName = "Fragment" + fragmentCounter.getAndIncrement();
                astNodeToNewName.put(fragmentDefinition, newName);
            } else {
                newName = astNodeToNewName.get(fragmentDefinition);
            }
            astNodeToNewName.put(queryVisitorFragmentSpreadEnvironment.getFragmentSpread(), newName);
        }

        @Override
        public TraversalControl visitArgument(QueryVisitorFieldArgumentEnvironment environment) {
            String newName = assertNotNull(newNames.get(environment.getGraphQLArgument()));
            astNodeToNewName.put(environment.getArgument(), newName);
            return CONTINUE;
        }
    });
    AtomicInteger stringValueCounter = new AtomicInteger(1);
    AtomicInteger intValueCounter = new AtomicInteger(1);
    AstTransformer astTransformer = new AstTransformer();
    AtomicInteger aliasCounter = new AtomicInteger(1);
    AtomicInteger defaultStringValueCounter = new AtomicInteger(1);
    AtomicInteger defaultIntValueCounter = new AtomicInteger(1);
    Document newDocument = (Document) astTransformer.transform(document, new NodeVisitorStub() {

        @Override
        public TraversalControl visitDirective(Directive directive, TraverserContext<Node> context) {
            String newName = assertNotNull(astNodeToNewName.get(directive));
            GraphQLDirective directiveDefinition = schema.getDirective(directive.getName());
            context.setVar(GraphQLDirective.class, directiveDefinition);
            return changeNode(context, directive.transform(builder -> builder.name(newName)));
        }

        @Override
        public TraversalControl visitOperationDefinition(OperationDefinition node, TraverserContext<Node> context) {
            if (node.getName() != null) {
                return changeNode(context, node.transform(builder -> builder.name("operation")));
            } else {
                return CONTINUE;
            }
        }

        @Override
        public TraversalControl visitField(Field field, TraverserContext<Node> context) {
            String newAlias = null;
            if (field.getAlias() != null) {
                newAlias = "alias" + aliasCounter.getAndIncrement();
            }
            String newName;
            if (field.getName().equals(Introspection.TypeNameMetaFieldDef.getName())) {
                newName = Introspection.TypeNameMetaFieldDef.getName();
            } else {
                newName = assertNotNull(astNodeToNewName.get(field));
                context.setVar(GraphQLFieldDefinition.class, assertNotNull(fieldToFieldDefinition.get(field)));
            }
            String finalNewAlias = newAlias;
            return changeNode(context, field.transform(builder -> builder.name(newName).alias(finalNewAlias)));
        }

        @Override
        public TraversalControl visitVariableDefinition(VariableDefinition node, TraverserContext<Node> context) {
            String newName = assertNotNull(variableNames.get(node.getName()));
            VariableDefinition newNode = node.transform(builder -> {
                builder.name(newName).comments(Collections.emptyList());
                // convert variable language type to renamed language type
                TypeName typeName = TypeUtil.unwrapAll(node.getType());
                GraphQLNamedType originalType = schema.getTypeAs(typeName.getName());
                // has the type name changed? (standard scalars such as String don't change)
                if (newNames.containsKey(originalType)) {
                    String newTypeName = newNames.get(originalType);
                    builder.type(replaceTypeName(node.getType(), newTypeName));
                }
                if (node.getDefaultValue() != null) {
                    Value<?> defaultValueLiteral = node.getDefaultValue();
                    GraphQLType graphQLType = fromTypeToGraphQLType(node.getType(), schema);
                    builder.defaultValue(replaceValue(defaultValueLiteral, (GraphQLInputType) graphQLType, newNames, defaultStringValueCounter, defaultIntValueCounter));
                }
            });
            return changeNode(context, newNode);
        }

        @Override
        public TraversalControl visitVariableReference(VariableReference node, TraverserContext<Node> context) {
            String newName = assertNotNull(variableNames.get(node.getName()), () -> format("No new variable name found for %s", node.getName()));
            return changeNode(context, node.transform(builder -> builder.name(newName)));
        }

        @Override
        public TraversalControl visitFragmentDefinition(FragmentDefinition node, TraverserContext<Node> context) {
            String newName = assertNotNull(astNodeToNewName.get(node));
            GraphQLType currentCondition = assertNotNull(schema.getType(node.getTypeCondition().getName()));
            String newCondition = newNames.get(currentCondition);
            return changeNode(context, node.transform(builder -> builder.name(newName).typeCondition(new TypeName(newCondition))));
        }

        @Override
        public TraversalControl visitInlineFragment(InlineFragment node, TraverserContext<Node> context) {
            GraphQLType currentCondition = assertNotNull(schema.getType(node.getTypeCondition().getName()));
            String newCondition = newNames.get(currentCondition);
            return changeNode(context, node.transform(builder -> builder.typeCondition(new TypeName(newCondition))));
        }

        @Override
        public TraversalControl visitFragmentSpread(FragmentSpread node, TraverserContext<Node> context) {
            String newName = assertNotNull(astNodeToNewName.get(node));
            return changeNode(context, node.transform(builder -> builder.name(newName)));
        }

        @Override
        public TraversalControl visitArgument(Argument argument, TraverserContext<Node> context) {
            GraphQLArgument graphQLArgumentDefinition;
            // An argument is either from a applied query directive or from a field
            if (context.getVarFromParents(GraphQLDirective.class) != null) {
                GraphQLDirective directiveDefinition = context.getVarFromParents(GraphQLDirective.class);
                graphQLArgumentDefinition = directiveDefinition.getArgument(argument.getName());
            } else {
                GraphQLFieldDefinition graphQLFieldDefinition = assertNotNull(context.getVarFromParents(GraphQLFieldDefinition.class));
                graphQLArgumentDefinition = graphQLFieldDefinition.getArgument(argument.getName());
            }
            GraphQLInputType argumentType = graphQLArgumentDefinition.getType();
            String newName = assertNotNull(astNodeToNewName.get(argument));
            Value newValue = replaceValue(argument.getValue(), argumentType, newNames, defaultStringValueCounter, defaultIntValueCounter);
            return changeNode(context, argument.transform(builder -> builder.name(newName).value(newValue)));
        }
    });
    return AstPrinter.printAstCompact(newDocument);
}
Also used : OperationDefinition(graphql.language.OperationDefinition) Value(graphql.language.Value) QueryVisitorInlineFragmentEnvironment(graphql.analysis.QueryVisitorInlineFragmentEnvironment) ValuesResolver(graphql.execution.ValuesResolver) GraphQLInputObjectType(graphql.schema.GraphQLInputObjectType) QueryTraverser(graphql.analysis.QueryTraverser) GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) FragmentSpread(graphql.language.FragmentSpread) GraphQLInterfaceType(graphql.schema.GraphQLInterfaceType) GraphQLInputObjectField(graphql.schema.GraphQLInputObjectField) GraphQLUnionType(graphql.schema.GraphQLUnionType) GraphQLEnumValueDefinition(graphql.schema.GraphQLEnumValueDefinition) GraphQLNamedSchemaElement(graphql.schema.GraphQLNamedSchemaElement) GraphQLTypeUtil.unwrapNonNullAs(graphql.schema.GraphQLTypeUtil.unwrapNonNullAs) Directives(graphql.Directives) GraphQLAppliedDirective(graphql.schema.GraphQLAppliedDirective) QueryVisitorFieldEnvironment(graphql.analysis.QueryVisitorFieldEnvironment) Type(graphql.language.Type) DirectiveInfo(graphql.schema.idl.DirectiveInfo) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) QueryVisitorFragmentSpreadEnvironment(graphql.analysis.QueryVisitorFragmentSpreadEnvironment) BigInteger(java.math.BigInteger) TypeName(graphql.language.TypeName) TypeResolver(graphql.schema.TypeResolver) GraphQLObjectType(graphql.schema.GraphQLObjectType) GraphQLDirective(graphql.schema.GraphQLDirective) GraphQLNamedOutputType(graphql.schema.GraphQLNamedOutputType) GraphQLNonNull(graphql.schema.GraphQLNonNull) ObjectField(graphql.language.ObjectField) GraphQLInputType(graphql.schema.GraphQLInputType) Set(java.util.Set) GraphQLArgument(graphql.schema.GraphQLArgument) String.format(java.lang.String.format) AstPrinter(graphql.language.AstPrinter) List(java.util.List) QueryVisitor(graphql.analysis.QueryVisitor) ArrayValue(graphql.language.ArrayValue) Optional(java.util.Optional) FragmentDefinition(graphql.language.FragmentDefinition) NonNullType(graphql.language.NonNullType) GraphQLEnumType(graphql.schema.GraphQLEnumType) ListType(graphql.language.ListType) AstTransformer(graphql.language.AstTransformer) ObjectValue(graphql.language.ObjectValue) GraphQLSchemaElement(graphql.schema.GraphQLSchemaElement) GraphQLCodeRegistry(graphql.schema.GraphQLCodeRegistry) GraphQLNamedType(graphql.schema.GraphQLNamedType) Node(graphql.language.Node) SchemaTransformer(graphql.schema.SchemaTransformer) TreeTransformerUtil.changeNode(graphql.util.TreeTransformerUtil.changeNode) GraphQLScalarType(graphql.schema.GraphQLScalarType) QueryVisitorFieldArgumentEnvironment(graphql.analysis.QueryVisitorFieldArgumentEnvironment) QueryVisitorFieldArgumentInputValue(graphql.analysis.QueryVisitorFieldArgumentInputValue) EnumValue(graphql.language.EnumValue) HashMap(java.util.HashMap) GraphQLType(graphql.schema.GraphQLType) ArrayList(java.util.ArrayList) Introspection(graphql.introspection.Introspection) LinkedHashMap(java.util.LinkedHashMap) Scalars(graphql.Scalars) Parser(graphql.parser.Parser) Definition(graphql.language.Definition) VariableReference(graphql.language.VariableReference) BiConsumer(java.util.function.BiConsumer) GraphQLSchema(graphql.schema.GraphQLSchema) GraphQLAppliedDirectiveArgument(graphql.schema.GraphQLAppliedDirectiveArgument) QueryVisitorFieldArgumentValueEnvironment(graphql.analysis.QueryVisitorFieldArgumentValueEnvironment) LinkedHashSet(java.util.LinkedHashSet) NodeVisitorStub(graphql.language.NodeVisitorStub) SchemaGenerator.createdMockedSchema(graphql.schema.idl.SchemaGenerator.createdMockedSchema) ScalarInfo(graphql.schema.idl.ScalarInfo) CONTINUE(graphql.util.TraversalControl.CONTINUE) GraphQLArgument.newArgument(graphql.schema.GraphQLArgument.newArgument) Field(graphql.language.Field) GraphQLImplementingType(graphql.schema.GraphQLImplementingType) GraphQLTypeVisitorStub(graphql.schema.GraphQLTypeVisitorStub) SchemaUtil(graphql.schema.impl.SchemaUtil) AssertException(graphql.AssertException) Directive(graphql.language.Directive) Consumer(java.util.function.Consumer) Argument(graphql.language.Argument) Document(graphql.language.Document) TypeUtil(graphql.schema.idl.TypeUtil) VariableDefinition(graphql.language.VariableDefinition) GraphQLList(graphql.schema.GraphQLList) StringValue(graphql.language.StringValue) GraphQLTypeReference(graphql.schema.GraphQLTypeReference) GraphQLTypeUtil.unwrapNonNull(graphql.schema.GraphQLTypeUtil.unwrapNonNull) PublicApi(graphql.PublicApi) IntValue(graphql.language.IntValue) Assert.assertNotNull(graphql.Assert.assertNotNull) GraphQLTypeVisitor(graphql.schema.GraphQLTypeVisitor) GraphQLTypeUtil.unwrapOneAs(graphql.schema.GraphQLTypeUtil.unwrapOneAs) InlineFragment(graphql.language.InlineFragment) Collections(java.util.Collections) QueryVisitor(graphql.analysis.QueryVisitor) TypeName(graphql.language.TypeName) GraphQLArgument(graphql.schema.GraphQLArgument) GraphQLAppliedDirectiveArgument(graphql.schema.GraphQLAppliedDirectiveArgument) GraphQLArgument.newArgument(graphql.schema.GraphQLArgument.newArgument) Argument(graphql.language.Argument) VariableDefinition(graphql.language.VariableDefinition) QueryVisitorFieldEnvironment(graphql.analysis.QueryVisitorFieldEnvironment) Node(graphql.language.Node) TreeTransformerUtil.changeNode(graphql.util.TreeTransformerUtil.changeNode) GraphQLType(graphql.schema.GraphQLType) GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) Document(graphql.language.Document) LinkedHashMap(java.util.LinkedHashMap) GraphQLInputType(graphql.schema.GraphQLInputType) GraphQLInputObjectField(graphql.schema.GraphQLInputObjectField) ObjectField(graphql.language.ObjectField) Field(graphql.language.Field) List(java.util.List) ArrayList(java.util.ArrayList) GraphQLList(graphql.schema.GraphQLList) GraphQLNamedType(graphql.schema.GraphQLNamedType) OperationDefinition(graphql.language.OperationDefinition) QueryVisitorFieldArgumentEnvironment(graphql.analysis.QueryVisitorFieldArgumentEnvironment) VariableReference(graphql.language.VariableReference) FragmentDefinition(graphql.language.FragmentDefinition) QueryVisitorFragmentSpreadEnvironment(graphql.analysis.QueryVisitorFragmentSpreadEnvironment) GraphQLArgument(graphql.schema.GraphQLArgument) GraphQLDirective(graphql.schema.GraphQLDirective) QueryVisitorFieldArgumentValueEnvironment(graphql.analysis.QueryVisitorFieldArgumentValueEnvironment) Parser(graphql.parser.Parser) FragmentSpread(graphql.language.FragmentSpread) QueryVisitorFieldArgumentInputValue(graphql.analysis.QueryVisitorFieldArgumentInputValue) AstTransformer(graphql.language.AstTransformer) QueryTraverser(graphql.analysis.QueryTraverser) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) QueryVisitorInlineFragmentEnvironment(graphql.analysis.QueryVisitorInlineFragmentEnvironment) Value(graphql.language.Value) ArrayValue(graphql.language.ArrayValue) ObjectValue(graphql.language.ObjectValue) QueryVisitorFieldArgumentInputValue(graphql.analysis.QueryVisitorFieldArgumentInputValue) EnumValue(graphql.language.EnumValue) StringValue(graphql.language.StringValue) IntValue(graphql.language.IntValue) NodeVisitorStub(graphql.language.NodeVisitorStub) GraphQLAppliedDirective(graphql.schema.GraphQLAppliedDirective) GraphQLDirective(graphql.schema.GraphQLDirective) Directive(graphql.language.Directive) InlineFragment(graphql.language.InlineFragment)

Example 3 with CONTINUE

use of graphql.util.TraversalControl.CONTINUE in project graphql-java by graphql-java.

the class SchemaTransformExamples method trasnformSchema.

void trasnformSchema() {
    GraphQLTypeVisitorStub visitor = new GraphQLTypeVisitorStub() {

        @Override
        public TraversalControl visitGraphQLObjectType(GraphQLObjectType objectType, TraverserContext<GraphQLSchemaElement> context) {
            GraphQLCodeRegistry.Builder codeRegistry = context.getVarFromParents(GraphQLCodeRegistry.Builder.class);
            // we need to change __XXX introspection types to have directive extensions
            if (someConditionalLogic(objectType)) {
                GraphQLObjectType newObjectType = buildChangedObjectType(objectType, codeRegistry);
                return changeNode(context, newObjectType);
            }
            return CONTINUE;
        }

        private boolean someConditionalLogic(GraphQLObjectType objectType) {
            // up to you to decide what causes a change, perhaps a directive is on the element
            return objectType.hasDirective("specialDirective");
        }

        private GraphQLObjectType buildChangedObjectType(GraphQLObjectType objectType, GraphQLCodeRegistry.Builder codeRegistry) {
            GraphQLFieldDefinition newField = GraphQLFieldDefinition.newFieldDefinition().name("newField").type(Scalars.GraphQLString).build();
            GraphQLObjectType newObjectType = objectType.transform(builder -> builder.field(newField));
            DataFetcher newDataFetcher = dataFetchingEnvironment -> {
                return "someValueForTheNewField";
            };
            FieldCoordinates coordinates = FieldCoordinates.coordinates(objectType.getName(), newField.getName());
            codeRegistry.dataFetcher(coordinates, newDataFetcher);
            return newObjectType;
        }
    };
    GraphQLSchema newSchema = SchemaTransformer.transformSchema(schema, visitor);
}
Also used : GraphQLObjectType(graphql.schema.GraphQLObjectType) FieldCoordinates(graphql.schema.FieldCoordinates) GraphQLSchemaElement(graphql.schema.GraphQLSchemaElement) GraphQLCodeRegistry(graphql.schema.GraphQLCodeRegistry) SchemaTransformer(graphql.schema.SchemaTransformer) TraversalControl(graphql.util.TraversalControl) CONTINUE(graphql.util.TraversalControl.CONTINUE) GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) GraphQLTypeVisitorStub(graphql.schema.GraphQLTypeVisitorStub) TraverserContext(graphql.util.TraverserContext) Scalars(graphql.Scalars) DataFetcher(graphql.schema.DataFetcher) GraphQLSchema(graphql.schema.GraphQLSchema) GraphQLObjectType(graphql.schema.GraphQLObjectType) GraphQLCodeRegistry(graphql.schema.GraphQLCodeRegistry) GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) DataFetcher(graphql.schema.DataFetcher) FieldCoordinates(graphql.schema.FieldCoordinates) GraphQLTypeVisitorStub(graphql.schema.GraphQLTypeVisitorStub) GraphQLSchema(graphql.schema.GraphQLSchema) TraverserContext(graphql.util.TraverserContext)

Example 4 with CONTINUE

use of graphql.util.TraversalControl.CONTINUE in project graphql-java by graphql-java.

the class Anonymizer method recordNewNamesForSchema.

public static Map<GraphQLNamedSchemaElement, String> recordNewNamesForSchema(GraphQLSchema schema) {
    AtomicInteger objectCounter = new AtomicInteger(1);
    AtomicInteger inputObjectCounter = new AtomicInteger(1);
    AtomicInteger inputObjectFieldCounter = new AtomicInteger(1);
    AtomicInteger fieldCounter = new AtomicInteger(1);
    AtomicInteger scalarCounter = new AtomicInteger(1);
    AtomicInteger directiveCounter = new AtomicInteger(1);
    AtomicInteger argumentCounter = new AtomicInteger(1);
    AtomicInteger interfaceCounter = new AtomicInteger(1);
    AtomicInteger unionCounter = new AtomicInteger(1);
    AtomicInteger enumCounter = new AtomicInteger(1);
    AtomicInteger enumValueCounter = new AtomicInteger(1);
    Map<GraphQLNamedSchemaElement, String> newNameMap = new LinkedHashMap<>();
    Map<String, String> directivesOriginalToNewNameMap = new HashMap<>();
    // DirectiveName.argumentName -> newArgumentName
    Map<String, String> seenArgumentsOnDirectivesMap = new HashMap<>();
    Map<String, List<GraphQLImplementingType>> interfaceToImplementations = new SchemaUtil().groupImplementationsForInterfacesAndObjects(schema);
    Consumer<GraphQLNamedSchemaElement> recordDirectiveName = (graphQLDirective) -> {
        String directiveName = graphQLDirective.getName();
        if (directivesOriginalToNewNameMap.containsKey(directiveName)) {
            newNameMap.put(graphQLDirective, directivesOriginalToNewNameMap.get(directiveName));
            return;
        }
        String newName = "Directive" + directiveCounter.getAndIncrement();
        newNameMap.put(graphQLDirective, newName);
        directivesOriginalToNewNameMap.put(directiveName, newName);
    };
    BiConsumer<GraphQLNamedSchemaElement, String> recordDirectiveArgumentName = (graphQLArgument, directiveArgumentKey) -> {
        if (seenArgumentsOnDirectivesMap.containsKey(directiveArgumentKey)) {
            newNameMap.put(graphQLArgument, seenArgumentsOnDirectivesMap.get(directiveArgumentKey));
            return;
        }
        String newName = "argument" + argumentCounter.getAndIncrement();
        newNameMap.put(graphQLArgument, newName);
        seenArgumentsOnDirectivesMap.put(directiveArgumentKey, newName);
    };
    GraphQLTypeVisitor visitor = new GraphQLTypeVisitorStub() {

        @Override
        public TraversalControl visitGraphQLArgument(GraphQLArgument graphQLArgument, TraverserContext<GraphQLSchemaElement> context) {
            String curName = graphQLArgument.getName();
            GraphQLSchemaElement parentNode = context.getParentNode();
            if (parentNode instanceof GraphQLDirective) {
                // if we already went over the argument for this directive name, no need to add new names
                String directiveArgumentKey = ((GraphQLDirective) parentNode).getName() + graphQLArgument.getName();
                recordDirectiveArgumentName.accept(graphQLArgument, directiveArgumentKey);
                return CONTINUE;
            }
            if (!(parentNode instanceof GraphQLFieldDefinition)) {
                String newName = "argument" + argumentCounter.getAndIncrement();
                newNameMap.put(graphQLArgument, newName);
                return CONTINUE;
            }
            GraphQLFieldDefinition fieldDefinition = (GraphQLFieldDefinition) parentNode;
            String fieldName = fieldDefinition.getName();
            GraphQLImplementingType implementingType = (GraphQLImplementingType) context.getParentContext().getParentNode();
            Set<GraphQLFieldDefinition> matchingInterfaceFieldDefinitions = getSameFields(fieldName, implementingType.getName(), interfaceToImplementations, schema);
            String newName;
            if (matchingInterfaceFieldDefinitions.size() == 0) {
                newName = "argument" + argumentCounter.getAndIncrement();
            } else {
                List<GraphQLArgument> matchingArgumentDefinitions = getMatchingArgumentDefinitions(curName, matchingInterfaceFieldDefinitions);
                if (matchingArgumentDefinitions.size() == 0) {
                    newName = "argument" + argumentCounter.getAndIncrement();
                } else {
                    if (newNameMap.containsKey(matchingArgumentDefinitions.get(0))) {
                        newName = newNameMap.get(matchingArgumentDefinitions.get(0));
                    } else {
                        newName = "argument" + argumentCounter.getAndIncrement();
                        for (GraphQLArgument argument : matchingArgumentDefinitions) {
                            newNameMap.put(argument, newName);
                        }
                    }
                }
            }
            newNameMap.put(graphQLArgument, newName);
            return CONTINUE;
        }

        @Override
        public TraversalControl visitGraphQLAppliedDirectiveArgument(GraphQLAppliedDirectiveArgument graphQLArgument, TraverserContext<GraphQLSchemaElement> context) {
            GraphQLSchemaElement parentNode = context.getParentNode();
            if (parentNode instanceof GraphQLAppliedDirective) {
                // if we already went over the argument for this directive name, no need to add new names
                String directiveArgumentKey = ((GraphQLAppliedDirective) parentNode).getName() + graphQLArgument.getName();
                recordDirectiveArgumentName.accept(graphQLArgument, directiveArgumentKey);
            }
            return CONTINUE;
        }

        @Override
        public TraversalControl visitGraphQLDirective(GraphQLDirective graphQLDirective, TraverserContext<GraphQLSchemaElement> context) {
            if (DirectiveInfo.isGraphqlSpecifiedDirective(graphQLDirective)) {
                return TraversalControl.ABORT;
            }
            recordDirectiveName.accept(graphQLDirective);
            return CONTINUE;
        }

        @Override
        public TraversalControl visitGraphQLAppliedDirective(GraphQLAppliedDirective graphQLAppliedDirective, TraverserContext<GraphQLSchemaElement> context) {
            if (DirectiveInfo.isGraphqlSpecifiedDirective(graphQLAppliedDirective.getName())) {
                return TraversalControl.ABORT;
            }
            recordDirectiveName.accept(graphQLAppliedDirective);
            return CONTINUE;
        }

        @Override
        public TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType graphQLInterfaceType, TraverserContext<GraphQLSchemaElement> context) {
            if (Introspection.isIntrospectionTypes(graphQLInterfaceType)) {
                return TraversalControl.ABORT;
            }
            String newName = "Interface" + interfaceCounter.getAndIncrement();
            newNameMap.put(graphQLInterfaceType, newName);
            return CONTINUE;
        }

        @Override
        public TraversalControl visitGraphQLEnumType(GraphQLEnumType graphQLEnumType, TraverserContext<GraphQLSchemaElement> context) {
            if (Introspection.isIntrospectionTypes(graphQLEnumType)) {
                return TraversalControl.ABORT;
            }
            String newName = "Enum" + enumCounter.getAndIncrement();
            newNameMap.put(graphQLEnumType, newName);
            return CONTINUE;
        }

        @Override
        public TraversalControl visitGraphQLEnumValueDefinition(GraphQLEnumValueDefinition enumValueDefinition, TraverserContext<GraphQLSchemaElement> context) {
            String newName = "EnumValue" + enumValueCounter.getAndIncrement();
            newNameMap.put(enumValueDefinition, newName);
            return CONTINUE;
        }

        @Override
        public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition graphQLFieldDefinition, TraverserContext<GraphQLSchemaElement> context) {
            String fieldName = graphQLFieldDefinition.getName();
            GraphQLImplementingType parentNode = (GraphQLImplementingType) context.getParentNode();
            Set<GraphQLFieldDefinition> sameFields = getSameFields(fieldName, parentNode.getName(), interfaceToImplementations, schema);
            String newName;
            if (sameFields.size() == 0) {
                newName = "field" + fieldCounter.getAndIncrement();
            } else {
                if (newNameMap.containsKey(sameFields.iterator().next())) {
                    newName = newNameMap.get(sameFields.iterator().next());
                } else {
                    newName = "field" + fieldCounter.getAndIncrement();
                    for (GraphQLFieldDefinition fieldDefinition : sameFields) {
                        newNameMap.put(fieldDefinition, newName);
                    }
                }
            }
            newNameMap.put(graphQLFieldDefinition, newName);
            return CONTINUE;
        }

        @Override
        public TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField graphQLInputObjectField, TraverserContext<GraphQLSchemaElement> context) {
            String newName = "inputField" + inputObjectFieldCounter.getAndIncrement();
            newNameMap.put(graphQLInputObjectField, newName);
            return CONTINUE;
        }

        @Override
        public TraversalControl visitGraphQLInputObjectType(GraphQLInputObjectType graphQLInputObjectType, TraverserContext<GraphQLSchemaElement> context) {
            if (Introspection.isIntrospectionTypes(graphQLInputObjectType)) {
                return TraversalControl.ABORT;
            }
            String newName = "InputObject" + inputObjectCounter.getAndIncrement();
            newNameMap.put(graphQLInputObjectType, newName);
            return CONTINUE;
        }

        @Override
        public TraversalControl visitGraphQLObjectType(GraphQLObjectType graphQLObjectType, TraverserContext<GraphQLSchemaElement> context) {
            if (Introspection.isIntrospectionTypes(graphQLObjectType)) {
                return TraversalControl.ABORT;
            }
            String newName = "Object" + objectCounter.getAndIncrement();
            newNameMap.put(graphQLObjectType, newName);
            return CONTINUE;
        }

        @Override
        public TraversalControl visitGraphQLScalarType(GraphQLScalarType graphQLScalarType, TraverserContext<GraphQLSchemaElement> context) {
            if (ScalarInfo.isGraphqlSpecifiedScalar(graphQLScalarType)) {
                return TraversalControl.ABORT;
            }
            String newName = "Scalar" + scalarCounter.getAndIncrement();
            newNameMap.put(graphQLScalarType, newName);
            return CONTINUE;
        }

        @Override
        public TraversalControl visitGraphQLUnionType(GraphQLUnionType graphQLUnionType, TraverserContext<GraphQLSchemaElement> context) {
            if (Introspection.isIntrospectionTypes(graphQLUnionType)) {
                return TraversalControl.ABORT;
            }
            String newName = "Union" + unionCounter.getAndIncrement();
            newNameMap.put(graphQLUnionType, newName);
            return CONTINUE;
        }
    };
    SchemaTransformer.transformSchema(schema, visitor);
    return newNameMap;
}
Also used : OperationDefinition(graphql.language.OperationDefinition) Value(graphql.language.Value) QueryVisitorInlineFragmentEnvironment(graphql.analysis.QueryVisitorInlineFragmentEnvironment) ValuesResolver(graphql.execution.ValuesResolver) GraphQLInputObjectType(graphql.schema.GraphQLInputObjectType) QueryTraverser(graphql.analysis.QueryTraverser) GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) FragmentSpread(graphql.language.FragmentSpread) GraphQLInterfaceType(graphql.schema.GraphQLInterfaceType) GraphQLInputObjectField(graphql.schema.GraphQLInputObjectField) GraphQLUnionType(graphql.schema.GraphQLUnionType) GraphQLEnumValueDefinition(graphql.schema.GraphQLEnumValueDefinition) GraphQLNamedSchemaElement(graphql.schema.GraphQLNamedSchemaElement) GraphQLTypeUtil.unwrapNonNullAs(graphql.schema.GraphQLTypeUtil.unwrapNonNullAs) Directives(graphql.Directives) GraphQLAppliedDirective(graphql.schema.GraphQLAppliedDirective) QueryVisitorFieldEnvironment(graphql.analysis.QueryVisitorFieldEnvironment) Type(graphql.language.Type) DirectiveInfo(graphql.schema.idl.DirectiveInfo) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) QueryVisitorFragmentSpreadEnvironment(graphql.analysis.QueryVisitorFragmentSpreadEnvironment) BigInteger(java.math.BigInteger) TypeName(graphql.language.TypeName) TypeResolver(graphql.schema.TypeResolver) GraphQLObjectType(graphql.schema.GraphQLObjectType) GraphQLDirective(graphql.schema.GraphQLDirective) GraphQLNamedOutputType(graphql.schema.GraphQLNamedOutputType) GraphQLNonNull(graphql.schema.GraphQLNonNull) ObjectField(graphql.language.ObjectField) GraphQLInputType(graphql.schema.GraphQLInputType) Set(java.util.Set) GraphQLArgument(graphql.schema.GraphQLArgument) String.format(java.lang.String.format) AstPrinter(graphql.language.AstPrinter) List(java.util.List) QueryVisitor(graphql.analysis.QueryVisitor) ArrayValue(graphql.language.ArrayValue) Optional(java.util.Optional) FragmentDefinition(graphql.language.FragmentDefinition) NonNullType(graphql.language.NonNullType) GraphQLEnumType(graphql.schema.GraphQLEnumType) ListType(graphql.language.ListType) AstTransformer(graphql.language.AstTransformer) ObjectValue(graphql.language.ObjectValue) GraphQLSchemaElement(graphql.schema.GraphQLSchemaElement) GraphQLCodeRegistry(graphql.schema.GraphQLCodeRegistry) GraphQLNamedType(graphql.schema.GraphQLNamedType) Node(graphql.language.Node) SchemaTransformer(graphql.schema.SchemaTransformer) TreeTransformerUtil.changeNode(graphql.util.TreeTransformerUtil.changeNode) GraphQLScalarType(graphql.schema.GraphQLScalarType) QueryVisitorFieldArgumentEnvironment(graphql.analysis.QueryVisitorFieldArgumentEnvironment) QueryVisitorFieldArgumentInputValue(graphql.analysis.QueryVisitorFieldArgumentInputValue) EnumValue(graphql.language.EnumValue) HashMap(java.util.HashMap) GraphQLType(graphql.schema.GraphQLType) ArrayList(java.util.ArrayList) Introspection(graphql.introspection.Introspection) LinkedHashMap(java.util.LinkedHashMap) Scalars(graphql.Scalars) Parser(graphql.parser.Parser) Definition(graphql.language.Definition) VariableReference(graphql.language.VariableReference) BiConsumer(java.util.function.BiConsumer) GraphQLSchema(graphql.schema.GraphQLSchema) GraphQLAppliedDirectiveArgument(graphql.schema.GraphQLAppliedDirectiveArgument) QueryVisitorFieldArgumentValueEnvironment(graphql.analysis.QueryVisitorFieldArgumentValueEnvironment) LinkedHashSet(java.util.LinkedHashSet) NodeVisitorStub(graphql.language.NodeVisitorStub) SchemaGenerator.createdMockedSchema(graphql.schema.idl.SchemaGenerator.createdMockedSchema) ScalarInfo(graphql.schema.idl.ScalarInfo) CONTINUE(graphql.util.TraversalControl.CONTINUE) GraphQLArgument.newArgument(graphql.schema.GraphQLArgument.newArgument) Field(graphql.language.Field) GraphQLImplementingType(graphql.schema.GraphQLImplementingType) GraphQLTypeVisitorStub(graphql.schema.GraphQLTypeVisitorStub) SchemaUtil(graphql.schema.impl.SchemaUtil) AssertException(graphql.AssertException) Directive(graphql.language.Directive) Consumer(java.util.function.Consumer) Argument(graphql.language.Argument) Document(graphql.language.Document) TypeUtil(graphql.schema.idl.TypeUtil) VariableDefinition(graphql.language.VariableDefinition) GraphQLList(graphql.schema.GraphQLList) StringValue(graphql.language.StringValue) GraphQLTypeReference(graphql.schema.GraphQLTypeReference) GraphQLTypeUtil.unwrapNonNull(graphql.schema.GraphQLTypeUtil.unwrapNonNull) PublicApi(graphql.PublicApi) IntValue(graphql.language.IntValue) Assert.assertNotNull(graphql.Assert.assertNotNull) GraphQLTypeVisitor(graphql.schema.GraphQLTypeVisitor) GraphQLTypeUtil.unwrapOneAs(graphql.schema.GraphQLTypeUtil.unwrapOneAs) InlineFragment(graphql.language.InlineFragment) Collections(java.util.Collections) GraphQLUnionType(graphql.schema.GraphQLUnionType) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) GraphQLInterfaceType(graphql.schema.GraphQLInterfaceType) GraphQLTypeVisitorStub(graphql.schema.GraphQLTypeVisitorStub) LinkedHashMap(java.util.LinkedHashMap) GraphQLSchemaElement(graphql.schema.GraphQLSchemaElement) GraphQLAppliedDirectiveArgument(graphql.schema.GraphQLAppliedDirectiveArgument) GraphQLNamedSchemaElement(graphql.schema.GraphQLNamedSchemaElement) List(java.util.List) ArrayList(java.util.ArrayList) GraphQLList(graphql.schema.GraphQLList) GraphQLEnumType(graphql.schema.GraphQLEnumType) GraphQLEnumValueDefinition(graphql.schema.GraphQLEnumValueDefinition) GraphQLArgument(graphql.schema.GraphQLArgument) GraphQLDirective(graphql.schema.GraphQLDirective) GraphQLImplementingType(graphql.schema.GraphQLImplementingType) GraphQLAppliedDirective(graphql.schema.GraphQLAppliedDirective) GraphQLScalarType(graphql.schema.GraphQLScalarType) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SchemaUtil(graphql.schema.impl.SchemaUtil) GraphQLTypeVisitor(graphql.schema.GraphQLTypeVisitor) GraphQLInputObjectField(graphql.schema.GraphQLInputObjectField) GraphQLInputObjectType(graphql.schema.GraphQLInputObjectType) GraphQLObjectType(graphql.schema.GraphQLObjectType)

Example 5 with CONTINUE

use of graphql.util.TraversalControl.CONTINUE in project graphql-java by graphql-java.

the class SchemaUsageSupport method getSchemaUsage.

/**
 * This builds out {@link SchemaUsage} statistics about the usage of types and directives within a schema
 *
 * @param schema the schema to check
 *
 * @return usage stats
 */
public static SchemaUsage getSchemaUsage(GraphQLSchema schema) {
    assertNotNull(schema);
    SchemaUsage.Builder builder = new SchemaUsage.Builder();
    GraphQLTypeVisitor visitor = new GraphQLTypeVisitorStub() {

        private BiFunction<String, Integer, Integer> incCount() {
            return (k, v) -> v == null ? 1 : v + 1;
        }

        private void recordBackReference(GraphQLNamedSchemaElement referencedElement, GraphQLSchemaElement referencingElement) {
            String referencedElementName = referencedElement.getName();
            if (referencingElement instanceof GraphQLType) {
                String typeName = (GraphQLTypeUtil.unwrapAll((GraphQLType) referencingElement)).getName();
                builder.elementBackReferences.computeIfAbsent(referencedElementName, k -> new HashSet<>()).add(typeName);
            }
            if (referencingElement instanceof GraphQLDirective) {
                String typeName = ((GraphQLDirective) referencingElement).getName();
                builder.elementBackReferences.computeIfAbsent(referencedElementName, k -> new HashSet<>()).add(typeName);
            }
        }

        private void memberInterfaces(GraphQLNamedType containingType, List<GraphQLNamedOutputType> members) {
            for (GraphQLNamedOutputType member : members) {
                builder.interfaceReferenceCount.compute(member.getName(), incCount());
                builder.interfaceImplementors.computeIfAbsent(member.getName(), k -> new HashSet<>()).add(containingType.getName());
                recordBackReference(containingType, member);
            }
        }

        @Override
        public TraversalControl visitGraphQLArgument(GraphQLArgument node, TraverserContext<GraphQLSchemaElement> context) {
            GraphQLNamedType inputType = GraphQLTypeUtil.unwrapAll(node.getType());
            builder.argReferenceCount.compute(inputType.getName(), incCount());
            GraphQLSchemaElement parentElement = context.getParentNode();
            if (parentElement instanceof GraphQLFieldDefinition) {
                parentElement = context.getParentContext().getParentNode();
            }
            recordBackReference(inputType, parentElement);
            return CONTINUE;
        }

        @Override
        public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext<GraphQLSchemaElement> context) {
            GraphQLNamedType fieldType = GraphQLTypeUtil.unwrapAll(node.getType());
            builder.fieldReferenceCounts.compute(fieldType.getName(), incCount());
            builder.outputFieldReferenceCounts.compute(fieldType.getName(), incCount());
            recordBackReference(fieldType, context.getParentNode());
            return CONTINUE;
        }

        @Override
        public TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField node, TraverserContext<GraphQLSchemaElement> context) {
            GraphQLNamedType fieldType = GraphQLTypeUtil.unwrapAll(node.getType());
            builder.fieldReferenceCounts.compute(fieldType.getName(), incCount());
            builder.inputFieldReferenceCounts.compute(fieldType.getName(), incCount());
            recordBackReference(fieldType, context.getParentNode());
            return CONTINUE;
        }

        @Override
        public TraversalControl visitGraphQLDirective(GraphQLDirective directive, TraverserContext<GraphQLSchemaElement> context) {
            GraphQLSchemaElement parentElement = context.getParentNode();
            if (parentElement != null) {
                // a null parent is a directive definition
                // we record a count if the directive is applied to something - not just defined
                builder.directiveReferenceCount.compute(directive.getName(), incCount());
            }
            if (parentElement instanceof GraphQLArgument) {
                context = context.getParentContext();
                parentElement = context.getParentNode();
            }
            if (parentElement instanceof GraphQLFieldDefinition) {
                context = context.getParentContext();
                parentElement = context.getParentNode();
            }
            if (parentElement instanceof GraphQLInputObjectField) {
                context = context.getParentContext();
                parentElement = context.getParentNode();
            }
            recordBackReference(directive, parentElement);
            return CONTINUE;
        }

        @Override
        public TraversalControl visitGraphQLUnionType(GraphQLUnionType unionType, TraverserContext<GraphQLSchemaElement> context) {
            List<GraphQLNamedOutputType> members = unionType.getTypes();
            for (GraphQLNamedOutputType member : members) {
                builder.unionReferenceCount.compute(member.getName(), incCount());
                recordBackReference(unionType, member);
            }
            return CONTINUE;
        }

        @Override
        public TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType interfaceType, TraverserContext<GraphQLSchemaElement> context) {
            memberInterfaces(interfaceType, interfaceType.getInterfaces());
            return CONTINUE;
        }

        @Override
        public TraversalControl visitGraphQLObjectType(GraphQLObjectType objectType, TraverserContext<GraphQLSchemaElement> context) {
            memberInterfaces(objectType, objectType.getInterfaces());
            return CONTINUE;
        }
    };
    new SchemaTraverser().depthFirstFullSchema(visitor, schema);
    return builder.build();
}
Also used : GraphQLSchemaElement(graphql.schema.GraphQLSchemaElement) GraphQLNamedType(graphql.schema.GraphQLNamedType) TraversalControl(graphql.util.TraversalControl) BiFunction(java.util.function.BiFunction) GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) GraphQLInterfaceType(graphql.schema.GraphQLInterfaceType) GraphQLInputObjectField(graphql.schema.GraphQLInputObjectField) GraphQLUnionType(graphql.schema.GraphQLUnionType) GraphQLType(graphql.schema.GraphQLType) TraverserContext(graphql.util.TraverserContext) GraphQLNamedSchemaElement(graphql.schema.GraphQLNamedSchemaElement) HashSet(java.util.HashSet) GraphQLSchema(graphql.schema.GraphQLSchema) GraphQLTypeUtil(graphql.schema.GraphQLTypeUtil) SchemaTraverser(graphql.schema.SchemaTraverser) GraphQLObjectType(graphql.schema.GraphQLObjectType) GraphQLDirective(graphql.schema.GraphQLDirective) GraphQLNamedOutputType(graphql.schema.GraphQLNamedOutputType) CONTINUE(graphql.util.TraversalControl.CONTINUE) GraphQLArgument(graphql.schema.GraphQLArgument) GraphQLTypeVisitorStub(graphql.schema.GraphQLTypeVisitorStub) List(java.util.List) PublicApi(graphql.PublicApi) Assert.assertNotNull(graphql.Assert.assertNotNull) GraphQLTypeVisitor(graphql.schema.GraphQLTypeVisitor) GraphQLUnionType(graphql.schema.GraphQLUnionType) GraphQLType(graphql.schema.GraphQLType) GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) GraphQLNamedOutputType(graphql.schema.GraphQLNamedOutputType) GraphQLInterfaceType(graphql.schema.GraphQLInterfaceType) GraphQLTypeVisitorStub(graphql.schema.GraphQLTypeVisitorStub) TraverserContext(graphql.util.TraverserContext) GraphQLSchemaElement(graphql.schema.GraphQLSchemaElement) GraphQLNamedSchemaElement(graphql.schema.GraphQLNamedSchemaElement) List(java.util.List) GraphQLNamedType(graphql.schema.GraphQLNamedType) HashSet(java.util.HashSet) GraphQLArgument(graphql.schema.GraphQLArgument) GraphQLDirective(graphql.schema.GraphQLDirective) GraphQLTypeVisitor(graphql.schema.GraphQLTypeVisitor) GraphQLInputObjectField(graphql.schema.GraphQLInputObjectField) GraphQLObjectType(graphql.schema.GraphQLObjectType) SchemaTraverser(graphql.schema.SchemaTraverser)

Aggregations

CONTINUE (graphql.util.TraversalControl.CONTINUE)5 Assert.assertNotNull (graphql.Assert.assertNotNull)4 PublicApi (graphql.PublicApi)4 GraphQLFieldDefinition (graphql.schema.GraphQLFieldDefinition)4 GraphQLObjectType (graphql.schema.GraphQLObjectType)4 GraphQLSchema (graphql.schema.GraphQLSchema)4 GraphQLSchemaElement (graphql.schema.GraphQLSchemaElement)4 GraphQLTypeVisitorStub (graphql.schema.GraphQLTypeVisitorStub)4 List (java.util.List)4 Scalars (graphql.Scalars)3 AssertException (graphql.AssertException)2 Directives (graphql.Directives)2 QueryTraverser (graphql.analysis.QueryTraverser)2 QueryVisitor (graphql.analysis.QueryVisitor)2 QueryVisitorFieldArgumentEnvironment (graphql.analysis.QueryVisitorFieldArgumentEnvironment)2 QueryVisitorFieldArgumentInputValue (graphql.analysis.QueryVisitorFieldArgumentInputValue)2 QueryVisitorFieldArgumentValueEnvironment (graphql.analysis.QueryVisitorFieldArgumentValueEnvironment)2 QueryVisitorFieldEnvironment (graphql.analysis.QueryVisitorFieldEnvironment)2 QueryVisitorFragmentSpreadEnvironment (graphql.analysis.QueryVisitorFragmentSpreadEnvironment)2 QueryVisitorInlineFragmentEnvironment (graphql.analysis.QueryVisitorInlineFragmentEnvironment)2