|
14 | 14 | */ |
15 | 15 | package graphql.annotations; |
16 | 16 |
|
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; |
21 | 19 |
|
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.*; |
31 | 22 |
|
32 | 23 | import static graphql.annotations.ReflectionKit.constructNewInstance; |
33 | 24 | import static graphql.annotations.ReflectionKit.constructor; |
34 | 25 | import static graphql.annotations.ReflectionKit.newInstance; |
| 26 | +import static graphql.annotations.util.NamingKit.toGraphqlName; |
35 | 27 |
|
36 | 28 | class MethodDataFetcher implements DataFetcher { |
37 | 29 | private final Method method; |
@@ -79,14 +71,48 @@ private Object[] invocationArgs(DataFetchingEnvironment environment) { |
79 | 71 | continue; |
80 | 72 | } |
81 | 73 | 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 | + } |
85 | 79 |
|
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)); |
88 | 111 | } |
| 112 | + |
| 113 | + return list; |
| 114 | + } else { |
| 115 | + return arg; |
89 | 116 | } |
90 | | - return result.toArray(); |
91 | 117 | } |
92 | 118 | } |
0 commit comments