Skip to content

Commit 2c62fdc

Browse files
committed
Upgrade to GraphQL Java 15.0 and fix tests
wip x
1 parent 1c381c5 commit 2c62fdc

File tree

9 files changed

+237
-219
lines changed

9 files changed

+237
-219
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<kotlin.version>1.3.70</kotlin.version>
2020
<kotlin-coroutines.version>1.2.1</kotlin-coroutines.version>
2121
<jackson.version>2.10.3</jackson.version>
22-
<graphql-java.version>14.0</graphql-java.version>
22+
<graphql-java.version>15.0</graphql-java.version>
2323

2424
<maven.compiler.source>${java.version}</maven.compiler.source>
2525
<maven.compiler.target>${java.version}</maven.compiler.target>

src/main/kotlin/graphql/kickstart/tools/ScannedSchemaObjects.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package graphql.kickstart.tools
33
import graphql.kickstart.tools.resolver.FieldResolver
44
import graphql.kickstart.tools.util.BiMap
55
import graphql.kickstart.tools.util.JavaType
6+
import graphql.language.DirectiveDefinition
67
import graphql.language.FieldDefinition
78
import graphql.language.ObjectTypeDefinition
89
import graphql.language.TypeDefinition

src/main/kotlin/graphql/kickstart/tools/SchemaClassScanner.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ internal class SchemaClassScanner(
3838

3939
private val definitionsByName = (allDefinitions.filterIsInstance<TypeDefinition<*>>() - extensionDefinitions - inputExtensionDefinitions).associateBy { it.name }
4040
private val objectDefinitions = (allDefinitions.filterIsInstance<ObjectTypeDefinition>() - extensionDefinitions)
41+
private val directiveDefinitions = allDefinitions.filterIsInstance<DirectiveDefinition>().toSet()
4142
private val objectDefinitionsByName = objectDefinitions.associateBy { it.name }
4243
private val interfaceDefinitionsByName = allDefinitions.filterIsInstance<InterfaceTypeDefinition>().associateBy { it.name }
4344

@@ -147,7 +148,7 @@ internal class SchemaClassScanner(
147148
val scalars = scalarDefinitions
148149
.filter {
149150
// Filter for any defined scalars OR scalars that aren't defined but also aren't standard
150-
scalars.containsKey(it.name) || !ScalarInfo.STANDARD_SCALAR_DEFINITIONS.containsKey(it.name)
151+
scalars.containsKey(it.name) || !ScalarInfo.GRAPHQL_SPECIFICATION_SCALARS_DEFINITIONS.containsKey(it.name)
151152
}.map { definition ->
152153
val provided = scalars[definition.name]
153154
?: throw SchemaClassScannerError("Expected a user-defined GraphQL scalar type with name '${definition.name}' but found none!")
@@ -322,7 +323,7 @@ internal class SchemaClassScanner(
322323
is InputObjectTypeDefinition -> {
323324
graphQLType.inputValueDefinitions.forEach { inputValueDefinition ->
324325
val inputGraphQLType = inputValueDefinition.type.unwrap()
325-
if (inputGraphQLType is TypeName && !ScalarInfo.STANDARD_SCALAR_DEFINITIONS.containsKey(inputGraphQLType.name)) {
326+
if (inputGraphQLType is TypeName && !ScalarInfo.GRAPHQL_SPECIFICATION_SCALARS_DEFINITIONS.containsKey(inputGraphQLType.name)) {
326327
val inputValueJavaType = findInputValueType(inputValueDefinition.name, inputGraphQLType, javaType.unwrap())
327328
if (inputValueJavaType != null) {
328329
handleFoundType(typeClassMatcher.match(TypeClassMatcher.PotentialMatch.parameterType(

src/main/kotlin/graphql/kickstart/tools/SchemaParser.kt

Lines changed: 68 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package graphql.kickstart.tools
22

3+
import graphql.Scalars
34
import graphql.introspection.Introspection
45
import graphql.kickstart.tools.directive.SchemaGeneratorDirectiveHelper
56
import graphql.kickstart.tools.util.getExtendedFieldDefinitions
@@ -11,7 +12,6 @@ import graphql.schema.idl.ScalarInfo
1112
import graphql.schema.idl.SchemaGeneratorHelper
1213
import graphql.schema.visibility.NoIntrospectionGraphqlFieldVisibility
1314
import org.slf4j.LoggerFactory
14-
import java.util.*
1515
import kotlin.reflect.KClass
1616

1717
/**
@@ -129,7 +129,7 @@ class SchemaParser internal constructor(
129129
.definition(objectDefinition)
130130
.description(if (objectDefinition.description != null) objectDefinition.description.content else getDocumentation(objectDefinition))
131131

132-
builder.withDirectives(*buildDirectives(objectDefinition.directives, setOf(), Introspection.DirectiveLocation.OBJECT))
132+
builder.withDirectives(*buildDirectives(objectDefinition.directives, Introspection.DirectiveLocation.OBJECT))
133133

134134
objectDefinition.implements.forEach { implementsDefinition ->
135135
val interfaceName = (implementsDefinition as TypeName).name
@@ -160,19 +160,6 @@ class SchemaParser internal constructor(
160160
return schemaGeneratorDirectiveHelper.onObject(objectType, directiveHelperParameters)
161161
}
162162

163-
private fun buildDirectives(directives: List<Directive>, directiveDefinitions: Set<GraphQLDirective>, directiveLocation: Introspection.DirectiveLocation): Array<GraphQLDirective> {
164-
val names = HashSet<String>()
165-
166-
val output = ArrayList<GraphQLDirective>()
167-
for (directive in directives) {
168-
if (!names.contains(directive.name)) {
169-
names.add(directive.name)
170-
output.add(schemaGeneratorHelper.buildDirective(directive, directiveDefinitions, directiveLocation, runtimeWiring.comparatorRegistry))
171-
}
172-
}
173-
return output.toTypedArray()
174-
}
175-
176163
private fun createInputObject(definition: InputObjectTypeDefinition, inputObjects: List<GraphQLInputObjectType>): GraphQLInputObjectType {
177164
val extensionDefinitions = inputExtensionDefinitions.filter { it.name == definition.name }
178165

@@ -182,17 +169,17 @@ class SchemaParser internal constructor(
182169
.extensionDefinitions(extensionDefinitions)
183170
.description(if (definition.description != null) definition.description.content else getDocumentation(definition))
184171

185-
builder.withDirectives(*buildDirectives(definition.directives, setOf(), Introspection.DirectiveLocation.INPUT_OBJECT))
172+
builder.withDirectives(*buildDirectives(definition.directives, Introspection.DirectiveLocation.INPUT_OBJECT))
186173

187174
(extensionDefinitions + definition).forEach {
188175
it.inputValueDefinitions.forEach { inputDefinition ->
189176
val fieldBuilder = GraphQLInputObjectField.newInputObjectField()
190-
.name(inputDefinition.name)
191-
.definition(inputDefinition)
192-
.description(if (inputDefinition.description != null) inputDefinition.description.content else getDocumentation(inputDefinition))
193-
.defaultValue(buildDefaultValue(inputDefinition.defaultValue))
194-
.type(determineInputType(inputDefinition.type, inputObjects))
195-
.withDirectives(*buildDirectives(inputDefinition.directives, setOf(), Introspection.DirectiveLocation.INPUT_FIELD_DEFINITION))
177+
.name(inputDefinition.name)
178+
.definition(inputDefinition)
179+
.description(if (inputDefinition.description != null) inputDefinition.description.content else getDocumentation(inputDefinition))
180+
.defaultValue(buildDefaultValue(inputDefinition.defaultValue))
181+
.type(determineInputType(inputDefinition.type, inputObjects))
182+
.withDirectives(*buildDirectives(inputDefinition.directives, Introspection.DirectiveLocation.INPUT_FIELD_DEFINITION))
196183
builder.field(fieldBuilder.build())
197184
}
198185
}
@@ -211,14 +198,14 @@ class SchemaParser internal constructor(
211198
.definition(definition)
212199
.description(if (definition.description != null) definition.description.content else getDocumentation(definition))
213200

214-
builder.withDirectives(*buildDirectives(definition.directives, setOf(), Introspection.DirectiveLocation.ENUM))
201+
builder.withDirectives(*buildDirectives(definition.directives, Introspection.DirectiveLocation.ENUM))
215202

216203
definition.enumValueDefinitions.forEach { enumDefinition ->
217204
val enumName = enumDefinition.name
218205
val enumValue = type.unwrap().enumConstants.find { (it as Enum<*>).name == enumName }
219206
?: throw SchemaError("Expected value for name '$enumName' in enum '${type.unwrap().simpleName}' but found none!")
220207

221-
val enumValueDirectives = buildDirectives(enumDefinition.directives, setOf(), Introspection.DirectiveLocation.ENUM_VALUE)
208+
val enumValueDirectives = buildDirectives(enumDefinition.directives, Introspection.DirectiveLocation.ENUM_VALUE)
222209
getDeprecated(enumDefinition.directives).let {
223210
val enumValueDefinition = GraphQLEnumValueDefinition.newEnumValueDefinition()
224211
.name(enumName)
@@ -243,7 +230,7 @@ class SchemaParser internal constructor(
243230
.definition(interfaceDefinition)
244231
.description(if (interfaceDefinition.description != null) interfaceDefinition.description.content else getDocumentation(interfaceDefinition))
245232

246-
builder.withDirectives(*buildDirectives(interfaceDefinition.directives, setOf(), Introspection.DirectiveLocation.INTERFACE))
233+
builder.withDirectives(*buildDirectives(interfaceDefinition.directives, Introspection.DirectiveLocation.INTERFACE))
247234

248235
interfaceDefinition.fieldDefinitions.forEach { fieldDefinition ->
249236
builder.field { field -> createField(field, fieldDefinition, inputObjects) }
@@ -259,7 +246,7 @@ class SchemaParser internal constructor(
259246
.definition(definition)
260247
.description(if (definition.description != null) definition.description.content else getDocumentation(definition))
261248

262-
builder.withDirectives(*buildDirectives(definition.directives, setOf(), Introspection.DirectiveLocation.UNION))
249+
builder.withDirectives(*buildDirectives(definition.directives, Introspection.DirectiveLocation.UNION))
263250

264251
getLeafUnionObjects(definition, types).forEach { builder.possibleType(it) }
265252
return schemaGeneratorDirectiveHelper.onUnion(builder.build(), schemaDirectiveParameters)
@@ -286,25 +273,71 @@ class SchemaParser internal constructor(
286273
}
287274

288275
private fun createField(field: GraphQLFieldDefinition.Builder, fieldDefinition: FieldDefinition, inputObjects: List<GraphQLInputObjectType>): GraphQLFieldDefinition.Builder {
289-
field.name(fieldDefinition.name)
290-
field.description(if (fieldDefinition.description != null) fieldDefinition.description.content else getDocumentation(fieldDefinition))
291-
field.definition(fieldDefinition)
292-
getDeprecated(fieldDefinition.directives)?.let { field.deprecate(it) }
293-
field.type(determineOutputType(fieldDefinition.type, inputObjects))
276+
field
277+
.name(fieldDefinition.name)
278+
.description(fieldDefinition.description?.content ?: getDocumentation(fieldDefinition))
279+
.definition(fieldDefinition)
280+
.apply { getDeprecated(fieldDefinition.directives)?.let { deprecate(it) } }
281+
.type(determineOutputType(fieldDefinition.type, inputObjects))
282+
294283
fieldDefinition.inputValueDefinitions.forEach { argumentDefinition ->
295284
val argumentBuilder = GraphQLArgument.newArgument()
296285
.name(argumentDefinition.name)
297286
.definition(argumentDefinition)
298287
.description(if (argumentDefinition.description != null) argumentDefinition.description.content else getDocumentation(argumentDefinition))
299-
.defaultValue(buildDefaultValue(argumentDefinition.defaultValue))
300288
.type(determineInputType(argumentDefinition.type, inputObjects))
301-
.withDirectives(*buildDirectives(argumentDefinition.directives, setOf(), Introspection.DirectiveLocation.ARGUMENT_DEFINITION))
289+
.apply { buildDefaultValue(argumentDefinition.defaultValue)?.let { defaultValue(it) } }
290+
.withDirectives(*buildDirectives(argumentDefinition.directives, Introspection.DirectiveLocation.ARGUMENT_DEFINITION))
291+
302292
field.argument(argumentBuilder.build())
303293
}
304-
field.withDirectives(*buildDirectives(fieldDefinition.directives, setOf(), Introspection.DirectiveLocation.FIELD_DEFINITION))
294+
field.withDirectives(*buildDirectives(fieldDefinition.directives, Introspection.DirectiveLocation.FIELD_DEFINITION))
295+
305296
return field
306297
}
307298

299+
private fun buildDirectives(directives: List<Directive>, directiveLocation: Introspection.DirectiveLocation): Array<GraphQLDirective> {
300+
val names = mutableSetOf<String>()
301+
302+
val output = mutableListOf<GraphQLDirective>()
303+
for (directive in directives) {
304+
if (!names.contains(directive.name)) {
305+
names.add(directive.name)
306+
val graphQLDirective = GraphQLDirective.newDirective()
307+
.name(directive.name)
308+
.apply {
309+
// TODO or enforce directive to be declared instead of inferring the type
310+
directive.arguments.forEach { arg ->
311+
argument(GraphQLArgument.newArgument()
312+
.name(arg.name)
313+
.type(buildDirectiveInputType(arg.value))
314+
.build())
315+
}
316+
}
317+
.build()
318+
319+
320+
output.add(schemaGeneratorHelper.buildDirective(directive, setOf(graphQLDirective), directiveLocation, runtimeWiring.comparatorRegistry))
321+
}
322+
}
323+
324+
return output.toTypedArray()
325+
}
326+
327+
private fun buildDirectiveInputType(value: Value<*>): GraphQLInputType? {
328+
when (value) {
329+
is NullValue -> return Scalars.GraphQLString
330+
is FloatValue -> return Scalars.GraphQLFloat
331+
is StringValue -> return Scalars.GraphQLString
332+
is IntValue -> return Scalars.GraphQLInt
333+
is BooleanValue -> return Scalars.GraphQLBoolean
334+
is ArrayValue -> {
335+
TODO()
336+
}
337+
else -> throw SchemaError("Directive values of type '${value::class.simpleName}' are not supported yet.")
338+
}
339+
}
340+
308341
private fun buildDefaultValue(value: Value<*>?): Any? {
309342
return when (value) {
310343
null -> null
@@ -406,4 +439,4 @@ class SchemaParser internal constructor(
406439

407440
class SchemaError(message: String, cause: Throwable? = null) : RuntimeException(message, cause)
408441

409-
val graphQLScalars = ScalarInfo.STANDARD_SCALARS.associateBy { it.name }
442+
val graphQLScalars = ScalarInfo.GRAPHQL_SPECIFICATION_SCALARS.associateBy { it.name }

src/main/kotlin/graphql/kickstart/tools/TypeClassMatcher.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ internal class TypeClassMatcher(private val definitionsByName: Map<String, TypeD
8080
}
8181

8282
is TypeName -> {
83-
val typeDefinition = ScalarInfo.STANDARD_SCALAR_DEFINITIONS[graphQLType.name]
83+
val typeDefinition = ScalarInfo.GRAPHQL_SPECIFICATION_SCALARS_DEFINITIONS[graphQLType.name]
8484
?: definitionsByName[graphQLType.name]
8585
?: throw error(potentialMatch, "No ${TypeDefinition::class.java.simpleName} for type name ${graphQLType.name}")
8686
if (typeDefinition is ScalarTypeDefinition) {

src/main/kotlin/graphql/kickstart/tools/directive/SchemaDirectiveWiringEnvironmentImpl.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
/*
1818
* DO NOT EDIT THIS FILE!
1919
*
20-
* File copied from com.graphql-java.graphql-java:14.0 without changes.
20+
* File copied from com.graphql-java.graphql-java:15.0 without any changes.
2121
*/
2222
@Internal
2323
public class SchemaDirectiveWiringEnvironmentImpl<T extends GraphQLDirectiveContainer> implements SchemaDirectiveWiringEnvironment<T> {
@@ -113,15 +113,15 @@ public GraphQLFieldDefinition getFieldDefinition() {
113113

114114
@Override
115115
public DataFetcher getFieldDataFetcher() {
116-
assertNotNull(fieldDefinition, "An output field must be in context to call this method");
117-
assertNotNull(fieldsContainer, "An output field container must be in context to call this method");
116+
assertNotNull(fieldDefinition, () -> "An output field must be in context to call this method");
117+
assertNotNull(fieldsContainer, () -> "An output field container must be in context to call this method");
118118
return codeRegistry.getDataFetcher(fieldsContainer, fieldDefinition);
119119
}
120120

121121
@Override
122122
public GraphQLFieldDefinition setFieldDataFetcher(DataFetcher newDataFetcher) {
123-
assertNotNull(fieldDefinition, "An output field must be in context to call this method");
124-
assertNotNull(fieldsContainer, "An output field container must be in context to call this method");
123+
assertNotNull(fieldDefinition, () -> "An output field must be in context to call this method");
124+
assertNotNull(fieldsContainer, () -> "An output field container must be in context to call this method");
125125

126126
FieldCoordinates coordinates = FieldCoordinates.coordinates(fieldsContainer, fieldDefinition);
127127
codeRegistry.dataFetcher(coordinates, newDataFetcher);

0 commit comments

Comments
 (0)