From a4824653ab9da1ad5929ef21c0c12512b9dc7266 Mon Sep 17 00:00:00 2001 From: peter royal Date: Tue, 24 Nov 2015 11:11:40 -0600 Subject: [PATCH] translate BigDecimal into a double for serialization. deserialization is not supported yet --- .../avro/ser/NonBSGenericDatumWriter.java | 22 ++++++++++ .../dataformat/avro/BigDecimalTest.java | 40 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 src/test/java/com/fasterxml/jackson/dataformat/avro/BigDecimalTest.java diff --git a/src/main/java/com/fasterxml/jackson/dataformat/avro/ser/NonBSGenericDatumWriter.java b/src/main/java/com/fasterxml/jackson/dataformat/avro/ser/NonBSGenericDatumWriter.java index 22a1560..6e923b8 100644 --- a/src/main/java/com/fasterxml/jackson/dataformat/avro/ser/NonBSGenericDatumWriter.java +++ b/src/main/java/com/fasterxml/jackson/dataformat/avro/ser/NonBSGenericDatumWriter.java @@ -1,10 +1,13 @@ package com.fasterxml.jackson.dataformat.avro.ser; +import java.io.IOException; +import java.math.BigDecimal; import java.util.List; import org.apache.avro.Schema; import org.apache.avro.Schema.Type; import org.apache.avro.generic.GenericDatumWriter; +import org.apache.avro.io.Encoder; /** * Need to sub-class to prevent encoder from crapping on writing an optional @@ -36,8 +39,27 @@ public int resolveUnion(Schema union, Object datum) { default: } } + } else if( datum instanceof BigDecimal) { + List schemas = union.getTypes(); + for (int i = 0, len = schemas.size(); i < len; ++i) { + Schema s = schemas.get(i); + switch (s.getType()) { + case DOUBLE: + return i; + default: + } + } } // otherwise just default to base impl, stupid as it is... return super.resolveUnion(union, datum); } + + @Override + protected void write(Schema schema, Object datum, Encoder out) throws IOException { + if(schema.getType() == Type.DOUBLE && datum instanceof BigDecimal) { + out.writeDouble(((BigDecimal)datum).doubleValue()); + } else { + super.write(schema, datum, out); + } + } } diff --git a/src/test/java/com/fasterxml/jackson/dataformat/avro/BigDecimalTest.java b/src/test/java/com/fasterxml/jackson/dataformat/avro/BigDecimalTest.java new file mode 100644 index 0000000..b0c0103 --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/dataformat/avro/BigDecimalTest.java @@ -0,0 +1,40 @@ +package com.fasterxml.jackson.dataformat.avro; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import junit.framework.TestCase; +import org.junit.Test; + +import java.math.BigDecimal; + + +public class BigDecimalTest extends TestCase { + + @Test + public void testSSerializeBigDecimal() throws Exception { + AvroMapper mapper = new AvroMapper(); + AvroSchema schema = mapper.schemaFor(NamedAmount.class); + + byte[] bytes = mapper.writer(schema) + .writeValueAsBytes(new NamedAmount("peter", 42.0)); + + NamedAmount result = mapper.reader(schema).forType(NamedAmount.class).readValue(bytes); + + assertEquals("peter", result.name); + assertEquals(BigDecimal.valueOf(42.0), result.amount); + } + + public static class NamedAmount { + public final String name; + public final BigDecimal amount; + + @JsonCreator + public NamedAmount(@JsonProperty("name") String name, + @JsonProperty("amount") double amount) { + this.name = name; + this.amount = BigDecimal.valueOf(amount); + } + + + } +}