Skip to content

Commit f35ebfb

Browse files
committed
Copy SchemaDirective helper from graphql-java to prevent using reflection
1 parent 161d180 commit f35ebfb

File tree

4 files changed

+483
-37
lines changed

4 files changed

+483
-37
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<groupId>com.graphql-java-kickstart</groupId>
66
<artifactId>graphql-java-tools</artifactId>
7-
<version>6.0.1-SNAPSHOT</version>
7+
<version>6.0.2-SNAPSHOT</version>
88
<packaging>jar</packaging>
99

1010
<name>GraphQL Java Tools</name>

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

Lines changed: 17 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,54 +2,35 @@ package graphql.kickstart.tools
22

33
import graphql.schema.*
44
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)
185

196
/**
207
* Directive behavior is used to wire up directives during schema parsing. Unfortunately, SchemaGeneratorDirectiveHelper
218
* which contains the logic has package-private access to some members and must be therefore accessed via reflection.
229
*/
2310
class DirectiveBehavior {
2411

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

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

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

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

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

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

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

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-
}
5536
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package graphql.kickstart.tools;
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)