|
1 | 1 | /*
|
2 |
| - * Copyright 2014-2016 the original author or authors. |
| 2 | + * Copyright 2014-2017 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
@@ -204,7 +204,7 @@ private <T> T doMerge(ObjectNode root, T target, ObjectMapper mapper) throws Exc
|
204 | 204 | continue;
|
205 | 205 | }
|
206 | 206 |
|
207 |
| - doMergeNestedMap((Map<String, Object>) rawValue, objectNode, mapper, property.getTypeInformation()); |
| 207 | + doMergeNestedMap((Map<Object, Object>) rawValue, objectNode, mapper, property.getTypeInformation()); |
208 | 208 |
|
209 | 209 | // Remove potentially emptied Map as values have been handled recursively
|
210 | 210 | if (!objectNode.fieldNames().hasNext()) {
|
@@ -313,33 +313,38 @@ private boolean handleArrayNode(ArrayNode array, Collection<Object> collection,
|
313 | 313 | * @param mapper must not be {@literal null}.
|
314 | 314 | * @throws Exception
|
315 | 315 | */
|
316 |
| - private void doMergeNestedMap(Map<String, Object> source, ObjectNode node, ObjectMapper mapper, |
| 316 | + private void doMergeNestedMap(Map<Object, Object> source, ObjectNode node, ObjectMapper mapper, |
317 | 317 | TypeInformation<?> type) throws Exception {
|
318 | 318 |
|
319 | 319 | if (source == null) {
|
320 | 320 | return;
|
321 | 321 | }
|
322 | 322 |
|
323 | 323 | Iterator<Entry<String, JsonNode>> fields = node.fields();
|
| 324 | + Class<?> keyType = typeOrObject(type.getComponentType()); |
| 325 | + Class<?> valueType = typeOrObject(type.getMapValueType()); |
324 | 326 |
|
325 | 327 | while (fields.hasNext()) {
|
326 | 328 |
|
327 | 329 | Entry<String, JsonNode> entry = fields.next();
|
328 |
| - JsonNode child = entry.getValue(); |
329 |
| - Object sourceValue = source.get(entry.getKey()); |
| 330 | + JsonNode value = entry.getValue(); |
| 331 | + String key = entry.getKey(); |
| 332 | + |
| 333 | + Object mappedKey = mapper.readValue(quote(key), keyType); |
| 334 | + Object sourceValue = source.get(mappedKey); |
330 | 335 |
|
331 |
| - if (child instanceof ObjectNode && sourceValue != null) { |
| 336 | + if (value instanceof ObjectNode && sourceValue != null) { |
332 | 337 |
|
333 |
| - doMerge((ObjectNode) child, sourceValue, mapper); |
| 338 | + doMerge((ObjectNode) value, sourceValue, mapper); |
334 | 339 |
|
335 |
| - } else if (child instanceof ArrayNode && sourceValue != null) { |
| 340 | + } else if (value instanceof ArrayNode && sourceValue != null) { |
336 | 341 |
|
337 |
| - handleArray(child, sourceValue, mapper, type); |
| 342 | + handleArray(value, sourceValue, mapper, type); |
338 | 343 |
|
339 | 344 | } else {
|
340 | 345 |
|
341 |
| - Class<?> valueType = sourceValue == null ? Object.class : sourceValue.getClass(); |
342 |
| - source.put(entry.getKey(), mapper.treeToValue(child, valueType)); |
| 346 | + Class<?> typeToRead = sourceValue != null ? sourceValue.getClass() : valueType; |
| 347 | + source.put(mappedKey, mapper.treeToValue(value, typeToRead)); |
343 | 348 | }
|
344 | 349 |
|
345 | 350 | fields.remove();
|
@@ -368,4 +373,24 @@ private static Collection<Object> ifCollection(Object source) {
|
368 | 373 |
|
369 | 374 | return null;
|
370 | 375 | }
|
| 376 | + |
| 377 | + /** |
| 378 | + * Surrounds the given source {@link String} with quotes so that they represent a valid JSON String. |
| 379 | + * |
| 380 | + * @param source can be {@literal null}. |
| 381 | + * @return |
| 382 | + */ |
| 383 | + private static String quote(String source) { |
| 384 | + return source == null ? null : "\"".concat(source).concat("\""); |
| 385 | + } |
| 386 | + |
| 387 | + /** |
| 388 | + * Returns the raw type of the given {@link TypeInformation} or {@link Object} as fallback. |
| 389 | + * |
| 390 | + * @param type can be {@literal null}. |
| 391 | + * @return |
| 392 | + */ |
| 393 | + private static Class<?> typeOrObject(TypeInformation<?> type) { |
| 394 | + return type == null ? Object.class : type.getType(); |
| 395 | + } |
371 | 396 | }
|
0 commit comments