Skip to content

Commit 0eaeb35

Browse files
authored
Added in local context to TypeResolutionEnvironment.java (graphql-java#2699)
And also cleaned up TypeResolutionEnvironment.java / TypeResolutionParameters.java a bit since there was lots of repeated code and really they should be merged at some point
1 parent 9c77ddd commit 0eaeb35

8 files changed

Lines changed: 203 additions & 84 deletions

src/main/java/graphql/TypeResolutionEnvironment.java

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package graphql;
22

33
import graphql.collect.ImmutableMapWithNullValues;
4+
import graphql.execution.DataFetcherResult;
45
import graphql.execution.MergedField;
6+
import graphql.execution.TypeResolutionParameters;
7+
import graphql.schema.DataFetchingEnvironment;
58
import graphql.schema.DataFetchingFieldSelectionSet;
69
import graphql.schema.GraphQLSchema;
710
import graphql.schema.GraphQLType;
@@ -24,24 +27,20 @@ public class TypeResolutionEnvironment {
2427
private final GraphQLSchema schema;
2528
private final Object context;
2629
private final GraphQLContext graphQLContext;
30+
private final Object localContext;
2731
private final DataFetchingFieldSelectionSet fieldSelectionSet;
2832

29-
public TypeResolutionEnvironment(Object object,
30-
Map<String, Object> arguments,
31-
MergedField field,
32-
GraphQLType fieldType,
33-
GraphQLSchema schema,
34-
Object context,
35-
GraphQLContext graphQLContext,
36-
DataFetchingFieldSelectionSet fieldSelectionSet) {
37-
this.object = object;
38-
this.arguments = ImmutableMapWithNullValues.copyOf(arguments);
39-
this.field = field;
40-
this.fieldType = fieldType;
41-
this.schema = schema;
42-
this.context = context;
43-
this.graphQLContext = graphQLContext;
44-
this.fieldSelectionSet = fieldSelectionSet;
33+
@Internal
34+
public TypeResolutionEnvironment(TypeResolutionParameters parameters) {
35+
this.object = parameters.getValue();
36+
this.arguments = ImmutableMapWithNullValues.copyOf(parameters.getArgumentValues());
37+
this.field = parameters.getField();
38+
this.fieldType = parameters.getFieldType();
39+
this.schema = parameters.getSchema();
40+
this.context = parameters.getContext();
41+
this.graphQLContext = parameters.getGraphQLContext();
42+
this.localContext = parameters.getLocalContext();
43+
this.fieldSelectionSet = parameters.getSelectionSet();
4544
}
4645

4746

@@ -97,6 +96,7 @@ public GraphQLSchema getSchema() {
9796
*/
9897
@Deprecated
9998
public <T> T getContext() {
99+
//noinspection unchecked
100100
return (T) context;
101101
}
102102

@@ -107,6 +107,18 @@ public GraphQLContext getGraphQLContext() {
107107
return graphQLContext;
108108
}
109109

110+
/**
111+
* Returns the local context object set in via {@link DataFetcherResult#getLocalContext()}
112+
*
113+
* @param <T> to two
114+
*
115+
* @return the local context object
116+
*/
117+
<T> T getLocalContext() {
118+
//noinspection unchecked
119+
return (T) localContext;
120+
}
121+
110122
/**
111123
* @return the {@link DataFetchingFieldSelectionSet} for the current field fetch that needs type resolution
112124
*/

src/main/java/graphql/execution/ExecutionStrategy.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ protected Iterable<Object> toIterable(Object result) {
692692
}
693693

694694
protected GraphQLObjectType resolveType(ExecutionContext executionContext, ExecutionStrategyParameters parameters, GraphQLType fieldType) {
695-
return resolvedType.resolveType(executionContext, parameters.getField(), parameters.getSource(), parameters.getExecutionStepInfo(), fieldType);
695+
return resolvedType.resolveType(executionContext, parameters.getField(), parameters.getSource(), parameters.getExecutionStepInfo(), fieldType, parameters.getLocalContext());
696696
}
697697

698698

src/main/java/graphql/execution/ResolveType.java

Lines changed: 23 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -20,33 +20,24 @@
2020
public class ResolveType {
2121

2222

23-
public GraphQLObjectType resolveType(ExecutionContext executionContext, MergedField field, Object source, ExecutionStepInfo executionStepInfo, GraphQLType fieldType) {
23+
public GraphQLObjectType resolveType(ExecutionContext executionContext, MergedField field, Object source, ExecutionStepInfo executionStepInfo, GraphQLType fieldType, Object localContext) {
2424
GraphQLObjectType resolvedType;
25+
DataFetchingFieldSelectionSet fieldSelectionSet = buildSelectionSet(executionContext, field, (GraphQLOutputType) fieldType, executionStepInfo);
26+
TypeResolutionEnvironment env = TypeResolutionParameters.newParameters()
27+
.field(field)
28+
.fieldType(fieldType)
29+
.value(source)
30+
.argumentValues(executionStepInfo.getArguments())
31+
.selectionSet(fieldSelectionSet)
32+
.context(executionContext.getContext())
33+
.graphQLContext(executionContext.getGraphQLContext())
34+
.localContext(localContext)
35+
.schema(executionContext.getGraphQLSchema())
36+
.build();
2537
if (fieldType instanceof GraphQLInterfaceType) {
26-
DataFetchingFieldSelectionSet fieldSelectionSet = buildSelectionSet(executionContext, field, (GraphQLOutputType) fieldType, executionStepInfo);
27-
TypeResolutionParameters resolutionParams = TypeResolutionParameters.newParameters()
28-
.graphQLInterfaceType((GraphQLInterfaceType) fieldType)
29-
.field(field)
30-
.value(source)
31-
.argumentValues(executionStepInfo.getArguments())
32-
.selectionSet(fieldSelectionSet)
33-
.context(executionContext.getContext())
34-
.graphQLContext(executionContext.getGraphQLContext())
35-
.schema(executionContext.getGraphQLSchema()).build();
36-
resolvedType = resolveTypeForInterface(resolutionParams);
37-
38+
resolvedType = resolveTypeForInterface(env, (GraphQLInterfaceType) fieldType);
3839
} else if (fieldType instanceof GraphQLUnionType) {
39-
DataFetchingFieldSelectionSet selectionSet = buildSelectionSet(executionContext, field, (GraphQLOutputType) fieldType, executionStepInfo);
40-
TypeResolutionParameters resolutionParams = TypeResolutionParameters.newParameters()
41-
.graphQLUnionType((GraphQLUnionType) fieldType)
42-
.field(field)
43-
.value(source)
44-
.argumentValues(executionStepInfo.getArguments())
45-
.selectionSet(selectionSet)
46-
.context(executionContext.getContext())
47-
.graphQLContext(executionContext.getGraphQLContext())
48-
.schema(executionContext.getGraphQLSchema()).build();
49-
resolvedType = resolveTypeForUnion(resolutionParams);
40+
resolvedType = resolveTypeForUnion(env, (GraphQLUnionType) fieldType);
5041
} else {
5142
resolvedType = (GraphQLObjectType) fieldType;
5243
}
@@ -59,28 +50,23 @@ private DataFetchingFieldSelectionSet buildSelectionSet(ExecutionContext executi
5950
return DataFetchingFieldSelectionSetImpl.newCollector(executionContext.getGraphQLSchema(), fieldType, normalizedFieldSupplier);
6051
}
6152

62-
public GraphQLObjectType resolveTypeForInterface(TypeResolutionParameters params) {
63-
TypeResolutionEnvironment env = new TypeResolutionEnvironment(params.getValue(), params.getArgumentValues(), params.getField(), params.getGraphQLInterfaceType(), params.getSchema(), params.getContext(), params.getGraphQLContext(), params.getSelectionSet());
64-
GraphQLInterfaceType abstractType = params.getGraphQLInterfaceType();
65-
TypeResolver typeResolver = params.getSchema().getCodeRegistry().getTypeResolver(abstractType);
66-
return resolveAbstractType(params, env, typeResolver, abstractType);
53+
public GraphQLObjectType resolveTypeForInterface(TypeResolutionEnvironment env, GraphQLInterfaceType abstractType) {
54+
TypeResolver typeResolver = env.getSchema().getCodeRegistry().getTypeResolver(abstractType);
55+
return resolveAbstractType(env, typeResolver, abstractType);
6756
}
6857

69-
public GraphQLObjectType resolveTypeForUnion(TypeResolutionParameters params) {
70-
TypeResolutionEnvironment env = new TypeResolutionEnvironment(params.getValue(), params.getArgumentValues(), params.getField(), params.getGraphQLUnionType(), params.getSchema(), params.getContext(), params.getGraphQLContext(), params.getSelectionSet());
71-
GraphQLUnionType abstractType = params.getGraphQLUnionType();
72-
TypeResolver typeResolver = params.getSchema().getCodeRegistry().getTypeResolver(abstractType);
73-
return resolveAbstractType(params, env, typeResolver, abstractType);
58+
public GraphQLObjectType resolveTypeForUnion(TypeResolutionEnvironment env, GraphQLUnionType abstractType) {
59+
TypeResolver typeResolver = env.getSchema().getCodeRegistry().getTypeResolver(abstractType);
60+
return resolveAbstractType(env, typeResolver, abstractType);
7461
}
7562

76-
private GraphQLObjectType resolveAbstractType(TypeResolutionParameters params, TypeResolutionEnvironment env, TypeResolver typeResolver, GraphQLNamedOutputType abstractType) {
63+
private GraphQLObjectType resolveAbstractType(TypeResolutionEnvironment env, TypeResolver typeResolver, GraphQLNamedOutputType abstractType) {
7764
GraphQLObjectType result = typeResolver.getType(env);
78-
7965
if (result == null) {
8066
throw new UnresolvedTypeException(abstractType);
8167
}
8268

83-
if (!params.getSchema().isPossibleType(abstractType, result)) {
69+
if (!env.getSchema().isPossibleType(abstractType, result)) {
8470
throw new UnresolvedTypeException(abstractType, result);
8571
}
8672

src/main/java/graphql/execution/TypeResolutionParameters.java

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,51 @@
22

33
import graphql.GraphQLContext;
44
import graphql.Internal;
5+
import graphql.TypeResolutionEnvironment;
56
import graphql.collect.ImmutableMapWithNullValues;
67
import graphql.schema.DataFetchingFieldSelectionSet;
7-
import graphql.schema.GraphQLInterfaceType;
88
import graphql.schema.GraphQLSchema;
9-
import graphql.schema.GraphQLUnionType;
9+
import graphql.schema.GraphQLType;
1010

1111
import java.util.Map;
1212

13+
/**
14+
* This class is a classic builder style one that SHOULD have been on have been on {@link TypeResolutionEnvironment}
15+
* but for legacy reasons was not. So it acts as the builder of {@link TypeResolutionEnvironment} objects
16+
*/
1317
@Internal
1418
public class TypeResolutionParameters {
1519

16-
private final GraphQLInterfaceType graphQLInterfaceType;
17-
private final GraphQLUnionType graphQLUnionType;
1820
private final MergedField field;
21+
private final GraphQLType fieldType;
1922
private final Object value;
2023
private final ImmutableMapWithNullValues<String, Object> argumentValues;
2124
private final GraphQLSchema schema;
2225
private final Object context;
26+
private final Object localContext;
2327
private final GraphQLContext graphQLContext;
2428
private final DataFetchingFieldSelectionSet selectionSet;
2529

2630
private TypeResolutionParameters(Builder builder) {
27-
this.graphQLInterfaceType = builder.graphQLInterfaceType;
28-
this.graphQLUnionType = builder.graphQLUnionType;
2931
this.field = builder.field;
32+
this.fieldType = builder.fieldType;
3033
this.value = builder.value;
3134
this.argumentValues = builder.argumentValues;
3235
this.schema = builder.schema;
3336
this.context = builder.context;
3437
this.graphQLContext = builder.graphQLContext;
38+
this.localContext = builder.localContext;
3539
this.selectionSet = builder.selectionSet;
3640
}
3741

38-
public GraphQLInterfaceType getGraphQLInterfaceType() {
39-
return graphQLInterfaceType;
40-
}
41-
42-
public GraphQLUnionType getGraphQLUnionType() {
43-
return graphQLUnionType;
44-
}
45-
4642
public MergedField getField() {
4743
return field;
4844
}
4945

46+
public GraphQLType getFieldType() {
47+
return fieldType;
48+
}
49+
5050
public Object getValue() {
5151
return value;
5252
}
@@ -81,30 +81,29 @@ public GraphQLContext getGraphQLContext() {
8181
return graphQLContext;
8282
}
8383

84+
public Object getLocalContext() {
85+
return localContext;
86+
}
87+
8488
public static class Builder {
8589

8690
private MergedField field;
87-
private GraphQLInterfaceType graphQLInterfaceType;
88-
private GraphQLUnionType graphQLUnionType;
91+
private GraphQLType fieldType;
8992
private Object value;
9093
private ImmutableMapWithNullValues<String, Object> argumentValues;
9194
private GraphQLSchema schema;
9295
private Object context;
9396
private GraphQLContext graphQLContext;
97+
private Object localContext;
9498
private DataFetchingFieldSelectionSet selectionSet;
9599

96100
public Builder field(MergedField field) {
97101
this.field = field;
98102
return this;
99103
}
100104

101-
public Builder graphQLInterfaceType(GraphQLInterfaceType graphQLInterfaceType) {
102-
this.graphQLInterfaceType = graphQLInterfaceType;
103-
return this;
104-
}
105-
106-
public Builder graphQLUnionType(GraphQLUnionType graphQLUnionType) {
107-
this.graphQLUnionType = graphQLUnionType;
105+
public Builder fieldType(GraphQLType fieldType) {
106+
this.fieldType = fieldType;
108107
return this;
109108
}
110109

@@ -134,13 +133,20 @@ public Builder graphQLContext(GraphQLContext context) {
134133
return this;
135134
}
136135

136+
public Builder localContext(Object localContext) {
137+
this.localContext = localContext;
138+
return this;
139+
}
140+
137141
public Builder selectionSet(DataFetchingFieldSelectionSet selectionSet) {
138142
this.selectionSet = selectionSet;
139143
return this;
140144
}
141145

142-
public TypeResolutionParameters build() {
143-
return new TypeResolutionParameters(this);
146+
public TypeResolutionEnvironment build() {
147+
// this build should have always been in TypeResolutionEnvironment but this little workaround improves it a smidge,
148+
// and we can fix it up later so this class is redundant
149+
return new TypeResolutionEnvironment(new TypeResolutionParameters(this));
144150
}
145151
}
146152
}

src/main/java/graphql/execution/nextgen/ExecutionStrategyUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public FieldSubSelection createFieldSubSelection(ExecutionContext executionConte
7777
Object localContext = resolvedValue.getLocalContext();
7878

7979
GraphQLOutputType sourceType = executionInfo.getUnwrappedNonNullType();
80-
GraphQLObjectType resolvedObjectType = resolveType.resolveType(executionContext, field, source, executionInfo, sourceType);
80+
GraphQLObjectType resolvedObjectType = resolveType.resolveType(executionContext, field, source, executionInfo, sourceType, localContext);
8181
FieldCollectorParameters collectorParameters = newParameters()
8282
.schema(executionContext.getGraphQLSchema())
8383
.objectType(resolvedObjectType)

src/main/java/graphql/execution/nextgen/FetchedValueAnalyzer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ private FetchedValueAnalysis analyzeFetchedValueImpl(ExecutionContext executionC
7373
.build();
7474
}
7575
try {
76-
GraphQLObjectType resolvedObjectType = resolveType.resolveType(executionContext, field, toAnalyze, executionInfo, fieldType);
76+
GraphQLObjectType resolvedObjectType = resolveType.resolveType(executionContext, field, toAnalyze, executionInfo, fieldType, fetchedValue.getLocalContext());
7777
return newFetchedValueAnalysis(OBJECT)
7878
.fetchedValue(fetchedValue)
7979
.executionStepInfo(executionInfo)

src/test/groovy/graphql/TypeResolutionEnvironmentTest.groovy

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package graphql
22

3+
4+
import graphql.execution.TypeResolutionParameters
35
import graphql.language.Field
46
import graphql.schema.GraphQLObjectType
57
import graphql.schema.TypeResolver
@@ -36,12 +38,23 @@ class TypeResolutionEnvironmentTest extends Specification {
3638

3739
def schema = TestUtil.schema(idl)
3840

41+
def interfaceType = schema.getType("Foo")
42+
3943
def graphqlContext = GraphQLContext.newContext().of("a", "b").build()
4044

4145
def "basic operations"() {
4246
given:
4347

44-
def environment = new TypeResolutionEnvironment("source", [:], mergedField(new Field("field")), Scalars.GraphQLString, schema, "FooBar", graphqlContext, null)
48+
def environment = TypeResolutionParameters.newParameters()
49+
.value("source")
50+
.argumentValues([a: "b"])
51+
.field(mergedField(new Field("field")))
52+
.fieldType(interfaceType)
53+
.schema(schema)
54+
.context("FooBar")
55+
.graphQLContext(graphqlContext)
56+
.localContext("LocalContext")
57+
.build()
4558

4659
when:
4760

@@ -50,6 +63,12 @@ class TypeResolutionEnvironmentTest extends Specification {
5063
GraphQLObjectType getType(TypeResolutionEnvironment env) {
5164
String source = env.getObject()
5265
assert source == "source"
66+
assert env.getField().getName() == "field"
67+
assert env.getFieldType() == interfaceType
68+
assert env.getContext() == "FooBar"
69+
assert env.getLocalContext() == "LocalContext"
70+
assert env.getGraphQLContext() == graphqlContext
71+
assert env.getArguments() == [a: "b"]
5372
return schema.getObjectType("FooBar")
5473
}
5574
}
@@ -96,14 +115,32 @@ class TypeResolutionEnvironmentTest extends Specification {
96115
}
97116

98117
when:
99-
def environmentFooBar = new TypeResolutionEnvironment("source", [:], mergedField(new Field("field")), Scalars.GraphQLString, schema, "FooBar", graphqlContext, null)
118+
def environmentFooBar = TypeResolutionParameters.newParameters()
119+
.value("source")
120+
.argumentValues([:])
121+
.field(mergedField(new Field("field")))
122+
.fieldType(interfaceType)
123+
.schema(schema)
124+
.context("FooBar")
125+
.graphQLContext(graphqlContext)
126+
.build()
127+
100128
def objTypeFooBar = resolverWithContext.getType(environmentFooBar)
101129

102130
then:
103131
objTypeFooBar.name == "FooBar"
104132

105133
when:
106-
def environmentFooImpl = new TypeResolutionEnvironment("source", [:], mergedField(new Field("field")), Scalars.GraphQLString, schema, "Foo", graphqlContext, null)
134+
def environmentFooImpl = TypeResolutionParameters.newParameters()
135+
.value("source")
136+
.argumentValues([:])
137+
.field(mergedField(new Field("field")))
138+
.fieldType(interfaceType)
139+
.schema(schema)
140+
.context("Foo")
141+
.graphQLContext(graphqlContext)
142+
.build()
143+
107144
def objTypeFooImpl = resolverWithContext.getType(environmentFooImpl)
108145

109146
then:

0 commit comments

Comments
 (0)