Skip to content

Commit

Permalink
support data classes for method arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
koenpunt committed Sep 20, 2021
1 parent bb1a526 commit b829935
Showing 1 changed file with 27 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@
package org.springframework.graphql.data.method.annotation.support;

import java.lang.reflect.Constructor;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
import java.util.Stack;
import java.util.*;

import graphql.schema.DataFetchingEnvironment;

Expand Down Expand Up @@ -107,13 +103,32 @@ private Object convert(Object rawValue, Class<?> targetType) {
Object target;
if (rawValue instanceof Map) {
Constructor<?> ctor = BeanUtils.getResolvableConstructor(targetType);
target = BeanUtils.instantiateClass(ctor);
DataBinder dataBinder = new DataBinder(target);
Assert.isTrue(ctor.getParameterCount() == 0,
() -> "Argument of type [" + targetType.getName() +
"] cannot be instantiated because of missing default constructor.");
MutablePropertyValues mpvs = extractPropertyValues((Map) rawValue);
dataBinder.bind(mpvs);
MutablePropertyValues propertyValues = extractPropertyValues((Map) rawValue);

if (ctor.getParameterCount() == 0) {
target = BeanUtils.instantiateClass(ctor);
DataBinder dataBinder = new DataBinder(target);
dataBinder.bind(propertyValues);
} else {
// Data class constructor
DataBinder binder = new DataBinder(null);
String[] paramNames = BeanUtils.getParameterNames(ctor);
Class<?>[] paramTypes = ctor.getParameterTypes();
Object[] args = new Object[paramTypes.length];
for (int i = 0; i < paramNames.length; i++) {
String paramName = paramNames[i];
Object value = propertyValues.get(paramName);
value = (value instanceof List ? ((List<?>) value).toArray() : value);
MethodParameter methodParam = new MethodParameter(ctor, i);
if (value == null && methodParam.isOptional()) {
args[i] = (methodParam.getParameterType() == Optional.class ? Optional.empty() : null);
}
else {
args[i] = binder.convertIfNecessary(value, paramTypes[i], methodParam);
}
}
target = BeanUtils.instantiateClass(ctor, args);
}
}
else if (targetType.isAssignableFrom(rawValue.getClass())) {
return returnValue(rawValue, targetType);
Expand Down

0 comments on commit b829935

Please sign in to comment.