diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java index 0a879c2559..1d5614f6aa 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java @@ -367,6 +367,24 @@ protected final boolean _parseBooleanPrimitive(DeserializationContext ctxt, return ((Boolean) ctxt.handleUnexpectedToken(ctxt.constructType(Boolean.TYPE), p)).booleanValue(); } + /** + * Helper method called for cases where non-primitive, boolean-based value + * is to be deserialized: result of this method will be {@link java.lang.Boolean}, + * although actual target type may be something different. + *

+ * Note: does NOT dynamically access "empty value" or "null value" of deserializer + * since those values could be of type other than {@link java.lang.Boolean}. + * Caller may need to translate from 3 possible result types into appropriately + * matching output types. + * + * @param ctxt Deserialization context for accessing configuration + * @param p Underlying parser + * @param targetType Actual type that is being deserialized, may be + * same as {@link #handledType} but could be {@code AtomicBoolean} for example. + * Used for coercion config access. + * + * @since 2.12 + */ protected final Boolean _parseBoolean(DeserializationContext ctxt, JsonParser p, Class targetType) throws IOException @@ -377,37 +395,36 @@ protected final Boolean _parseBoolean(DeserializationContext ctxt, CoercionAction act = _checkFromStringCoercion(ctxt, text, LogicalType.Boolean, targetType); if (act == CoercionAction.AsNull) { - return (Boolean) getNullValue(ctxt); + return null; } if (act == CoercionAction.AsEmpty) { - return (Boolean) getEmptyValue(ctxt); + return false; } text = text.trim(); // [databind#422]: Allow aliases if ("true".equals(text) || "True".equals(text)) { - return Boolean.TRUE; + return true; } if ("false".equals(text) || "False".equals(text)) { - return Boolean.FALSE; + return false; } if (_checkTextualNull(ctxt, text)) { - return (Boolean) getNullValue(ctxt); + return null; } - return (Boolean) ctxt.handleWeirdStringValue(_valueClass, text, + return (Boolean) ctxt.handleWeirdStringValue(targetType, text, "only \"true\" or \"false\" recognized"); case JsonTokenId.ID_TRUE: return true; case JsonTokenId.ID_FALSE: return false; case JsonTokenId.ID_NULL: // null fine for non-primitive - return (Boolean) getNullValue(ctxt); + return null; case JsonTokenId.ID_NUMBER_INT: // may accept ints too, (0 == false, otherwise true) return _coerceBooleanFromInt(ctxt, p, targetType); case JsonTokenId.ID_START_ARRAY: // unwrapping / from-empty-array coercion? return (Boolean) _deserializeFromArray(p, ctxt); } - // Otherwise, no can do: return (Boolean) ctxt.handleUnexpectedToken(ctxt.constructType(targetType), p); } diff --git a/src/test/java/com/fasterxml/jackson/databind/convert/CoerceJDKScalarsTest.java b/src/test/java/com/fasterxml/jackson/databind/convert/CoerceJDKScalarsTest.java index 6e553e401d..8a7c4075cb 100644 --- a/src/test/java/com/fasterxml/jackson/databind/convert/CoerceJDKScalarsTest.java +++ b/src/test/java/com/fasterxml/jackson/databind/convert/CoerceJDKScalarsTest.java @@ -5,6 +5,7 @@ import java.io.StringReader; import java.math.BigDecimal; import java.math.BigInteger; +import java.util.concurrent.atomic.AtomicBoolean; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; @@ -52,6 +53,7 @@ public void testNullValueFromEmpty() throws Exception _verifyNullOkFromEmpty(BigInteger.class, null); _verifyNullOkFromEmpty(BigDecimal.class, null); + _verifyNullOkFromEmpty(AtomicBoolean.class, null); } private void _verifyNullOkFromEmpty(Class type, Object exp) throws IOException @@ -88,6 +90,7 @@ public void testNullFailFromEmpty() throws Exception _verifyNullFail(BigInteger.class); _verifyNullFail(BigDecimal.class); + _verifyNullFail(AtomicBoolean.class); } private void _verifyNullFail(Class type) throws IOException @@ -137,6 +140,10 @@ public void testStringCoercionOk() throws Exception _verifyCoerceSuccess(quote("123"), BigInteger.class, BigInteger.valueOf(123)); _verifyCoerceSuccess(quote("123.0"), BigDecimal.class, new BigDecimal("123.0")); + + AtomicBoolean ab = COERCING_MAPPER.readValue(quote("true"), AtomicBoolean.class); + assertNotNull(ab); + assertTrue(ab.get()); } public void testStringCoercionFailBoolean() throws Exception