Skip to content

Commit

Permalink
fixup! fixup! fixup! fixup! fixup! Support for jsonformat in duration…
Browse files Browse the repository at this point in the history
… deserializer based on Duration::of(long,TemporalUnit). ref FasterXML#184
  • Loading branch information
obarcelonap committed Oct 14, 2020
1 parent 343abbc commit c481399
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,12 @@ public class DurationDeserializer extends JSR310DeserializerBase<Duration>

/**
* Since 2.12
* When set, values will be deserialized using the specified unit. Using this parser will tipically
* override the value specified in {@link DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS} as it is
* considered that the unit set in {@link JsonFormat#pattern()} has precedence since is more specific.
* @see [jackson-modules-java8#184] for more info
*/
private DurationPattern _durationPattern;
private DurationUnitParser _durationUnitParser;

private DurationDeserializer()
{
Expand All @@ -70,9 +74,9 @@ protected DurationDeserializer(DurationDeserializer base, Boolean leniency) {
super(base, leniency);
}

protected DurationDeserializer(DurationDeserializer base, DurationPattern durationPattern) {
protected DurationDeserializer(DurationDeserializer base, DurationUnitParser durationUnitParser) {
super(base, base._isLenient);
_durationPattern = durationPattern;
_durationUnitParser = durationUnitParser;
}

@Override
Expand All @@ -94,15 +98,15 @@ public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
}
}
if (format.hasPattern()) {
deser = DurationPattern.from(format.getPattern())
deser = DurationUnitParser.from(format.getPattern())
.map(deser::withPattern)
.orElse(deser);
}
}
return deser;
}

private DurationDeserializer withPattern(DurationPattern pattern) {
private DurationDeserializer withPattern(DurationUnitParser pattern) {
return new DurationDeserializer(this, pattern);
}

Expand All @@ -113,14 +117,14 @@ public Duration deserialize(JsonParser parser, DeserializationContext context) t
{
case JsonTokenId.ID_NUMBER_FLOAT:
BigDecimal decValue = parser.getDecimalValue();
if (_durationPattern != null) {
return _durationPattern.parse(decValue.longValue());
if (_durationUnitParser != null) {
return _durationUnitParser.parse(decValue.longValue());
}
return DecimalUtils.extractSecondsAndNanos(decValue, Duration::ofSeconds);
case JsonTokenId.ID_NUMBER_INT:
long intValue = parser.getLongValue();
if (_durationPattern != null) {
return _durationPattern.parse(intValue);
if (_durationUnitParser != null) {
return _durationUnitParser.parse(intValue);
}
return _fromTimestamp(context, intValue);
case JsonTokenId.ID_STRING:
Expand Down Expand Up @@ -160,8 +164,8 @@ && _isValidTimestampString(value)) {
}

try {
if (_durationPattern != null) {
return _durationPattern.parse(NumberInput.parseLong(value));
if (_durationUnitParser != null) {
return _durationUnitParser.parse(NumberInput.parseLong(value));
}

return Duration.parse(value);
Expand All @@ -177,21 +181,21 @@ protected Duration _fromTimestamp(DeserializationContext ctxt, long ts) {
return Duration.ofMillis(ts);
}

protected static class DurationPattern {
protected static class DurationUnitParser {
final TemporalUnit unit;

DurationPattern(TemporalUnit unit) {
DurationUnitParser(TemporalUnit unit) {
this.unit = unit;
}

Duration parse(long value) {
return Duration.of(value, unit);
}

static Optional<DurationPattern> from(String pattern) {
static Optional<DurationUnitParser> from(String unit) {
return Stream.of(ChronoUnit.values())
.filter(u -> u.toString().equalsIgnoreCase(pattern))
.map(DurationPattern::new)
.filter(u -> u.toString().equalsIgnoreCase(unit))
.map(DurationUnitParser::new)
.findFirst();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
package com.fasterxml.jackson.datatype.jsr310.deser;

import com.fasterxml.jackson.datatype.jsr310.deser.DurationDeserializer.DurationPattern;
import com.fasterxml.jackson.datatype.jsr310.deser.DurationDeserializer.DurationUnitParser;
import org.junit.Test;

import static java.util.Optional.empty;
import static org.junit.Assert.assertEquals;

public class DurationPatternEmptyTest {
public class DurationUnitParserEmptyTest {

@Test
public void shouldReturnEmpty_whenNull() {
assertEquals(empty(), DurationPattern.from(null));
assertEquals(empty(), DurationUnitParser.from(null));
}

@Test
public void shouldReturnEmpty_whenEmptyString() {
assertEquals(empty(), DurationPattern.from(""));
assertEquals(empty(), DurationUnitParser.from(""));
}

@Test
public void shouldReturnEmpty_whenSpaces() {
assertEquals(empty(), DurationPattern.from(" "));
assertEquals(empty(), DurationUnitParser.from(" "));
}

@Test
public void shouldReturnEmpty_whenDoesNotMatchAnyTemporalUnit() {
assertEquals(empty(), DurationPattern.from("DOESNOTMATCH"));
assertEquals(empty(), DurationUnitParser.from("DOESNOTMATCH"));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.fasterxml.jackson.datatype.jsr310.deser;

import com.fasterxml.jackson.datatype.jsr310.deser.DurationDeserializer.DurationPattern;
import com.fasterxml.jackson.datatype.jsr310.deser.DurationDeserializer.DurationUnitParser;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
Expand All @@ -19,19 +19,19 @@
import static org.junit.Assert.assertEquals;

@RunWith(Parameterized.class)
public class DurationPatternTest {
public class DurationUnitParserTest {

private final String stringPattern;
private final TemporalUnit temporalUnit;

public DurationPatternTest(String stringPattern, TemporalUnit temporalUnit) {
public DurationUnitParserTest(String stringPattern, TemporalUnit temporalUnit) {
this.stringPattern = stringPattern;
this.temporalUnit = temporalUnit;
}

@Test
public void shouldMapToTemporalUnit() {
Optional<DurationPattern> durationPattern = DurationPattern.from(stringPattern);
Optional<DurationUnitParser> durationPattern = DurationUnitParser.from(stringPattern);

assertEquals(of(temporalUnit), durationPattern.map(dp -> dp.unit));
}
Expand Down

0 comments on commit c481399

Please sign in to comment.