Skip to content

Commit f40e6c1

Browse files
committed
Fix #1208
1 parent 7dd671d commit f40e6c1

File tree

7 files changed

+55
-31
lines changed

7 files changed

+55
-31
lines changed

release-notes/CREDITS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,3 +439,8 @@ Yoann Rodière (fenrhil@github)
439439
Mark Woon (markwoon@github)
440440
* Reported #1178: `@JsonSerialize(contentAs=superType)` behavior disallowed in 2.7
441441
(2.7.4)
442+
443+
Tom Mack (tommack@github)
444+
* Reported #1208: treeToValue doesn't handle POJONodes that contain exactly
445+
the requested value type
446+
(2.7.4)

release-notes/VERSION

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ Project: jackson-databind
1919
#1197: `SNAKE_CASE` doesn't work when using Lombok's `@AllArgsConstructor`
2020
#1198: Problem with `@JsonTypeInfo.As.EXTERNAL_PROPERTY`, `defaultImpl`, missing type id, NPE
2121
#1203: `@JsonTypeInfo` does not work correctly for ReferenceTypes like `AtomicReference`
22+
#1208: treeToValue doesn't handle POJONodes that contain exactly the requested value type
23+
(reported by Tom M)
2224
- Improve handling of custom content (de)serializers for `AtomicReference`
2325

2426
2.7.3 (16-Mar-2016)

src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2529,11 +2529,21 @@ public <T> T treeToValue(TreeNode n, Class<T> valueType)
25292529
throws JsonProcessingException
25302530
{
25312531
try {
2532-
// [Issue-11]: Simple cast when we just want to cast to, say, ObjectNode
2532+
// Simple cast when we just want to cast to, say, ObjectNode
25332533
// ... one caveat; while everything is Object.class, let's not take shortcut
25342534
if (valueType != Object.class && valueType.isAssignableFrom(n.getClass())) {
25352535
return (T) n;
25362536
}
2537+
// 20-Apr-2016, tatu: Another thing: for VALUE_EMBEDDED_OBJECT, assume similar
2538+
// short-cut coercion
2539+
if (n.asToken() == JsonToken.VALUE_EMBEDDED_OBJECT) {
2540+
if (n instanceof POJONode) {
2541+
Object ob = ((POJONode) n).getPojo();
2542+
if ((ob == null) || valueType.isInstance(ob)) {
2543+
return (T) ob;
2544+
}
2545+
}
2546+
}
25372547
return readValue(treeAsTokens(n), valueType);
25382548
} catch (JsonProcessingException e) {
25392549
throw e;

src/main/java/com/fasterxml/jackson/databind/deser/std/DateDeserializers.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,9 @@ protected CalendarDeserializer withDateFormat(DateFormat df, String formatString
212212
}
213213

214214
@Override
215-
public Calendar deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
215+
public Calendar deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
216216
{
217-
Date d = _parseDate(jp, ctxt);
217+
Date d = _parseDate(p, ctxt);
218218
if (d == null) {
219219
return null;
220220
}

src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -762,12 +762,12 @@ protected final double _parseDoublePrimitive(JsonParser jp, DeserializationConte
762762
throw ctxt.mappingException(_valueClass, t);
763763
}
764764

765-
protected java.util.Date _parseDate(JsonParser jp, DeserializationContext ctxt)
765+
protected java.util.Date _parseDate(JsonParser p, DeserializationContext ctxt)
766766
throws IOException
767767
{
768-
JsonToken t = jp.getCurrentToken();
768+
JsonToken t = p.getCurrentToken();
769769
if (t == JsonToken.VALUE_NUMBER_INT) {
770-
return new java.util.Date(jp.getLongValue());
770+
return new java.util.Date(p.getLongValue());
771771
}
772772
if (t == JsonToken.VALUE_NULL) {
773773
return (java.util.Date) getNullValue(ctxt);
@@ -776,7 +776,7 @@ protected java.util.Date _parseDate(JsonParser jp, DeserializationContext ctxt)
776776
String value = null;
777777
try {
778778
// As per [JACKSON-203], take empty Strings to mean
779-
value = jp.getText().trim();
779+
value = p.getText().trim();
780780
if (value.length() == 0) {
781781
return (Date) getEmptyValue(ctxt);
782782
}
@@ -789,16 +789,18 @@ protected java.util.Date _parseDate(JsonParser jp, DeserializationContext ctxt)
789789
"not a valid representation (error: "+iae.getMessage()+")");
790790
}
791791
}
792-
// Issue#381
793-
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
794-
jp.nextToken();
795-
final Date parsed = _parseDate(jp, ctxt);
796-
t = jp.nextToken();
797-
if (t != JsonToken.END_ARRAY) {
798-
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
799-
"Attempted to unwrap single value array for single 'java.util.Date' value but there was more than a single value in the array");
800-
}
801-
return parsed;
792+
// [databind#381]
793+
if (t == JsonToken.START_ARRAY) {
794+
if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
795+
p.nextToken();
796+
final Date parsed = _parseDate(p, ctxt);
797+
t = p.nextToken();
798+
if (t != JsonToken.END_ARRAY) {
799+
throw ctxt.wrongTokenException(p, JsonToken.END_ARRAY,
800+
"Attempted to unwrap single value array for single 'java.util.Date' value but there was more than a single value in the array");
801+
}
802+
return parsed;
803+
}
802804
}
803805
throw ctxt.mappingException(_valueClass, t);
804806
}

