package org.gcube.portlets.user.geoportaldataentry.server.json; import java.io.IOException; import java.util.Iterator; import java.util.Map; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; /** * This class provides methods to merge two json of any nested level into a single json. * * copied from: https://github.com/hemantsonu20/json-merge */ public class JsonMerge { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); /** * Method to merge two json objects into single json object. * *
It merges two json of any nested level into a single json following below logic.
*When keys are same at some level, following table denotes what value will be used.
*Src / Target | *JSON Value | *JSON Array | *JSON Object | *
---|---|---|---|
JSON Value1 | *Src | *Src | *Src | *
JSON Array | *Src2 | *Merge | *Src | *
JSON Object | *Src | *Src | *Merge3 | *
Src
value will be copied.Src
and Target
values will be merged.Source Json
*{@code * { * "name": "json-merge-src" * } * }*
Target Json
*{@code * { * "name": "json-merge-target" * } * }*
Output
*{@code * { * "name": "json-merge-src" * } * }*
Source Json
*{@code * { * "level1": { * "key1": "SrcValue1" * } * } * }*
Target Json
*{@code * { * "level1": { * "key1": "targetValue1", * "level2": { * "key2": "value2" * } * } * } * }*
Output
*{@code * { * "level1": { * "key1": "SrcValue1", * "level2": { * "key2": "value2" * } * } * } * }* * @param srcJsonStr source json string * @param targetJsonStr target json string * @return merged json as a string */ public static String merge(String srcJsonStr, String targetJsonStr) { try { JsonNode srcNode = OBJECT_MAPPER.readTree(srcJsonStr); JsonNode targetNode = OBJECT_MAPPER.readTree(targetJsonStr); JsonNode result = merge(srcNode, targetNode); return OBJECT_MAPPER.writeValueAsString(result); } catch (IOException e) { throw new JsonMergeException("Unable to merge json", e); } } public static JsonNode merge(JsonNode srcNode, JsonNode targetNode) { // if both nodes are object node, merged object node is returned if (srcNode.isObject() && targetNode.isObject()) { return merge((ObjectNode) srcNode, (ObjectNode) targetNode); } // if both nodes are array node, merged array node is returned if (srcNode.isArray() && targetNode.isArray()) { return merge((ArrayNode) srcNode, (ArrayNode) targetNode); } // special case when src node is null if (srcNode.isNull()) { return targetNode; } return srcNode; } public static ObjectNode merge(ObjectNode srcNode, ObjectNode targetNode) { ObjectNode result = OBJECT_MAPPER.createObjectNode(); Iterator