Skip to content

Commit 833d68a

Browse files
authored
Sync with com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.2 (#139)
Disable failing tests - Refs ThreeTen/threetenbp#185 - Refs FasterXML/jackson-modules-java8#132 - Refs FasterXML/jackson-modules-java8#267
1 parent a690516 commit 833d68a

File tree

8 files changed

+165
-54
lines changed

8 files changed

+165
-54
lines changed

src/main/java/com/fasterxml/jackson/datatype/threetenbp/deser/InstantDeserializer.java

+30-10
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,6 @@ public class InstantDeserializer<T extends Temporal>
5656
{
5757
private static final long serialVersionUID = 1L;
5858

59-
/**
60-
* Constants used to check if the time offset is zero. See [jackson-modules-java8#18]
61-
*
62-
* @since 2.9.0
63-
*/
64-
private static final Pattern ISO8601_UTC_ZERO_OFFSET_SUFFIX_REGEX = Pattern.compile("\\+00:?(00)?$");
65-
6659
/**
6760
* Constants used to check if ISO 8601 time string is colonless. See [jackson-modules-java8#131]
6861
*
@@ -288,7 +281,7 @@ public T deserialize(JsonParser parser, DeserializationContext context) throws I
288281
return (T) parser.getEmbeddedObject();
289282

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

404399
private String replaceZeroOffsetAsZIfNecessary(String text)
405400
{
406401
if (replaceZeroOffsetAsZ) {
407-
return ISO8601_UTC_ZERO_OFFSET_SUFFIX_REGEX.matcher(text).replaceFirst("Z");
402+
return replaceZeroOffsetAsZ(text);
408403
}
409404

410405
return text;
411406
}
412407

408+
private static String replaceZeroOffsetAsZ(String text)
409+
{
410+
int plusIndex = text.lastIndexOf('+');
411+
if (plusIndex < 0) {
412+
return text;
413+
}
414+
int maybeOffsetIndex = plusIndex + 1;
415+
int remaining = text.length() - maybeOffsetIndex;
416+
switch (remaining) {
417+
case 2:
418+
return text.regionMatches(maybeOffsetIndex, "00", 0, remaining)
419+
? text.substring(0, plusIndex) + 'Z'
420+
: text;
421+
case 4:
422+
return text.regionMatches(maybeOffsetIndex, "0000", 0, remaining)
423+
? text.substring(0, plusIndex) + 'Z'
424+
: text;
425+
case 5:
426+
return text.regionMatches(maybeOffsetIndex, "00:00", 0, remaining)
427+
? text.substring(0, plusIndex) + 'Z'
428+
: text;
429+
}
430+
return text;
431+
}
432+
413433
// @since 2.13
414434
private String addInColonToOffsetIfMissing(String text)
415435
{

src/main/java/com/fasterxml/jackson/datatype/threetenbp/deser/ThreeTenDateTimeDeserializerBase.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,8 @@ protected ThreeTenDateTimeDeserializerBase<?> _withFormatOverrides(Deserializati
169169

170170
private boolean acceptCaseInsensitiveValues(DeserializationContext ctxt, JsonFormat.Value format)
171171
{
172-
Boolean enabled = format.getFeature( Feature.ACCEPT_CASE_INSENSITIVE_VALUES);
173-
if( enabled == null) {
172+
Boolean enabled = format.getFeature(Feature.ACCEPT_CASE_INSENSITIVE_VALUES);
173+
if (enabled == null) {
174174
enabled = ctxt.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_VALUES);
175175
}
176176
return enabled;

src/main/java/com/fasterxml/jackson/datatype/threetenbp/ser/InstantSerializerBase.java

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
3939
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonIntegerFormatVisitor;
4040
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonNumberFormatVisitor;
41+
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonValueFormat;
4142
import com.fasterxml.jackson.datatype.threetenbp.DecimalUtils;
4243

4344
/**
@@ -128,6 +129,7 @@ protected void _acceptTimestampVisitor(JsonFormatVisitorWrapper visitor, JavaTyp
128129
JsonIntegerFormatVisitor v2 = visitor.expectIntegerFormat(typeHint);
129130
if (v2 != null) {
130131
v2.numberType(NumberType.LONG);
132+
v2.format(JsonValueFormat.UTC_MILLISEC);
131133
}
132134
}
133135
}

src/test/java/com/fasterxml/jackson/datatype/threetenbp/deser/InstantDeserTest.java

+40-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.fasterxml.jackson.datatype.threetenbp.deser;
22

3+
import org.junit.Ignore;
34
import org.threeten.bp.*;
45
import org.threeten.bp.format.DateTimeFormatter;
56
import org.threeten.bp.temporal.ChronoUnit;
@@ -23,6 +24,7 @@
2324
import static com.fasterxml.jackson.datatype.threetenbp.deser.InstantDeserializer.ISO8601_COLONLESS_OFFSET_REGEX;
2425
import static org.junit.Assert.*;
2526
import static org.junit.Assert.assertNull;
27+
import static org.junit.Assume.assumeTrue;
2628

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

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

439+
@Test
440+
@Ignore("Currently not implemented in ThreeTenBP - https://bugs.openjdk.org/browse/JDK-8166138")
441+
public void testDeserializationFromStringWithZeroZoneOffset04() throws Exception {
442+
assumeInstantCanParseOffsets();
443+
Instant date = Instant.now();
444+
String json = formatWithZeroZoneOffset(date, "+00:30");
445+
Instant result = READER.readValue(json);
446+
assertNotEquals("The value is not correct.", date, result);
447+
}
448+
449+
@Test
450+
@Ignore("Currently not implemented in ThreeTenBP - https://bugs.openjdk.org/browse/JDK-8166138")
451+
public void testDeserializationFromStringWithZeroZoneOffset05() throws Exception {
452+
assumeInstantCanParseOffsets();
453+
Instant date = Instant.now();
454+
String json = formatWithZeroZoneOffset(date, "+01:30");
455+
Instant result = READER.readValue(json);
456+
assertNotEquals("The value is not correct.", date, result);
457+
}
458+
459+
@Test
460+
@Ignore("Currently not implemented in ThreeTenBP - https://bugs.openjdk.org/browse/JDK-8166138")
461+
public void testDeserializationFromStringWithZeroZoneOffset06() throws Exception {
462+
assumeInstantCanParseOffsets();
463+
Instant date = Instant.now();
464+
String json = formatWithZeroZoneOffset(date, "-00:00");
465+
Instant result = READER.readValue(json);
466+
assertEquals("The value is not correct.", date, result);
467+
}
468+
437469
private String formatWithZeroZoneOffset(Instant date, String offset){
438470
return '"' + FORMATTER.format(date).replaceFirst("Z$", offset) + '"';
439471
}
440472

473+
private static void assumeInstantCanParseOffsets() {
474+
// DateTimeFormatter.ISO_INSTANT didn't handle offsets until JDK 12+.
475+
// This was added by https://bugs.openjdk.org/browse/JDK-8166138
476+
assumeTrue(System.getProperty("java.specification.version").compareTo("12") > 0);
477+
}
478+
441479
/*
442480
/**********************************************************************
443481
/* Deserialization, misc other

src/test/java/com/fasterxml/jackson/datatype/threetenbp/deser/ZonedDateTimeDeserTest.java

+27-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.threeten.bp.ZoneId;
1717
import org.threeten.bp.ZoneOffset;
1818
import org.threeten.bp.ZonedDateTime;
19+
import org.threeten.bp.format.DateTimeFormatter;
1920
import org.threeten.bp.format.DateTimeParseException;
2021
import java.util.Map;
2122

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

45+
@Test
46+
public void testDeserializationComparedToStandard() throws Throwable
47+
{
48+
String inputString = "2021-02-01T19:49:04.0513486Z";
49+
50+
assertEquals("The value is not correct.",
51+
DateTimeFormatter.ISO_ZONED_DATE_TIME.parse(inputString, ZonedDateTime::from),
52+
READER.readValue(q(inputString)));
53+
}
54+
55+
@Test
56+
public void testDeserializationComparedToStandard2() throws Throwable
57+
{
58+
String inputString = "2021-02-01T19:49:04.0513486Z[UTC]";
59+
60+
ZonedDateTime converted = newMapper()
61+
.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false)
62+
.readerFor(ZonedDateTime.class).readValue(q(inputString));
63+
64+
assertEquals("The value is not correct.",
65+
DateTimeFormatter.ISO_ZONED_DATE_TIME.parse(inputString, ZonedDateTime::from),
66+
converted);
67+
}
68+
4469
@Test
4570
public void testBadDeserializationAsString01() throws Throwable
4671
{
@@ -92,7 +117,7 @@ public void testDeserializationAsArrayEnabled() throws Throwable
92117
.configure(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS, true)
93118
.readerFor(ZonedDateTime.class).readValue(a2q(json));
94119
assertEquals("The value is not correct.",
95-
ZonedDateTime.of(2000, 1, 1, 12, 0, 0, 0, ZoneId.of("UTC")),
120+
ZonedDateTime.of(2000, 1, 1, 12, 0, 0, 0, ZoneOffset.UTC),
96121
value);
97122

98123
}

src/test/java/com/fasterxml/jackson/datatype/threetenbp/misc/DateTimeSchemasTest.java

+26-4
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,13 @@ public void numberType(JsonParser.NumberType format) {
8686
public JsonIntegerFormatVisitor expectIntegerFormat(JavaType type) throws JsonMappingException {
8787
return new JsonIntegerFormatVisitor.Base() {
8888
@Override
89-
public void numberType(JsonParser.NumberType format) {
90-
traversedProperties.put(baseName, "INTEGER/"+format.name());
89+
public void numberType(JsonParser.NumberType numberType) {
90+
traversedProperties.put(baseName + "numberType", "INTEGER/" + numberType.name());
91+
}
92+
93+
@Override
94+
public void format(JsonValueFormat format) {
95+
traversedProperties.put(baseName + "format", "INTEGER/" + format.name());
9196
}
9297
};
9398
}
@@ -129,7 +134,7 @@ public void setProvider(SerializerProvider provider) {
129134
private final ObjectMapper MAPPER = newMapper();
130135

131136
// // // Local date/time types
132-
137+
133138
// [modules-java8#105]
134139
@Test
135140
public void testLocalTimeSchema() throws Exception
@@ -182,14 +187,23 @@ public void testDateTimeSchema() throws Exception
182187
Assert.assertEquals(1, properties.size());
183188
_verifyBigDecimalType(properties.get(""));
184189

190+
// but becomes long
191+
wrapper = new VisitorWrapper(null, "", new HashMap<String, String>());
192+
MAPPER.writer()
193+
.without(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS)
194+
.acceptJsonFormatVisitor(ZonedDateTime.class, wrapper);
195+
properties = wrapper.getTraversedProperties();
196+
_verifyLongType(properties.get("numberType"));
197+
_verifyLongFormat(properties.get("format"));
198+
185199
// but becomes date/time
186200
wrapper = new VisitorWrapper(null, "", new HashMap<String, String>());
187201
MAPPER.writer().without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
188202
.acceptJsonFormatVisitor(ZonedDateTime.class, wrapper);
189203
properties = wrapper.getTraversedProperties();
190204
_verifyDateTimeType(properties.get(""));
191205
}
192-
206+
193207
private void _verifyIntArrayType(String desc) {
194208
Assert.assertEquals("ARRAY/Ljava/util/List<Ljava/lang/Integer;>;", desc);
195209
}
@@ -209,4 +223,12 @@ private void _verifyDateTimeType(String desc) {
209223
private void _verifyBigDecimalType(String desc) {
210224
Assert.assertEquals("NUMBER/BIG_DECIMAL", desc);
211225
}
226+
227+
private void _verifyLongType(String desc) {
228+
Assert.assertEquals("INTEGER/LONG", desc);
229+
}
230+
231+
private void _verifyLongFormat(String desc) {
232+
Assert.assertEquals("INTEGER/UTC_MILLISEC", desc);
233+
}
212234
}

0 commit comments

Comments
 (0)