Skip to content

Commit

Permalink
Start work on #129
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Aug 17, 2019
1 parent bb8ad7f commit b00073e
Show file tree
Hide file tree
Showing 13 changed files with 187 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,19 @@ protected InstantDeserializer(InstantDeserializer<T> base, Boolean adjustToConte
}

@Override
protected JsonDeserializer<T> withDateFormat(DateTimeFormatter dtf) {
protected InstantDeserializer<T> withDateFormat(DateTimeFormatter dtf) {
if (dtf == _formatter) {
return this;
}
return new InstantDeserializer<T>(this, dtf);
}

// !!! TODO: lenient vs strict?
@Override
protected InstantDeserializer<T> withLeniency(Boolean leniency) {
return this;
}

@SuppressWarnings("unchecked")
@Override
public T deserialize(JsonParser parser, DeserializationContext context) throws IOException
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import com.fasterxml.jackson.annotation.JsonFormat;
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;
Expand All @@ -19,19 +20,60 @@ public abstract class JSR310DateTimeDeserializerBase<T>
{
protected final DateTimeFormatter _formatter;

protected JSR310DateTimeDeserializerBase(Class<T> supportedType, DateTimeFormatter f)
{
/**
* 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).
*<p>
* 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;

protected JSR310DateTimeDeserializerBase(Class<T> supportedType, DateTimeFormatter f) {
super(supportedType);
_formatter = f;
_isLenient = true;
}

protected abstract JsonDeserializer<T> withDateFormat(DateTimeFormatter dtf);
/**
* @since 2.10
*/
protected JSR310DateTimeDeserializerBase(JSR310DateTimeDeserializerBase<T> base,
DateTimeFormatter f) {
super(base);
_formatter = f;
_isLenient = base._isLenient;
}

/**
* @since 2.10
*/
protected JSR310DateTimeDeserializerBase(JSR310DateTimeDeserializerBase<T> base,
Boolean leniency) {
super(base);
_formatter = base._formatter;
_isLenient = !Boolean.FALSE.equals(leniency);
}

protected abstract JSR310DateTimeDeserializerBase<T> withDateFormat(DateTimeFormatter dtf);

/**
* @since 2.10
*/
protected abstract JSR310DateTimeDeserializerBase<T> withLeniency(Boolean leniency);

@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
BeanProperty property) throws JsonMappingException
{
JsonFormat.Value format = findFormatOverrides(ctxt, property, handledType());
JSR310DateTimeDeserializerBase<?> deser = this;
if (format != null) {
if (format.hasPattern()) {
final String pattern = format.getPattern();
Expand All @@ -47,18 +89,42 @@ public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
if (format.hasTimeZone()) {
df = df.withZone(format.getTimeZone().toZoneId());
}
return withDateFormat(df);
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);
}
}
// any use for TimeZone?
}
return this;
}
return deser;
}

/**
* @return {@code true} if lenient handling is enabled; {code false} if not (strict mode)
*
* @since 2.10
*/
protected boolean isLenient() {
return _isLenient;
}

