Search in sources :

Example 6 with GraphQLTypeVisitorStub

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

Example 7 with GraphQLTypeVisitorStub

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

the class FieldVisibilitySchemaTransformation method removeUnreferencedTypes.

private GraphQLSchema removeUnreferencedTypes(Set<GraphQLType> markedForRemovalTypes, GraphQLSchema connectedSchema) {
    GraphQLSchema withoutAdditionalTypes = connectedSchema.transform(builder -> {
        Set<GraphQLType> additionalTypes = new HashSet<>(connectedSchema.getAdditionalTypes());
        additionalTypes.removeAll(markedForRemovalTypes);
        builder.clearAdditionalTypes();
        builder.additionalTypes(additionalTypes);
    });
    // remove from markedForRemovalTypes any type that might still be referenced by other schema elements
    transformSchema(withoutAdditionalTypes, new AdditionalTypeVisibilityVisitor(markedForRemovalTypes));
    // finally remove the types on the schema we are certain aren't referenced by any other node.
    return transformSchema(connectedSchema, new GraphQLTypeVisitorStub() {

        @Override
        protected TraversalControl visitGraphQLType(GraphQLSchemaElement node, TraverserContext<GraphQLSchemaElement> context) {
            if (node instanceof GraphQLType && markedForRemovalTypes.contains(node)) {
                return deleteNode(context);
            }
            return super.visitGraphQLType(node, context);
        }
    });
}
Also used : GraphQLSchemaElement(graphql.schema.GraphQLSchemaElement) TraversalControl(graphql.util.TraversalControl) GraphQLType(graphql.schema.GraphQLType) GraphQLTypeVisitorStub(graphql.schema.GraphQLTypeVisitorStub) GraphQLSchema(graphql.schema.GraphQLSchema) HashSet(java.util.HashSet)

Aggregations

GraphQLTypeVisitorStub (graphql.schema.GraphQLTypeVisitorStub)7 GraphQLObjectType (graphql.schema.GraphQLObjectType)6 GraphQLSchema (graphql.schema.GraphQLSchema)6 GraphQLSchemaElement (graphql.schema.GraphQLSchemaElement)6 GraphQLCodeRegistry (graphql.schema.GraphQLCodeRegistry)4 GraphQLFieldDefinition (graphql.schema.GraphQLFieldDefinition)4 CONTINUE (graphql.util.TraversalControl.CONTINUE)4 Assert.assertNotNull (graphql.Assert.assertNotNull)3 PublicApi (graphql.PublicApi)3 Scalars (graphql.Scalars)3 GraphQLType (graphql.schema.GraphQLType)3 TraverserContext (graphql.util.TraverserContext)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