Fixed override problem when expecting merge #117

This commit is contained in:
Francis Dong
2021-04-12 11:15:49 +08:00
committed by hongqiaowei
parent 1d9aae8f1d
commit cf3711b6cd
3 changed files with 147 additions and 2 deletions

View File

@@ -211,4 +211,29 @@ public class MapUtil {
return null;
}
/**
* Merge maps, merge src to target
* @param target
* @param src
* @return
*/
@SuppressWarnings("unchecked")
public static Map<String, Object> merge(Map<String, Object> target, Map<String, Object> src) {
if(src == null || src.isEmpty()) {
return target;
}
src.forEach((key, value) -> {
if(value != null) {
target.merge(key, value, (oldValue, newValue) -> {
if (oldValue instanceof Map && newValue instanceof Map) {
oldValue = merge((Map<String, Object>) oldValue, (Map<String, Object>) newValue);
return oldValue;
}
return newValue;
});
}
});
return target;
}
}

View File

@@ -0,0 +1,119 @@
package we.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
public class MapUtilTests {
@Test
public void TestMerge() {
/**
* target = {
a: 1,
c: 3,
b: {
b1: "b1",
b2: {
c1: "c1"
c2: "c2"
},
b3: [1, 2, 3],
b4: "b4"
}
};
*/
Map<String, Object> target = new HashMap<>();
target.put("a", 1);
target.put("c", 3);
Map<String, Object> b = new HashMap<>();
target.put("b", b);
b.put("b1", "b1");
Map<String, Object> c = new HashMap<>();
c.put("c1", "c1");
c.put("c2", "c2");
b.put("b2", c);
List<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(2);
list1.add(3);
b.put("b3", list1);
b.put("b4", "b4");
/**
* src = {
b: {
b1: "b1-src",
b2: {
c1: "c1-src"
},
b3: [1, 4]
},
d: "d1"
};
*/
Map<String, Object> src = new HashMap<>();
Map<String, Object> srcb = new HashMap<>();
srcb.put("b1", "b1-src");
Map<String, Object> srcc = new HashMap<>();
srcc.put("c1", "c1-src");
srcb.put("b2", srcc);
List<Integer> list2 = new ArrayList<>();
list2.add(1);
list2.add(4);
srcb.put("b3", list2);
src.put("b", srcb);
src.put("d", "d1");
MapUtil.merge(target, src);
/**
* expected output:
* {
"a": 1,
"b": {
"b1": "b1-src",
"b2": {
"c1": "c1-src",
"c2": "c2"
},
"b3": [1, 4],
"b4": "b4"
},
"c": 3,
"d": "d1"
}
*/
assertEquals(1, Integer.valueOf(target.get("a").toString()));
assertEquals(3, Integer.valueOf(target.get("c").toString()));
assertEquals("d1", target.get("d"));
Map<String, Object> mapb = (Map<String, Object>) target.get("b");
assertEquals("b1-src", mapb.get("b1"));
assertEquals("b4", mapb.get("b4"));
List<Integer> list = (List<Integer>) mapb.get("b3");
assertEquals(2, list.size());
assertEquals(1, list.get(0));
assertEquals(4, list.get(1));
Map<String, Object> mapc = (Map<String, Object>) mapb.get("b2");
assertEquals("c1-src", mapc.get("c1"));
assertEquals("c2", mapc.get("c2"));
}
}

View File

@@ -29,6 +29,7 @@ import org.noear.snack.ONode;
import we.constants.CommonConstants;
import we.fizz.StepContext;
import we.util.MapUtil;
/**
*
@@ -380,12 +381,12 @@ public class PathMapping {
Map<String, Object> scriptRules = PathMapping.getScriptRules(mappingRules);
Map<String, Object> scriptResult = ScriptHelper.executeScripts(target, scriptRules, ctxNode, stepContext, supportMultiLevels);
if (scriptResult != null && !scriptResult.isEmpty()) {
result.putAll(scriptResult);
result = MapUtil.merge(result, scriptResult);
}
}
return result;
}
public static Map<String, Object> convertPath(Map<String, Object> fixed, boolean supportMultiLevels) {
ONode target = ONode.load(new HashMap());
if (fixed.isEmpty()) {