Skip to content

Commit fcd6679

Browse files
committed
introduce MergedFields class
1 parent 8e766d1 commit fcd6679

32 files changed

+329
-193
lines changed

src/main/java/graphql/Assert.java

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,16 @@
99
public class Assert {
1010

1111
public static <T> T assertNotNull(T object, String format, Object... args) {
12-
if (object != null) return object;
12+
if (object != null) {
13+
return object;
14+
}
1315
throw new AssertException(format(format, args));
1416
}
1517

1618
public static <T> T assertNotNull(T object) {
17-
if (object != null) return object;
19+
if (object != null) {
20+
return object;
21+
}
1822
throw new AssertException("Object required to be not null");
1923
}
2024

@@ -30,14 +34,24 @@ public static <T> T assertShouldNeverHappen() {
3034
throw new AssertException("Internal error: should never happen");
3135
}
3236

33-
public static <T> Collection<T> assertNotEmpty(Collection<T> c, String format, Object... args) {
34-
if (c == null || c.isEmpty())
37+
public static <T> Collection<T> assertNotEmpty(Collection<T> collection) {
38+
if (collection == null || collection.isEmpty()) {
39+
throw new AssertException("collection must be not null and not empty");
40+
}
41+
return collection;
42+
}
43+
44+
public static <T> Collection<T> assertNotEmpty(Collection<T> collection, String format, Object... args) {
45+
if (collection == null || collection.isEmpty()) {
3546
throw new AssertException(format(format, args));
36-
return c;
47+
}
48+
return collection;
3749
}
3850

3951
public static void assertTrue(boolean condition, String format, Object... args) {
40-
if (condition) return;
52+
if (condition) {
53+
return;
54+
}
4155
throw new AssertException(format(format, args));
4256
}
4357

@@ -55,7 +69,7 @@ public static String assertValidName(String name) {
5569
if (name != null && !name.isEmpty() && name.matches("[_A-Za-z][_0-9A-Za-z]*")) {
5670
return name;
5771
}
58-
throw new AssertException(String.format(invalidNameErrorMessage,name));
72+
throw new AssertException(String.format(invalidNameErrorMessage, name));
5973
}
6074

6175
}

src/main/java/graphql/execution/AbsoluteGraphQLError.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import graphql.ErrorType;
44
import graphql.GraphQLError;
55
import graphql.Internal;
6-
import graphql.language.Field;
76
import graphql.language.SourceLocation;
87
import graphql.schema.DataFetcher;
98

@@ -44,7 +43,7 @@ public AbsoluteGraphQLError(ExecutionStrategyParameters executionStrategyParamet
4443
}
4544
}
4645

