diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/RangeDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/RangeDeserializer.java index f639e26a..137a4d48 100644 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/RangeDeserializer.java +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/RangeDeserializer.java @@ -197,16 +197,26 @@ private BoundType deserializeBoundType(DeserializationContext context, JsonParse { expect(context, JsonToken.VALUE_STRING, p.getCurrentToken()); String name = p.getText(); - try { - if (context.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS) && name != null) { - return BoundType.valueOf(name.toUpperCase()); + if (name == null) { + name = ""; + } + switch (name) { + case "OPEN": + return BoundType.OPEN; + case "CLOSED": + return BoundType.CLOSED; + } + if (context.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS)) { + if (name.equalsIgnoreCase("open")) { + return BoundType.OPEN; + } + if (name.equalsIgnoreCase("closed")) { + return BoundType.CLOSED; } - return BoundType.valueOf(name); - } catch (IllegalArgumentException e) { - return (BoundType) context.handleWeirdStringValue(BoundType.class, name, - "not a valid BoundType name (should be one oF: %s)", - Arrays.asList(BoundType.values())); } + return (BoundType) context.handleWeirdStringValue(BoundType.class, name, + "not a valid BoundType name (should be one of: %s)", + Arrays.asList(BoundType.values())); } private Comparable deserializeEndpoint(DeserializationContext context, JsonParser p) throws IOException diff --git a/guava/src/test/java/com/fasterxml/jackson/datatype/guava/RangeDeserializer102Test.java b/guava/src/test/java/com/fasterxml/jackson/datatype/guava/RangeDeserializer102Test.java index 5cceb057..ffcbb33f 100644 --- a/guava/src/test/java/com/fasterxml/jackson/datatype/guava/RangeDeserializer102Test.java +++ b/guava/src/test/java/com/fasterxml/jackson/datatype/guava/RangeDeserializer102Test.java @@ -6,18 +6,31 @@ import com.google.common.collect.BoundType; import com.google.common.collect.Range; -public class RangeDeserializer102Test extends ModuleTestBase { - - public void testBoundTypeIsOnlyOneOfOpenOrClosedInUpperCase() { - assertEquals(2, BoundType.values().length); - assertEquals("OPEN", BoundType.values()[0].name()); - assertEquals("CLOSED", BoundType.values()[1].name()); +public class RangeDeserializer102Test extends ModuleTestBase +{ + private final ObjectMapper MAPPER_DEFAULT = mapperWithModule(); + private final ObjectMapper MAPPER_CASE_INSENSITIVE = builderWithModule() + .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS) + .build(); + + public void testDeserializeDefaultSuccess() throws Exception + { + _testDeserializeOk(MAPPER_DEFAULT, "CLOSED", "OPEN"); } - public void testDeserializeAcceptCaseInsensitiveBoundTypeSuccess() throws Exception { - String json = a2q("{'lowerEndpoint': 1, 'lowerBoundType': 'closed', 'upperEndpoint': 2, 'upperBoundType': 'oPeN'}"); - ObjectMapper mapper = mapperWithModule().enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS); + public void testDeserializeAcceptCaseInsensitiveBoundTypeSuccess() throws Exception + { + _testDeserializeOk(MAPPER_CASE_INSENSITIVE, "CLOSED", "OPEN"); + _testDeserializeOk(MAPPER_CASE_INSENSITIVE, "closed", "OPEN"); + _testDeserializeOk(MAPPER_CASE_INSENSITIVE, "CLOSED", "open"); + _testDeserializeOk(MAPPER_CASE_INSENSITIVE, "Closed", "Open"); + _testDeserializeOk(MAPPER_CASE_INSENSITIVE, "ClOseD", "opEN"); + } + private void _testDeserializeOk(ObjectMapper mapper, + String lowerType, String upperType) throws Exception { + String json = a2q("{'lowerEndpoint': 1, 'lowerBoundType': '"+lowerType + +"', 'upperEndpoint': 2, 'upperBoundType': '"+upperType+"'}"); Range range = mapper.readValue(json, Range.class); assertEquals(1, range.lowerEndpoint()); @@ -28,27 +41,23 @@ public void testDeserializeAcceptCaseInsensitiveBoundTypeSuccess() throws Except public void testDeserializeBoundTypeFailWithFirstInvalidValue() throws Exception { String json = a2q("{'lowerEndpoint': 1, 'lowerBoundType': 'closed', 'upperEndpoint': 2, 'upperBoundType': 'oPeN'}"); - ObjectMapper mapper = mapperWithModule().disable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS); - try { - mapper.readValue(json, Range.class); + MAPPER_DEFAULT.readValue(json, Range.class); fail("should not pass"); } catch (InvalidFormatException e) { verifyException(e, "Cannot deserialize value of type `com.google.common.collect.BoundType` from " + - "String \"closed\": not a valid BoundType name (should be one oF: [OPEN, CLOSED])"); + "String \"closed\": not a valid BoundType name (should be one of: [OPEN, CLOSED])"); } } public void testDeserializeBoundTypeFailWithFirstInvalidValueFlip() throws Exception { String json = a2q("{'upperEndpoint': 2, 'upperBoundType': 'oPeN', 'lowerEndpoint': 1, 'lowerBoundType': 'closed'}"); - ObjectMapper mapper = mapperWithModule().disable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS); - try { - mapper.readValue(json, Range.class); + MAPPER_DEFAULT.readValue(json, Range.class); fail("should not pass"); } catch (InvalidFormatException e) { verifyException(e, "Cannot deserialize value of type `com.google.common.collect.BoundType` from " + - "String \"oPeN\": not a valid BoundType name (should be one oF: [OPEN, CLOSED])"); + "String \"oPeN\": not a valid BoundType name (should be one of: [OPEN, CLOSED])"); } } } diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x index fbc1cdb5..a98bd173 100644 --- a/release-notes/CREDITS-2.x +++ b/release-notes/CREDITS-2.x @@ -82,3 +82,12 @@ Migwel Gonzalez (Migwel@github) by default (2.12.0) +Andrey Borisov (turbospaces@github) + * Requested #102: (guava) accept lowerCase enums for `Range` `BoundType` + serialization + (2.15.0) + +Joo Hyuk Kim (JooHyukKim@github) + * Contributed fix for #102: (guava) accept lowerCase enums for `Range` + `BoundType` serialization + (2.15.0) diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index b2bd481a..1da62c29 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -18,6 +18,9 @@ Active Maintainers: 2.15.0 (not yet released) +#102: (guava) accept lowerCase enums for `Range` `BoundType` serialization + (requested by Andrey B) + (fix contributed by Joo-Hyuk K) #105: (guava) Update Guava dependency to 23.6.1-jre (from 21.0) #106: (guava) There maybe a misusage in GuavaMultimapDeserializer.findTransformer method (contributed by @magical-l)