Skip to content

Commit

Permalink
Sync with com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15…
Browse files Browse the repository at this point in the history
  • Loading branch information
joschi authored Aug 14, 2023
1 parent a690516 commit 833d68a
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,6 @@ public class InstantDeserializer<T extends Temporal>
{
private static final long serialVersionUID = 1L;

/**
* Constants used to check if the time offset is zero. See [jackson-modules-java8#18]
*
* @since 2.9.0
*/
private static final Pattern ISO8601_UTC_ZERO_OFFSET_SUFFIX_REGEX = Pattern.compile("\\+00:?(00)?$");

/**
* Constants used to check if ISO 8601 time string is colonless. See [jackson-modules-java8#131]
*
Expand Down Expand Up @@ -288,7 +281,7 @@ public T deserialize(JsonParser parser, DeserializationContext context) throws I
return (T) parser.getEmbeddedObject();

case JsonTokenId.ID_START_ARRAY:
return _deserializeFromArray(parser, context);
return _deserializeFromArray(parser, context);
}
return _handleUnexpectedToken(context, parser, JsonToken.VALUE_STRING,
JsonToken.VALUE_NUMBER_INT, JsonToken.VALUE_NUMBER_FLOAT);
Expand Down Expand Up @@ -398,18 +391,45 @@ public FromDecimalArguments apply(Long s, Integer ns) {
private ZoneId getZone(DeserializationContext context)
{
// Instants are always in UTC, so don't waste compute cycles
return (_valueClass == Instant.class) ? null : DateTimeUtils.toZoneId(context.getTimeZone());
// Normalizing the zone to prevent discrepancies.
// See https://github.com/FasterXML/jackson-modules-java8/pull/267 for details
return (_valueClass == Instant.class) ? null : DateTimeUtils.toZoneId(context.getTimeZone()).normalized();
}

private String replaceZeroOffsetAsZIfNecessary(String text)
{
if (replaceZeroOffsetAsZ) {
return ISO8601_UTC_ZERO_OFFSET_SUFFIX_REGEX.matcher(text).replaceFirst("Z");
return replaceZeroOffsetAsZ(text);
}

return text;
}

private static String replaceZeroOffsetAsZ(String text)
{
int plusIndex = text.lastIndexOf('+');
if (plusIndex < 0) {
return text;
}
int maybeOffsetIndex = plusIndex + 1;
int remaining = text.length() - maybeOffsetIndex;
switch (remaining) {
case 2:
return text.regionMatches(maybeOffsetIndex, "00", 0, remaining)
? text.substring(0, plusIndex) + 'Z'
: text;
case 4:
return text.regionMatches(maybeOffsetIndex, "0000", 0, remaining)
? text.substring(0, plusIndex) + 'Z'
: text;
case 5:
return text.regionMatches(maybeOffsetIndex, "00:00", 0, remaining)
? text.substring(0, plusIndex) + 'Z'
: text;
}
return text;
}

// @since 2.13
private String addInColonToOffsetIfMissing(String text)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ protected ThreeTenDateTimeDeserializerBase<?> _withFormatOverrides(Deserializati

private boolean acceptCaseInsensitiveValues(DeserializationContext ctxt, JsonFormat.Value format)
{
Boolean enabled = format.getFeature( Feature.ACCEPT_CASE_INSENSITIVE_VALUES);
if( enabled == null) {
Boolean enabled = format.getFeature(Feature.ACCEPT_CASE_INSENSITIVE_VALUES);
if (enabled == null) {
enabled = ctxt.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_VALUES);
}
return enabled;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonIntegerFormatVisitor;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonNumberFormatVisitor;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonValueFormat;
import com.fasterxml.jackson.datatype.threetenbp.DecimalUtils;

/**
Expand Down Expand Up @@ -128,6 +129,7 @@ protected void _acceptTimestampVisitor(JsonFormatVisitorWrapper visitor, JavaTyp
JsonIntegerFormatVisitor v2 = visitor.expectIntegerFormat(typeHint);
if (v2 != null) {
v2.numberType(NumberType.LONG);
v2.format(JsonValueFormat.UTC_MILLISEC);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.fasterxml.jackson.datatype.threetenbp.deser;

import org.junit.Ignore;
import org.threeten.bp.*;
import org.threeten.bp.format.DateTimeFormatter;
import org.threeten.bp.temporal.ChronoUnit;
Expand All @@ -23,6 +24,7 @@
import static com.fasterxml.jackson.datatype.threetenbp.deser.InstantDeserializer.ISO8601_COLONLESS_OFFSET_REGEX;
import static org.junit.Assert.*;
import static org.junit.Assert.assertNull;
import static org.junit.Assume.assumeTrue;

public class InstantDeserTest extends ModuleTestBase
{
Expand Down Expand Up @@ -388,9 +390,9 @@ public void testCustomPatternWithAnnotations02() throws Exception
{
//Test date is pushed one year after start of the epoch just to avoid possible issues with UTC-X TZs which could
//push the instant before tha start of the epoch
final Instant instant = ZonedDateTime.ofInstant(Instant.ofEpochMilli(0), ZoneId.of("UTC")).plusYears(1).toInstant();
final Instant instant = ZonedDateTime.ofInstant(Instant.ofEpochMilli(0), ZoneOffset.UTC).plusYears(1).toInstant();
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(CUSTOM_PATTERN);
final String valueInUTC = formatter.withZone(ZoneId.of("UTC")).format(instant);
final String valueInUTC = formatter.withZone(ZoneOffset.UTC).format(instant);

final WrapperWithCustomPattern input = new WrapperWithCustomPattern(instant);
String json = MAPPER.writeValueAsString(input);
Expand Down Expand Up @@ -434,10 +436,46 @@ public void testDeserializationFromStringWithZeroZoneOffset03() throws Exception
assertEquals("The value is not correct.", date, result);
}

@Test
@Ignore("Currently not implemented in ThreeTenBP - https://bugs.openjdk.org/browse/JDK-8166138")
public void testDeserializationFromStringWithZeroZoneOffset04() throws Exception {
assumeInstantCanParseOffsets();
Instant date = Instant.now();
String json = formatWithZeroZoneOffset(date, "+00:30");
Instant result = READER.readValue(json);
assertNotEquals("The value is not correct.", date, result);
}

@Test
@Ignore("Currently not implemented in ThreeTenBP - https://bugs.openjdk.org/browse/JDK-8166138")
public void testDeserializationFromStringWithZeroZoneOffset05() throws Exception {
assumeInstantCanParseOffsets();
Instant date = Instant.now();
String json = formatWithZeroZoneOffset(date, "+01:30");
Instant result = READER.readValue(json);
assertNotEquals("The value is not correct.", date, result);
}

@Test
@Ignore("Currently not implemented in ThreeTenBP - https://bugs.openjdk.org/browse/JDK-8166138")
public void testDeserializationFromStringWithZeroZoneOffset06() throws Exception {
assumeInstantCanParseOffsets();
Instant date = Instant.now();
String json = formatWithZeroZoneOffset(date, "-00:00");
Instant result = READER.readValue(json);
assertEquals("The value is not correct.", date, result);
}

private String formatWithZeroZoneOffset(Instant date, String offset){
return '"' + FORMATTER.format(date).replaceFirst("Z$", offset) + '"';
}

private static void assumeInstantCanParseOffsets() {
// DateTimeFormatter.ISO_INSTANT didn't handle offsets until JDK 12+.
// This was added by https://bugs.openjdk.org/browse/JDK-8166138
assumeTrue(System.getProperty("java.specification.version").compareTo("12") > 0);
}

/*
/**********************************************************************
/* Deserialization, misc other
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.threeten.bp.ZoneId;
import org.threeten.bp.ZoneOffset;
import org.threeten.bp.ZonedDateTime;
import org.threeten.bp.format.DateTimeFormatter;
import org.threeten.bp.format.DateTimeParseException;
import java.util.Map;

Expand All @@ -37,10 +38,34 @@ static class WrapperWithFeatures {
public void testDeserializationAsString01() throws Exception
{
assertEquals("The value is not correct.",
ZonedDateTime.of(2000, 1, 1, 12, 0, 0, 0, ZoneId.of("UTC")),
ZonedDateTime.of(2000, 1, 1, 12, 0, 0, 0, ZoneOffset.UTC),
READER.readValue(q("2000-01-01T12:00Z")));
}

@Test
public void testDeserializationComparedToStandard() throws Throwable
{
String inputString = "2021-02-01T19:49:04.0513486Z";

assertEquals("The value is not correct.",
DateTimeFormatter.ISO_ZONED_DATE_TIME.parse(inputString, ZonedDateTime::from),
READER.readValue(q(inputString)));
}

@Test
public void testDeserializationComparedToStandard2() throws Throwable
{
String inputString = "2021-02-01T19:49:04.0513486Z[UTC]";

ZonedDateTime converted = newMapper()
.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false)
.readerFor(ZonedDateTime.class).readValue(q(inputString));

assertEquals("The value is not correct.",
DateTimeFormatter.ISO_ZONED_DATE_TIME.parse(inputString, ZonedDateTime::from),
converted);
}

@Test
public void testBadDeserializationAsString01() throws Throwable
{
Expand Down Expand Up @@ -92,7 +117,7 @@ public void testDeserializationAsArrayEnabled() throws Throwable
.configure(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS, true)
.readerFor(ZonedDateTime.class).readValue(a2q(json));
assertEquals("The value is not correct.",
ZonedDateTime.of(2000, 1, 1, 12, 0, 0, 0, ZoneId.of("UTC")),
ZonedDateTime.of(2000, 1, 1, 12, 0, 0, 0, ZoneOffset.UTC),
value);

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,13 @@ public void numberType(JsonParser.NumberType format) {
public JsonIntegerFormatVisitor expectIntegerFormat(JavaType type) throws JsonMappingException {
return new JsonIntegerFormatVisitor.Base() {
@Override
public void numberType(JsonParser.NumberType format) {
traversedProperties.put(baseName, "INTEGER/"+format.name());
public void numberType(JsonParser.NumberType numberType) {
traversedProperties.put(baseName + "numberType", "INTEGER/" + numberType.name());
}

@Override
public void format(JsonValueFormat format) {
traversedProperties.put(baseName + "format", "INTEGER/" + format.name());
}
};
}
Expand Down Expand Up @@ -129,7 +134,7 @@ public void setProvider(SerializerProvider provider) {
private final ObjectMapper MAPPER = newMapper();

// // // Local date/time types

// [modules-java8#105]
@Test
public void testLocalTimeSchema() throws Exception
Expand Down Expand Up @@ -182,14 +187,23 @@ public void testDateTimeSchema() throws Exception
Assert.assertEquals(1, properties.size());
_verifyBigDecimalType(properties.get(""));

// but becomes long
wrapper = new VisitorWrapper(null, "", new HashMap<String, String>());
MAPPER.writer()
.without(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS)
.acceptJsonFormatVisitor(ZonedDateTime.class, wrapper);
properties = wrapper.getTraversedProperties();
_verifyLongType(properties.get("numberType"));
_verifyLongFormat(properties.get("format"));

// but becomes date/time
wrapper = new VisitorWrapper(null, "", new HashMap<String, String>());
MAPPER.writer().without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.acceptJsonFormatVisitor(ZonedDateTime.class, wrapper);
properties = wrapper.getTraversedProperties();
_verifyDateTimeType(properties.get(""));
}

private void _verifyIntArrayType(String desc) {
Assert.assertEquals("ARRAY/Ljava/util/List<Ljava/lang/Integer;>;", desc);
}
Expand All @@ -209,4 +223,12 @@ private void _verifyDateTimeType(String desc) {
private void _verifyBigDecimalType(String desc) {
Assert.assertEquals("NUMBER/BIG_DECIMAL", desc);
}

private void _verifyLongType(String desc) {
Assert.assertEquals("INTEGER/LONG", desc);
}

private void _verifyLongFormat(String desc) {
Assert.assertEquals("INTEGER/UTC_MILLISEC", desc);
}
}
Loading

0 comments on commit 833d68a

Please sign in to comment.