use of graphql.util.TraversalControl.CONTINUE in project graphql-java by graphql-java.
the class SchemaTransformer method traverseAndTransform.
private boolean traverseAndTransform(DummyRoot dummyRoot, Map<String, GraphQLNamedType> changedTypes, Map<String, GraphQLTypeReference> typeReferences, GraphQLTypeVisitor visitor, GraphQLCodeRegistry.Builder codeRegistry) {
List<NodeZipper<GraphQLSchemaElement>> zippers = new LinkedList<>();
Map<GraphQLSchemaElement, NodeZipper<GraphQLSchemaElement>> zipperByNodeAfterTraversing = new LinkedHashMap<>();
Map<GraphQLSchemaElement, NodeZipper<GraphQLSchemaElement>> zipperByOriginalNode = new LinkedHashMap<>();
Map<NodeZipper<GraphQLSchemaElement>, List<List<Breadcrumb<GraphQLSchemaElement>>>> breadcrumbsByZipper = new LinkedHashMap<>();
Map<GraphQLSchemaElement, List<GraphQLSchemaElement>> reverseDependencies = new LinkedHashMap<>();
Map<String, List<GraphQLSchemaElement>> typeRefReverseDependencies = new LinkedHashMap<>();
TraverserVisitor<GraphQLSchemaElement> nodeTraverserVisitor = new TraverserVisitor<GraphQLSchemaElement>() {
@Override
public TraversalControl enter(TraverserContext<GraphQLSchemaElement> context) {
GraphQLSchemaElement currentSchemaElement = context.thisNode();
if (currentSchemaElement == dummyRoot) {
return TraversalControl.CONTINUE;
}
if (currentSchemaElement instanceof GraphQLTypeReference) {
GraphQLTypeReference typeRef = (GraphQLTypeReference) currentSchemaElement;
typeReferences.put(typeRef.getName(), typeRef);
}
NodeZipper<GraphQLSchemaElement> nodeZipper = new NodeZipper<>(currentSchemaElement, context.getBreadcrumbs(), SCHEMA_ELEMENT_ADAPTER);
context.setVar(NodeZipper.class, nodeZipper);
context.setVar(NodeAdapter.class, SCHEMA_ELEMENT_ADAPTER);
int zippersBefore = zippers.size();
TraversalControl result = currentSchemaElement.accept(context, visitor);
// detection if the node was changed
if (zippersBefore + 1 == zippers.size()) {
nodeZipper = zippers.get(zippers.size() - 1);
if (context.originalThisNode() instanceof GraphQLNamedType && context.isChanged()) {
GraphQLNamedType originalNamedType = (GraphQLNamedType) context.originalThisNode();
GraphQLNamedType changedNamedType = (GraphQLNamedType) context.thisNode();
if (!originalNamedType.getName().equals(changedNamedType.getName())) {
changedTypes.put(originalNamedType.getName(), changedNamedType);
}
}
}
zipperByOriginalNode.put(context.originalThisNode(), nodeZipper);
if (context.isDeleted()) {
zipperByNodeAfterTraversing.put(context.originalThisNode(), nodeZipper);
} else {
zipperByNodeAfterTraversing.put(context.thisNode(), nodeZipper);
}
breadcrumbsByZipper.put(nodeZipper, new ArrayList<>());
breadcrumbsByZipper.get(nodeZipper).add(context.getBreadcrumbs());
if (nodeZipper.getModificationType() != NodeZipper.ModificationType.DELETE) {
reverseDependencies.computeIfAbsent(context.thisNode(), ign -> new ArrayList<>()).add(context.getParentNode());
if (context.originalThisNode() instanceof GraphQLTypeReference) {
String typeName = ((GraphQLTypeReference) context.originalThisNode()).getName();
typeRefReverseDependencies.computeIfAbsent(typeName, ign -> new ArrayList<>()).add(context.getParentNode());
}
}
return result;
}
@Override
public TraversalControl leave(TraverserContext<GraphQLSchemaElement> context) {
return TraversalControl.CONTINUE;
}
@Override
public TraversalControl backRef(TraverserContext<GraphQLSchemaElement> context) {
NodeZipper<GraphQLSchemaElement> zipper = zipperByOriginalNode.get(context.thisNode());
breadcrumbsByZipper.get(zipper).add(context.getBreadcrumbs());
if (zipper.getModificationType() == DELETE) {
return CONTINUE;
}
visitor.visitBackRef(context);
List<GraphQLSchemaElement> reverseDependenciesForCurNode = reverseDependencies.get(zipper.getCurNode());
assertNotNull(reverseDependenciesForCurNode);
reverseDependenciesForCurNode.add(context.getParentNode());
return TraversalControl.CONTINUE;
}
};
Traverser<GraphQLSchemaElement> traverser = Traverser.depthFirstWithNamedChildren(SCHEMA_ELEMENT_ADAPTER::getNamedChildren, zippers, null);
if (codeRegistry != null) {
traverser.rootVar(GraphQLCodeRegistry.Builder.class, codeRegistry);
}
traverser.traverse(dummyRoot, nodeTraverserVisitor);
List<List<GraphQLSchemaElement>> stronglyConnectedTopologicallySorted = getStronglyConnectedComponentsTopologicallySorted(reverseDependencies, typeRefReverseDependencies);
return zipUpToDummyRoot(zippers, stronglyConnectedTopologicallySorted, breadcrumbsByZipper, zipperByNodeAfterTraversing);
}
use of graphql.util.TraversalControl.CONTINUE in project graphql-java by graphql-java.
the class Anonymizer method rewriteQuery.
private static String rewriteQuery(String query, GraphQLSchema schema, Map<GraphQLNamedSchemaElement, String> newNames, Map<String, Object> variables) {
AtomicInteger fragmentCounter = new AtomicInteger(1);
AtomicInteger variableCounter = new AtomicInteger(1);
Map<Node, String> astNodeToNewName = new LinkedHashMap<>();
Map<String, String> variableNames = new LinkedHashMap<>();
Map<Field, GraphQLFieldDefinition> fieldToFieldDefinition = new LinkedHashMap<>();
Document document = new Parser().parseDocument(query);
assertUniqueOperation(document);
QueryTraverser queryTraverser = QueryTraverser.newQueryTraverser().document(document).schema(schema).variables(variables).build();
queryTraverser.visitDepthFirst(new QueryVisitor() {
@Override
public void visitField(QueryVisitorFieldEnvironment env) {
if (env.isTypeNameIntrospectionField()) {
return;
}
fieldToFieldDefinition.put(env.getField(), env.getFieldDefinition());
String newName = assertNotNull(newNames.get(env.getFieldDefinition()));
Field field = env.getField();
astNodeToNewName.put(field, newName);
List<Directive> directives = field.getDirectives();
for (Directive directive : directives) {
// this is a directive definition
GraphQLDirective directiveDefinition = assertNotNull(schema.getDirective(directive.getName()), () -> format("%s directive definition not found ", directive.getName()));
String directiveName = directiveDefinition.getName();
String newDirectiveName = assertNotNull(newNames.get(directiveDefinition), () -> format("No new name found for directive %s", directiveName));
astNodeToNewName.put(directive, newDirectiveName);
for (Argument argument : directive.getArguments()) {
GraphQLArgument argumentDefinition = directiveDefinition.getArgument(argument.getName());
String newArgumentName = assertNotNull(newNames.get(argumentDefinition), () -> format("%s no new name found for directive argument %s %s", directiveName, argument.getName()));
astNodeToNewName.put(argument, newArgumentName);
visitDirectiveArgumentValues(directive, argument.getValue());
}
}
}
private void visitDirectiveArgumentValues(Directive directive, Value value) {
if (value instanceof VariableReference) {
String name = ((VariableReference) value).getName();
if (!variableNames.containsKey(name)) {
String newName = "var" + variableCounter.getAndIncrement();
variableNames.put(name, newName);
}
}
}
@Override
public void visitInlineFragment(QueryVisitorInlineFragmentEnvironment queryVisitorInlineFragmentEnvironment) {
}
@Override
public TraversalControl visitArgumentValue(QueryVisitorFieldArgumentValueEnvironment environment) {
QueryVisitorFieldArgumentInputValue argumentInputValue = environment.getArgumentInputValue();
if (argumentInputValue.getValue() instanceof VariableReference) {
String name = ((VariableReference) argumentInputValue.getValue()).getName();
if (!variableNames.containsKey(name)) {
String newName = "var" + variableCounter.getAndIncrement();
variableNames.put(name, newName);
}
}
return CONTINUE;
}
@Override
public void visitFragmentSpread(QueryVisitorFragmentSpreadEnvironment queryVisitorFragmentSpreadEnvironment) {
FragmentDefinition fragmentDefinition = queryVisitorFragmentSpreadEnvironment.getFragmentDefinition();
String newName;
if (!astNodeToNewName.containsKey(fragmentDefinition)) {
newName = "Fragment" + fragmentCounter.getAndIncrement();
astNodeToNewName.put(fragmentDefinition, newName);
} else {
newName = astNodeToNewName.get(fragmentDefinition);
}
astNodeToNewName.put(queryVisitorFragmentSpreadEnvironment.getFragmentSpread(), newName);
}
@Override
public TraversalControl visitArgument(QueryVisitorFieldArgumentEnvironment environment) {
String newName = assertNotNull(newNames.get(environment.getGraphQLArgument()));
astNodeToNewName.put(environment.getArgument(), newName);
return CONTINUE;
}
});
AtomicInteger stringValueCounter = new AtomicInteger(1);
AtomicInteger intValueCounter = new AtomicInteger(1);
AstTransformer astTransformer = new AstTransformer();
AtomicInteger aliasCounter = new AtomicInteger(1);
AtomicInteger defaultStringValueCounter = new AtomicInteger(1);
AtomicInteger defaultIntValueCounter = new AtomicInteger(1);
Document newDocument = (Document) astTransformer.transform(document, new NodeVisitorStub() {
@Override
public TraversalControl visitDirective(Directive directive, TraverserContext<Node> context) {
String newName = assertNotNull(astNodeToNewName.get(directive));
GraphQLDirective directiveDefinition = schema.getDirective(directive.getName());
context.setVar(GraphQLDirective.class, directiveDefinition);
return changeNode(context, directive.transform(builder -> builder.name(newName)));
}
@Override
public TraversalControl visitOperationDefinition(OperationDefinition node, TraverserContext<Node> context) {
if (node.getName() != null) {
return changeNode(context, node.transform(builder -> builder.name("operation")));
} else {
return CONTINUE;
}
}
@Override
public TraversalControl visitField(Field field, TraverserContext<Node> context) {
String newAlias = null;
if (field.getAlias() != null) {
newAlias = "alias" + aliasCounter.getAndIncrement();
}
String newName;
if (field.getName().equals(Introspection.TypeNameMetaFieldDef.getName())) {
newName = Introspection.TypeNameMetaFieldDef.getName();
} else {
newName = assertNotNull(astNodeToNewName.get(field));
context.setVar(GraphQLFieldDefinition.class, assertNotNull(fieldToFieldDefinition.get(field)));
}
String finalNewAlias = newAlias;
return changeNode(context, field.transform(builder -> builder.name(newName).alias(finalNewAlias)));
}
@Override
public TraversalControl visitVariableDefinition(VariableDefinition node, TraverserContext<Node> context) {
String newName = assertNotNull(variableNames.get(node.getName()));
VariableDefinition newNode = node.transform(builder -> {
builder.name(newName).comments(Collections.emptyList());
// convert variable language type to renamed language type
TypeName typeName = TypeUtil.unwrapAll(node.getType());
GraphQLNamedType originalType = schema.getTypeAs(typeName.getName());
// has the type name changed? (standard scalars such as String don't change)
if (newNames.containsKey(originalType)) {
String newTypeName = newNames.get(originalType);
builder.type(replaceTypeName(node.getType(), newTypeName));
}
if (node.getDefaultValue() != null) {
Value<?> defaultValueLiteral = node.getDefaultValue();
GraphQLType graphQLType = fromTypeToGraphQLType(node.getType(), schema);
builder.defaultValue(replaceValue(defaultValueLiteral, (GraphQLInputType) graphQLType, newNames, defaultStringValueCounter, defaultIntValueCounter));
}
});
return changeNode(context, newNode);
}
@Override
public TraversalControl visitVariableReference(VariableReference node, TraverserContext<Node> context) {
String newName = assertNotNull(variableNames.get(node.getName()), () -> format("No new variable name found for %s", node.getName()));
return changeNode(context, node.transform(builder -> builder.name(newName)));
}
@Override
public TraversalControl visitFragmentDefinition(FragmentDefinition node, TraverserContext<Node> context) {
String newName = assertNotNull(astNodeToNewName.get(node));
GraphQLType currentCondition = assertNotNull(schema.getType(node.getTypeCondition().getName()));
String newCondition = newNames.get(currentCondition);
return changeNode(context, node.transform(builder -> builder.name(newName).typeCondition(new TypeName(newCondition))));
}
@Override
public TraversalControl visitInlineFragment(InlineFragment node, TraverserContext<Node> context) {
GraphQLType currentCondition = assertNotNull(schema.getType(node.getTypeCondition().getName()));
String newCondition = newNames.get(currentCondition);
return changeNode(context, node.transform(builder -> builder.typeCondition(new TypeName(newCondition))));
}
@Override
public TraversalControl visitFragmentSpread(FragmentSpread node, TraverserContext<Node> context) {
String newName = assertNotNull(astNodeToNewName.get(node));
return changeNode(context, node.transform(builder -> builder.name(newName)));
}
@Override
public TraversalControl visitArgument(Argument argument, TraverserContext<Node> context) {
GraphQLArgument graphQLArgumentDefinition;
// An argument is either from a applied query directive or from a field
if (context.getVarFromParents(GraphQLDirective.class) != null) {
GraphQLDirective directiveDefinition = context.getVarFromParents(GraphQLDirective.class);
graphQLArgumentDefinition = directiveDefinition.getArgument(argument.getName());
} else {
GraphQLFieldDefinition graphQLFieldDefinition = assertNotNull(context.getVarFromParents(GraphQLFieldDefinition.class));
graphQLArgumentDefinition = graphQLFieldDefinition.getArgument(argument.getName());
}
GraphQLInputType argumentType = graphQLArgumentDefinition.getType();
String newName = assertNotNull(astNodeToNewName.get(argument));
Value newValue = replaceValue(argument.getValue(), argumentType, newNames, defaultStringValueCounter, defaultIntValueCounter);
return changeNode(context, argument.transform(builder -> builder.name(newName).value(newValue)));
}
});
return AstPrinter.printAstCompact(newDocument);
}
use of graphql.util.TraversalControl.CONTINUE in project graphql-java by graphql-java.
the class SchemaTransformExamples method trasnformSchema.
void trasnformSchema() {
GraphQLTypeVisitorStub visitor = new GraphQLTypeVisitorStub() {
@Override
public TraversalControl visitGraphQLObjectType(GraphQLObjectType objectType, TraverserContext<GraphQLSchemaElement> context) {
GraphQLCodeRegistry.Builder codeRegistry = context.getVarFromParents(GraphQLCodeRegistry.Builder.class);
// we need to change __XXX introspection types to have directive extensions
if (someConditionalLogic(objectType)) {
GraphQLObjectType newObjectType = buildChangedObjectType(objectType, codeRegistry);
return changeNode(context, newObjectType);
}
return CONTINUE;
}
private boolean someConditionalLogic(GraphQLObjectType objectType) {
// up to you to decide what causes a change, perhaps a directive is on the element
return objectType.hasDirective("specialDirective");
}
private GraphQLObjectType buildChangedObjectType(GraphQLObjectType objectType, GraphQLCodeRegistry.Builder codeRegistry) {
GraphQLFieldDefinition newField = GraphQLFieldDefinition.newFieldDefinition().name("newField").type(Scalars.GraphQLString).build();
GraphQLObjectType newObjectType = objectType.transform(builder -> builder.field(newField));
DataFetcher newDataFetcher = dataFetchingEnvironment -> {
return "someValueForTheNewField";
};
FieldCoordinates coordinates = FieldCoordinates.coordinates(objectType.getName(), newField.getName());
codeRegistry.dataFetcher(coordinates, newDataFetcher);
return newObjectType;
}
};
GraphQLSchema newSchema = SchemaTransformer.transformSchema(schema, visitor);
}
use of graphql.util.TraversalControl.CONTINUE in project graphql-java by graphql-java.
the class Anonymizer method recordNewNamesForSchema.
public static Map<GraphQLNamedSchemaElement, String> recordNewNamesForSchema(GraphQLSchema schema) {
AtomicInteger objectCounter = new AtomicInteger(1);
AtomicInteger inputObjectCounter = new AtomicInteger(1);
AtomicInteger inputObjectFieldCounter = new AtomicInteger(1);
AtomicInteger fieldCounter = new AtomicInteger(1);
AtomicInteger scalarCounter = new AtomicInteger(1);
AtomicInteger directiveCounter = new AtomicInteger(1);
AtomicInteger argumentCounter = new AtomicInteger(1);
AtomicInteger interfaceCounter = new AtomicInteger(1);
AtomicInteger unionCounter = new AtomicInteger(1);
AtomicInteger enumCounter = new AtomicInteger(1);
AtomicInteger enumValueCounter = new AtomicInteger(1);
Map<GraphQLNamedSchemaElement, String> newNameMap = new LinkedHashMap<>();
Map<String, String> directivesOriginalToNewNameMap = new HashMap<>();
// DirectiveName.argumentName -> newArgumentName
Map<String, String> seenArgumentsOnDirectivesMap = new HashMap<>();
Map<String, List<GraphQLImplementingType>> interfaceToImplementations = new SchemaUtil().groupImplementationsForInterfacesAndObjects(schema);
Consumer<GraphQLNamedSchemaElement> recordDirectiveName = (graphQLDirective) -> {
String directiveName = graphQLDirective.getName();
if (directivesOriginalToNewNameMap.containsKey(directiveName)) {
newNameMap.put(graphQLDirective, directivesOriginalToNewNameMap.get(directiveName));
return;
}
String newName = "Directive" + directiveCounter.getAndIncrement();
newNameMap.put(graphQLDirective, newName);
directivesOriginalToNewNameMap.put(directiveName, newName);
};
BiConsumer<GraphQLNamedSchemaElement, String> recordDirectiveArgumentName = (graphQLArgument, directiveArgumentKey) -> {
if (seenArgumentsOnDirectivesMap.containsKey(directiveArgumentKey)) {
newNameMap.put(graphQLArgument, seenArgumentsOnDirectivesMap.get(directiveArgumentKey));
return;
}
String newName = "argument" + argumentCounter.getAndIncrement();
newNameMap.put(graphQLArgument, newName);
seenArgumentsOnDirectivesMap.put(directiveArgumentKey, newName);
};
GraphQLTypeVisitor visitor = new GraphQLTypeVisitorStub() {
@Override
public TraversalControl visitGraphQLArgument(GraphQLArgument graphQLArgument, TraverserContext<GraphQLSchemaElement> context) {
String curName = graphQLArgument.getName();
GraphQLSchemaElement parentNode = context.getParentNode();
if (parentNode instanceof GraphQLDirective) {
// if we already went over the argument for this directive name, no need to add new names
String directiveArgumentKey = ((GraphQLDirective) parentNode).getName() + graphQLArgument.getName();
recordDirectiveArgumentName.accept(graphQLArgument, directiveArgumentKey);
return CONTINUE;
}
if (!(parentNode instanceof GraphQLFieldDefinition)) {
String newName = "argument" + argumentCounter.getAndIncrement();
newNameMap.put(graphQLArgument, newName);
return CONTINUE;
}
GraphQLFieldDefinition fieldDefinition = (GraphQLFieldDefinition) parentNode;
String fieldName = fieldDefinition.getName();
GraphQLImplementingType implementingType = (GraphQLImplementingType) context.getParentContext().getParentNode();
Set<GraphQLFieldDefinition> matchingInterfaceFieldDefinitions = getSameFields(fieldName, implementingType.getName(), interfaceToImplementations, schema);
String newName;
if (matchingInterfaceFieldDefinitions.size() == 0) {
newName = "argument" + argumentCounter.getAndIncrement();
} else {
List<GraphQLArgument> matchingArgumentDefinitions = getMatchingArgumentDefinitions(curName, matchingInterfaceFieldDefinitions);
if (matchingArgumentDefinitions.size() == 0) {
newName = "argument" + argumentCounter.getAndIncrement();
} else {
if (newNameMap.containsKey(matchingArgumentDefinitions.get(0))) {
newName = newNameMap.get(matchingArgumentDefinitions.get(0));
} else {
newName = "argument" + argumentCounter.getAndIncrement();
for (GraphQLArgument argument : matchingArgumentDefinitions) {
newNameMap.put(argument, newName);
}
}
}
}
newNameMap.put(graphQLArgument, newName);
return CONTINUE;
}
@Override
public TraversalControl visitGraphQLAppliedDirectiveArgument(GraphQLAppliedDirectiveArgument graphQLArgument, TraverserContext<GraphQLSchemaElement> context) {
GraphQLSchemaElement parentNode = context.getParentNode();
if (parentNode instanceof GraphQLAppliedDirective) {
// if we already went over the argument for this directive name, no need to add new names
String directiveArgumentKey = ((GraphQLAppliedDirective) parentNode).getName() + graphQLArgument.getName();
recordDirectiveArgumentName.accept(graphQLArgument, directiveArgumentKey);
}
return CONTINUE;
}
@Override
public TraversalControl visitGraphQLDirective(GraphQLDirective graphQLDirective, TraverserContext<GraphQLSchemaElement> context) {
if (DirectiveInfo.isGraphqlSpecifiedDirective(graphQLDirective)) {
return TraversalControl.ABORT;
}
recordDirectiveName.accept(graphQLDirective);
return CONTINUE;
}
@Override
public TraversalControl visitGraphQLAppliedDirective(GraphQLAppliedDirective graphQLAppliedDirective, TraverserContext<GraphQLSchemaElement> context) {
if (DirectiveInfo.isGraphqlSpecifiedDirective(graphQLAppliedDirective.getName())) {
return TraversalControl.ABORT;
}
recordDirectiveName.accept(graphQLAppliedDirective);
return CONTINUE;
}
@Override
public TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType graphQLInterfaceType, TraverserContext<GraphQLSchemaElement> context) {
if (Introspection.isIntrospectionTypes(graphQLInterfaceType)) {
return TraversalControl.ABORT;
}
String newName = "Interface" + interfaceCounter.getAndIncrement();
newNameMap.put(graphQLInterfaceType, newName);
return CONTINUE;
}
@Override
public TraversalControl visitGraphQLEnumType(GraphQLEnumType graphQLEnumType, TraverserContext<GraphQLSchemaElement> context) {
if (Introspection.isIntrospectionTypes(graphQLEnumType)) {
return TraversalControl.ABORT;
}
String newName = "Enum" + enumCounter.getAndIncrement();
newNameMap.put(graphQLEnumType, newName);
return CONTINUE;
}
@Override
public TraversalControl visitGraphQLEnumValueDefinition(GraphQLEnumValueDefinition enumValueDefinition, TraverserContext<GraphQLSchemaElement> context) {
String newName = "EnumValue" + enumValueCounter.getAndIncrement();
newNameMap.put(enumValueDefinition, newName);
return CONTINUE;
}
@Override
public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition graphQLFieldDefinition, TraverserContext<GraphQLSchemaElement> context) {
String fieldName = graphQLFieldDefinition.getName();
GraphQLImplementingType parentNode = (GraphQLImplementingType) context.getParentNode();
Set<GraphQLFieldDefinition> sameFields = getSameFields(fieldName, parentNode.getName(), interfaceToImplementations, schema);
String newName;
if (sameFields.size() == 0) {
newName = "field" + fieldCounter.getAndIncrement();
} else {
if (newNameMap.containsKey(sameFields.iterator().next())) {
newName = newNameMap.get(sameFields.iterator().next());
} else {
newName = "field" + fieldCounter.getAndIncrement();
for (GraphQLFieldDefinition fieldDefinition : sameFields) {
newNameMap.put(fieldDefinition, newName);
}
}
}
newNameMap.put(graphQLFieldDefinition, newName);
return CONTINUE;
}
@Override
public TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField graphQLInputObjectField, TraverserContext<GraphQLSchemaElement> context) {
String newName = "inputField" + inputObjectFieldCounter.getAndIncrement();
newNameMap.put(graphQLInputObjectField, newName);
return CONTINUE;
}
@Override
public TraversalControl visitGraphQLInputObjectType(GraphQLInputObjectType graphQLInputObjectType, TraverserContext<GraphQLSchemaElement> context) {
if (Introspection.isIntrospectionTypes(graphQLInputObjectType)) {
return TraversalControl.ABORT;
}
String newName = "InputObject" + inputObjectCounter.getAndIncrement();
newNameMap.put(graphQLInputObjectType, newName);
return CONTINUE;
}
@Override
public TraversalControl visitGraphQLObjectType(GraphQLObjectType graphQLObjectType, TraverserContext<GraphQLSchemaElement> context) {
if (Introspection.isIntrospectionTypes(graphQLObjectType)) {
return TraversalControl.ABORT;
}
String newName = "Object" + objectCounter.getAndIncrement();
newNameMap.put(graphQLObjectType, newName);
return CONTINUE;
}
@Override
public TraversalControl visitGraphQLScalarType(GraphQLScalarType graphQLScalarType, TraverserContext<GraphQLSchemaElement> context) {
if (ScalarInfo.isGraphqlSpecifiedScalar(graphQLScalarType)) {
return TraversalControl.ABORT;
}
String newName = "Scalar" + scalarCounter.getAndIncrement();
newNameMap.put(graphQLScalarType, newName);
return CONTINUE;
}
@Override
public TraversalControl visitGraphQLUnionType(GraphQLUnionType graphQLUnionType, TraverserContext<GraphQLSchemaElement> context) {
if (Introspection.isIntrospectionTypes(graphQLUnionType)) {
return TraversalControl.ABORT;
}
String newName = "Union" + unionCounter.getAndIncrement();
newNameMap.put(graphQLUnionType, newName);
return CONTINUE;
}
};
SchemaTransformer.transformSchema(schema, visitor);
return newNameMap;
}
use of graphql.util.TraversalControl.CONTINUE 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