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

graphql.schema.SchemaTransformer Maven / Gradle / Ivy

There is a newer version: 230521-nf-execution
Show newest version
package graphql.schema;

import graphql.PublicApi;
import graphql.introspection.Introspection;
import graphql.util.TraversalControl;
import graphql.util.TraverserContext;
import graphql.util.TraverserVisitor;
import graphql.util.TreeTransformer;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import static graphql.Assert.assertShouldNeverHappen;
import static graphql.schema.GraphQLSchemaElementAdapter.SCHEMA_ELEMENT_ADAPTER;
import static graphql.schema.SchemaElementChildrenContainer.newSchemaElementChildrenContainer;

/**
 * Transforms a {@link GraphQLSchema} object.
 */
@PublicApi
public class SchemaTransformer {

    // artificial schema element which serves as root element for the transformation
    private static class DummyRoot implements GraphQLSchemaElement {

        static final String QUERY = "query";
        static final String MUTATION = "mutation";
        static final String SUBSCRIPTION = "subscription";
        static final String ADD_TYPES = "addTypes";
        static final String DIRECTIVES = "directives";
        static final String INTROSPECTION = "introspection";
        GraphQLSchema schema;

        GraphQLObjectType query;
        GraphQLObjectType mutation;
        GraphQLObjectType subscription;
        Set additionalTypes;
        Set directives;

        DummyRoot(GraphQLSchema schema) {
            this.schema = schema;
            query = schema.getQueryType();
            mutation = schema.isSupportingMutations() ? schema.getMutationType() : null;
            subscription = schema.isSupportingSubscriptions() ? schema.getSubscriptionType() : null;
            additionalTypes = schema.getAdditionalTypes();
            directives = new LinkedHashSet<>(schema.getDirectives());
        }


        @Override
        public List getChildren() {
            return assertShouldNeverHappen();
        }

        @Override
        public SchemaElementChildrenContainer getChildrenWithTypeReferences() {
            SchemaElementChildrenContainer.Builder builder = newSchemaElementChildrenContainer()
                    .child(QUERY, query);
            if (schema.isSupportingMutations()) {
                builder.child(MUTATION, mutation);
            }
            if (schema.isSupportingSubscriptions()) {
                builder.child(SUBSCRIPTION, subscription);
            }
            builder.children(ADD_TYPES, additionalTypes);
            builder.children(DIRECTIVES, directives);
            builder.child(INTROSPECTION, Introspection.__Schema);
            return builder.build();
        }

        @Override
        public GraphQLSchemaElement withNewChildren(SchemaElementChildrenContainer newChildren) {
            query = newChildren.getChildOrNull(QUERY);
            mutation = newChildren.getChildOrNull(MUTATION);
            subscription = newChildren.getChildOrNull(SUBSCRIPTION);
            additionalTypes = new LinkedHashSet<>(newChildren.getChildren(ADD_TYPES));
            directives = new LinkedHashSet<>(newChildren.getChildren(DIRECTIVES));
            return this;
        }

        @Override
        public TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor) {
            return assertShouldNeverHappen();
        }
    }

    /**
     * Transforms a GrapQLSchema and returns a new GraphQLSchema object.
     *
     * @param schema
     * @param visitor
     *
     * @return a new GraphQLSchema instance.
     */
    public static GraphQLSchema transformSchema(GraphQLSchema schema, GraphQLTypeVisitor visitor) {
        SchemaTransformer schemaTransformer = new SchemaTransformer();
        return schemaTransformer.transform(schema, visitor);
    }

    public GraphQLSchema transform(final GraphQLSchema schema, GraphQLTypeVisitor visitor) {


        DummyRoot dummyRoot = new DummyRoot(schema);
        TraverserVisitor traverserVisitor = new TraverserVisitor() {
            @Override
            public TraversalControl enter(TraverserContext context) {
                if (context.thisNode() == dummyRoot) {
                    return TraversalControl.CONTINUE;
                }
                return context.thisNode().accept(context, visitor);
            }

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

        TreeTransformer treeTransformer = new TreeTransformer<>(SCHEMA_ELEMENT_ADAPTER);

        treeTransformer.transform(dummyRoot, traverserVisitor);
        GraphQLSchema newSchema = GraphQLSchema.newSchema()
                .query(dummyRoot.query)
                .mutation(dummyRoot.mutation)
                .subscription(dummyRoot.subscription)
                .additionalTypes(dummyRoot.additionalTypes)
                .additionalDirectives(dummyRoot.directives)
                .buildImpl(true);
        return newSchema;
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy