Search in sources :

Example 1 with GraphQLNamedSchemaElement

use of graphql.schema.GraphQLNamedSchemaElement in project graphql-java by graphql-java.

the class Anonymizer method anonymizeSchemaAndQueries.

public static AnonymizeResult anonymizeSchemaAndQueries(GraphQLSchema schema, List<String> queries, Map<String, Object> variables) {
    assertNotNull(queries, () -> "queries can't be null");
    AtomicInteger defaultStringValueCounter = new AtomicInteger(1);
    AtomicInteger defaultIntValueCounter = new AtomicInteger(1);
    Map<GraphQLNamedSchemaElement, String> newNameMap = recordNewNamesForSchema(schema);
    // stores a reverse index of anonymized argument name to argument instance
    // this is to handle cases where the fields on implementing types MUST have the same exact argument and default
    // value definitions as the fields on the implemented interface. (argument default values must match exactly)
    Map<String, GraphQLArgument> renamedArgumentsMap = new HashMap<>();
    SchemaTransformer schemaTransformer = new SchemaTransformer();
    GraphQLSchema newSchema = schemaTransformer.transform(schema, new GraphQLTypeVisitorStub() {

        @Override
        public TraversalControl visitGraphQLTypeReference(GraphQLTypeReference graphQLTypeReference, TraverserContext<GraphQLSchemaElement> context) {
            GraphQLNamedSchemaElement type = (GraphQLNamedSchemaElement) schema.getType(graphQLTypeReference.getName());
            String newName = newNameMap.get(type);
            GraphQLTypeReference newReference = GraphQLTypeReference.typeRef(newName);
            return changeNode(context, newReference);
        }

        @Override
        public TraversalControl visitGraphQLArgument(GraphQLArgument graphQLArgument, TraverserContext<GraphQLSchemaElement> context) {
            String newName = assertNotNull(newNameMap.get(graphQLArgument));
            if (context.getParentNode() instanceof GraphQLFieldDefinition) {
                // arguments on field definitions must be identical across implementing types and interfaces.
                if (renamedArgumentsMap.containsKey(newName)) {
                    return changeNode(context, renamedArgumentsMap.get(newName).transform(b -> {
                    }));
                }
            }
            GraphQLArgument newElement = graphQLArgument.transform(builder -> {
                builder.name(newName).description(null).definition(null);
                if (graphQLArgument.hasSetDefaultValue()) {
                    Value<?> defaultValueLiteral = ValuesResolver.valueToLiteral(graphQLArgument.getArgumentDefaultValue(), graphQLArgument.getType());
                    builder.defaultValueLiteral(replaceValue(defaultValueLiteral, graphQLArgument.getType(), newNameMap, defaultStringValueCounter, defaultIntValueCounter));
                }
                if (graphQLArgument.hasSetValue()) {
                    Value<?> valueLiteral = ValuesResolver.valueToLiteral(graphQLArgument.getArgumentValue(), graphQLArgument.getType());
                    builder.valueLiteral(replaceValue(valueLiteral, graphQLArgument.getType(), newNameMap, defaultStringValueCounter, defaultIntValueCounter));
                }
            });
            renamedArgumentsMap.put(newName, newElement);
            return changeNode(context, newElement);
        }

        @Override
        public TraversalControl visitGraphQLAppliedDirectiveArgument(GraphQLAppliedDirectiveArgument graphQLArgument, TraverserContext<GraphQLSchemaElement> context) {
            String newName = assertNotNull(newNameMap.get(graphQLArgument));
            GraphQLAppliedDirectiveArgument newElement = graphQLArgument.transform(builder -> {
                builder.name(newName).description(null).definition(null);
                if (graphQLArgument.hasSetValue()) {
                    Value<?> valueLiteral = ValuesResolver.valueToLiteral(graphQLArgument.getArgumentValue(), graphQLArgument.getType());
                    builder.valueLiteral(replaceValue(valueLiteral, graphQLArgument.getType(), newNameMap, defaultStringValueCounter, defaultIntValueCounter));
                }
            });
            return changeNode(context, newElement);
        }

        @Override
        public TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType graphQLInterfaceType, TraverserContext<GraphQLSchemaElement> context) {
            if (Introspection.isIntrospectionTypes(graphQLInterfaceType)) {
                return TraversalControl.ABORT;
            }
            String newName = assertNotNull(newNameMap.get(graphQLInterfaceType));
            GraphQLInterfaceType newElement = graphQLInterfaceType.transform(builder -> {
                builder.name(newName).description(null).definition(null);
            });
            GraphQLCodeRegistry.Builder codeRegistry = assertNotNull(context.getVarFromParents(GraphQLCodeRegistry.Builder.class));
            TypeResolver typeResolver = codeRegistry.getTypeResolver(graphQLInterfaceType);
            codeRegistry.typeResolver(newName, typeResolver);
            return changeNode(context, newElement);
        }

        @Override
        public TraversalControl visitGraphQLEnumType(GraphQLEnumType graphQLEnumType, TraverserContext<GraphQLSchemaElement> context) {
            if (Introspection.isIntrospectionTypes(graphQLEnumType)) {
                return TraversalControl.ABORT;
            }
            String newName = assertNotNull(newNameMap.get(graphQLEnumType));
            GraphQLEnumType newElement = graphQLEnumType.transform(builder -> {
                builder.name(newName).description(null).definition(null);
            });
            return changeNode(context, newElement);
        }

        @Override
        public TraversalControl visitGraphQLEnumValueDefinition(GraphQLEnumValueDefinition enumValueDefinition, TraverserContext<GraphQLSchemaElement> context) {
            String newName = assertNotNull(newNameMap.get(enumValueDefinition));
            GraphQLEnumValueDefinition newElement = enumValueDefinition.transform(builder -> {
                builder.name(newName).description(null).definition(null);
            });
            return changeNode(context, newElement);
        }

        @Override
        public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition graphQLFieldDefinition, TraverserContext<GraphQLSchemaElement> context) {
            String newName = assertNotNull(newNameMap.get(graphQLFieldDefinition));
            GraphQLFieldDefinition newElement = graphQLFieldDefinition.transform(builder -> {
                builder.name(newName).description(null).definition(null);
            });
            return changeNode(context, newElement);
        }

        @Override
        public TraversalControl visitGraphQLDirective(GraphQLDirective graphQLDirective, TraverserContext<GraphQLSchemaElement> context) {
            if (Directives.DEPRECATED_DIRECTIVE_DEFINITION.getName().equals(graphQLDirective.getName())) {
                GraphQLArgument reason = newArgument().name("reason").type(Scalars.GraphQLString).clearValue().build();
                GraphQLDirective newElement = graphQLDirective.transform(builder -> {
                    builder.description(null).argument(reason);
                });
                changeNode(context, newElement);
                return TraversalControl.ABORT;
            }
            if (DirectiveInfo.isGraphqlSpecifiedDirective(graphQLDirective.getName())) {
                return TraversalControl.ABORT;
            }
            String newName = assertNotNull(newNameMap.get(graphQLDirective));
            GraphQLDirective newElement = graphQLDirective.transform(builder -> {
                builder.name(newName).description(null).definition(null);
            });
            return changeNode(context, newElement);
        }

        @Override
        public TraversalControl visitGraphQLAppliedDirective(GraphQLAppliedDirective graphQLDirective, TraverserContext<GraphQLSchemaElement> context) {
            if (Directives.DEPRECATED_DIRECTIVE_DEFINITION.getName().equals(graphQLDirective.getName())) {
                GraphQLAppliedDirectiveArgument reason = GraphQLAppliedDirectiveArgument.newArgument().name("reason").type(Scalars.GraphQLString).clearValue().build();
                GraphQLAppliedDirective newElement = graphQLDirective.transform(builder -> {
                    builder.description(null).argument(reason);
                });
                changeNode(context, newElement);
                return TraversalControl.ABORT;
            }
            if (DirectiveInfo.isGraphqlSpecifiedDirective(graphQLDirective.getName())) {
                return TraversalControl.ABORT;
            }
            String newName = assertNotNull(newNameMap.get(graphQLDirective));
            GraphQLAppliedDirective newElement = graphQLDirective.transform(builder -> {
                builder.name(newName).description(null).definition(null);
            });
            return changeNode(context, newElement);
        }

        @Override
        public TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField graphQLInputObjectField, TraverserContext<GraphQLSchemaElement> context) {
            String newName = assertNotNull(newNameMap.get(graphQLInputObjectField));
            Value<?> defaultValue = null;
            if (graphQLInputObjectField.hasSetDefaultValue()) {
                defaultValue = ValuesResolver.valueToLiteral(graphQLInputObjectField.getInputFieldDefaultValue(), graphQLInputObjectField.getType());
                defaultValue = replaceValue(defaultValue, graphQLInputObjectField.getType(), newNameMap, defaultStringValueCounter, defaultIntValueCounter);
            }
            Value<?> finalDefaultValue = defaultValue;
            GraphQLInputObjectField newElement = graphQLInputObjectField.transform(builder -> {
                builder.name(newName);
                if (finalDefaultValue != null) {
                    builder.defaultValueLiteral(finalDefaultValue);
                }
                builder.description(null);
                builder.definition(null);
            });
            return changeNode(context, newElement);
        }

        @Override
        public TraversalControl visitGraphQLInputObjectType(GraphQLInputObjectType graphQLInputObjectType, TraverserContext<GraphQLSchemaElement> context) {
            if (Introspection.isIntrospectionTypes(graphQLInputObjectType)) {
                return TraversalControl.ABORT;
            }
            String newName = assertNotNull(newNameMap.get(graphQLInputObjectType));
            GraphQLInputObjectType newElement = graphQLInputObjectType.transform(builder -> {
                builder.name(newName).description(null).definition(null);
            });
            return changeNode(context, newElement);
        }

        @Override
        public TraversalControl visitGraphQLObjectType(GraphQLObjectType graphQLObjectType, TraverserContext<GraphQLSchemaElement> context) {
            if (Introspection.isIntrospectionTypes(graphQLObjectType)) {
                return TraversalControl.ABORT;
            }
            String newName = assertNotNull(newNameMap.get(graphQLObjectType));
            GraphQLObjectType newElement = graphQLObjectType.transform(builder -> {
                builder.name(newName).description(null).definition(null);
            });
            return changeNode(context, newElement);
        }

        @Override
        public TraversalControl visitGraphQLScalarType(GraphQLScalarType graphQLScalarType, TraverserContext<GraphQLSchemaElement> context) {
            if (ScalarInfo.isGraphqlSpecifiedScalar(graphQLScalarType)) {
                return TraversalControl.ABORT;
            }
            String newName = assertNotNull(newNameMap.get(graphQLScalarType));
            GraphQLScalarType newElement = graphQLScalarType.transform(builder -> {
                builder.name(newName).description(null).definition(null);
            });
            return changeNode(context, newElement);
        }

        @Override
        public TraversalControl visitGraphQLUnionType(GraphQLUnionType graphQLUnionType, TraverserContext<GraphQLSchemaElement> context) {
            if (Introspection.isIntrospectionTypes(graphQLUnionType)) {
                return TraversalControl.ABORT;
            }
            String newName = assertNotNull(newNameMap.get(graphQLUnionType));
            GraphQLUnionType newElement = graphQLUnionType.transform(builder -> {
                builder.name(newName).description(null).definition(null);
            });
            GraphQLCodeRegistry.Builder codeRegistry = assertNotNull(context.getVarFromParents(GraphQLCodeRegistry.Builder.class));
            TypeResolver typeResolver = codeRegistry.getTypeResolver(graphQLUnionType);
            codeRegistry.typeResolver(newName, typeResolver);
            return changeNode(context, newElement);
        }
    });
    List<String> newQueries = new ArrayList<>();
    for (String query : queries) {
        String newQuery = rewriteQuery(query, schema, newNameMap, variables);
        newQueries.add(newQuery);
    }
    AnonymizeResult result = new AnonymizeResult(newSchema, newQueries);
    return result;
}
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) GraphQLTypeReference(graphql.schema.GraphQLTypeReference) GraphQLUnionType(graphql.schema.GraphQLUnionType) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TypeResolver(graphql.schema.TypeResolver) ArrayList(java.util.ArrayList) GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) GraphQLInterfaceType(graphql.schema.GraphQLInterfaceType) GraphQLTypeVisitorStub(graphql.schema.GraphQLTypeVisitorStub) GraphQLSchemaElement(graphql.schema.GraphQLSchemaElement) GraphQLAppliedDirectiveArgument(graphql.schema.GraphQLAppliedDirectiveArgument) GraphQLCodeRegistry(graphql.schema.GraphQLCodeRegistry) GraphQLNamedSchemaElement(graphql.schema.GraphQLNamedSchemaElement) GraphQLEnumType(graphql.schema.GraphQLEnumType) GraphQLEnumValueDefinition(graphql.schema.GraphQLEnumValueDefinition) GraphQLArgument(graphql.schema.GraphQLArgument) SchemaTransformer(graphql.schema.SchemaTransformer) GraphQLDirective(graphql.schema.GraphQLDirective) GraphQLAppliedDirective(graphql.schema.GraphQLAppliedDirective) GraphQLSchema(graphql.schema.GraphQLSchema) GraphQLScalarType(graphql.schema.GraphQLScalarType) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) GraphQLInputObjectField(graphql.schema.GraphQLInputObjectField) GraphQLInputObjectType(graphql.schema.GraphQLInputObjectType) 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) GraphQLObjectType(graphql.schema.GraphQLObjectType)

