Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ gradle.projectsEvaluated {

dependencies {
compile 'javax.validation:validation-api:1.1.0.Final'
compile 'com.graphql-java:graphql-java:3.0.0'
compile 'com.graphql-java:graphql-java:4.2'

// OSGi
compileOnly 'org.osgi:org.osgi.core:6.0.0'
Expand Down
50 changes: 21 additions & 29 deletions src/main/java/graphql/annotations/EnhancedExecutionStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,24 @@
package graphql.annotations;

import graphql.ExecutionResult;
import graphql.execution.ExecutionContext;
import graphql.execution.ExecutionParameters;
import graphql.execution.SimpleExecutionStrategy;
import graphql.execution.TypeInfo;
import graphql.language.Argument;
import graphql.language.Field;
import graphql.language.ObjectValue;
import graphql.language.StringValue;
import graphql.language.VariableReference;
import graphql.execution.*;
import graphql.language.*;
import graphql.schema.GraphQLEnumType;
import graphql.schema.GraphQLFieldDefinition;
import graphql.schema.GraphQLObjectType;
import graphql.schema.GraphQLType;

import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;

import static graphql.execution.ExecutionParameters.newParameters;
import static graphql.execution.TypeInfoWorkaround.newTypeInfo;

public class EnhancedExecutionStrategy extends SimpleExecutionStrategy {
public class EnhancedExecutionStrategy extends AsyncSerialExecutionStrategy {

private static final String CLIENT_MUTATION_ID = "clientMutationId";

@Override
protected ExecutionResult resolveField(ExecutionContext executionContext, ExecutionParameters parameters, List<Field> fields) {
GraphQLObjectType parentType = (GraphQLObjectType) parameters.typeInfo().type();
GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, fields.get(0));
protected CompletableFuture<ExecutionResult> resolveField(ExecutionContext executionContext, ExecutionStrategyParameters parameters) {
GraphQLObjectType parentType = (GraphQLObjectType) parameters.typeInfo().getType();
GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, parameters.field().get(0));
if (fieldDef == null) return null;

if (fieldDef.getName().contentEquals(CLIENT_MUTATION_ID)) {
Expand All @@ -63,45 +52,48 @@ protected ExecutionResult resolveField(ExecutionContext executionContext, Execut
clientMutationId = clientMutationIdVal.getValue();
}

TypeInfo fieldTypeInfo = newTypeInfo(fieldDef.getType(), parameters.typeInfo());
ExecutionParameters newParameters = newParameters()
ExecutionTypeInfo fieldTypeInfo = ExecutionTypeInfo.newTypeInfo().type(fieldDef.getType()).parentInfo(parameters.typeInfo()).build();
ExecutionStrategyParameters newParameters = ExecutionStrategyParameters.newParameters()
.arguments(parameters.arguments())
.fields(parameters.fields())
.nonNullFieldValidator(parameters.nonNullFieldValidator())
.typeInfo(fieldTypeInfo)
.source(clientMutationId)
.build();


return completeValue(executionContext, newParameters, fields);
return completeValue(executionContext, newParameters);
} else {
return super.resolveField(executionContext, parameters, fields);
return super.resolveField(executionContext, parameters);
}
}

@Override
protected ExecutionResult completeValue(ExecutionContext executionContext, ExecutionParameters parameters, List<Field> fields) {
GraphQLType fieldType = parameters.typeInfo().type();
protected CompletableFuture<ExecutionResult> completeValue(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException {
graphql.schema.GraphQLType fieldType = parameters.typeInfo().getType();
Object result = parameters.source();
if (result instanceof Enum && fieldType instanceof GraphQLEnumType) {
Object value = ((GraphQLEnumType) fieldType).getCoercing().parseValue(((Enum) result).name());
return super.completeValue(executionContext, withSource(parameters, value), fields);
return super.completeValue(executionContext, withSource(parameters, value));
}
if (result instanceof Optional) {
Object value = ((Optional<?>) result).orElse(null);
return completeValue(executionContext, withSource(parameters, value), fields);
return completeValue(executionContext, withSource(parameters, value));
}
return super.completeValue(executionContext, parameters, fields);
return super.completeValue(executionContext, parameters);
}

/*
Creates a new parameters with the specified object as its source
*/
private ExecutionParameters withSource(ExecutionParameters parameters, Object source) {
return newParameters()
private ExecutionStrategyParameters withSource(ExecutionStrategyParameters parameters, Object source) {
return ExecutionStrategyParameters.newParameters()
.arguments(parameters.arguments())
.fields(parameters.fields())
.nonNullFieldValidator(parameters.nonNullFieldValidator())
.typeInfo(parameters.typeInfo())
.source(source)
.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ public ExtensionDataFetcherWrapper(Class declaringClass, DataFetcher<T> dataFetc
public T get(DataFetchingEnvironment environment) {
Object source = environment.getSource();
if (source != null && (!declaringClass.isInstance(source)) && !(source instanceof Map)) {
environment = new DataFetchingEnvironmentImpl(newInstance(declaringClass, source), environment.getArguments(),
environment.getContext(), environment.getFields(), environment.getFieldType(), environment.getParentType(),
environment.getGraphQLSchema(), environment.getFragmentsByName(), environment.getExecutionId(), environment.getSelectionSet());
environment = new DataFetchingEnvironmentImpl(newInstance(declaringClass, source), environment.getArguments(), environment.getContext(),
environment.getRoot(), environment.getFieldDefinition(), environment.getFields(), environment.getFieldType(), environment.getParentType(), environment.getGraphQLSchema(),
environment.getFragmentsByName(), environment.getExecutionId(), environment.getSelectionSet(), environment.getFieldTypeInfo());
}

return dataFetcher.get(environment);
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/graphql/annotations/GraphQLAnnotations.java
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ protected GraphQLFieldDefinition getField(Method method) throws GraphQLAnnotatio
relayFieldDefinition = relay.mutationWithClientMutationId(title, method.getName(),
args.stream().
map(t -> newInputObjectField().name(t.getName()).type(t.getType()).description(t.getDescription()).build()).
collect(Collectors.toList()), fieldDefinitions, null);
collect(Collectors.toList()), fieldDefinitions, new StaticDataFetcher(null));
builder.argument(relayFieldDefinition.getArguments());
builder.type(relayFieldDefinition.getType());
} else {
Expand Down Expand Up @@ -843,8 +843,8 @@ public Object get(DataFetchingEnvironment environment) {
HashMap<String, Object> arguments = new HashMap<>(environment.getArguments());
arguments.keySet().removeAll(Arrays.asList("first", "last", "before", "after"));
DataFetchingEnvironment env = new DataFetchingEnvironmentImpl(environment.getSource(), arguments, environment.getContext(),
environment.getFields(), environment.getFieldType(), environment.getParentType(), environment.getGraphQLSchema(),
environment.getFragmentsByName(), environment.getExecutionId(), environment.getSelectionSet());
environment.getRoot(), environment.getFieldDefinition(), environment.getFields(), environment.getFieldType(), environment.getParentType(), environment.getGraphQLSchema(),
environment.getFragmentsByName(), environment.getExecutionId(), environment.getSelectionSet(), environment.getFieldTypeInfo());
Object data = actualDataFetcher.get(env);
if (data != null) {
Connection conn = constructNewInstance(constructor, data);
Expand Down
22 changes: 19 additions & 3 deletions src/main/java/graphql/annotations/MethodDataFetcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
import graphql.schema.GraphQLType;

import java.lang.reflect.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.util.*;

import static graphql.annotations.ReflectionKit.constructNewInstance;
Expand Down Expand Up @@ -63,17 +68,28 @@ public Object get(DataFetchingEnvironment environment) {

private Object[] invocationArgs(DataFetchingEnvironment environment) {
List<Object> result = new ArrayList<>();
Iterator envArgs = environment.getArguments().values().iterator();
Map<String,Object> envArgs = environment.getArguments();
for (Parameter p : method.getParameters()) {
String parameterName;
GraphQLName name = p.getAnnotation(GraphQLName.class);
if (name != null) {
parameterName = toGraphqlName(name.value());
} else {
parameterName = toGraphqlName(p.getName());
}

Class<?> paramType = p.getType();
if (DataFetchingEnvironment.class.isAssignableFrom(paramType)) {
result.add(environment);
continue;
}

graphql.schema.GraphQLType graphQLType = typeFunction.buildType(true, paramType, p.getAnnotatedType());
Object arg = envArgs.next();
result.add(buildArg(p.getParameterizedType(), graphQLType, arg));
if (envArgs.containsKey(parameterName)) {
result.add(buildArg(p.getParameterizedType(), graphQLType, envArgs.get(parameterName)));
} else {
result.add(null);
}
}
return result.toArray();
}
Expand Down
30 changes: 0 additions & 30 deletions src/main/java/graphql/execution/TypeInfoWorkaround.java

This file was deleted.

8 changes: 4 additions & 4 deletions src/test/java/graphql/annotations/GraphQLConnectionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ public List<Obj> getNonNullObjs() {
}

@GraphQLField
@GraphQLConnection(name = "null")
public List<Obj> getNull() {
@GraphQLConnection(name = "nullObj")
public List<Obj> getNullObj() {
return null;
}

Expand Down Expand Up @@ -197,14 +197,14 @@ public void methodNull() {
GraphQLSchema schema = newSchema().query(object).build();

GraphQL graphQL = GraphQL.newGraphQL(schema).build();
ExecutionResult result = graphQL.execute("{ null(first: 1) { edges { cursor node { id, val } } } }",
ExecutionResult result = graphQL.execute("{ nullObj(first: 1) { edges { cursor node { id, val } } } }",
new TestConnections(Arrays.asList(new Obj("1", "test"), new Obj("2", "hello"), new Obj("3", "world"))));

assertTrue(result.getErrors().isEmpty());

Map<String, Map<String, List<Map<String, Map<String, Object>>>>> data = result.getData();

assertEquals(data.get("null"), null);
assertEquals(data.get("nullObj"), null);
}

@Test
Expand Down
6 changes: 3 additions & 3 deletions src/test/java/graphql/annotations/GraphQLObjectTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ public void queryOptional() {
GraphQLObjectType object = GraphQLAnnotations.object(OptionalTest.class);
GraphQLSchema schema = newSchema().query(object).build();

GraphQL graphQL = GraphQL.newGraphQL(schema).queryExecutionStrategy(new EnhancedExecutionStrategy()).build();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you remove the queryExecutionStrategy?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I restored an EnhancedExecutionStrategy for gql4.2, but did not put it back on tests where it was not needed - it's only used for relay mutations, so kept it only in RelayTest. I could restore it in these tests also, but it won't change much.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If its not necessary, no need

GraphQL graphQL = GraphQL.newGraphQL(schema).build();
ExecutionResult result = graphQL.execute("{empty, nonempty}", new OptionalTest());
assertTrue(result.getErrors().isEmpty());
Map<String, Object> v = (Map<String, Object>) result.getData();
Expand All @@ -676,7 +676,7 @@ public void optionalInput() {
}).build()).build();
GraphQLSchema schema = newSchema().query(object).mutation(mutation).build();

GraphQL graphQL = GraphQL.newGraphQL(schema).queryExecutionStrategy(new EnhancedExecutionStrategy()).build();
GraphQL graphQL = GraphQL.newGraphQL(schema).build();
ExecutionResult result = graphQL.execute("mutation {test(input: {empty: \"test\"}) { empty nonempty } }", new OptionalTest());
assertTrue(result.getErrors().isEmpty());
Map<String, Object> v = (Map<String, Object>) ((Map<String, Object>) result.getData()).get("test");
Expand Down Expand Up @@ -707,7 +707,7 @@ public String toString() {
public void queryEnum() {
GraphQLObjectType object = GraphQLAnnotations.object(EnumTest.class);
GraphQLSchema schema = newSchema().query(object).build();
GraphQL graphQL = GraphQL.newGraphQL(schema).queryExecutionStrategy(new EnhancedExecutionStrategy()).build();
GraphQL graphQL = GraphQL.newGraphQL(schema).build();

ExecutionResult result = graphQL.execute("{e}", new EnumTest(EnumTest.E.B));
assertTrue(result.getErrors().isEmpty());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public String method() throws TestException {
public void exceptionRethrowing() {
try {
MethodDataFetcher methodDataFetcher = new MethodDataFetcher(getClass().getMethod("method"));
methodDataFetcher.get(new DataFetchingEnvironmentImpl(this, new HashMap<>(), null, new ArrayList<>(), null, null, null, null, null, null));
methodDataFetcher.get(new DataFetchingEnvironmentImpl(this, new HashMap<String,Object>(), null, null, null, new ArrayList<>(), null, null, null, null, null, null, null));
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
Expand Down