@@ -23,7 +23,9 @@ import graphql.language.TypeDefinition
2323import graphql.language.TypeName
2424import graphql.language.UnionTypeDefinition
2525import graphql.language.Value
26+ import graphql.schema.FieldCoordinates
2627import graphql.schema.GraphQLArgument
28+ import graphql.schema.GraphQLCodeRegistry
2729import graphql.schema.GraphQLDirective
2830import graphql.schema.GraphQLEnumType
2931import graphql.schema.GraphQLEnumValueDefinition
@@ -40,15 +42,12 @@ import graphql.schema.GraphQLSchema
4042import graphql.schema.GraphQLType
4143import graphql.schema.GraphQLTypeReference
4244import graphql.schema.GraphQLUnionType
43- import graphql.schema.TypeResolverProxy
4445import graphql.schema.idl.DirectiveBehavior
4546import graphql.schema.idl.RuntimeWiring
4647import graphql.schema.idl.ScalarInfo
4748import graphql.schema.idl.SchemaGeneratorHelper
4849import java.util.*
4950import kotlin.reflect.KClass
50- import kotlin.reflect.full.memberProperties
51- import kotlin.reflect.jvm.isAccessible
5251
5352/* *
5453 * Parses a GraphQL Schema and maps object fields to provided class methods.
@@ -95,6 +94,8 @@ class SchemaParser internal constructor(scanResult: ScannedSchemaObjects, privat
9594 private val schemaGeneratorHelper = SchemaGeneratorHelper ()
9695 private val directiveGenerator = DirectiveBehavior ()
9796
97+ private val codeRegistryBuilder = GraphQLCodeRegistry .newCodeRegistry()
98+
9899 /* *
99100 * Parses the given schema with respect to the given dictionary and returns GraphQL objects.
100101 */
@@ -107,16 +108,9 @@ class SchemaParser internal constructor(scanResult: ScannedSchemaObjects, privat
107108 val inputObjects = inputObjectDefinitions.map { createInputObject(it) }
108109 val enums = enumDefinitions.map { createEnumObject(it) }
109110
110- // Unfortunately, since graphql-java 12, the getTypeResolver method has been made package-protected,
111- // so we need reflection to access the 'typeResolver' field on GraphQLInterfaceType and GraphQLUnionType
112- val interfaceTypeResolverField = GraphQLInterfaceType ::class .memberProperties.find { it.name == " typeResolver" }
113- interfaceTypeResolverField!! .isAccessible = true
114- val unionTypeResolverField = GraphQLUnionType ::class .memberProperties.find { it.name == " typeResolver" }
115- unionTypeResolverField!! .isAccessible = true
116-
117111 // Assign type resolver to interfaces now that we know all of the object types
118- interfaces.forEach { (interfaceTypeResolverField.get (it) as TypeResolverProxy ).typeResolver = InterfaceTypeResolver (dictionary.inverse(), it, objects) }
119- unions.forEach { (unionTypeResolverField.get (it) as TypeResolverProxy ).typeResolver = UnionTypeResolver (dictionary.inverse(), it, objects) }
112+ interfaces.forEach { codeRegistryBuilder.typeResolver (it, InterfaceTypeResolver (dictionary.inverse(), it, objects) ) }
113+ unions.forEach { codeRegistryBuilder.typeResolver (it, UnionTypeResolver (dictionary.inverse(), it, objects) ) }
120114
121115 // Find query type and mutation/subscription type (if mutation/subscription type exists)
122116 val queryName = rootInfo.getQueryName()
@@ -130,7 +124,7 @@ class SchemaParser internal constructor(scanResult: ScannedSchemaObjects, privat
130124 val subscription = objects.find { it.name == subscriptionName }
131125 ? : if (rootInfo.isSubscriptionRequired()) throw SchemaError (" Expected a Subscription object with name '$subscriptionName ' but found none!" ) else null
132126
133- return SchemaObjects (query, mutation, subscription, (objects + inputObjects + enums + interfaces + unions).toSet())
127+ return SchemaObjects (query, mutation, subscription, (objects + inputObjects + enums + interfaces + unions).toSet(), codeRegistryBuilder )
134128 }
135129
136130 /* *
@@ -141,29 +135,33 @@ class SchemaParser internal constructor(scanResult: ScannedSchemaObjects, privat
141135 /* *
142136 * Returns any unused type definitions that were found in the schema
143137 */
138+ @Suppress(" unused" )
144139 fun getUnusedDefinitions (): Set <TypeDefinition <* >> = unusedDefinitions
145140
146- private fun createObject (definition : ObjectTypeDefinition , interfaces : List <GraphQLInterfaceType >): GraphQLObjectType {
147- val name = definition .name
141+ private fun createObject (objectDefinition : ObjectTypeDefinition , interfaces : List <GraphQLInterfaceType >): GraphQLObjectType {
142+ val name = objectDefinition .name
148143 val builder = GraphQLObjectType .newObject()
149144 .name(name)
150- .definition(definition )
151- .description(if (definition .description != null ) definition .description.content else getDocumentation(definition ))
145+ .definition(objectDefinition )
146+ .description(if (objectDefinition .description != null ) objectDefinition .description.content else getDocumentation(objectDefinition ))
152147
153- builder.withDirectives(* buildDirectives(definition .directives, setOf (), Introspection .DirectiveLocation .OBJECT ))
148+ builder.withDirectives(* buildDirectives(objectDefinition .directives, setOf (), Introspection .DirectiveLocation .OBJECT ))
154149
155- definition .implements.forEach { implementsDefinition ->
150+ objectDefinition .implements.forEach { implementsDefinition ->
156151 val interfaceName = (implementsDefinition as TypeName ).name
157152 builder.withInterface(interfaces.find { it.name == interfaceName }
158153 ? : throw SchemaError (" Expected interface type with name '$interfaceName ' but found none!" ))
159154 }
160155
161- definition .getExtendedFieldDefinitions(extensionDefinitions).forEach { fieldDefinition ->
156+ objectDefinition .getExtendedFieldDefinitions(extensionDefinitions).forEach { fieldDefinition ->
162157 fieldDefinition.description
163158 builder.field { field ->
164159 createField(field, fieldDefinition)
165- field.dataFetcher(fieldResolversByType[definition]?.get(fieldDefinition)?.createDataFetcher()
166- ? : throw SchemaError (" No resolver method found for object type '${definition.name} ' and field '${fieldDefinition.name} ', this is most likely a bug with graphql-java-tools" ))
160+ codeRegistryBuilder.dataFetcher(
161+ FieldCoordinates .coordinates(objectDefinition.name, fieldDefinition.name),
162+ fieldResolversByType[objectDefinition]?.get(fieldDefinition)?.createDataFetcher()
163+ ? : throw SchemaError (" No resolver method found for object type '${objectDefinition.name} ' and field '${fieldDefinition.name} ', this is most likely a bug with graphql-java-tools" )
164+ )
167165
168166 val wiredField = directiveGenerator.onField(field.build(), DirectiveBehavior .Params (runtimeWiring))
169167 GraphQLFieldDefinition .Builder (wiredField)
@@ -246,17 +244,16 @@ class SchemaParser internal constructor(scanResult: ScannedSchemaObjects, privat
246244 return directiveGenerator.onEnum(builder.build(), DirectiveBehavior .Params (runtimeWiring))
247245 }
248246
249- private fun createInterfaceObject (definition : InterfaceTypeDefinition ): GraphQLInterfaceType {
250- val name = definition .name
247+ private fun createInterfaceObject (interfaceDefinition : InterfaceTypeDefinition ): GraphQLInterfaceType {
248+ val name = interfaceDefinition .name
251249 val builder = GraphQLInterfaceType .newInterface()
252250 .name(name)
253- .definition(definition)
254- .description(if (definition.description != null ) definition.description.content else getDocumentation(definition))
255- .typeResolver(TypeResolverProxy ())
251+ .definition(interfaceDefinition)
252+ .description(if (interfaceDefinition.description != null ) interfaceDefinition.description.content else getDocumentation(interfaceDefinition))
256253
257- builder.withDirectives(* buildDirectives(definition .directives, setOf (), Introspection .DirectiveLocation .INTERFACE ))
254+ builder.withDirectives(* buildDirectives(interfaceDefinition .directives, setOf (), Introspection .DirectiveLocation .INTERFACE ))
258255
259- definition .fieldDefinitions.forEach { fieldDefinition ->
256+ interfaceDefinition .fieldDefinitions.forEach { fieldDefinition ->
260257 builder.field { field -> createField(field, fieldDefinition) }
261258 }
262259
@@ -269,7 +266,6 @@ class SchemaParser internal constructor(scanResult: ScannedSchemaObjects, privat
269266 .name(name)
270267 .definition(definition)
271268 .description(if (definition.description != null ) definition.description.content else getDocumentation(definition))
272- .typeResolver(TypeResolverProxy ())
273269
274270 builder.withDirectives(* buildDirectives(definition.directives, setOf (), Introspection .DirectiveLocation .UNION ))
275271
0 commit comments