Skip to content

Commit 29e7bed

Browse files
author
Thomas Draier
committed
Better support for input types : allows nested types and lists
1 parent fe80a68 commit 29e7bed

File tree

1 file changed

+45
-19
lines changed

1 file changed

+45
-19
lines changed

src/main/java/graphql/annotations/MethodDataFetcher.java

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,16 @@
1414
*/
1515
package graphql.annotations;
1616

17-
import graphql.schema.DataFetcher;
18-
import graphql.schema.DataFetchingEnvironment;
19-
import graphql.schema.GraphQLInputObjectType;
20-
import graphql.schema.GraphQLObjectType;
17+
import graphql.schema.*;
18+
import graphql.schema.GraphQLType;
2119

22-
import java.lang.reflect.Constructor;
23-
import java.lang.reflect.InvocationTargetException;
24-
import java.lang.reflect.Method;
25-
import java.lang.reflect.Modifier;
26-
import java.lang.reflect.Parameter;
27-
import java.util.ArrayList;
28-
import java.util.HashMap;
29-
import java.util.Iterator;
30-
import java.util.List;
20+
import java.lang.reflect.*;
21+
import java.util.*;
3122

3223
import static graphql.annotations.ReflectionKit.constructNewInstance;
3324
import static graphql.annotations.ReflectionKit.constructor;
3425
import static graphql.annotations.ReflectionKit.newInstance;
26+
import static graphql.annotations.util.NamingKit.toGraphqlName;
3527

3628
class MethodDataFetcher implements DataFetcher {
3729
private final Method method;
@@ -79,14 +71,48 @@ private Object[] invocationArgs(DataFetchingEnvironment environment) {
7971
continue;
8072
}
8173
graphql.schema.GraphQLType graphQLType = typeFunction.buildType(paramType, p.getAnnotatedType());
82-
if (graphQLType instanceof GraphQLInputObjectType) {
83-
Constructor<?> constructor = constructor(paramType, HashMap.class);
84-
result.add(constructNewInstance(constructor, envArgs.next()));
74+
Object arg = envArgs.next();
75+
result.add(buildArg(p.getParameterizedType(), graphQLType, arg));
76+
}
77+
return result.toArray();
78+
}
8579

86-
} else {
87-
result.add(envArgs.next());
80+
private Object buildArg(Type p, GraphQLType graphQLType, Object arg) {
81+
if (arg == null) {
82+
return null;
83+
}
84+
if (graphQLType instanceof graphql.schema.GraphQLNonNull) {
85+
graphQLType = ((graphql.schema.GraphQLNonNull) graphQLType).getWrappedType();
86+
}
87+
if (p instanceof Class<?> && graphQLType instanceof GraphQLInputObjectType) {
88+
Constructor<?> constructors[] = ((Class) p).getConstructors();
89+
for (Constructor<?> constructor : constructors) {
90+
Parameter[] parameters = constructor.getParameters();
91+
if (parameters.length == 1 && parameters[0].getType().isAssignableFrom(arg.getClass())) {
92+
return constructNewInstance(constructor, arg);
93+
} else {
94+
List<Object> objects = new ArrayList<>();
95+
Map map = (Map) arg;
96+
for (Parameter parameter : parameters) {
97+
String name = toGraphqlName(parameter.getAnnotation(GraphQLName.class) != null ? parameter.getAnnotation(GraphQLName.class).value() : parameter.getName());
98+
objects.add(buildArg(parameter.getType(), ((GraphQLInputObjectType)graphQLType).getField(name).getType(),map.get(name)));
99+
}
100+
return constructNewInstance(constructor, objects.toArray(new Object[objects.size()]));
101+
}
102+
}
103+
return null;
104+
} else if (p instanceof ParameterizedType && graphQLType instanceof GraphQLList) {
105+
List<Object> list = new ArrayList<>();
106+
Type subType = ((ParameterizedType)p).getActualTypeArguments()[0];
107+
GraphQLType wrappedType = ((GraphQLList) graphQLType).getWrappedType();
108+
109+
for (Object item : ((List) arg)) {
110+
list.add(buildArg(subType, wrappedType, item));
88111
}
112+
113+
return list;
114+
} else {
115+
return arg;
89116
}
90-
return result.toArray();
91117
}
92118
}

0 commit comments

Comments
 (0)