use of graphql.language.Type in project graphql-java by graphql-java.
the class SchemaTypeExtensionsChecker method checkInterfaceTypeExtensions.
/*
* Interface type extensions have the potential to be invalid if incorrectly defined.
*
* The named type must already be defined and must be an Interface type.
* The fields of an Interface type extension must have unique names; no two fields may share the same name.
* Any fields of an Interface type extension must not be already defined on the original Interface type.
* Any Object type which implemented the original Interface type must also be a super-set of the fields of the Interface type extension (which may be due to Object type extension).
* Any directives provided must not already apply to the original Interface type.
*/
private void checkInterfaceTypeExtensions(List<GraphQLError> errors, TypeDefinitionRegistry typeRegistry) {
typeRegistry.interfaceTypeExtensions().forEach((name, extensions) -> {
checkTypeExtensionHasCorrespondingType(errors, typeRegistry, name, extensions, InterfaceTypeDefinition.class);
checkTypeExtensionDirectiveRedefinition(errors, typeRegistry, name, extensions, InterfaceTypeDefinition.class);
extensions.forEach(extension -> {
List<FieldDefinition> fieldDefinitions = extension.getFieldDefinitions();
// field unique ness
checkNamedUniqueness(errors, extension.getFieldDefinitions(), FieldDefinition::getName, (namedField, fieldDef) -> new NonUniqueNameError(extension, fieldDef));
// field arg unique ness
extension.getFieldDefinitions().forEach(fld -> checkNamedUniqueness(errors, fld.getInputValueDefinitions(), InputValueDefinition::getName, (namedField, inputValueDefinition) -> new NonUniqueArgumentError(extension, fld, name)));
// directive checks
extension.getFieldDefinitions().forEach(fld -> checkNamedUniqueness(errors, fld.getDirectives(), Directive::getName, (directiveName, directive) -> new NonUniqueDirectiveError(extension, fld, directiveName)));
fieldDefinitions.forEach(fld -> fld.getDirectives().forEach(directive -> {
checkDeprecatedDirective(errors, directive, () -> new InvalidDeprecationDirectiveError(extension, fld));
checkNamedUniqueness(errors, directive.getArguments(), Argument::getName, (argumentName, argument) -> new NonUniqueArgumentError(extension, fld, argumentName));
}));
//
// fields must be unique within a type extension
forEachBut(extension, extensions, otherTypeExt -> checkForFieldRedefinition(errors, otherTypeExt, otherTypeExt.getFieldDefinitions(), fieldDefinitions));
//
// then check for field re-defs from the base type
Optional<InterfaceTypeDefinition> baseTypeOpt = typeRegistry.getType(extension.getName(), InterfaceTypeDefinition.class);
baseTypeOpt.ifPresent(baseTypeDef -> checkForFieldRedefinition(errors, extension, fieldDefinitions, baseTypeDef.getFieldDefinitions()));
});
});
}
use of graphql.language.Type in project graphql-java by graphql-java.
the class TypeDefinitionRegistry method isPossibleType.
/**
* Returns true of the abstract type is in implemented by the object type
*
* @param abstractType the abstract type to check (interface or union)
* @param possibleObjectType the object type to check
*
* @return true if the object type implements the abstract type
*/
@SuppressWarnings("ConstantConditions")
public boolean isPossibleType(Type abstractType, Type possibleObjectType) {
if (!isInterfaceOrUnion(abstractType)) {
return false;
}
if (!isObjectType(possibleObjectType)) {
return false;
}
ObjectTypeDefinition targetObjectTypeDef = getType(possibleObjectType, ObjectTypeDefinition.class).get();
TypeDefinition abstractTypeDef = getType(abstractType).get();
if (abstractTypeDef instanceof UnionTypeDefinition) {
List<Type> memberTypes = ((UnionTypeDefinition) abstractTypeDef).getMemberTypes();
for (Type memberType : memberTypes) {
Optional<ObjectTypeDefinition> checkType = getType(memberType, ObjectTypeDefinition.class);
if (checkType.isPresent()) {
if (checkType.get().getName().equals(targetObjectTypeDef.getName())) {
return true;
}
}
}
return false;
} else {
InterfaceTypeDefinition iFace = (InterfaceTypeDefinition) abstractTypeDef;
List<ObjectTypeDefinition> objectTypeDefinitions = getImplementationsOf(iFace);
return objectTypeDefinitions.stream().anyMatch(od -> od.getName().equals(targetObjectTypeDef.getName()));
}
}
use of graphql.language.Type in project graphql-java by graphql-java.
the class SchemaGenerator method makeExecutableSchemaImpl.
private GraphQLSchema makeExecutableSchemaImpl(BuildContext buildCtx) {
GraphQLObjectType query;
GraphQLObjectType mutation;
GraphQLObjectType subscription;
GraphQLSchema.Builder schemaBuilder = GraphQLSchema.newSchema();
//
// Schema can be missing if the type is called 'Query'. Pre flight checks have checked that!
//
TypeDefinitionRegistry typeRegistry = buildCtx.getTypeRegistry();
if (!typeRegistry.schemaDefinition().isPresent()) {
@SuppressWarnings({ "OptionalGetWithoutIsPresent", "ConstantConditions" }) TypeDefinition queryTypeDef = typeRegistry.getType("Query").get();
query = buildOutputType(buildCtx, new TypeName(queryTypeDef.getName()));
schemaBuilder.query(query);
Optional<TypeDefinition> mutationTypeDef = typeRegistry.getType("Mutation");
if (mutationTypeDef.isPresent()) {
mutation = buildOutputType(buildCtx, new TypeName(mutationTypeDef.get().getName()));
schemaBuilder.mutation(mutation);
}
Optional<TypeDefinition> subscriptionTypeDef = typeRegistry.getType("Subscription");
if (subscriptionTypeDef.isPresent()) {
subscription = buildOutputType(buildCtx, new TypeName(subscriptionTypeDef.get().getName()));
schemaBuilder.subscription(subscription);
}
} else {
SchemaDefinition schemaDefinition = typeRegistry.schemaDefinition().get();
List<OperationTypeDefinition> operationTypes = schemaDefinition.getOperationTypeDefinitions();
// pre-flight checked via checker
@SuppressWarnings({ "OptionalGetWithoutIsPresent", "ConstantConditions" }) OperationTypeDefinition queryOp = operationTypes.stream().filter(op -> "query".equals(op.getName())).findFirst().get();
Optional<OperationTypeDefinition> mutationOp = operationTypes.stream().filter(op -> "mutation".equals(op.getName())).findFirst();
Optional<OperationTypeDefinition> subscriptionOp = operationTypes.stream().filter(op -> "subscription".equals(op.getName())).findFirst();
query = buildOperation(buildCtx, queryOp);
schemaBuilder.query(query);
if (mutationOp.isPresent()) {
mutation = buildOperation(buildCtx, mutationOp.get());
schemaBuilder.mutation(mutation);
}
if (subscriptionOp.isPresent()) {
subscription = buildOperation(buildCtx, subscriptionOp.get());
schemaBuilder.subscription(subscription);
}
}
Set<GraphQLType> additionalTypes = buildAdditionalTypes(buildCtx);
schemaBuilder.fieldVisibility(buildCtx.getWiring().getFieldVisibility());
return schemaBuilder.build(additionalTypes);
}
use of graphql.language.Type in project graphql-java by graphql-java.
the class SchemaDiff method checkOperation.
private void checkOperation(DiffCtx ctx, String opName, Optional<SchemaDefinition> oldSchemaDef, Optional<SchemaDefinition> newSchemaDef) {
// if schema declaration is missing then it is assumed to contain Query / Mutation / Subscription
Optional<OperationTypeDefinition> oldOpTypeDef;
oldOpTypeDef = oldSchemaDef.map(schemaDefinition -> getOpDef(opName, schemaDefinition)).orElseGet(() -> synthOperationTypeDefinition(type -> ctx.getOldTypeDef(type, ObjectTypeDefinition.class), opName));
Optional<OperationTypeDefinition> newOpTypeDef;
newOpTypeDef = newSchemaDef.map(schemaDefinition -> getOpDef(opName, schemaDefinition)).orElseGet(() -> synthOperationTypeDefinition(type -> ctx.getNewTypeDef(type, ObjectTypeDefinition.class), opName));
// must be new
if (!oldOpTypeDef.isPresent()) {
return;
}
ctx.report(DiffEvent.apiInfo().typeName(capitalize(opName)).typeKind(TypeKind.Operation).components(opName).reasonMsg("Examining operation '%s' ...", capitalize(opName)).build());
if (oldOpTypeDef.isPresent() && !newOpTypeDef.isPresent()) {
ctx.report(DiffEvent.apiBreakage().category(DiffCategory.MISSING).typeName(capitalize(opName)).typeKind(TypeKind.Operation).components(opName).reasonMsg("The new API no longer has the operation '%s'", opName).build());
return;
}
OperationTypeDefinition oldOpTypeDefinition = oldOpTypeDef.get();
OperationTypeDefinition newOpTypeDefinition = newOpTypeDef.get();
Type oldType = oldOpTypeDefinition.getType();
//
// if we have no old op, then it must have been added (which is ok)
Optional<TypeDefinition> oldTD = ctx.getOldTypeDef(oldType, TypeDefinition.class);
if (!oldTD.isPresent()) {
return;
}
checkType(ctx, oldType, newOpTypeDefinition.getType());
}
use of graphql.language.Type in project graphql-java by graphql-java.
the class SchemaTypeExtensionsChecker method checkInputObjectTypeExtensions.
/*
* Input object type extensions have the potential to be invalid if incorrectly defined.
*
* The named type must already be defined and must be a Input Object type.
* All fields of an Input Object type extension must have unique names.
* All fields of an Input Object type extension must not already be a field of the original Input Object.
* Any directives provided must not already apply to the original Input Object type.
*/
private void checkInputObjectTypeExtensions(List<GraphQLError> errors, TypeDefinitionRegistry typeRegistry) {
typeRegistry.inputObjectTypeExtensions().forEach((name, extensions) -> {
checkTypeExtensionHasCorrespondingType(errors, typeRegistry, name, extensions, InputObjectTypeDefinition.class);
checkTypeExtensionDirectiveRedefinition(errors, typeRegistry, name, extensions, InputObjectTypeDefinition.class);
// field redefinitions
extensions.forEach(extension -> {
List<InputValueDefinition> inputValueDefinitions = extension.getInputValueDefinitions();
// field unique ness
checkNamedUniqueness(errors, inputValueDefinitions, InputValueDefinition::getName, (namedField, fieldDef) -> new NonUniqueNameError(extension, fieldDef));
// directive checks
inputValueDefinitions.forEach(fld -> checkNamedUniqueness(errors, fld.getDirectives(), Directive::getName, (directiveName, directive) -> new NonUniqueDirectiveError(extension, fld, directiveName)));
inputValueDefinitions.forEach(fld -> fld.getDirectives().forEach(directive -> {
checkDeprecatedDirective(errors, directive, () -> new InvalidDeprecationDirectiveError(extension, fld));
checkNamedUniqueness(errors, directive.getArguments(), Argument::getName, (argumentName, argument) -> new NonUniqueArgumentError(extension, fld, argumentName));
}));
//
// fields must be unique within a type extension
forEachBut(extension, extensions, otherTypeExt -> checkForInputValueRedefinition(errors, otherTypeExt, otherTypeExt.getInputValueDefinitions(), inputValueDefinitions));
//
// then check for field re-defs from the base type
Optional<InputObjectTypeDefinition> baseTypeOpt = typeRegistry.getType(extension.getName(), InputObjectTypeDefinition.class);
baseTypeOpt.ifPresent(baseTypeDef -> checkForInputValueRedefinition(errors, extension, inputValueDefinitions, baseTypeDef.getInputValueDefinitions()));
});
});
}
Aggregations