src/main/java/com/fasterxml/jackson/databind/node/POJONode.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ public class POJONode
2626
*/
2727

2828
@Override
29-
public JsonNodeType getNodeType()
30-
{
29+
public JsonNodeType getNodeType() {
3130
return JsonNodeType.POJO;
3231
}
3332

src/test/java/com/fasterxml/jackson/databind/node/TestConversions.java

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,11 @@ static class Leaf {
3131
public Leaf() { }
3232
public Leaf(int v) { value = v; }
3333
}
34-
35-
// MixIn for [JACKSON-554]
34+
3635
@JsonDeserialize(using = LeafDeserializer.class)
37-
public static class LeafMixIn
38-
{
39-
}
36+
public static class LeafMixIn { }
4037

41-
// for [Issue#467]
38+
// for [databind#467]
4239
@JsonSerialize(using=Issue467Serializer.class)
4340
static class Issue467Bean {
4441
public int i;
@@ -121,7 +118,6 @@ public Leaf deserialize(JsonParser jp, DeserializationContext ctxt)
121118
}
122119
}
123120

124-
// Test for [JACKSON-554]
125121
public void testTreeToValue() throws Exception
126122
{
127123
String JSON = "{\"leaf\":{\"value\":13}}";
@@ -134,7 +130,17 @@ public void testTreeToValue() throws Exception
134130
assertEquals(13, r1.leaf.value);
135131
}
136132

137-
// Test for [JACKSON-631]
133+
// [databind#1208]: should coerce POJOs at least at root level
134+
public void testTreeToValueWithPOJO() throws Exception
135+
{
136+
Calendar c = Calendar.getInstance();
137+
c.setTime(new java.util.Date(0));
138+
ValueNode pojoNode = MAPPER.getNodeFactory().pojoNode(c);
139+
Calendar result = MAPPER.treeToValue(pojoNode, Calendar.class);
140+
assertNotNull(result);
141+
assertEquals(result.getTimeInMillis(), c.getTimeInMillis());
142+
}
143+
138144
public void testBase64Text() throws Exception
139145
{
140146
// let's actually iterate over sets of encoding modes, lengths
@@ -202,7 +208,7 @@ public void testEmbeddedByteArray() throws Exception
202208
assertEquals(3, data.length);
203209
}
204210

205-
// [Issue#232]
211+
// [databind#232]
206212
public void testBigDecimalAsPlainStringTreeConversion() throws Exception
207213
{
208214
ObjectMapper mapper = new ObjectMapper();
@@ -239,7 +245,7 @@ public void serializeWithType(JsonGenerator jgen,
239245
}
240246
}
241247

242-
// [#433]
248+
// [databind#433]
243249
public void testBeanToTree() throws Exception
244250
{
245251
final CustomSerializedPojo pojo = new CustomSerializedPojo();
@@ -248,7 +254,7 @@ public void testBeanToTree() throws Exception
248254
assertEquals(JsonNodeType.OBJECT, node.getNodeType());
249255
}
250256

251-
// [#467]
257+
// [databind#467]
252258
public void testConversionOfPojos() throws Exception
253259
{
254260
final Issue467Bean input = new Issue467Bean(13);
@@ -264,7 +270,7 @@ public void testConversionOfPojos() throws Exception
264270
assertEquals(EXP, MAPPER.writeValueAsString(tree));
265271
}
266272

267-
// [#467]
273+
// [databind#467]
268274
public void testConversionOfTrees() throws Exception
269275
{
270276
final Issue467Tree input = new Issue467Tree();

0 commit comments

Comments
 (0)