use of graphql.schema.GraphQLImplementingType in project graphql-java by graphql-java.
the class SchemaUtil method groupImplementationsForInterfacesAndObjects.
public Map<String, List<GraphQLImplementingType>> groupImplementationsForInterfacesAndObjects(GraphQLSchema schema) {
Map<String, List<GraphQLImplementingType>> result = new LinkedHashMap<>();
for (GraphQLType type : schema.getAllTypesAsList()) {
if (type instanceof GraphQLImplementingType) {
List<GraphQLNamedOutputType> interfaces = ((GraphQLImplementingType) type).getInterfaces();
for (GraphQLNamedOutputType interfaceType : interfaces) {
List<GraphQLImplementingType> myGroup = result.computeIfAbsent(interfaceType.getName(), k -> new ArrayList<>());
myGroup.add((GraphQLImplementingType) type);
}
}
}
return ImmutableMap.copyOf(new TreeMap<>(result));
}
use of graphql.schema.GraphQLImplementingType in project graphql-java by graphql-java.
the class Anonymizer method getSameFieldsImpl.
private static void getSameFieldsImpl(String fieldName, String curObjectOrInterface, Map<String, List<GraphQLImplementingType>> interfaceToImplementations, GraphQLSchema schema, Set<String> alreadyChecked, Set<GraphQLFieldDefinition> result) {
if (alreadyChecked.contains(curObjectOrInterface)) {
return;
}
alreadyChecked.add(curObjectOrInterface);
// "up": get all Interfaces
GraphQLImplementingType type = (GraphQLImplementingType) schema.getType(curObjectOrInterface);
List<GraphQLNamedOutputType> interfaces = type.getInterfaces();
getMatchingFieldDefinitions(fieldName, interfaces, result);
for (GraphQLNamedOutputType interfaze : interfaces) {
getSameFieldsImpl(fieldName, interfaze.getName(), interfaceToImplementations, schema, alreadyChecked, result);
}
// "down": get all Object or Interfaces
List<GraphQLImplementingType> implementations = interfaceToImplementations.get(curObjectOrInterface);
if (implementations == null) {
return;
}
getMatchingFieldDefinitions(fieldName, implementations, result);
for (GraphQLImplementingType implementingType : implementations) {
getSameFieldsImpl(fieldName, implementingType.getName(), interfaceToImplementations, schema, alreadyChecked, result);
}
}
use of graphql.schema.GraphQLImplementingType in project graphql-java by graphql-java.
the class TypesImplementInterfaces method checkFieldArgumentEquivalence.
private void checkFieldArgumentEquivalence(GraphQLImplementingType implementingType, GraphQLInterfaceType interfaceType, SchemaValidationErrorCollector validationErrorCollector, GraphQLFieldDefinition interfaceFieldDef, GraphQLFieldDefinition objectFieldDef) {
List<GraphQLArgument> interfaceArgs = interfaceFieldDef.getArguments();
List<GraphQLArgument> objectArgs = objectFieldDef.getArguments();
Map<String, GraphQLArgument> interfaceArgsByName = FpKit.getByName(interfaceArgs, GraphQLArgument::getName);
List<String> objectArgsNames = map(objectArgs, GraphQLArgument::getName);
if (!objectArgsNames.containsAll(interfaceArgsByName.keySet())) {
final String missingArgsNames = interfaceArgsByName.keySet().stream().filter(name -> !objectArgsNames.contains(name)).collect(Collectors.joining(", "));
validationErrorCollector.addError(error(format("%s type '%s' does not implement interface '%s' because field '%s' is missing argument(s): '%s'", TYPE_OF_MAP.get(implementingType.getClass()), implementingType.getName(), interfaceType.getName(), interfaceFieldDef.getName(), missingArgsNames)));
} else {
objectArgs.forEach(objectArg -> {
GraphQLArgument interfaceArg = interfaceArgsByName.get(objectArg.getName());
if (interfaceArg == null) {
if (objectArg.getType() instanceof GraphQLNonNull) {
validationErrorCollector.addError(error(format("%s type '%s' field '%s' defines an additional non-optional argument '%s' which is not allowed because field is also defined in interface '%s'", TYPE_OF_MAP.get(implementingType.getClass()), implementingType.getName(), objectFieldDef.getName(), objectArg.getName(), interfaceType.getName())));
}
} else {
String interfaceArgStr = makeArgStr(objectArg);
String objectArgStr = makeArgStr(interfaceArg);
boolean same = true;
if (!interfaceArgStr.equals(objectArgStr)) {
same = false;
}
if (objectArg.hasSetDefaultValue() && interfaceArg.hasSetDefaultValue()) {
Value<?> objectDefaultValue = ValuesResolver.valueToLiteral(objectArg.getArgumentDefaultValue(), objectArg.getType());
Value<?> interfaceDefaultValue = ValuesResolver.valueToLiteral(interfaceArg.getArgumentDefaultValue(), interfaceArg.getType());
if (!Objects.equals(printAst(objectDefaultValue), printAst(interfaceDefaultValue))) {
same = false;
}
} else if (objectArg.hasSetDefaultValue() || interfaceArg.hasSetDefaultValue()) {
same = false;
}
if (!same) {
validationErrorCollector.addError(error(format("%s type '%s' does not implement interface '%s' because field '%s' argument '%s' is defined differently", TYPE_OF_MAP.get(implementingType.getClass()), implementingType.getName(), interfaceType.getName(), interfaceFieldDef.getName(), objectArg.getName())));
}
}
});
}
}
use of graphql.schema.GraphQLImplementingType 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;
}
Aggregations