Example 2 with GraphQLNamedSchemaElement

use of graphql.schema.GraphQLNamedSchemaElement 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 GraphQLNamedSchemaElement

use of graphql.schema.GraphQLNamedSchemaElement 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 4 with GraphQLNamedSchemaElement

use of graphql.schema.GraphQLNamedSchemaElement 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

Assert.assertNotNull (graphql.Assert.assertNotNull)4 PublicApi (graphql.PublicApi)4 AssertException (graphql.AssertException)3 Directives (graphql.Directives)3 Scalars (graphql.Scalars)3 QueryTraverser (graphql.analysis.QueryTraverser)3 QueryVisitor (graphql.analysis.QueryVisitor)3 QueryVisitorFieldArgumentEnvironment (graphql.analysis.QueryVisitorFieldArgumentEnvironment)3 QueryVisitorFieldArgumentInputValue (graphql.analysis.QueryVisitorFieldArgumentInputValue)3 QueryVisitorFieldArgumentValueEnvironment (graphql.analysis.QueryVisitorFieldArgumentValueEnvironment)3 QueryVisitorFieldEnvironment (graphql.analysis.QueryVisitorFieldEnvironment)3 QueryVisitorFragmentSpreadEnvironment (graphql.analysis.QueryVisitorFragmentSpreadEnvironment)3 QueryVisitorInlineFragmentEnvironment (graphql.analysis.QueryVisitorInlineFragmentEnvironment)3 ValuesResolver (graphql.execution.ValuesResolver)3 Introspection (graphql.introspection.Introspection)3 Argument (graphql.language.Argument)3 ArrayValue (graphql.language.ArrayValue)3 AstPrinter (graphql.language.AstPrinter)3 AstTransformer (graphql.language.AstTransformer)3 Definition (graphql.language.Definition)3