diff --git a/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/key/YearKeyDeserializer.java b/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/key/YearKeyDeserializer.java index 1ffae9b7..d1b8fc90 100644 --- a/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/key/YearKeyDeserializer.java +++ b/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/key/YearKeyDeserializer.java @@ -15,23 +15,19 @@ public class YearKeyDeserializer extends Jsr310KeyDeserializer { public static final YearKeyDeserializer INSTANCE = new YearKeyDeserializer(); - /* - * formatter copied from Year. There is no way of getting a reference to the formatter it uses. - */ - private static final DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder() - .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD) - .toFormatter(); - private YearKeyDeserializer() { // singleton } @Override protected Year deserialize(String key, DeserializationContext ctxt) throws IOException { + try { - return Year.parse(key, FORMATTER); - } catch (DateTimeException e) { - return _handleDateTimeException(ctxt, Year.class, e, key); + return Year.of(Integer.parseInt(key)); + } catch (NumberFormatException nfe) { + return _handleDateTimeException(ctxt, Year.class, new DateTimeException("Number format exception", nfe), key); + } catch (DateTimeException dte) { + return _handleDateTimeException(ctxt, Year.class, dte, key); } } } diff --git a/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/key/YearAsKeyTest.java b/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/key/YearAsKeyTest.java index 8b6f9e79..2eaf626f 100644 --- a/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/key/YearAsKeyTest.java +++ b/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/key/YearAsKeyTest.java @@ -1,16 +1,18 @@ package com.fasterxml.jackson.datatype.jsr310.key; -import java.time.Year; -import java.util.Map; - import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.exc.InvalidFormatException; import com.fasterxml.jackson.datatype.jsr310.ModuleTestBase; - -import org.junit.Assert; import org.junit.Test; +import java.time.Year; +import java.util.Collections; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + public class YearAsKeyTest extends ModuleTestBase { private static final TypeReference> TYPE_REF = new TypeReference>() { @@ -20,13 +22,34 @@ public class YearAsKeyTest extends ModuleTestBase @Test public void testSerialization() throws Exception { - Assert.assertEquals("Value is incorrect", mapAsString("3141", "test"), + assertEquals("Value is incorrect", mapAsString("3141", "test"), MAPPER.writeValueAsString(asMap(Year.of(3141), "test"))); } @Test public void testDeserialization() throws Exception { - Assert.assertEquals("Value is incorrect", asMap(Year.of(3141), "test"), + assertEquals("Value is incorrect", asMap(Year.of(3141), "test"), READER.readValue(mapAsString("3141", "test"))); } + + @Test(expected = InvalidFormatException.class) + public void deserializeYearKey_notANumber() throws Exception { + READER.readValue(mapAsString("10000BC", "test")); + } + + @Test(expected = InvalidFormatException.class) + public void deserializeYearKey_notAYear() throws Exception { + READER.readValue(mapAsString(Integer.toString(Year.MAX_VALUE+1), "test")); + } + + @Test + public void serializeAndDeserializeYearKeyUnpadded() throws Exception { + // fix for issue #51 verify we can deserialize an unpadded year e.g. "1" + ObjectMapper unpaddedMapper = newMapper(); + Map testMap = Collections.singletonMap(Year.of(1), 1F); + String serialized = unpaddedMapper.writeValueAsString(testMap); + TypeReference> yearFloatTypeReference = new TypeReference>() {}; + Map deserialized = unpaddedMapper.readValue(serialized, yearFloatTypeReference); + assertEquals(testMap, deserialized); + } }