Skip to content

Commit 7ed2d00

Browse files
committed
Merge branch '2.5' into 2.6
Conflicts: pom.xml release-notes/VERSION src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsWrapperTypeDeserializer.java
2 parents e43a71b + cecd409 commit 7ed2d00

File tree

3 files changed

+112
-21
lines changed

3 files changed

+112
-21
lines changed

release-notes/VERSION

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ Project: jackson-databind
44
=== Releases ===
55
------------------------------------------------------------------------
66

7+
2.6.5 (not yet released)
8+
9+
#1061: Problem with Object Id and Type Id as Wrapper Object (regression in 2.5.1)
10+
711
2.6.4 (07-Dec-2015)
812

913
#984: JsonStreamContexts are not build the same way for write.. and convert methods
@@ -147,7 +151,7 @@ Project: jackson-databind
147151
- Remove old cglib compatibility tests; cause problems in Eclipse
148152
- Add `withFilterId()` method in `JsonSerializer` (demote from `BeanSerializer`)
149153

150-
2.5.5 (not released)
154+
2.5.5 (07-Dec-2015)
151155

152156
#844: Using JsonCreator still causes invalid path references in JsonMappingException
153157
(reported by Ian B)

src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsWrapperTypeDeserializer.java

+21-20
Original file line numberDiff line numberDiff line change
@@ -76,45 +76,46 @@ public Object deserializeTypedFromAny(JsonParser jp, DeserializationContext ctxt
7676
* deserialization.
7777
*/
7878
@SuppressWarnings("resource")
79-
protected Object _deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
79+
protected Object _deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
8080
{
8181
// 02-Aug-2013, tatu: May need to use native type ids
82-
if (jp.canReadTypeId()) {
83-
Object typeId = jp.getTypeId();
82+
if (p.canReadTypeId()) {
83+
Object typeId = p.getTypeId();
8484
if (typeId != null) {
85-
return _deserializeWithNativeTypeId(jp, ctxt, typeId);
85+
return _deserializeWithNativeTypeId(p, ctxt, typeId);
8686
}
8787
}
88-
8988
// first, sanity checks
90-
if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
91-
throw ctxt.wrongTokenException(jp, JsonToken.START_OBJECT,
89+
JsonToken t = p.getCurrentToken();
90+
if (t == JsonToken.START_OBJECT) {
91+
// should always get field name, but just in case...
92+
if (p.nextToken() != JsonToken.FIELD_NAME) {
93+
throw ctxt.wrongTokenException(p, JsonToken.FIELD_NAME,
94+
"need JSON String that contains type id (for subtype of "+baseTypeName()+")");
95+
}
96+
} else if (t != JsonToken.FIELD_NAME) {
97+
throw ctxt.wrongTokenException(p, JsonToken.START_OBJECT,
9298
"need JSON Object to contain As.WRAPPER_OBJECT type information for class "+baseTypeName());
9399
}
94-
// should always get field name, but just in case...
95-
if (jp.nextToken() != JsonToken.FIELD_NAME) {
96-
throw ctxt.wrongTokenException(jp, JsonToken.FIELD_NAME,
97-
"need JSON String that contains type id (for subtype of "+baseTypeName()+")");
98-
}
99-
final String typeId = jp.getText();
100+
final String typeId = p.getText();
100101
JsonDeserializer<Object> deser = _findDeserializer(ctxt, typeId);
101-
jp.nextToken();
102+
p.nextToken();
102103

103104
// Minor complication: we may need to merge type id in?
104-
if (_typeIdVisible && jp.getCurrentToken() == JsonToken.START_OBJECT) {
105+
if (_typeIdVisible && p.getCurrentToken() == JsonToken.START_OBJECT) {
105106
// but what if there's nowhere to add it in? Error? Or skip? For now, skip.
106107
TokenBuffer tb = new TokenBuffer(null, false);
107108
tb.writeStartObject(); // recreate START_OBJECT
108109
tb.writeFieldName(_typePropertyName);
109110
tb.writeString(typeId);
110-
jp = JsonParserSequence.createFlattened(tb.asParser(jp), jp);
111-
jp.nextToken();
111+
p = JsonParserSequence.createFlattened(tb.asParser(p), p);
112+
p.nextToken();
112113
}
113114

114-
Object value = deser.deserialize(jp, ctxt);
115+
Object value = deser.deserialize(p, ctxt);
115116
// And then need the closing END_OBJECT
116-
if (jp.nextToken() != JsonToken.END_OBJECT) {
117-
throw ctxt.wrongTokenException(jp, JsonToken.END_OBJECT,
117+
if (p.nextToken() != JsonToken.END_OBJECT) {
118+
throw ctxt.wrongTokenException(p, JsonToken.END_OBJECT,
118119
"expected closing END_OBJECT after type information and deserialized value");
119120
}
120121
return value;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package com.fasterxml.jackson.databind.jsontype;
2+
3+
import java.util.*;
4+
5+
import com.fasterxml.jackson.annotation.*;
6+
7+
import com.fasterxml.jackson.databind.*;
8+
9+
// Test for [databind#1051], issue with combination of Type and Object ids,
10+
// if (but only if) `JsonTypeInfo.As.WRAPPER_OBJECT` used.
11+
public class WrapperObjectWithObjectIdTest extends BaseMapTest
12+
{
13+
@JsonRootName(value = "company")
14+
static class Company {
15+
public List<Computer> computers;
16+
17+
public Company() {
18+
computers = new ArrayList<Computer>();
19+
}
20+
21+
public Company addComputer(Computer computer) {
22+
if (computers == null) {
23+
computers = new ArrayList<Computer>();
24+
}
25+
computers.add(computer);
26+
return this;
27+
}
28+
}
29+
30+
@JsonIdentityInfo(
31+
generator = ObjectIdGenerators.PropertyGenerator.class,
32+
property = "id"
33+
)
34+
@JsonTypeInfo(
35+
use = JsonTypeInfo.Id.NAME,
36+
include = JsonTypeInfo.As.WRAPPER_OBJECT,
37+
property = "type"
38+
)
39+
@JsonSubTypes({
40+
@JsonSubTypes.Type(value = DesktopComputer.class, name = "desktop"),
41+
@JsonSubTypes.Type(value = LaptopComputer.class, name = "laptop")
42+
})
43+
static class Computer {
44+
public String id;
45+
}
46+
47+
@JsonTypeName("desktop")
48+
static class DesktopComputer extends Computer {
49+
public String location;
50+
51+
protected DesktopComputer() { }
52+
public DesktopComputer(String id, String loc) {
53+
this.id = id;
54+
location = loc;
55+
}
56+
}
57+
58+
@JsonTypeName("laptop")
59+
static class LaptopComputer extends Computer {
60+
public String vendor;
61+
62+
protected LaptopComputer() { }
63+
public LaptopComputer(String id, String v) {
64+
this.id = id;
65+
vendor = v;
66+
}
67+
}
68+
69+
public void testSimple() throws Exception
70+
{
71+
Company comp = new Company();
72+
comp.addComputer(new DesktopComputer("computer-1", "Bangkok"));
73+
comp.addComputer(new DesktopComputer("computer-2", "Pattaya"));
74+
comp.addComputer(new LaptopComputer("computer-3", "Apple"));
75+
76+
final ObjectMapper mapper = new ObjectMapper();
77+
78+
String json = mapper.writerWithDefaultPrettyPrinter()
79+
.writeValueAsString(comp);
80+
81+
Company result = mapper.readValue(json, Company.class);
82+
assertNotNull(result);
83+
assertNotNull(result.computers);
84+
assertEquals(3, result.computers.size());
85+
}
86+
}

0 commit comments

Comments
 (0)