diff --git a/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/InstantDeserializer.java b/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/InstantDeserializer.java index 519cb30f..880f7c39 100644 --- a/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/InstantDeserializer.java +++ b/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/InstantDeserializer.java @@ -173,9 +173,6 @@ protected InstantDeserializer withDateFormat(DateTimeFormatter dtf) { @Override protected InstantDeserializer withLeniency(Boolean leniency) { - if (_isLenient == !Boolean.FALSE.equals(leniency)) { - return this; - } return new InstantDeserializer(this, _formatter, leniency); } diff --git a/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/JSR310DateTimeDeserializerBase.java b/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/JSR310DateTimeDeserializerBase.java index 07837b94..81c8caff 100644 --- a/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/JSR310DateTimeDeserializerBase.java +++ b/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/JSR310DateTimeDeserializerBase.java @@ -9,15 +9,15 @@ import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat.Feature; import com.fasterxml.jackson.annotation.JsonFormat.Shape; + import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; + import com.fasterxml.jackson.databind.BeanProperty; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.deser.ContextualDeserializer; -import com.fasterxml.jackson.databind.util.ClassUtil; @SuppressWarnings("serial") public abstract class JSR310DateTimeDeserializerBase @@ -26,21 +26,6 @@ public abstract class JSR310DateTimeDeserializerBase { protected final DateTimeFormatter _formatter; - /** - * Flag that indicates what leniency setting is enabled for this deserializer (either - * due {@link JsonFormat} annotation on property or class, or due to per-type - * "config override", or from global settings): leniency/strictness has effect - * on accepting some non-default input value representations (such as integer values - * for dates). - *

- * Note that global default setting is for leniency to be enabled, for Jackson 2.x, - * and has to be explicitly change to force strict handling: this is to keep backwards - * compatibility with earlier versions. - * - * @since 2.10 - */ - protected final boolean _isLenient; - /** * Setting that indicates the {@Link JsonFormat.Shape} specified for this deserializer * as a {@link JsonFormat.Shape} annotation on property or class, or due to per-type @@ -57,7 +42,6 @@ public abstract class JSR310DateTimeDeserializerBase protected JSR310DateTimeDeserializerBase(Class supportedType, DateTimeFormatter f) { super(supportedType); _formatter = f; - _isLenient = true; _shape = null; } @@ -65,9 +49,8 @@ protected JSR310DateTimeDeserializerBase(Class supportedType, DateTimeFormatt * @since 2.11 */ public JSR310DateTimeDeserializerBase(Class supportedType, DateTimeFormatter f, Boolean leniency) { - super(supportedType); + super(supportedType, leniency); _formatter = f; - _isLenient = !Boolean.FALSE.equals(leniency); _shape = null; } @@ -78,7 +61,6 @@ protected JSR310DateTimeDeserializerBase(JSR310DateTimeDeserializerBase base, DateTimeFormatter f) { super(base); _formatter = f; - _isLenient = base._isLenient; _shape = base._shape; } @@ -87,9 +69,8 @@ protected JSR310DateTimeDeserializerBase(JSR310DateTimeDeserializerBase base, */ protected JSR310DateTimeDeserializerBase(JSR310DateTimeDeserializerBase base, Boolean leniency) { - super(base); + super(base, leniency); _formatter = base._formatter; - _isLenient = !Boolean.FALSE.equals(leniency); _shape = base._shape; } @@ -97,11 +78,10 @@ protected JSR310DateTimeDeserializerBase(JSR310DateTimeDeserializerBase base, * @since 2.11 */ protected JSR310DateTimeDeserializerBase(JSR310DateTimeDeserializerBase base, - Shape shape) { + Shape shape) { super(base); _formatter = base._formatter; _shape = shape; - _isLenient = base._isLenient; } protected abstract JSR310DateTimeDeserializerBase withDateFormat(DateTimeFormatter dtf); @@ -109,6 +89,7 @@ protected JSR310DateTimeDeserializerBase(JSR310DateTimeDeserializerBase base, /** * @since 2.10 */ + @Override protected abstract JSR310DateTimeDeserializerBase withLeniency(Boolean leniency); /** @@ -116,7 +97,6 @@ protected JSR310DateTimeDeserializerBase(JSR310DateTimeDeserializerBase base, */ protected abstract JSR310DateTimeDeserializerBase withShape(Shape shape); - @Override public JsonDeserializer createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException @@ -124,6 +104,13 @@ public JsonDeserializer createContextual(DeserializationContext ctxt, JsonFormat.Value format = findFormatOverrides(ctxt, property, handledType()); JSR310DateTimeDeserializerBase deser = this; if (format != null) { + // 17-Aug-2019, tatu: For 2.10 let's start considering leniency/strictness too + if (format.hasLenient()) { + Boolean leniency = format.getLenient(); + if (leniency != null) { + deser = deser.withLeniency(leniency); + } + } if (format.hasPattern()) { final String pattern = format.getPattern(); final Locale locale = format.hasLocale() ? format.getLocale() : ctxt.getLocale(); @@ -139,25 +126,19 @@ public JsonDeserializer createContextual(DeserializationContext ctxt, df = builder.toFormatter(locale); } - if (format.hasLenient() && !format.isLenient()) { + // [#148]: allow strict parsing + if (!deser.isLenient()) { df = df.withResolverStyle(ResolverStyle.STRICT); } - //Issue #69: For instant serializers/deserializers we need to configure the formatter with + // [#69]: For instant serializers/deserializers we need to configure the formatter with //a time zone picked up from JsonFormat annotation, otherwise serialization might not work if (format.hasTimeZone()) { df = df.withZone(format.getTimeZone().toZoneId()); } deser = deser.withDateFormat(df); } - // 17-Aug-2019, tatu: For 2.10 let's start considering leniency/strictness too - if (format.hasLenient()) { - Boolean leniency = format.getLenient(); - if (leniency != null) { - deser = deser.withLeniency(leniency); - } - } - //Issue #58: For LocalDate deserializers we need to configure the formatter with + // [#58]: For LocalDate deserializers we need to configure the formatter with //a shape picked up from JsonFormat annotation, to decide if the value is EpochSeconds JsonFormat.Shape shape = format.getShape(); if (shape != null && shape != _shape) { @@ -168,15 +149,6 @@ public JsonDeserializer createContextual(DeserializationContext ctxt, return deser; } - /** - * @return {@code true} if lenient handling is enabled; {code false} if not (strict mode) - * - * @since 2.10 - */ - protected boolean isLenient() { - return _isLenient; - } - private boolean acceptCaseInsensitiveValues(DeserializationContext ctxt, JsonFormat.Value format) { Boolean enabled = format.getFeature( Feature.ACCEPT_CASE_INSENSITIVE_VALUES); @@ -193,13 +165,4 @@ protected void _throwNoNumericTimestampNeedTimeZone(JsonParser p, Deserializatio "raw timestamp (%d) not allowed for `%s`: need additional information such as an offset or time-zone (see class Javadocs)", p.getNumberValue(), handledType().getName()); } - - @SuppressWarnings("unchecked") - protected T _failForNotLenient(JsonParser p, DeserializationContext ctxt, - JsonToken expToken) throws IOException - { - return (T) ctxt.handleUnexpectedToken(handledType(), expToken, p, -"Cannot deserialize instance of %s out of %s token: not allowed because 'strict' mode set for property or type (enable 'lenient' handling to allow)", - ClassUtil.nameOf(handledType()), p.currentToken()); - } } diff --git a/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/JSR310DeserializerBase.java b/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/JSR310DeserializerBase.java index a075d011..f89a5da0 100644 --- a/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/JSR310DeserializerBase.java +++ b/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/JSR310DeserializerBase.java @@ -70,7 +70,7 @@ protected JSR310DeserializerBase(Class supportedType, protected JSR310DeserializerBase(JSR310DeserializerBase base) { super(base); - _isLenient = true; + _isLenient = base._isLenient; } protected JSR310DeserializerBase(JSR310DeserializerBase base, Boolean leniency) { @@ -155,7 +155,6 @@ protected R _handleUnexpectedToken(DeserializationContext context, } } - @SuppressWarnings("unchecked") protected R _handleUnexpectedToken(DeserializationContext context, JsonParser parser, JsonToken... expTypes) throws JsonMappingException { return _handleUnexpectedToken(context, parser, diff --git a/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserTest.java b/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserTest.java index f1b25232..d6868ee0 100644 --- a/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserTest.java +++ b/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserTest.java @@ -317,7 +317,7 @@ public void testCustomFormat() throws Exception @Test(expected = InvalidFormatException.class) public void testStrictCustomFormat() throws Exception { - StrictWrapper w = MAPPER.readValue("{\"value\":\"2019-11-31\"}", StrictWrapper.class); + /*StrictWrapper w =*/ MAPPER.readValue("{\"value\":\"2019-11-31\"}", StrictWrapper.class); } /* @@ -379,9 +379,9 @@ public void testDeserializationCaseInsensitiveDisabled_InvalidDate() throws Thro /* * Tests for issue 58 - NUMBER_INT should be specified when deserializing * LocalDate as EpochDays + * + /********************************************************************** */ - /********************************************************************** - */ @Test public void testLenientDeserializeFromNumberInt() throws Exception { ObjectMapper mapper = newMapper(); @@ -420,7 +420,7 @@ public void testStrictDeserializeFromString() throws Exception /********************************************************************** /* Helper methods /********************************************************************** - */ + */ private void expectFailure(ObjectReader reader, String json) throws Throwable { try { reader.readValue(aposToQuotes(json)); diff --git a/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalTimeDeserTest.java b/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalTimeDeserTest.java index 4c8c1848..e12b4aad 100644 --- a/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalTimeDeserTest.java +++ b/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalTimeDeserTest.java @@ -269,7 +269,7 @@ public void testStrictDeserializeFromEmptyString() throws Exception { objectReader.readValue(valueFromEmptyStr); } - /* + /* /********************************************************************** /* Strict JsonFormat tests /********************************************************************** @@ -280,7 +280,7 @@ public void testStrictDeserializeFromEmptyString() throws Exception { @Test(expected = InvalidFormatException.class) public void testStrictCustomFormatInvalidTime() throws Exception { - StrictWrapper w = MAPPER.readValue("{\"value\":\"25:45\"}", StrictWrapper.class); + /*StrictWrapper w =*/ MAPPER.readValue("{\"value\":\"25:45\"}", StrictWrapper.class); } private void expectFailure(String aposJson) throws Throwable {