47-
public AbsoluteGraphQLError(List<Field> sameField, ExecutionPath executionPath, GraphQLError relativeError) {
46+
public AbsoluteGraphQLError(MergedFields sameField, ExecutionPath executionPath, GraphQLError relativeError) {
4847
this.absolutePath = createAbsolutePath(executionPath, relativeError);
4948
this.locations = createAbsoluteLocations(relativeError, sameField);
5049
this.message = relativeError.getMessage();
@@ -116,13 +115,13 @@ private List<Object> createAbsolutePath(ExecutionPath executionPath,
116115
*
117116
* @return List of locations from the root.
118117
*/
119-
private List<SourceLocation> createAbsoluteLocations(GraphQLError relativeError, List<Field> fields) {
120-
Optional<SourceLocation> baseLocation;
121-
if (!fields.isEmpty()) {
122-
baseLocation = Optional.ofNullable(fields.get(0).getSourceLocation());
123-
} else {
124-
baseLocation = Optional.empty();
125-
}
118+
private List<SourceLocation> createAbsoluteLocations(GraphQLError relativeError, MergedFields fields) {
119+
Optional<SourceLocation> baseLocation = Optional.ofNullable(fields.getSingleField().getSourceLocation());
120+
// if (!fields.isEmpty()) {
121+
// baseLocation = Optional.ofNullable(fields.get(0).getSourceLocation());
122+
// } else {
123+
// baseLocation = Optional.empty();
124+
// }
126125

127126
// relative error empty path should yield an absolute error with the base path
128127
if (relativeError.getLocations() != null && relativeError.getLocations().isEmpty()) {

src/main/java/graphql/execution/AsyncExecutionStrategy.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import graphql.execution.instrumentation.Instrumentation;
1010
import graphql.execution.instrumentation.parameters.InstrumentationDeferredFieldParameters;
1111
import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters;
12-
import graphql.language.Field;
1312
import graphql.schema.GraphQLFieldDefinition;
1413

1514
import java.util.ArrayList;
@@ -51,12 +50,12 @@ public CompletableFuture<ExecutionResult> execute(ExecutionContext executionCont
5150

5251
ExecutionStrategyInstrumentationContext executionStrategyCtx = instrumentation.beginExecutionStrategy(instrumentationParameters);
5352

54-
Map<String, List<Field>> fields = parameters.getFields();
53+
Map<String, MergedFields> fields = parameters.getFields();
5554
List<String> fieldNames = new ArrayList<>(fields.keySet());
5655
List<CompletableFuture<FieldValueInfo>> futures = new ArrayList<>();
5756
List<String> resolvedFields = new ArrayList<>();
5857
for (String fieldName : fieldNames) {
59-
List<Field> currentField = fields.get(fieldName);
58+
MergedFields currentField = fields.get(fieldName);
6059

6160
ExecutionPath fieldPath = parameters.getPath().segment(mkNameForPath(currentField));
6261
ExecutionStrategyParameters newParameters = parameters
@@ -94,14 +93,14 @@ public CompletableFuture<ExecutionResult> execute(ExecutionContext executionCont
9493
return overallResult;
9594
}
9695

97-
private boolean isDeferred(ExecutionContext executionContext, ExecutionStrategyParameters parameters, List<Field> currentField) {
96+
private boolean isDeferred(ExecutionContext executionContext, ExecutionStrategyParameters parameters, MergedFields currentField) {
9897
DeferSupport deferSupport = executionContext.getDeferSupport();
9998
if (deferSupport.checkForDeferDirective(currentField)) {
10099
DeferredErrorSupport errorSupport = new DeferredErrorSupport();
101100

102101
// with a deferred field we are really resetting where we execute from, that is from this current field onwards
103-
Map<String, List<Field>> fields = new LinkedHashMap<>();
104-
fields.put(currentField.get(0).getName(), currentField);
102+
Map<String, MergedFields> fields = new LinkedHashMap<>();
103+
fields.put(currentField.getName(), currentField);
105104

106105
ExecutionStrategyParameters callParameters = parameters.transform(builder ->
107106
builder.deferredErrorSupport(errorSupport)
@@ -122,7 +121,7 @@ private boolean isDeferred(ExecutionContext executionContext, ExecutionStrategyP
122121
@SuppressWarnings("FutureReturnValueIgnored")
123122
private Supplier<CompletableFuture<ExecutionResult>> deferredExecutionResult(ExecutionContext executionContext, ExecutionStrategyParameters parameters) {
124123
return () -> {
125-
GraphQLFieldDefinition fieldDef = getFieldDef(executionContext, parameters, parameters.getField().get(0));
124+
GraphQLFieldDefinition fieldDef = getFieldDef(executionContext, parameters, parameters.getField().getSingleField());
126125

127126
Instrumentation instrumentation = executionContext.getInstrumentation();
128127
DeferredFieldInstrumentationContext fieldCtx = instrumentation.beginDeferredField(

src/main/java/graphql/execution/AsyncSerialExecutionStrategy.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import graphql.execution.instrumentation.Instrumentation;
55
import graphql.execution.instrumentation.InstrumentationContext;
66
import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters;
7-
import graphql.language.Field;
87

98
import java.util.ArrayList;
109
import java.util.List;
@@ -32,11 +31,11 @@ public CompletableFuture<ExecutionResult> execute(ExecutionContext executionCont
3231
Instrumentation instrumentation = executionContext.getInstrumentation();
3332
InstrumentationExecutionStrategyParameters instrumentationParameters = new InstrumentationExecutionStrategyParameters(executionContext, parameters);
3433
InstrumentationContext<ExecutionResult> executionStrategyCtx = instrumentation.beginExecutionStrategy(instrumentationParameters);
35-
Map<String, List<Field>> fields = parameters.getFields();
34+
Map<String, MergedFields> fields = parameters.getFields();
3635
List<String> fieldNames = new ArrayList<>(fields.keySet());
3736

3837
CompletableFuture<List<ExecutionResult>> resultsFuture = Async.eachSequentially(fieldNames, (fieldName, index, prevResults) -> {
39-
List<Field> currentField = fields.get(fieldName);
38+
MergedFields currentField = fields.get(fieldName);
4039
ExecutionPath fieldPath = parameters.getPath().segment(mkNameForPath(currentField));
4140
ExecutionStrategyParameters newParameters = parameters
4241
.transform(builder -> builder.field(currentField).path(fieldPath));

src/main/java/graphql/execution/Execution.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters;
1515
import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters;
1616
import graphql.language.Document;
17-
import graphql.language.Field;
1817
import graphql.language.FragmentDefinition;
1918
import graphql.language.NodeUtil;
2019
import graphql.language.OperationDefinition;
@@ -131,7 +130,7 @@ private CompletableFuture<ExecutionResult> executeOperation(ExecutionContext exe
131130
.variables(executionContext.getVariables())
132131
.build();
133132

134-
Map<String, List<Field>> fields = fieldCollector.collectFields(collectorParameters, operationDefinition.getSelectionSet());
133+
Map<String, MergedFields> fields = fieldCollector.collectFields(collectorParameters, operationDefinition.getSelectionSet());
135134

136135
ExecutionPath path = ExecutionPath.rootPath();
137136
ExecutionStepInfo executionStepInfo = newExecutionStepInfo().type(operationRootType).path(path).build();

src/main/java/graphql/execution/ExecutionStepInfoFactory.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import graphql.schema.GraphQLList;
1010
import graphql.schema.GraphQLObjectType;
1111
import graphql.schema.GraphQLOutputType;
12-
import graphql.schema.visibility.GraphqlFieldVisibility;
1312

1413
import java.util.List;
1514
import java.util.Map;
@@ -21,8 +20,8 @@ public class ExecutionStepInfoFactory {
2120
ValuesResolver valuesResolver = new ValuesResolver();
2221

2322

24-
public ExecutionStepInfo newExecutionStepInfoForSubField(ExecutionContext executionContext, List<Field> sameFields, ExecutionStepInfo parentInfo) {
25-
Field field = sameFields.get(0);
23+
public ExecutionStepInfo newExecutionStepInfoForSubField(ExecutionContext executionContext, MergedFields sameFields, ExecutionStepInfo parentInfo) {
24+
Field field = sameFields.getSingleField();
2625
GraphQLObjectType parentType = (GraphQLObjectType) parentInfo.getUnwrappedNonNullType();
2726
GraphQLFieldDefinition fieldDefinition = Introspection.getFieldDef(executionContext.getGraphQLSchema(), parentType, field.getName());
2827
GraphQLOutputType fieldType = fieldDefinition.getType();
@@ -51,8 +50,8 @@ public ExecutionStepInfo newExecutionStepInfoForListElement(ExecutionStepInfo ex
5150
.path(indexedPath));
5251
}
5352

54-
private static String mkNameForPath(List<Field> currentField) {
55-
Field field = currentField.get(0);
53+
private static String mkNameForPath(MergedFields currentField) {
54+
Field field = currentField.getSingleField();
5655
return field.getAlias() != null ? field.getAlias() : field.getName();
5756
}
5857
}

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

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ protected CompletableFuture<ExecutionResult> resolveField(ExecutionContext execu
187187
* @throws NonNullableFieldWasNullException in the {@link FieldValueInfo#getFieldValue()} future if a non null field resolves to a null value
188188
*/
189189
protected CompletableFuture<FieldValueInfo> resolveFieldWithInfo(ExecutionContext executionContext, ExecutionStrategyParameters parameters) {
190-
GraphQLFieldDefinition fieldDef = getFieldDef(executionContext, parameters, parameters.getField().get(0));
190+
GraphQLFieldDefinition fieldDef = getFieldDef(executionContext, parameters, parameters.getField().getSingleField());
191191

192192
Instrumentation instrumentation = executionContext.getInstrumentation();
193193
InstrumentationContext<ExecutionResult> fieldCtx = instrumentation.beginField(
@@ -220,7 +220,7 @@ protected CompletableFuture<FieldValueInfo> resolveFieldWithInfo(ExecutionContex
220220
* @throws NonNullableFieldWasNullException in the future if a non null field resolves to a null value
221221
*/
222222
protected CompletableFuture<Object> fetchField(ExecutionContext executionContext, ExecutionStrategyParameters parameters) {
223-
Field field = parameters.getField().get(0);
223+
Field field = parameters.getField().getSingleField();
224224
GraphQLObjectType parentType = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType();
225225
GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, field);
226226

@@ -235,7 +235,7 @@ protected CompletableFuture<Object> fetchField(ExecutionContext executionContext
235235
.source(parameters.getSource())
236236
.arguments(argumentValues)
237237
.fieldDefinition(fieldDef)
238-
.fields(parameters.getField())
238+
.mergedFields(parameters.getField())
239239
.fieldType(fieldType)
240240
.executionStepInfo(executionStepInfo)
241241
.parentType(parentType)
@@ -334,7 +334,7 @@ private void handleFetchingException(ExecutionContext executionContext,
334334
* @throws NonNullableFieldWasNullException in the {@link FieldValueInfo#getFieldValue()} future if a non null field resolves to a null value
335335
*/
336336
protected FieldValueInfo completeField(ExecutionContext executionContext, ExecutionStrategyParameters parameters, Object fetchedValue) {
337-
Field field = parameters.getField().get(0);
337+
Field field = parameters.getField().getSingleField();
338338
GraphQLObjectType parentType = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType();
339339
GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, field);
340340
ExecutionStepInfo executionStepInfo = createExecutionStepInfo(executionContext, parameters, fieldDef);
@@ -607,7 +607,7 @@ protected CompletableFuture<ExecutionResult> completeValueForObject(ExecutionCon
607607
.variables(executionContext.getVariables())
608608
.build();
609609

610-
Map<String, List<Field>> subFields = fieldCollector.collectFields(collectorParameters, parameters.getField());
610+
Map<String, MergedFields> subFields = fieldCollector.collectFields(collectorParameters, parameters.getField());
611611

612612
ExecutionStepInfo newExecutionStepInfo = executionStepInfo.changeTypeWithPreservedNonNull(resolvedObjectType);
613613
NonNullableFieldValidator nonNullableFieldValidator = new NonNullableFieldValidator(executionContext, newExecutionStepInfo);
@@ -651,7 +651,7 @@ protected Iterable<Object> toIterable(Object result) {
651651
}
652652

653653
protected GraphQLObjectType resolveType(ExecutionContext executionContext, ExecutionStrategyParameters parameters, GraphQLType fieldType) {
654-
return resolvedType.resolveType(executionContext, parameters.getField().get(0), parameters.getSource(), parameters.getArguments(), fieldType);
654+
return resolvedType.resolveType(executionContext, parameters.getField().getSingleField(), parameters.getSource(), parameters.getArguments(), fieldType);
655655
}
656656

657657

@@ -763,7 +763,7 @@ protected ExecutionResult handleNonNullException(ExecutionContext executionConte
763763
*/
764764
protected ExecutionStepInfo createExecutionStepInfo(ExecutionContext executionContext, ExecutionStrategyParameters parameters, GraphQLFieldDefinition fieldDefinition) {
765765
GraphQLOutputType fieldType = fieldDefinition.getType();
766-
Field field = parameters.getField().get(0);
766+
Field field = parameters.getField().getSingleField();
767767
List<Argument> fieldArgs = field.getArguments();
768768
GraphQLCodeRegistry codeRegistry = executionContext.getGraphQLSchema().getCodeRegistry();
769769
Map<String, Object> argumentValues = valuesResolver.getArgumentValues(codeRegistry, fieldDefinition.getArguments(), fieldArgs, executionContext.getVariables());
@@ -785,6 +785,12 @@ public static String mkNameForPath(Field currentField) {
785785
return mkNameForPath(Collections.singletonList(currentField));
786786
}
787787

788+
@Internal
789+
public static String mkNameForPath(MergedFields mergedFields) {
790+
return mkNameForPath(mergedFields.getFields());
791+
}
792+
793+
788794
@Internal
789795
public static String mkNameForPath(List<Field> currentField) {
790796
Field field = currentField.get(0);

src/main/java/graphql/execution/ExecutionStrategyParameters.java

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
import graphql.Assert;
44
import graphql.PublicApi;
55
import graphql.execution.defer.DeferredErrorSupport;
6-
import graphql.language.Field;
76

8-
import java.util.List;
97
import java.util.Map;
108
import java.util.function.Consumer;
119

@@ -19,22 +17,22 @@ public class ExecutionStrategyParameters {
1917
private final ExecutionStepInfo executionStepInfo;
2018
private final Object source;
2119
private final Map<String, Object> arguments;
22-
private final Map<String, List<Field>> fields;
20+
private final Map<String, MergedFields> fields;
2321
private final NonNullableFieldValidator nonNullableFieldValidator;
2422
private final ExecutionPath path;
25-
private final List<Field> currentField;
23+
private final MergedFields currentField;
2624
private final int listSize;
2725
private final int currentListIndex;
2826
private final ExecutionStrategyParameters parent;
2927
private final DeferredErrorSupport deferredErrorSupport;
3028

3129
private ExecutionStrategyParameters(ExecutionStepInfo executionStepInfo,
3230
Object source,
33-
Map<String, List<Field>> fields,
31+
Map<String, MergedFields> fields,
3432
Map<String, Object> arguments,
3533
NonNullableFieldValidator nonNullableFieldValidator,
3634
ExecutionPath path,
37-
List<Field> currentField,
35+
MergedFields currentField,
3836
int listSize,
3937
int currentListIndex,
4038
ExecutionStrategyParameters parent,
@@ -61,7 +59,7 @@ public Object getSource() {
6159
return source;
6260
}
6361

64-
public Map<String, List<Field>> getFields() {
62+
public Map<String, MergedFields> getFields() {
6563
return fields;
6664
}
6765

@@ -94,13 +92,10 @@ public DeferredErrorSupport deferredErrorSupport() {
9492
}
9593

9694
/**
97-
* This returns the current field in its query representations. Global fragments mean that
98-
* a single named field can have multiple representations and different field subselections
99-
* hence the use of a list of Field
100-
*
101-
* @return the current field in list form or null if this has not be computed yet
95+
* This returns the current field in its query representations.
96+
* @return the current merged fields
10297
*/
103-
public List<Field> getField() {
98+
public MergedFields getField() {
10499
return currentField;
105100
}
106101

@@ -127,11 +122,11 @@ public static Builder newParameters(ExecutionStrategyParameters oldParameters) {
127122
public static class Builder {
128123
ExecutionStepInfo executionStepInfo;
129124
Object source;
130-
Map<String, List<Field>> fields;
125+
Map<String, MergedFields> fields;
131126
Map<String, Object> arguments;
132127
NonNullableFieldValidator nonNullableFieldValidator;
133128
ExecutionPath path = ExecutionPath.rootPath();
134-
List<Field> currentField;
129+
MergedFields currentField;
135130
int listSize;
136131
int currentListIndex;
137132
ExecutionStrategyParameters parent;
@@ -170,12 +165,12 @@ public Builder executionStepInfo(ExecutionStepInfo.Builder executionStepInfoBuil
170165
return this;
171166
}
172167

173-
public Builder fields(Map<String, List<Field>> fields) {
168+
public Builder fields(Map<String, MergedFields> fields) {
174169
this.fields = fields;
175170
return this;
176171
}
177172

178-
public Builder field(List<Field> currentField) {
173+
public Builder field(MergedFields currentField) {
179174
this.currentField = currentField;
180175
return this;
181176
}

0 commit comments

Comments
 (0)