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

graphql.schema.SchemaTraverser Maven / Gradle / Ivy

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


import graphql.PublicApi;
import graphql.util.TraversalControl;
import graphql.util.Traverser;
import graphql.util.TraverserContext;
import graphql.util.TraverserResult;
import graphql.util.TraverserVisitor;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;

import static graphql.util.TraversalControl.CONTINUE;

@PublicApi
public class SchemaTraverser {


    private final Function> getChildren;

    public SchemaTraverser(Function> getChildren) {
        this.getChildren = getChildren;
    }

    public SchemaTraverser() {
        this(GraphQLSchemaElement::getChildren);
    }

    public TraverserResult depthFirstFullSchema(List typeVisitors, GraphQLSchema schema, Map, Object> rootVars) {
        Set roots = new LinkedHashSet<>();
        roots.add(schema.getQueryType());
        if (schema.isSupportingMutations()) {
            roots.add(schema.getMutationType());
        }
        if (schema.isSupportingSubscriptions()) {
            roots.add(schema.getSubscriptionType());
        }
        roots.addAll(schema.getAdditionalTypes());
        roots.addAll(schema.getDirectives());
        roots.addAll(schema.getSchemaDirectives());
        roots.add(schema.getIntrospectionSchemaType());
        TraverserDelegateListVisitor traverserDelegateListVisitor = new TraverserDelegateListVisitor(typeVisitors);
        return initTraverser().rootVars(rootVars).traverse(roots, traverserDelegateListVisitor);
    }

    public TraverserResult depthFirst(GraphQLTypeVisitor graphQLTypeVisitor, GraphQLSchemaElement root) {
        return depthFirst(graphQLTypeVisitor, Collections.singletonList(root));
    }

    public TraverserResult depthFirst(final GraphQLTypeVisitor graphQLTypeVisitor, Collection roots) {
        return depthFirst(initTraverser(), new TraverserDelegateVisitor(graphQLTypeVisitor), roots);
    }


    public TraverserResult depthFirst(final Traverser traverser,
                                      final TraverserDelegateVisitor traverserDelegateVisitor,
                                      Collection roots) {
        return doTraverse(traverser, roots, traverserDelegateVisitor);
    }

    private Traverser initTraverser() {
        return Traverser.depthFirst(getChildren);
    }

    private TraverserResult doTraverse(Traverser traverser,
                                       Collection roots,
                                       TraverserDelegateVisitor traverserDelegateVisitor) {
        return traverser.traverse(roots, traverserDelegateVisitor);
    }

    private static class TraverserDelegateVisitor implements TraverserVisitor {
        private final GraphQLTypeVisitor delegate;

        TraverserDelegateVisitor(GraphQLTypeVisitor delegate) {
            this.delegate = delegate;

        }

        @Override
        public TraversalControl enter(TraverserContext context) {
            return context.thisNode().accept(context, delegate);
        }

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

        @Override
        public TraversalControl backRef(TraverserContext context) {
            return delegate.visitBackRef(context);
        }
    }

    private static class TraverserDelegateListVisitor implements TraverserVisitor {
        private final List typeVisitors;

        TraverserDelegateListVisitor(List typeVisitors) {
            this.typeVisitors = typeVisitors;

        }

        @Override
        public TraversalControl enter(TraverserContext context) {
            for (GraphQLTypeVisitor graphQLTypeVisitor : typeVisitors) {
                context.thisNode().accept(context, graphQLTypeVisitor);
            }
            return CONTINUE;
        }

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

        @Override
        public TraversalControl backRef(TraverserContext context) {
            for (GraphQLTypeVisitor graphQLTypeVisitor : typeVisitors) {
                graphQLTypeVisitor.visitBackRef(context);
            }
            return CONTINUE;
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy