From 0e2c5be01b71d740b824c94cd0d1f9ca4d87a297 Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Tue, 22 Mar 2022 14:21:09 +0000 Subject: [PATCH] Minor refactoring Avoid creating a map for a nested list. See gh-280 --- .../graphql/data/GraphQlArgumentBinder.java | 61 ++++++++++--------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlArgumentBinder.java b/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlArgumentBinder.java index 2c5fd9c5..7388491e 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlArgumentBinder.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlArgumentBinder.java @@ -19,7 +19,6 @@ package org.springframework.graphql.data; import java.lang.reflect.Constructor; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -222,14 +221,11 @@ public class GraphQlArgumentBinder { // Default constructor with data binding if (ctor.getParameterCount() == 0) { - MutablePropertyValues mpvs = new MutablePropertyValues(); - visitArgumentMap(rawMap, mpvs, new Stack<>()); - target = BeanUtils.instantiateClass(ctor); DataBinder dataBinder = new DataBinder(target); dataBinder.getBindingResult().setNestedPath(toArgumentPath(segments)); dataBinder.setConversionService(getConversionService()); - dataBinder.bind(mpvs); + dataBinder.bind(initBindValues(rawMap)); if (dataBinder.getBindingResult().hasErrors()) { addErrors(dataBinder, bindingResult, segments); @@ -284,36 +280,43 @@ public class GraphQlArgumentBinder { } } - @SuppressWarnings("unchecked") - private void visitArgumentMap(Map rawMap, MutablePropertyValues mpvs, Stack segments) { + private MutablePropertyValues initBindValues(Map rawMap) { + MutablePropertyValues mpvs = new MutablePropertyValues(); + Stack segments = new Stack<>(); for (String key : rawMap.keySet()) { - Object rawValue = rawMap.get(key); - if (rawValue instanceof List) { - List items = (List) rawValue; - if (items.isEmpty()) { - segments.push(key); - mpvs.add(toArgumentPath(segments), rawValue); - segments.pop(); - } - else { - Map subValues = new HashMap<>(items.size()); - for (int i = 0; i < items.size(); i++) { - subValues.put(key + "[" + i + "]", items.get(i)); - } - visitArgumentMap(subValues, mpvs, segments); - } - } - else if (rawValue instanceof Map) { - segments.push(key + "."); - visitArgumentMap((Map) rawValue, mpvs, segments); + addBindValues(mpvs, key, rawMap.get(key), segments); + } + return mpvs; + } + + @SuppressWarnings("unchecked") + private void addBindValues(MutablePropertyValues mpvs, String name, Object value, Stack segments) { + if (value instanceof List) { + List items = (List) value; + if (items.isEmpty()) { + segments.push(name); + mpvs.add(toArgumentPath(segments), value); segments.pop(); } else { - segments.push(key); - mpvs.add(toArgumentPath(segments), rawValue); - segments.pop(); + for (int i = 0; i < items.size(); i++) { + addBindValues(mpvs, name + "[" + i + "]", items.get(i), segments); + } } } + else if (value instanceof Map) { + segments.push(name + "."); + Map map = (Map) value; + for (String key : map.keySet()) { + addBindValues(mpvs, key, map.get(key), segments); + } + segments.pop(); + } + else { + segments.push(name); + mpvs.add(toArgumentPath(segments), value); + segments.pop(); + } } private String toArgumentPath(Stack path) {