protected void _throwNoNumericTimestampNeedTimeZone(JsonParser p, DeserializationContext ctxt)
throws IOException
{
ctxt.reportInputMismatch(handledType(),
"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,
"not allowed because 'strict' mode set for property or type (enabled 'lenient' handling to allow)");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,17 @@ abstract class JSR310DeserializerBase<T> extends StdScalarDeserializer<T>
{
private static final long serialVersionUID = 1L;

protected JSR310DeserializerBase(Class<T> supportedType)
{
protected JSR310DeserializerBase(Class<T> supportedType) {
super(supportedType);
}

/**
* @since 2.10
*/
protected JSR310DeserializerBase(JSR310DeserializerBase<?> base) {
super(base);
}

@Override
public Object deserializeWithType(JsonParser parser, DeserializationContext context,
TypeDeserializer typeDeserializer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,11 @@
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;

/**
* Deserializer for Java 8 temporal {@link LocalDate}s.
*
* @author Nick Williams
* @since 2.2.0
*/
public class LocalDateDeserializer extends JSR310DateTimeDeserializerBase<LocalDate>
{
Expand All @@ -43,19 +41,38 @@ public class LocalDateDeserializer extends JSR310DateTimeDeserializerBase<LocalD

public static final LocalDateDeserializer INSTANCE = new LocalDateDeserializer();

private LocalDateDeserializer() {
protected LocalDateDeserializer() {
this(DEFAULT_FORMATTER);
}

public LocalDateDeserializer(DateTimeFormatter dtf) {
super(LocalDate.class, dtf);
}

/**
* Since 2.10
*/
public LocalDateDeserializer(LocalDateDeserializer base, DateTimeFormatter dtf) {
super(base, dtf);
}

/**
* Since 2.10
*/
protected LocalDateDeserializer(LocalDateDeserializer base, Boolean leniency) {
super(base, leniency);
}

@Override
protected JsonDeserializer<LocalDate> withDateFormat(DateTimeFormatter dtf) {
return new LocalDateDeserializer(dtf);
protected LocalDateDeserializer withDateFormat(DateTimeFormatter dtf) {
return new LocalDateDeserializer(this, dtf);
}


@Override
protected LocalDateDeserializer withLeniency(Boolean leniency) {
return new LocalDateDeserializer(this, leniency);
}

@Override
public LocalDate deserialize(JsonParser parser, DeserializationContext context) throws IOException
{
Expand Down Expand Up @@ -116,6 +133,9 @@ public LocalDate deserialize(JsonParser parser, DeserializationContext context)
}
// 06-Jan-2018, tatu: Is this actually safe? Do users expect such coercion?
if (parser.hasToken(JsonToken.VALUE_NUMBER_INT)) {
if (!isLenient()) {
return _failForNotLenient(parser, context, JsonToken.VALUE_STRING);
}
return LocalDate.ofEpochDay(parser.getLongValue());
}
return _handleUnexpectedToken(context, parser, "Expected array or string.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import com.fasterxml.jackson.core.JsonTokenId;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;

/**
* Deserializer for Java 8 temporal {@link LocalDateTime}s.
Expand All @@ -54,10 +53,16 @@ public LocalDateTimeDeserializer(DateTimeFormatter formatter) {
}

@Override
protected JsonDeserializer<LocalDateTime> withDateFormat(DateTimeFormatter formatter) {
protected LocalDateTimeDeserializer withDateFormat(DateTimeFormatter formatter) {
return new LocalDateTimeDeserializer(formatter);
}

// !!! TODO: lenient vs strict?
@Override
protected LocalDateTimeDeserializer withLeniency(Boolean leniency) {
return this;
}

@Override
public LocalDateTime deserialize(JsonParser parser, DeserializationContext context) throws IOException
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;

/**
* Deserializer for Java 8 temporal {@link LocalTime}s.
*
* @author Nick Williams
* @since 2.2.0
*/
public class LocalTimeDeserializer extends JSR310DateTimeDeserializerBase<LocalTime>
{
Expand All @@ -50,10 +48,16 @@ public LocalTimeDeserializer(DateTimeFormatter formatter) {
}

@Override
protected JsonDeserializer<LocalTime> withDateFormat(DateTimeFormatter formatter) {
protected LocalTimeDeserializer withDateFormat(DateTimeFormatter formatter) {
return new LocalTimeDeserializer(formatter);
}


// !!! TODO: lenient vs strict?
@Override
protected LocalTimeDeserializer withLeniency(Boolean leniency) {
return this;
}

@Override
public LocalTime deserialize(JsonParser parser, DeserializationContext context) throws IOException
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;

/**
* Deserializer for Java 8 temporal {@link MonthDay}s.
Expand All @@ -25,10 +24,16 @@ public MonthDayDeserializer(DateTimeFormatter formatter) {
}

@Override
protected JsonDeserializer<MonthDay> withDateFormat(DateTimeFormatter dtf) {
protected MonthDayDeserializer withDateFormat(DateTimeFormatter dtf) {
return new MonthDayDeserializer(dtf);
}


// !!! TODO: lenient vs strict?
@Override
protected MonthDayDeserializer withLeniency(Boolean leniency) {
return this;
}

@Override
public MonthDay deserialize(JsonParser parser, DeserializationContext context) throws IOException
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,16 @@ protected OffsetTimeDeserializer(DateTimeFormatter dtf) {
}

@Override
protected JsonDeserializer<OffsetTime> withDateFormat(DateTimeFormatter dtf) {
protected OffsetTimeDeserializer withDateFormat(DateTimeFormatter dtf) {
return new OffsetTimeDeserializer(dtf);
}


// !!! TODO: lenient vs strict?
@Override
protected OffsetTimeDeserializer withLeniency(Boolean leniency) {
return this;
}

@Override
public OffsetTime deserialize(JsonParser parser, DeserializationContext context) throws IOException
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

import java.io.IOException;
import java.time.DateTimeException;
Expand All @@ -30,7 +29,6 @@
* Deserializer for Java 8 temporal {@link Year}s.
*
* @author Nick Williams
* @since 2.2
*/
public class YearDeserializer extends JSR310DateTimeDeserializerBase<Year>
{
Expand All @@ -48,10 +46,16 @@ public YearDeserializer(DateTimeFormatter formatter) {
}

@Override
protected JsonDeserializer<Year> withDateFormat(DateTimeFormatter dtf) {
protected YearDeserializer withDateFormat(DateTimeFormatter dtf) {
return new YearDeserializer(dtf);
}

// !!! TODO: lenient vs strict?
@Override
protected YearDeserializer withLeniency(Boolean leniency) {
return this;
}

@Override
public Year deserialize(JsonParser parser, DeserializationContext context) throws IOException
{
Expand Down
Loading

0 comments on commit b00073e

Please sign in to comment.