Skip to content

Commit c3aeaa5

Browse files
author
Jiayu Liu
committed
Merge branch 'master' into feature/relay-param
2 parents d9a69c9 + 09d6dc0 commit c3aeaa5

40 files changed

+1296
-549
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ If you have a question or want to discuss anything else related to this project:
7373
This is the famous "hello world" in graphql-java:
7474

7575
```java
76+
import graphql.GraphQL;
7677
import graphql.schema.GraphQLObjectType;
7778
import graphql.schema.GraphQLSchema;
7879
import java.util.Map;

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ dependencies {
3333
antlr "org.antlr:antlr4:4.5.1"
3434
testCompile group: 'junit', name: 'junit', version: '4.11'
3535
testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
36-
testCompile 'org.codehaus.groovy:groovy-all:2.4.4'
36+
testCompile 'org.codehaus.groovy:groovy-all:2.4.10'
3737
testCompile 'cglib:cglib-nodep:3.1'
3838
testCompile 'org.objenesis:objenesis:2.1'
3939
}
@@ -145,6 +145,6 @@ tasks.withType(PublishToMavenRepository) {
145145

146146

147147
task wrapper(type: Wrapper) {
148-
gradleVersion = '3.2'
148+
gradleVersion = '3.4'
149149
distributionUrl = "http://services.gradle.org/distributions/gradle-${gradleVersion}-all.zip"
150150
}

gradle/wrapper/gradle-wrapper.jar

1.37 KB
Binary file not shown.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#Tue Nov 15 12:32:05 CET 2016
1+
#Fri Apr 07 17:23:20 CEST 2017
22
distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=http\://services.gradle.org/distributions/gradle-3.2-all.zip
6+
distributionUrl=http\://services.gradle.org/distributions/gradle-3.4-all.zip

gradlew

Lines changed: 11 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main/antlr/Graphql.g4

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -209,14 +209,14 @@ Digit : '0'..'9';
209209

210210
StringValue: '"' (~(["\\\n\r\u2028\u2029])|EscapedChar)* '"';
211211
212+
Comment: '#' ~[\n\r\u2028\u2029]* -> channel(2);
213+
214+
Ignored: (Whitespace|Comma|LineTerminator) -> skip;
215+
212216
fragment EscapedChar : '\\' (["\\/bfnrt] | Unicode) ;
213217
fragment Unicode : 'u' Hex Hex Hex Hex ;
214218
fragment Hex : [0-9a-fA-F] ;
215219
216-
Ignored: (Whitespace|Comma|LineTerminator|Comment) -> skip;
217-
218-
fragment Comment: '#' ~[\n\r\u2028\u2029]*;
219-
220220
fragment LineTerminator: [\n\r\u2028\u2029];
221221
222222
fragment Whitespace : [\t\u000b\f\u0020\u00a0];

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

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
import java.util.List;
2121
import java.util.Map;
2222

23+
import static graphql.execution.ExecutionParameters.newParameters;
24+
import static graphql.execution.TypeInfo.newTypeInfo;
25+
2326
import static graphql.language.OperationDefinition.Operation.MUTATION;
2427
import static graphql.language.OperationDefinition.Operation.QUERY;
2528

@@ -78,11 +81,29 @@ private ExecutionResult executeOperation(
7881
Map<String, List<Field>> fields = new LinkedHashMap<>();
7982
fieldCollector.collectFields(executionContext, operationRootType, operationDefinition.getSelectionSet(), new ArrayList<>(), fields);
8083

84+
85+
ExecutionParameters parameters = newParameters()
86+
.typeInfo(newTypeInfo().type(operationRootType))
87+
.source(root)
88+
.fields(fields)
89+
.build();
90+
8191
ExecutionResult result;
82-
if (operation == MUTATION) {
83-
result = mutationStrategy.execute(executionContext, operationRootType, root, fields);
84-
} else {
85-
result = queryStrategy.execute(executionContext, operationRootType, root, fields);
92+
try {
93+
if (operation == OperationDefinition.Operation.MUTATION) {
94+
result = mutationStrategy.execute(executionContext, parameters);
95+
} else {
96+
result = queryStrategy.execute(executionContext, parameters);
97+
}
98+
} catch (NonNullableFieldWasNullException e) {
99+
// this means it was non null types all the way from an offending non null type
100+
// up to the root object type and there was a a null value some where.
101+
//
102+
// The spec says we should return null for the data in this case
103+
//
104+
// http://facebook.github.io/graphql/#sec-Errors-and-Non-Nullability
105+
//
106+
result = new ExecutionResultImpl(null, executionContext.getErrors());
86107
}
87108

88109
dataFetchCtx.onEnd(result);
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package graphql.execution;
2+
3+
import graphql.language.Field;
4+
5+
import java.util.List;
6+
import java.util.Map;
7+
8+
import static graphql.Assert.assertNotNull;
9+
10+
/**
11+
* The parameters that are passed to execution strategies
12+
*/
13+
public class ExecutionParameters {
14+
private final TypeInfo typeInfo;
15+
private final Object source;
16+
private final Map<String, List<Field>> fields;
17+
18+
private ExecutionParameters(TypeInfo typeInfo, Object source, Map<String, List<Field>> fields) {
19+
this.typeInfo = assertNotNull(typeInfo, "");
20+
this.fields = assertNotNull(fields, "");
21+
this.source = source;
22+
}
23+
24+
public TypeInfo typeInfo() {
25+
return typeInfo;
26+
}
27+
28+
public Object source() {
29+
return source;
30+
}
31+
32+
public Map<String, List<Field>> fields() {
33+
return fields;
34+
}
35+
36+
public static Builder newParameters() {
37+
return new Builder();
38+
}
39+
40+
@Override
41+
public String toString() {
42+
return String.format("ExecutionParameters { typeInfo=%s, source=%s, fields=%s }",
43+
typeInfo, source, fields);
44+
}
45+
46+
public static class Builder {
47+
TypeInfo typeInfo;
48+
Object source;
49+
Map<String, List<Field>> fields;
50+
51+
public Builder typeInfo(TypeInfo type) {
52+
this.typeInfo = type;
53+
return this;
54+
}
55+
56+
public Builder typeInfo(TypeInfo.Builder type) {
57+
this.typeInfo = type.build();
58+
return this;
59+
}
60+
61+
public Builder fields(Map<String, List<Field>> fields) {
62+
this.fields = fields;
63+
return this;
64+
}
65+
66+
public Builder source(Object source) {
67+
this.source = source;
68+
return this;
69+
}
70+
71+
public ExecutionParameters build() {
72+
return new ExecutionParameters(typeInfo, source, fields);
73+
}
74+
}
75+
}

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

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import graphql.schema.GraphQLFieldDefinition;
1616
import graphql.schema.GraphQLInterfaceType;
1717
import graphql.schema.GraphQLList;
18-
import graphql.schema.GraphQLNonNull;
1918
import graphql.schema.GraphQLObjectType;
2019
import graphql.schema.GraphQLScalarType;
2120
import graphql.schema.GraphQLSchema;
@@ -30,29 +29,32 @@
3029
import java.util.List;
3130
import java.util.Map;
3231

32+
import static graphql.execution.TypeInfo.newTypeInfo;
3333
import static graphql.introspection.Introspection.SchemaMetaFieldDef;
3434
import static graphql.introspection.Introspection.TypeMetaFieldDef;
3535
import static graphql.introspection.Introspection.TypeNameMetaFieldDef;
3636

3737
public abstract class ExecutionStrategy {
38+
3839
private static final Logger log = LoggerFactory.getLogger(ExecutionStrategy.class);
3940

4041
protected final ValuesResolver valuesResolver = new ValuesResolver();
4142
protected final FieldCollector fieldCollector = new FieldCollector();
4243

43-
public abstract ExecutionResult execute(ExecutionContext executionContext, GraphQLObjectType parentType, Object source, Map<String, List<Field>> fields);
44+
public abstract ExecutionResult execute(ExecutionContext executionContext, ExecutionParameters parameters) throws NonNullableFieldWasNullException;
4445

45-
protected ExecutionResult resolveField(ExecutionContext executionContext, GraphQLObjectType parentType, Object source, List<Field> fields) {
46-
GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, fields.get(0));
46+
protected ExecutionResult resolveField(ExecutionContext executionContext, ExecutionParameters parameters, List<Field> fields) {
47+
GraphQLObjectType type = parameters.typeInfo().castType(GraphQLObjectType.class);
48+
GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), type, fields.get(0));
4749

4850
Map<String, Object> argumentValues = valuesResolver.getArgumentValues(fieldDef.getArguments(), fields.get(0).getArguments(), executionContext.getVariables());
4951
DataFetchingEnvironment environment = new DataFetchingEnvironmentImpl(
50-
source,
52+
parameters.source(),
5153
argumentValues,
5254
executionContext.getRoot(),
5355
fields,
5456
fieldDef.getType(),
55-
parentType,
57+
type,
5658
executionContext.getGraphQLSchema()
5759
);
5860

@@ -73,25 +75,38 @@ protected ExecutionResult resolveField(ExecutionContext executionContext, GraphQ
7375
fetchCtx.onEnd(e);
7476
}
7577

76-
ExecutionResult result = completeValue(executionContext, fieldDef.getType(), fields, resolvedValue);
78+
TypeInfo fieldType = newTypeInfo()
79+
.type(fieldDef.getType())
80+
.parentInfo(parameters.typeInfo())
81+
.build();
82+
83+
84+
ExecutionParameters newParameters = ExecutionParameters.newParameters()
85+
.typeInfo(fieldType)
86+
.fields(parameters.fields())
87+
.source(resolvedValue).build();
88+
89+
ExecutionResult result = completeValue(executionContext, newParameters, fields);
7790

7891
fieldCtx.onEnd(result);
7992
return result;
8093
}
8194

82-
protected ExecutionResult completeValue(ExecutionContext executionContext, GraphQLType fieldType, List<Field> fields, Object result) {
83-
if (fieldType instanceof GraphQLNonNull) {
84-
GraphQLNonNull graphQLNonNull = (GraphQLNonNull) fieldType;
85-
ExecutionResult completed = completeValue(executionContext, graphQLNonNull.getWrappedType(), fields, result);
86-
if (completed == null) {
87-
throw new GraphQLException("Cannot return null for non-nullable type: " + fields);
88-
}
89-
return completed;
95+
protected ExecutionResult completeValue(ExecutionContext executionContext, ExecutionParameters parameters, List<Field> fields) {
96+
TypeInfo typeInfo = parameters.typeInfo();
97+
Object result = parameters.source();
98+
GraphQLType fieldType = parameters.typeInfo().type();
9099

91-
} else if (result == null) {
100+
if (result == null) {
101+
if (typeInfo.typeIsNonNull()) {
102+
// see http://facebook.github.io/graphql/#sec-Errors-and-Non-Nullability
103+
NonNullableFieldWasNullException nonNullException = new NonNullableFieldWasNullException(typeInfo);
104+
executionContext.addError(nonNullException);
105+
throw nonNullException;
106+
}
92107
return null;
93108
} else if (fieldType instanceof GraphQLList) {
94-
return completeValueForList(executionContext, (GraphQLList) fieldType, fields, result);
109+
return completeValueForList(executionContext, parameters, fields, toIterable(result));
95110
} else if (fieldType instanceof GraphQLScalarType) {
96111
return completeValueForScalar((GraphQLScalarType) fieldType, result);
97112
} else if (fieldType instanceof GraphQLEnumType) {
@@ -115,18 +130,22 @@ protected ExecutionResult completeValue(ExecutionContext executionContext, Graph
115130
fieldCollector.collectFields(executionContext, resolvedType, field.getSelectionSet(), visitedFragments, subFields);
116131
}
117132

133+
ExecutionParameters newParameters = ExecutionParameters.newParameters()
134+
.typeInfo(typeInfo.asType(resolvedType))
135+
.fields(subFields)
136+
.source(result).build();
137+
118138
// Calling this from the executionContext to ensure we shift back from mutation strategy to the query strategy.
119139

120-
return executionContext.getQueryStrategy().execute(executionContext, resolvedType, result, subFields);
140+
return executionContext.getQueryStrategy().execute(executionContext, newParameters);
121141
}
122142

123-
private ExecutionResult completeValueForList(ExecutionContext executionContext, GraphQLList fieldType, List<Field> fields, Object result) {
143+
private Iterable<Object> toIterable(Object result) {
124144
if (result.getClass().isArray()) {
125145
result = Arrays.asList((Object[]) result);
126146
}
127-
128147
//noinspection unchecked
129-
return completeValueForList(executionContext, fieldType, fields, (Iterable<Object>) result);
148+
return (Iterable<Object>) result;
130149
}
131150

132151
protected GraphQLObjectType resolveType(GraphQLInterfaceType graphQLInterfaceType, Object value) {
@@ -145,7 +164,6 @@ protected GraphQLObjectType resolveType(GraphQLUnionType graphQLUnionType, Objec
145164
return result;
146165
}
147166

148-
149167
protected ExecutionResult completeValueForEnum(GraphQLEnumType enumType, Object result) {
150168
return new ExecutionResultImpl(enumType.getCoercing().serialize(result), null);
151169
}
@@ -159,10 +177,18 @@ protected ExecutionResult completeValueForScalar(GraphQLScalarType scalarType, O
159177
return new ExecutionResultImpl(serialized, null);
160178
}
161179

162-
protected ExecutionResult completeValueForList(ExecutionContext executionContext, GraphQLList fieldType, List<Field> fields, Iterable<Object> result) {
180+
protected ExecutionResult completeValueForList(ExecutionContext executionContext, ExecutionParameters parameters, List<Field> fields, Iterable<Object> result) {
163181
List<Object> completedResults = new ArrayList<>();
182+
TypeInfo typeInfo = parameters.typeInfo();
183+
GraphQLList fieldType = typeInfo.castType(GraphQLList.class);
164184
for (Object item : result) {
165-
ExecutionResult completedValue = completeValue(executionContext, fieldType.getWrappedType(), fields, item);
185+
186+
ExecutionParameters newParameters = ExecutionParameters.newParameters()
187+
.typeInfo(typeInfo.asType(fieldType.getWrappedType()))
188+
.fields(parameters.fields())
189+
.source(item).build();
190+
191+
ExecutionResult completedValue = completeValue(executionContext, newParameters, fields);
166192
completedResults.add(completedValue != null ? completedValue.getData() : null);
167193
}
168194
return new ExecutionResultImpl(completedResults, null);

src/main/java/graphql/execution/ExecutorServiceExecutionStrategy.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
/**
1818
* <p>ExecutorServiceExecutionStrategy uses an {@link ExecutorService} to parallelize the resolve.</p>
1919
*
20-
* Due to the nature of {@link #execute(ExecutionContext, GraphQLObjectType, Object, Map)} implementation, {@link ExecutorService}
20+
* Due to the nature of {@link #execute(ExecutionContext, ExecutionParameters)} implementation, {@link ExecutorService}
2121
* MUST have the following 2 characteristics:
2222
* <ul>
2323
* <li>1. The underlying {@link java.util.concurrent.ThreadPoolExecutor} MUST have a reasonable {@code maximumPoolSize}
@@ -37,17 +37,18 @@ public ExecutorServiceExecutionStrategy(ExecutorService executorService) {
3737
}
3838

3939
@Override
40-
public ExecutionResult execute(final ExecutionContext executionContext, final GraphQLObjectType parentType, final Object source, final Map<String, List<Field>> fields) {
40+
public ExecutionResult execute(final ExecutionContext executionContext, final ExecutionParameters parameters) {
4141
if (executorService == null)
42-
return new SimpleExecutionStrategy().execute(executionContext, parentType, source, fields);
42+
return new SimpleExecutionStrategy().execute(executionContext,parameters);
4343

44+
Map<String, List<Field>> fields = parameters.fields();
4445
Map<String, Future<ExecutionResult>> futures = new LinkedHashMap<>();
4546
for (String fieldName : fields.keySet()) {
4647
final List<Field> fieldList = fields.get(fieldName);
4748
Callable<ExecutionResult> resolveField = new Callable<ExecutionResult>() {
4849
@Override
4950
public ExecutionResult call() throws Exception {
50-
return resolveField(executionContext, parentType, source, fieldList);
51+
return resolveField(executionContext, parameters, fieldList);
5152

5253
}
5354
};

0 commit comments

Comments
 (0)