use of graphql.schema.SchemaTraverser in project graphql-java by graphql-java.
the class SchemaUtil method replaceTypeReferences.
public static void replaceTypeReferences(GraphQLSchema schema) {
final Map<String, GraphQLNamedType> typeMap = schema.getTypeMap();
List<GraphQLSchemaElement> roots = new ArrayList<>(typeMap.values());
roots.addAll(schema.getDirectives());
SchemaTraverser schemaTraverser = new SchemaTraverser(schemaElement -> schemaElement.getChildrenWithTypeReferences().getChildrenAsList());
schemaTraverser.depthFirst(new GraphQLTypeResolvingVisitor(typeMap), roots);
}
use of graphql.schema.SchemaTraverser in project graphql-java by graphql-java.
the class SchemaUtil method visitPartiallySchema.
/**
* Called to visit a partially build schema (during {@link GraphQLSchema} build phases) with a set of visitors
*
* Each visitor is expected to hold its own side effects that might be last used to construct a full schema
*
* @param partiallyBuiltSchema the partially built schema
* @param visitors the visitors to call
*/
public static void visitPartiallySchema(final GraphQLSchema partiallyBuiltSchema, GraphQLTypeVisitor... visitors) {
List<GraphQLSchemaElement> roots = new ArrayList<>();
roots.add(partiallyBuiltSchema.getQueryType());
if (partiallyBuiltSchema.isSupportingMutations()) {
roots.add(partiallyBuiltSchema.getMutationType());
}
if (partiallyBuiltSchema.isSupportingSubscriptions()) {
roots.add(partiallyBuiltSchema.getSubscriptionType());
}
if (partiallyBuiltSchema.getAdditionalTypes() != null) {
roots.addAll(partiallyBuiltSchema.getAdditionalTypes());
}
if (partiallyBuiltSchema.getDirectives() != null) {
roots.addAll(partiallyBuiltSchema.getDirectives());
}
roots.add(partiallyBuiltSchema.getIntrospectionSchemaType());
GraphQLTypeVisitor visitor = new MultiReadOnlyGraphQLTypeVisitor(Arrays.asList(visitors));
SchemaTraverser traverser;
traverser = new SchemaTraverser(schemaElement -> schemaElement.getChildrenWithTypeReferences().getChildrenAsList());
traverser.depthFirst(visitor, roots);
}
use of graphql.schema.SchemaTraverser in project graphql-java by graphql-java.
the class SchemaValidator method validateSchema.
public Set<SchemaValidationError> validateSchema(GraphQLSchema schema) {
SchemaValidationErrorCollector validationErrorCollector = new SchemaValidationErrorCollector();
Map<Class<?>, Object> rootVars = new LinkedHashMap<>();
rootVars.put(GraphQLSchema.class, schema);
rootVars.put(SchemaValidationErrorCollector.class, validationErrorCollector);
new SchemaTraverser().depthFirstFullSchema(rules, schema, rootVars);
return validationErrorCollector.getErrors();
}
use of graphql.schema.SchemaTraverser in project spring-graphql by spring-projects.
the class DefaultGraphQlSourceBuilder method applyTypeVisitors.
private GraphQLSchema applyTypeVisitors(GraphQLSchema schema) {
List<GraphQLTypeVisitor> visitors = new ArrayList<>(this.typeVisitors);
visitors.add(ContextDataFetcherDecorator.TYPE_VISITOR);
GraphQLCodeRegistry.Builder codeRegistry = GraphQLCodeRegistry.newCodeRegistry(schema.getCodeRegistry());
Map<Class<?>, Object> vars = Collections.singletonMap(GraphQLCodeRegistry.Builder.class, codeRegistry);
SchemaTraverser traverser = new SchemaTraverser();
traverser.depthFirstFullSchema(visitors, schema, vars);
return schema.transformWithoutTypes(builder -> builder.codeRegistry(codeRegistry));
}
use of graphql.schema.SchemaTraverser 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();
}
Aggregations