Skip to content

Commit 8280a1e

Browse files
committed
Merge branch '2.9' of github.com:FasterXML/jackson-modules-java8 into 2.9
2 parents f3379a1 + 2bda69d commit 8280a1e

11 files changed

+265
-40
lines changed

datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/DurationSerializer.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import com.fasterxml.jackson.core.JsonToken;
2323
import com.fasterxml.jackson.databind.JavaType;
2424
import com.fasterxml.jackson.databind.JsonMappingException;
25-
import com.fasterxml.jackson.databind.SerializationFeature;
2625
import com.fasterxml.jackson.databind.SerializerProvider;
2726
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
2827
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonIntegerFormatVisitor;
@@ -54,6 +53,11 @@ protected DurationSerializer(DurationSerializer base,
5453
super(base, useTimestamp, dtf, null);
5554
}
5655

56+
protected DurationSerializer(DurationSerializer base,
57+
Boolean useTimestamp, Boolean useNanoseconds, DateTimeFormatter dtf) {
58+
super(base, useTimestamp, useNanoseconds, dtf, null);
59+
}
60+
5761
@Override
5862
protected DurationSerializer withFormat(Boolean useTimestamp, DateTimeFormatter dtf, JsonFormat.Shape shape) {
5963
return new DurationSerializer(this, useTimestamp, dtf);
@@ -63,7 +67,7 @@ protected DurationSerializer withFormat(Boolean useTimestamp, DateTimeFormatter
6367
public void serialize(Duration duration, JsonGenerator generator, SerializerProvider provider) throws IOException
6468
{
6569
if (useTimestamp(provider)) {
66-
if (provider.isEnabled(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS)) {
70+
if (useNanoseconds(provider)) {
6771
generator.writeNumber(DecimalUtils.toBigDecimal(
6872
duration.getSeconds(), duration.getNano()
6973
));
@@ -83,7 +87,7 @@ protected void _acceptTimestampVisitor(JsonFormatVisitorWrapper visitor, JavaTyp
8387
if (v2 != null) {
8488
v2.numberType(JsonParser.NumberType.LONG);
8589
SerializerProvider provider = visitor.getProvider();
86-
if ((provider != null) && provider.isEnabled(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS)) {
90+
if ((provider != null) && useNanoseconds(provider)) {
8791
// big number, no more specific qualifier to use...
8892
} else { // otherwise good old Unix timestamp, in milliseconds
8993
v2.format(JsonValueFormat.UTC_MILLISEC);
@@ -94,11 +98,16 @@ protected void _acceptTimestampVisitor(JsonFormatVisitorWrapper visitor, JavaTyp
9498
@Override // since 2.9
9599
protected JsonToken serializationShape(SerializerProvider provider) {
96100
if (useTimestamp(provider)) {
97-
if (provider.isEnabled(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS)) {
101+
if (useNanoseconds(provider)) {
98102
return JsonToken.VALUE_NUMBER_FLOAT;
99103
}
100104
return JsonToken.VALUE_NUMBER_INT;
101105
}
102106
return JsonToken.VALUE_STRING;
103107
}
108+
109+
@Override
110+
protected JSR310FormattedSerializerBase<?> withFeatures(Boolean writeZoneId, Boolean writeNanoseconds) {
111+
return new DurationSerializer(this, _useTimestamp, writeNanoseconds, _formatter);
112+
}
104113
}

datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/InstantSerializer.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,22 @@ protected InstantSerializer() {
4242

4343
protected InstantSerializer(InstantSerializer base,
4444
Boolean useTimestamp, DateTimeFormatter formatter) {
45-
super(base, useTimestamp, formatter);
45+
this(base, useTimestamp, null, formatter);
46+
}
47+
48+
protected InstantSerializer(InstantSerializer base,
49+
Boolean useTimestamp, Boolean useNanoseconds, DateTimeFormatter formatter) {
50+
super(base, useTimestamp, useNanoseconds, formatter);
4651
}
4752

4853
@Override
49-
protected JSR310FormattedSerializerBase<Instant> withFormat(
50-
Boolean useTimestamp,
51-
DateTimeFormatter formatter,
52-
JsonFormat.Shape shape) {
54+
protected JSR310FormattedSerializerBase<Instant> withFormat(Boolean useTimestamp,
55+
DateTimeFormatter formatter, JsonFormat.Shape shape) {
5356
return new InstantSerializer(this, useTimestamp, formatter);
5457
}
58+
59+
@Override
60+
protected JSR310FormattedSerializerBase<?> withFeatures(Boolean writeZoneId, Boolean writeNanoseconds) {
61+
return new InstantSerializer(this, _useTimestamp, writeNanoseconds, _formatter);
62+
}
5563
}

datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/InstantSerializerBase.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import com.fasterxml.jackson.core.JsonParser.NumberType;
2929
import com.fasterxml.jackson.databind.JavaType;
3030
import com.fasterxml.jackson.databind.JsonMappingException;
31-
import com.fasterxml.jackson.databind.SerializationFeature;
3231
import com.fasterxml.jackson.databind.SerializerProvider;
3332
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
3433
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonIntegerFormatVisitor;
@@ -66,7 +65,13 @@ protected InstantSerializerBase(Class<T> supportedType, ToLongFunction<T> getEpo
6665
protected InstantSerializerBase(InstantSerializerBase<T> base,
6766
Boolean useTimestamp, DateTimeFormatter dtf)
6867
{
69-
super(base, useTimestamp, dtf, null);
68+
this(base, useTimestamp, null, dtf);
69+
}
70+
71+
protected InstantSerializerBase(InstantSerializerBase<T> base,
72+
Boolean useTimestamp, Boolean useNanoseconds, DateTimeFormatter dtf)
73+
{
74+
super(base, useTimestamp, useNanoseconds, dtf, null);
7075
defaultFormat = base.defaultFormat;
7176
getEpochMillis = base.getEpochMillis;
7277
getEpochSeconds = base.getEpochSeconds;
@@ -82,7 +87,7 @@ protected abstract JSR310FormattedSerializerBase<?> withFormat(
8287
public void serialize(T value, JsonGenerator generator, SerializerProvider provider) throws IOException
8388
{
8489
if (useTimestamp(provider)) {
85-
if (provider.isEnabled(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS)) {
90+
if (useNanoseconds(provider)) {
8691
generator.writeNumber(DecimalUtils.toBigDecimal(
8792
getEpochSeconds.applyAsLong(value), getNanoseconds.applyAsInt(value)
8893
));
@@ -109,8 +114,7 @@ protected void _acceptTimestampVisitor(JsonFormatVisitorWrapper visitor, JavaTyp
109114
throws JsonMappingException
110115
{
111116
SerializerProvider prov = visitor.getProvider();
112-
if ((prov != null) &&
113-
prov.isEnabled(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS)) {
117+
if ((prov != null) && useNanoseconds(prov)) {
114118
JsonNumberFormatVisitor v2 = visitor.expectNumberFormat(typeHint);
115119
if (v2 != null) {
116120
v2.numberType(NumberType.BIG_DECIMAL);
@@ -126,7 +130,7 @@ protected void _acceptTimestampVisitor(JsonFormatVisitorWrapper visitor, JavaTyp
126130
@Override // since 2.9
127131
protected JsonToken serializationShape(SerializerProvider provider) {
128132
if (useTimestamp(provider)) {
129-
if (provider.isEnabled(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS)) {
133+
if (useNanoseconds(provider)) {
130134
return JsonToken.VALUE_NUMBER_FLOAT;
131135
}
132136
return JsonToken.VALUE_NUMBER_INT;

datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/JSR310FormattedSerializerBase.java

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,14 @@ abstract class JSR310FormattedSerializerBase<T>
4949
* Java timestamp, regardless of other settings.
5050
*/
5151
protected final Boolean _useTimestamp;
52-
52+
53+
/**
54+
* Flag that indicates that numeric timestamp values must be written using
55+
* nanosecond timestamps if the datatype supports such resolution,
56+
* regardless of other settings.
57+
*/
58+
protected final Boolean _useNanoseconds;
59+
5360
/**
5461
* Specific format to use, if not default format: non null value
5562
* also indicates that serialization is to be done as JSON String,
@@ -67,15 +74,24 @@ protected JSR310FormattedSerializerBase(Class<T> supportedType,
6774
DateTimeFormatter formatter) {
6875
super(supportedType);
6976
_useTimestamp = null;
77+
_useNanoseconds = null;
7078
_shape = null;
7179
_formatter = formatter;
7280
}
7381

7482
protected JSR310FormattedSerializerBase(JSR310FormattedSerializerBase<?> base,
7583
Boolean useTimestamp, DateTimeFormatter dtf, JsonFormat.Shape shape)
76-
{
84+
{
85+
this(base, useTimestamp, null, dtf, shape);
86+
}
87+
88+
protected JSR310FormattedSerializerBase(JSR310FormattedSerializerBase<?> base,
89+
Boolean useTimestamp, Boolean useNanoseconds, DateTimeFormatter dtf,
90+
JsonFormat.Shape shape)
91+
{
7792
super(base.handledType());
7893
_useTimestamp = useTimestamp;
94+
_useNanoseconds = useNanoseconds;
7995
_formatter = dtf;
8096
_shape = shape;
8197
}
@@ -90,7 +106,15 @@ protected JSR310FormattedSerializerBase<?> withFeatures(Boolean writeZoneId) {
90106
// 01-Jul-2016, tatu: Sub-classes need to override
91107
return this;
92108
}
93-
109+
110+
/**
111+
* @since 2.9
112+
*/
113+
protected JSR310FormattedSerializerBase<?> withFeatures(Boolean writeZoneId,
114+
Boolean writeNanoseconds) {
115+
return this;
116+
}
117+
94118
@Override
95119
public JsonSerializer<?> createContextual(SerializerProvider prov,
96120
BeanProperty property) throws JsonMappingException
@@ -128,8 +152,9 @@ public JsonSerializer<?> createContextual(SerializerProvider prov,
128152
ser = ser.withFormat(useTimestamp, dtf, shape);
129153
}
130154
Boolean writeZoneId = format.getFeature(JsonFormat.Feature.WRITE_DATES_WITH_ZONE_ID);
131-
if (writeZoneId != null) {
132-
ser = ser.withFeatures(writeZoneId);
155+
Boolean writeNanoseconds = format.getFeature(JsonFormat.Feature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);
156+
if (writeZoneId != null || writeNanoseconds != null) {
157+
ser = ser.withFeatures(writeZoneId, writeNanoseconds);
133158
}
134159
return ser;
135160
}
@@ -170,7 +195,7 @@ protected void _acceptTimestampVisitor(JsonFormatVisitorWrapper visitor, JavaTyp
170195

171196
protected boolean useTimestamp(SerializerProvider provider) {
172197
if (_useTimestamp != null) {
173-
return _useTimestamp.booleanValue();
198+
return _useTimestamp;
174199
}
175200
if (_shape != null) {
176201
if (_shape == Shape.STRING) {
@@ -181,16 +206,28 @@ protected boolean useTimestamp(SerializerProvider provider) {
181206
}
182207
}
183208
// assume that explicit formatter definition implies use of textual format
184-
if (_formatter != null) {
185-
return false;
186-
}
187-
return provider.isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
209+
return _formatter == null && provider.isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
188210
}
189211

190212
protected boolean _useTimestampExplicitOnly(SerializerProvider provider) {
191213
if (_useTimestamp != null) {
192-
return _useTimestamp.booleanValue();
214+
return _useTimestamp;
193215
}
194216
return false;
195217
}
218+
219+
protected boolean useNanoseconds(SerializerProvider provider) {
220+
if (_useNanoseconds != null) {
221+
return _useNanoseconds;
222+
}
223+
if (_shape != null) {
224+
if (_shape == Shape.NUMBER_INT) {
225+
return false;
226+
}
227+
if (_shape == Shape.NUMBER_FLOAT) {
228+
return true;
229+
}
230+
}
231+
return provider.isEnabled(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);
232+
}
196233
}

datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/LocalDateTimeSerializer.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import com.fasterxml.jackson.core.JsonGenerator;
2626
import com.fasterxml.jackson.core.JsonToken;
2727
import com.fasterxml.jackson.core.type.WritableTypeId;
28-
import com.fasterxml.jackson.databind.SerializationFeature;
2928
import com.fasterxml.jackson.databind.SerializerProvider;
3029
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
3130

@@ -49,13 +48,13 @@ public LocalDateTimeSerializer(DateTimeFormatter f) {
4948
super(LocalDateTime.class, f);
5049
}
5150

52-
private LocalDateTimeSerializer(LocalDateTimeSerializer base, Boolean useTimestamp, DateTimeFormatter f) {
53-
super(base, useTimestamp, f, null);
51+
private LocalDateTimeSerializer(LocalDateTimeSerializer base, Boolean useTimestamp, Boolean useNanoseconds, DateTimeFormatter f) {
52+
super(base, useTimestamp, useNanoseconds, f, null);
5453
}
5554

5655
@Override
5756
protected JSR310FormattedSerializerBase<LocalDateTime> withFormat(Boolean useTimestamp, DateTimeFormatter f, JsonFormat.Shape shape) {
58-
return new LocalDateTimeSerializer(this, useTimestamp, f);
57+
return new LocalDateTimeSerializer(this, useTimestamp, _useNanoseconds, f);
5958
}
6059

6160
protected DateTimeFormatter _defaultFormatter() {
@@ -111,7 +110,7 @@ private final void _serializeAsArrayContents(LocalDateTime value, JsonGenerator
111110
if ((secs > 0) || (nanos > 0)) {
112111
g.writeNumber(secs);
113112
if (nanos > 0) {
114-
if (provider.isEnabled(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS)) {
113+
if (useNanoseconds(provider)) {
115114
g.writeNumber(nanos);
116115
} else {
117116
g.writeNumber(value.get(ChronoField.MILLI_OF_SECOND));
@@ -124,4 +123,9 @@ private final void _serializeAsArrayContents(LocalDateTime value, JsonGenerator
124123
protected JsonToken serializationShape(SerializerProvider provider) {
125124
return useTimestamp(provider) ? JsonToken.START_ARRAY : JsonToken.VALUE_STRING;
126125
}
126+
127+
@Override
128+
protected JSR310FormattedSerializerBase<?> withFeatures(Boolean writeZoneId, Boolean writeNanoseconds) {
129+
return new LocalDateTimeSerializer(this, _useTimestamp, writeNanoseconds, _formatter);
130+
}
127131
}

datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/LocalTimeSerializer.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import com.fasterxml.jackson.core.JsonGenerator;
2626
import com.fasterxml.jackson.core.JsonToken;
2727
import com.fasterxml.jackson.core.type.WritableTypeId;
28-
import com.fasterxml.jackson.databind.SerializationFeature;
2928
import com.fasterxml.jackson.databind.SerializerProvider;
3029
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
3130

@@ -50,7 +49,11 @@ public LocalTimeSerializer(DateTimeFormatter formatter) {
5049
}
5150

5251
protected LocalTimeSerializer(LocalTimeSerializer base, Boolean useTimestamp, DateTimeFormatter formatter) {
53-
super(base, useTimestamp, formatter, null);
52+
this(base, useTimestamp, null, formatter);
53+
}
54+
55+
protected LocalTimeSerializer(LocalTimeSerializer base, Boolean useTimestamp, Boolean useNanoseconds, DateTimeFormatter formatter) {
56+
super(base, useTimestamp, useNanoseconds, formatter, null);
5457
}
5558

5659
@Override
@@ -110,7 +113,7 @@ private final void _serializeAsArrayContents(LocalTime value, JsonGenerator g,
110113
{
111114
g.writeNumber(secs);
112115
if (nanos > 0) {
113-
if (provider.isEnabled(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS)) {
116+
if (useNanoseconds(provider)) {
114117
g.writeNumber(nanos);
115118
} else {
116119
g.writeNumber(value.get(ChronoField.MILLI_OF_SECOND));
@@ -123,4 +126,9 @@ private final void _serializeAsArrayContents(LocalTime value, JsonGenerator g,
123126
protected JsonToken serializationShape(SerializerProvider provider) {
124127
return useTimestamp(provider) ? JsonToken.START_ARRAY : JsonToken.VALUE_STRING;
125128
}
129+
130+
@Override
131+
protected JSR310FormattedSerializerBase<?> withFeatures(Boolean writeZoneId, Boolean writeNanoseconds) {
132+
return new LocalTimeSerializer(this, _useTimestamp, writeNanoseconds, _formatter);
133+
}
126134
}

datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/OffsetDateTimeSerializer.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,12 @@ protected OffsetDateTimeSerializer() {
1818

1919
protected OffsetDateTimeSerializer(OffsetDateTimeSerializer base,
2020
Boolean useTimestamp, DateTimeFormatter formatter) {
21-
super(base, useTimestamp, formatter);
21+
this(base, useTimestamp, null, formatter);
22+
}
23+
24+
protected OffsetDateTimeSerializer(OffsetDateTimeSerializer base,
25+
Boolean useTimestamp, Boolean useNanoseconds, DateTimeFormatter formatter) {
26+
super(base, useTimestamp, useNanoseconds, formatter);
2227
}
2328

2429
@Override
@@ -27,4 +32,9 @@ protected JSR310FormattedSerializerBase<?> withFormat(Boolean useTimestamp,
2732
{
2833
return new OffsetDateTimeSerializer(this, useTimestamp, formatter);
2934
}
35+
36+
@Override
37+
protected JSR310FormattedSerializerBase<?> withFeatures(Boolean writeZoneId, Boolean writeNanoseconds) {
38+
return new OffsetDateTimeSerializer(this, _useTimestamp, writeNanoseconds, _formatter);
39+
}
3040
}

datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/OffsetTimeSerializer.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import com.fasterxml.jackson.core.JsonGenerator;
2121
import com.fasterxml.jackson.core.JsonToken;
2222
import com.fasterxml.jackson.core.type.WritableTypeId;
23-
import com.fasterxml.jackson.databind.SerializationFeature;
2423
import com.fasterxml.jackson.databind.SerializerProvider;
2524
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
2625

@@ -47,7 +46,12 @@ protected OffsetTimeSerializer() {
4746

4847
protected OffsetTimeSerializer(OffsetTimeSerializer base,
4948
Boolean useTimestamp, DateTimeFormatter dtf) {
50-
super(base, useTimestamp, dtf, null);
49+
this(base, useTimestamp, null, dtf);
50+
}
51+
52+
protected OffsetTimeSerializer(OffsetTimeSerializer base,
53+
Boolean useTimestamp, Boolean useNanoseconds, DateTimeFormatter dtf) {
54+
super(base, useTimestamp, useNanoseconds, dtf, null);
5155
}
5256

5357
@Override
@@ -94,7 +98,7 @@ private final void _serializeAsArrayContents(OffsetTime value, JsonGenerator g,
9498
if ((secs > 0) || (nanos > 0)) {
9599
g.writeNumber(secs);
96100
if (nanos > 0) {
97-
if(provider.isEnabled(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS)) {
101+
if(useNanoseconds(provider)) {
98102
g.writeNumber(nanos);
99103
} else {
100104
g.writeNumber(value.get(ChronoField.MILLI_OF_SECOND));
@@ -108,4 +112,9 @@ private final void _serializeAsArrayContents(OffsetTime value, JsonGenerator g,
108112
protected JsonToken serializationShape(SerializerProvider provider) {
109113
return useTimestamp(provider) ? JsonToken.START_ARRAY : JsonToken.VALUE_STRING;
110114
}
115+
116+
@Override
117+
protected JSR310FormattedSerializerBase<?> withFeatures(Boolean writeZoneId, Boolean writeNanoseconds) {
118+
return new OffsetTimeSerializer(this, _useTimestamp, writeNanoseconds, _formatter);
119+
}
111120
}

0 commit comments

Comments
 (0)