|
| 1 | +package graphql.kickstart.tools |
| 2 | + |
| 3 | +import graphql.schema.* |
| 4 | +import graphql.schema.idl.RuntimeWiring |
| 5 | +import graphql.schema.idl.SchemaGeneratorDirectiveHelper |
| 6 | +import graphql.schema.idl.TypeDefinitionRegistry |
| 7 | +import kotlin.reflect.full.createInstance |
| 8 | + |
| 9 | +private val PARAMETERS = Class.forName("graphql.schema.idl.SchemaGeneratorDirectiveHelper\$Parameters") |
| 10 | +private val DIRECTIVE_HELPER = SchemaGeneratorDirectiveHelper::class.java |
| 11 | + |
| 12 | +private val ON_OBJECT_METHOD = DIRECTIVE_HELPER.getMethod("onObject", GraphQLObjectType::class.java, PARAMETERS) |
| 13 | +private val ON_INTERFACE_METHOD = DIRECTIVE_HELPER.getMethod("onInterface", GraphQLInterfaceType::class.java, PARAMETERS) |
| 14 | +private val ON_UNION_METHOD = DIRECTIVE_HELPER.getMethod("onUnion", GraphQLUnionType::class.java, PARAMETERS) |
| 15 | +private val ON_SCALAR_METHOD = DIRECTIVE_HELPER.getMethod("onScalar", GraphQLScalarType::class.java, PARAMETERS) |
| 16 | +private val ON_ENUM_METHOD = DIRECTIVE_HELPER.getMethod("onEnum", GraphQLEnumType::class.java, PARAMETERS) |
| 17 | +private val ON_INPUT_OBJECT_TYPE = DIRECTIVE_HELPER.getMethod("onInputObjectType", GraphQLInputObjectType::class.java, PARAMETERS) |
| 18 | + |
| 19 | +/** |
| 20 | + * Directive behavior is used to wire up directives during schema parsing. Unfortunately, SchemaGeneratorDirectiveHelper |
| 21 | + * which contains the logic has package-private access to some members and must be therefore accessed via reflection. |
| 22 | + */ |
| 23 | +class DirectiveBehavior { |
| 24 | + |
| 25 | + private val directiveHelper = SchemaGeneratorDirectiveHelper::class.createInstance() |
| 26 | + |
| 27 | + fun onObject(element: GraphQLObjectType, params: Params): GraphQLObjectType = |
| 28 | + ON_OBJECT_METHOD.invoke(directiveHelper, element, params.toParameters()) as GraphQLObjectType |
| 29 | + |
| 30 | + fun onInterface(element: GraphQLInterfaceType, params: Params): GraphQLInterfaceType = |
| 31 | + ON_INTERFACE_METHOD.invoke(directiveHelper, element, params.toParameters()) as GraphQLInterfaceType |
| 32 | + |
| 33 | + fun onUnion(element: GraphQLUnionType, params: Params): GraphQLUnionType = |
| 34 | + ON_UNION_METHOD.invoke(directiveHelper, element, params.toParameters()) as GraphQLUnionType |
| 35 | + |
| 36 | + fun onScalar(element: GraphQLScalarType, params: Params): GraphQLScalarType = |
| 37 | + ON_SCALAR_METHOD.invoke(directiveHelper, element, params.toParameters()) as GraphQLScalarType |
| 38 | + |
| 39 | + fun onEnum(element: GraphQLEnumType, params: Params): GraphQLEnumType = |
| 40 | + ON_ENUM_METHOD.invoke(directiveHelper, element, params.toParameters()) as GraphQLEnumType |
| 41 | + |
| 42 | + fun onInputObject(element: GraphQLInputObjectType, params: Params): GraphQLInputObjectType = |
| 43 | + ON_INPUT_OBJECT_TYPE.invoke(directiveHelper, element, params.toParameters()) as GraphQLInputObjectType |
| 44 | + |
| 45 | + data class Params(val runtimeWiring: RuntimeWiring, val codeRegistryBuilder: GraphQLCodeRegistry.Builder) { |
| 46 | + internal fun toParameters() = PARAMETERS |
| 47 | + .getDeclaredConstructor( |
| 48 | + TypeDefinitionRegistry::class.java, |
| 49 | + RuntimeWiring::class.java, |
| 50 | + Map::class.java, |
| 51 | + GraphQLCodeRegistry.Builder::class.java |
| 52 | + ).apply { isAccessible = true } |
| 53 | + .newInstance(null, runtimeWiring, null, codeRegistryBuilder) |
| 54 | + } |
| 55 | +} |
0 commit comments