nl.vpro.jackson2.Utils Maven / Gradle / Ivy
package nl.vpro.jackson2;
import java.util.*;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.MapDifference;
import com.google.common.collect.Maps;
/**
* @author Michiel Meeuwissen
* @since 2.9
*/
public class Utils {
@SuppressWarnings("unchecked")
public static MapDifference flattenedDifference(
JsonNode j1, JsonNode j2) {
ObjectMapper mapper = Jackson2Mapper.getPublisherInstance();
Map map1 = mapper.convertValue(j1, Map.class);
Map flatten1= flatten(map1);
Map map2 = mapper.convertValue(j2, Map.class);
Map flatten2 = flatten(map2);
return Maps.difference(flatten1, flatten2);
}
static Map flatten(Map map) {
return map.entrySet().stream()
.flatMap(Utils::flatten)
.collect(LinkedHashMap::new, (m, e) -> m.put("/" + e.getKey(), e.getValue()), LinkedHashMap::putAll);
}
private static Stream> flatten(Map.Entry entry) {
if (entry == null) {
return Stream.empty();
}
if (entry.getValue() instanceof Map, ?>) {
return ((Map, ?>) entry.getValue()).entrySet().stream()
.flatMap(e -> flatten(new AbstractMap.SimpleEntry<>(entry.getKey() + "/" + e.getKey(), e.getValue())));
}
if (entry.getValue() instanceof Integer) {
entry.setValue(((Integer) entry.getValue()).longValue());
}
if (entry.getValue() instanceof List> list) {
return IntStream.range(0, list.size())
.mapToObj(i -> new AbstractMap.SimpleEntry(entry.getKey() + "/" + i, list.get(i)))
.flatMap(Utils::flatten);
}
return Stream.of(entry);
}
}