Skip to content

Commit

Permalink
Fixed #237
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Jun 6, 2013
1 parent df7fb3d commit 3955abb
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 5 deletions.
3 changes: 3 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ Version: 2.3.0 (xx-xxx-2013)

New minor version.

#237: Add `DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY` to optionally
throw `JsonMappingException` on duplicate keys, tree model (`JsonNode`)

------------------------------------------------------------------------
=== History: ===
------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,21 @@ public enum DeserializationFeature implements ConfigFeature
* @since 2.2
*/
FAIL_ON_INVALID_SUBTYPE(true),

/**
* Feature that determines what happens when reading JSON content into tree
* ({@link com.fasterxml.jackson.core.TreeNode}) and a duplicate key
* is encountered (property name that was already seen for the JSON Object).
* If enabled, {@link JsonMappingException} will be thrown; if disabled, no exception
* is thrown and the new (later) value overwrites the earlier value.
*<p>
* Note that this property does NOT affect other aspects of data-binding; that is,
* no detection is done with respect to POJO properties or {@link java.util.Map}
* keys. New features may be added to control additional cases.
*
* @since 2.3
*/
FAIL_ON_READING_DUP_TREE_KEY(false),

/**
* Feature that determines whether Jackson code should catch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,19 @@ protected void _reportProblem(JsonParser jp, String msg)
throw new JsonMappingException(msg, jp.getTokenLocation());
}

/**
*
* @deprecated Since 2.3, use the overloaded variant
*/
@Deprecated
protected void _handleDuplicateField(String fieldName, ObjectNode objectNode,
JsonNode oldValue, JsonNode newValue)
throws JsonProcessingException
{
// By default, we don't do anything
;
}

/**
* Method called when there is a duplicate value for a field.
* By default we don't care, and the last value is used.
Expand All @@ -173,12 +186,18 @@ protected void _reportProblem(JsonParser jp, String msg)
* was added
* @param newValue Newly added value just added to the object node
*/
protected void _handleDuplicateField(String fieldName, ObjectNode objectNode,
JsonNode oldValue, JsonNode newValue)
protected void _handleDuplicateField(JsonParser jp, DeserializationContext ctxt,
JsonNodeFactory nodeFactory,
String fieldName, ObjectNode objectNode,
JsonNode oldValue, JsonNode newValue)
throws JsonProcessingException
{
// By default, we don't do anything
;
// [Issue#237]: Report an error if asked to do so:
if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY)) {
_reportProblem(jp, "Duplicate field '"+fieldName+"' for ObjectNode: not allowed when FAIL_ON_READING_DUP_TREE_KEY enabled");
}
// Backwards-compatibility; call in case it's overloaded
_handleDuplicateField(fieldName, objectNode, oldValue, newValue);
}

/*
Expand Down Expand Up @@ -214,7 +233,8 @@ protected final ObjectNode deserializeObject(JsonParser jp, DeserializationConte
}
JsonNode old = node.replace(fieldName, value);
if (old != null) {
_handleDuplicateField(fieldName, node, old, value);
_handleDuplicateField(jp, ctxt, nodeFactory,
fieldName, node, old, value);
}
}
return node;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,4 +229,24 @@ public void testSetAll() throws Exception
assertEquals(3, root3.size());
assertEquals(1, root3.path("a").intValue());
}

// [Issue#237] (databind): support DeserializationFeature#FAIL_ON_READING_DUP_TREE_KEY
public void testFailOnDupKeys() throws Exception
{
final String DUP_JSON = "{ \"a\":1, \"a\":2 }";

// first: verify defaults:
ObjectMapper mapper = new ObjectMapper();
assertFalse(mapper.isEnabled(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY));
ObjectNode root = (ObjectNode) mapper.readTree(DUP_JSON);
assertEquals(2, root.path("a").asInt());

// and then enable checks:
try {
mapper.reader(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY).readTree(DUP_JSON);
fail("Should have thrown exception!");
} catch (JsonMappingException e) {
verifyException(e, "duplicate field 'a'");
}
}
}

0 comments on commit 3955abb

Please sign in to comment.