Skip to content

Commit 6b2fd9c

Browse files
committed
Add tests and fixes for custom serialization involving unions
1 parent 4cba6b6 commit 6b2fd9c

File tree

3 files changed

+125
-1
lines changed

3 files changed

+125
-1
lines changed

avro/src/main/java/com/fasterxml/jackson/dataformat/avro/ser/AvroWriteContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public final AvroWriteContext createChildArrayContext() throws JsonMappingExcept
8787

8888
public abstract AvroWriteContext createChildArrayContext(Object currValue) throws JsonMappingException;
8989

90-
public final AvroWriteContext createChildObjectContext() throws JsonMappingException {
90+
public AvroWriteContext createChildObjectContext() throws JsonMappingException {
9191
return createChildObjectContext(null);
9292
}
9393

avro/src/main/java/com/fasterxml/jackson/dataformat/avro/ser/ObjectWriteContext.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public ObjectWriteContext(AvroWriteContext parent, AvroGenerator generator,
3232
@Override
3333
public Object rawValue() { return _record; }
3434

35+
3536
@Override
3637
public final AvroWriteContext createChildArrayContext(Object currValue)
3738
{
@@ -46,6 +47,18 @@ public final AvroWriteContext createChildArrayContext(Object currValue)
4647
return child;
4748
}
4849

50+
@Override
51+
public AvroWriteContext createChildObjectContext() throws JsonMappingException {
52+
_verifyValueWrite();
53+
Schema.Field field = _findField();
54+
if (field == null) { // unknown, to ignore
55+
return new NopWriteContext(TYPE_OBJECT, this, _generator, null);
56+
}
57+
AvroWriteContext child = _createObjectContext(field.schema());
58+
_record.put(_currentName, child.rawValue());
59+
return child;
60+
}
61+
4962
@Override
5063
public AvroWriteContext createChildObjectContext(Object currValue) throws JsonMappingException {
5164
_verifyValueWrite();
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package com.fasterxml.jackson.dataformat.avro.interop.annotations;
2+
3+
import java.io.IOException;
4+
import java.util.Objects;
5+
import com.fasterxml.jackson.core.JsonGenerator;
6+
import com.fasterxml.jackson.core.JsonParser;
7+
import com.fasterxml.jackson.databind.DeserializationContext;
8+
import com.fasterxml.jackson.databind.JsonDeserializer;
9+
import com.fasterxml.jackson.databind.JsonSerializer;
10+
import com.fasterxml.jackson.databind.SerializerProvider;
11+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
12+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
13+
import com.fasterxml.jackson.dataformat.avro.interop.annotations.UnionTest.Animal;
14+
import com.fasterxml.jackson.dataformat.avro.interop.annotations.UnionTest.Cat;
15+
import org.apache.avro.Schema;
16+
import org.apache.avro.SchemaBuilder;
17+
import org.junit.Test;
18+
19+
import static com.fasterxml.jackson.dataformat.avro.interop.ApacheAvroInteropUtil.getApacheSchema;
20+
import static com.fasterxml.jackson.dataformat.avro.interop.ApacheAvroInteropUtil.jacksonDeserialize;
21+
import static com.fasterxml.jackson.dataformat.avro.interop.ApacheAvroInteropUtil.jacksonSerialize;
22+
import static org.assertj.core.api.Assertions.assertThat;
23+
24+
public final class CustomSerializationTest {
25+
@JsonSerialize(using = House.Serializer.class)
26+
@JsonDeserialize(using = House.Deserializer.class)
27+
public final static class House {
28+
public String ownerName;
29+
30+
public House(final String ownerName) {
31+
this.ownerName = ownerName;
32+
}
33+
34+
@Override
35+
public boolean equals(final Object other) {
36+
return other instanceof House && ownerName.equals(((House) other).ownerName);
37+
}
38+
39+
@Override
40+
public int hashCode() {
41+
return Objects.hash(ownerName);
42+
}
43+
44+
public static class Serializer extends JsonSerializer<House> {
45+
@Override
46+
public void serialize(
47+
final House house,
48+
final JsonGenerator generator,
49+
final SerializerProvider serializers
50+
) throws IOException {
51+
generator.writeStartObject();
52+
generator.writeFieldName("owner");
53+
generator.writeStartObject();
54+
generator.writeFieldName("name");
55+
generator.writeObject(house.ownerName);
56+
generator.writeEndObject();
57+
generator.writeEndObject();
58+
}
59+
}
60+
61+
public static class Deserializer extends JsonDeserializer<House> {
62+
@Override
63+
public House deserialize(
64+
final JsonParser parser,
65+
final DeserializationContext context
66+
) throws IOException {
67+
// startObject
68+
parser.nextToken();
69+
// fieldName("owner")
70+
parser.nextToken();
71+
// writeStartObject
72+
parser.nextToken();
73+
// fieldName("name")
74+
parser.nextToken();
75+
76+
String ownerName = parser.readValueAs(String.class);
77+
78+
// endObject
79+
parser.nextToken();
80+
// endObject
81+
parser.nextToken();
82+
83+
return new House(ownerName);
84+
}
85+
}
86+
}
87+
88+
@Test
89+
public void testUnionCustomDeSerialization() throws IOException {
90+
Schema schema = SchemaBuilder.builder(House.class.getPackage().getName())
91+
.record(House.class.getSimpleName())
92+
.fields()
93+
.name("owner")
94+
.type()
95+
.optional()
96+
.record("Owner")
97+
.fields()
98+
.name("name")
99+
.type().nullable().stringType()
100+
.noDefault()
101+
.endRecord()
102+
.endRecord();
103+
104+
House house = new House("Jackson");
105+
106+
byte[] bytes = jacksonSerialize(schema, house);
107+
House result = jacksonDeserialize(schema, House.class, bytes);
108+
109+
assertThat(result).isEqualTo(house);
110+
}
111+
}

0 commit comments

Comments
 (0)