graphql.schema.SchemaTraverser Maven / Gradle / Ivy
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 super GraphQLSchemaElement, ? extends List> getChildren;
public SchemaTraverser(Function super GraphQLSchemaElement, ? extends List> 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 extends GraphQLSchemaElement> roots) {
return depthFirst(initTraverser(), new TraverserDelegateVisitor(graphQLTypeVisitor), roots);
}
public TraverserResult depthFirst(final Traverser traverser,
final TraverserDelegateVisitor traverserDelegateVisitor,
Collection extends GraphQLSchemaElement> roots) {
return doTraverse(traverser, roots, traverserDelegateVisitor);
}
private Traverser initTraverser() {
return Traverser.depthFirst(getChildren);
}
private TraverserResult doTraverse(Traverser traverser,
Collection extends GraphQLSchemaElement> 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