Skip to content

Commit 3501a99

Browse files
authored
Merge pull request #381 from graphql-java-kickstart/bugs/remove-reflection-schemahelper
Bugs/remove reflection schemahelper
2 parents 8b3f431 + 5022ea8 commit 3501a99

File tree

3 files changed

+483
-36
lines changed

3 files changed

+483
-36
lines changed
Lines changed: 18 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,37 @@
11
package graphql.kickstart.tools
22

3+
import graphql.kickstart.tools.directive.SchemaGeneratorDirectiveHelper
34
import graphql.schema.*
45
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)
186

197
/**
208
* Directive behavior is used to wire up directives during schema parsing. Unfortunately, SchemaGeneratorDirectiveHelper
219
* which contains the logic has package-private access to some members and must be therefore accessed via reflection.
2210
*/
2311
class DirectiveBehavior {
2412

25-
private val directiveHelper = SchemaGeneratorDirectiveHelper::class.createInstance()
13+
private val directiveHelper = SchemaGeneratorDirectiveHelper()
14+
15+
fun onObject(element: GraphQLObjectType, params: Params): GraphQLObjectType =
16+
directiveHelper.onObject(element, params.toParameters()) as GraphQLObjectType
2617

27-
fun onObject(element: GraphQLObjectType, params: Params): GraphQLObjectType =
28-
ON_OBJECT_METHOD.invoke(directiveHelper, element, params.toParameters()) as GraphQLObjectType
18+
fun onInterface(element: GraphQLInterfaceType, params: Params): GraphQLInterfaceType =
19+
directiveHelper.onInterface(element, params.toParameters()) as GraphQLInterfaceType
2920

30-
fun onInterface(element: GraphQLInterfaceType, params: Params): GraphQLInterfaceType =
31-
ON_INTERFACE_METHOD.invoke(directiveHelper, element, params.toParameters()) as GraphQLInterfaceType
21+
fun onUnion(element: GraphQLUnionType, params: Params): GraphQLUnionType =
22+
directiveHelper.onUnion(element, params.toParameters()) as GraphQLUnionType
3223

33-
fun onUnion(element: GraphQLUnionType, params: Params): GraphQLUnionType =
34-
ON_UNION_METHOD.invoke(directiveHelper, element, params.toParameters()) as GraphQLUnionType
24+
fun onScalar(element: GraphQLScalarType, params: Params): GraphQLScalarType =
25+
directiveHelper.onScalar(element, params.toParameters()) as GraphQLScalarType
3526

36-
fun onScalar(element: GraphQLScalarType, params: Params): GraphQLScalarType =
37-
ON_SCALAR_METHOD.invoke(directiveHelper, element, params.toParameters()) as GraphQLScalarType
27+
fun onEnum(element: GraphQLEnumType, params: Params): GraphQLEnumType =
28+
directiveHelper.onEnum(element, params.toParameters()) as GraphQLEnumType
3829

39-
fun onEnum(element: GraphQLEnumType, params: Params): GraphQLEnumType =
40-
ON_ENUM_METHOD.invoke(directiveHelper, element, params.toParameters()) as GraphQLEnumType
30+
fun onInputObject(element: GraphQLInputObjectType, params: Params): GraphQLInputObjectType =
31+
directiveHelper.onInputObjectType(element, params.toParameters()) as GraphQLInputObjectType
4132

42-
fun onInputObject(element: GraphQLInputObjectType, params: Params): GraphQLInputObjectType =
43-
ON_INPUT_OBJECT_TYPE.invoke(directiveHelper, element, params.toParameters()) as GraphQLInputObjectType
33+
data class Params(val runtimeWiring: RuntimeWiring, val codeRegistryBuilder: GraphQLCodeRegistry.Builder) {
34+
internal fun toParameters() = SchemaGeneratorDirectiveHelper.Parameters(null, runtimeWiring, null, codeRegistryBuilder)
35+
}
4436

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-
}
5537
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package graphql.kickstart.tools.directive;
2+
3+
import graphql.Internal;
4+
import graphql.language.NamedNode;
5+
import graphql.language.NodeParentTree;
6+
import graphql.schema.DataFetcher;
7+
import graphql.schema.FieldCoordinates;
8+
import graphql.schema.GraphQLCodeRegistry;
9+
import graphql.schema.GraphQLDirective;
10+
import graphql.schema.GraphQLDirectiveContainer;
11+
import graphql.schema.GraphQLFieldDefinition;
12+
import graphql.schema.GraphQLFieldsContainer;
13+
import graphql.schema.GraphqlElementParentTree;
14+
import graphql.schema.idl.SchemaDirectiveWiringEnvironment;
15+
import graphql.schema.idl.TypeDefinitionRegistry;
16+
import graphql.util.FpKit;
17+
18+
import java.util.LinkedHashMap;
19+
import java.util.List;
20+
import java.util.Map;
21+
22+
import static graphql.Assert.assertNotNull;
23+
24+
@Internal
25+
public class SchemaDirectiveWiringEnvironmentImpl<T extends GraphQLDirectiveContainer> implements
26+
SchemaDirectiveWiringEnvironment<T> {
27+
28+
private final T element;
29+
private final Map<String, GraphQLDirective> directives;
30+
private final NodeParentTree<NamedNode> nodeParentTree;
31+
private final TypeDefinitionRegistry typeDefinitionRegistry;
32+
private final Map<String, Object> context;
33+
private final GraphQLCodeRegistry.Builder codeRegistry;
34+
private final GraphqlElementParentTree elementParentTree;
35+
private final GraphQLFieldsContainer fieldsContainer;
36+
private final GraphQLFieldDefinition fieldDefinition;
37+
private final GraphQLDirective registeredDirective;
38+
39+
public SchemaDirectiveWiringEnvironmentImpl(T element, List<GraphQLDirective> directives, GraphQLDirective registeredDirective, SchemaGeneratorDirectiveHelper.Parameters parameters) {
40+
this.element = element;
41+
this.registeredDirective = registeredDirective;
42+
this.typeDefinitionRegistry = parameters.getTypeRegistry();
43+
this.directives = FpKit.getByName(directives, GraphQLDirective::getName);
44+
this.context = parameters.getContext();
45+
this.codeRegistry = parameters.getCodeRegistry();
46+
this.nodeParentTree = parameters.getNodeParentTree();
47+
this.elementParentTree = parameters.getElementParentTree();
48+
this.fieldsContainer = parameters.getFieldsContainer();
49+
this.fieldDefinition = parameters.getFieldsDefinition();
50+
}
51+
52+
@Override
53+
public T getElement() {
54+
return element;
55+
}
56+
57+
@Override
58+
public GraphQLDirective getDirective() {
59+
return registeredDirective;
60+
}
61+
62+
@Override
63+
public Map<String, GraphQLDirective> getDirectives() {
64+
return new LinkedHashMap<>(directives);
65+
}
66+
67+
@Override
68+
public GraphQLDirective getDirective(String directiveName) {
69+
return directives.get(directiveName);
70+
}
71+
72+
@Override
73+
public boolean containsDirective(String directiveName) {
74+
return directives.containsKey(directiveName);
75+
}
76+
77+
@Override
78+
public NodeParentTree<NamedNode> getNodeParentTree() {
79+
return nodeParentTree;
80+
}
81+
82+
@Override
83+
public TypeDefinitionRegistry getRegistry() {
84+
return typeDefinitionRegistry;
85+
}
86+
87+
@Override
88+
public Map<String, Object> getBuildContext() {
89+
return context;
90+
}
91+
92+
@Override
93+
public GraphQLCodeRegistry.Builder getCodeRegistry() {
94+
return codeRegistry;
95+
}
96+
97+
@Override
98+
public GraphQLFieldsContainer getFieldsContainer() {
99+
return fieldsContainer;
100+
}
101+
102+
@Override
103+
public GraphqlElementParentTree getElementParentTree() {
104+
return elementParentTree;
105+
}
106+
107+
@Override
108+
public GraphQLFieldDefinition getFieldDefinition() {
109+
return fieldDefinition;
110+
}
111+
112+
@Override
113+
public DataFetcher getFieldDataFetcher() {
114+
assertNotNull(fieldDefinition, "An output field must be in context to call this method");
115+
assertNotNull(fieldsContainer, "An output field container must be in context to call this method");
116+
return codeRegistry.getDataFetcher(fieldsContainer, fieldDefinition);
117+
}
118+
119+
@Override
120+
public GraphQLFieldDefinition setFieldDataFetcher(DataFetcher newDataFetcher) {
121+
assertNotNull(fieldDefinition, "An output field must be in context to call this method");
122+
assertNotNull(fieldsContainer, "An output field container must be in context to call this method");
123+
124+
FieldCoordinates coordinates = FieldCoordinates.coordinates(fieldsContainer, fieldDefinition);
125+
codeRegistry.dataFetcher(coordinates, newDataFetcher);
126+
return fieldDefinition;
127+
}
128+
}

0 commit comments

Comments
 (0)