Skip to content

Commit f2f7686

Browse files
committed
Extract duration unit converter to util package. ref FasterXML#189
1 parent ce77a34 commit f2f7686

File tree

3 files changed

+82
-53
lines changed

3 files changed

+82
-53
lines changed

datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/DurationDeserializer.java

+5-49
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import com.fasterxml.jackson.databind.*;
3737
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
3838
import com.fasterxml.jackson.datatype.jsr310.DecimalUtils;
39+
import com.fasterxml.jackson.datatype.jsr310.util.DurationUnitConverter;
3940

4041
/**
4142
* Deserializer for Java 8 temporal {@link Duration}s.
@@ -90,8 +91,8 @@ protected DurationDeserializer withLeniency(Boolean leniency) {
9091
return new DurationDeserializer(this, leniency);
9192
}
9293

93-
protected DurationDeserializer withConverter(DurationUnitConverter pattern) {
94-
return new DurationDeserializer(this, pattern);
94+
protected DurationDeserializer withConverter(DurationUnitConverter converter) {
95+
return new DurationDeserializer(this, converter);
9596
}
9697

9798
@Override
@@ -113,8 +114,8 @@ public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
113114
if (p == null) {
114115
ctxt.reportBadDefinition(getValueType(ctxt),
115116
String.format(
116-
"Bad 'pattern' definition (\"%s\") for `Duration`: expected one of [%s]",
117-
pattern, DurationUnitConverter.descForAllowed()));
117+
"Bad 'pattern' definition (\"%s\") for `Duration`: expected one of [%s]",
118+
pattern, DurationUnitConverter.descForAllowed()));
118119
}
119120
deser = deser.withConverter(p);
120121
}
@@ -185,49 +186,4 @@ protected Duration _fromTimestamp(DeserializationContext ctxt, long ts) {
185186
}
186187
return Duration.ofMillis(ts);
187188
}
188-
189-
protected static class DurationUnitConverter {
190-
private final static Map<String, ChronoUnit> PARSEABLE_UNITS;
191-
static {
192-
Map<String, ChronoUnit> units = new LinkedHashMap<>();
193-
for (ChronoUnit unit : new ChronoUnit[] {
194-
ChronoUnit.NANOS,
195-
ChronoUnit.MICROS,
196-
ChronoUnit.MILLIS,
197-
ChronoUnit.SECONDS,
198-
ChronoUnit.MINUTES,
199-
ChronoUnit.HOURS,
200-
ChronoUnit.HALF_DAYS,
201-
ChronoUnit.DAYS
202-
}) {
203-
units.put(unit.name(), unit);
204-
}
205-
PARSEABLE_UNITS = units;
206-
}
207-
208-
final TemporalUnit unit;
209-
210-
DurationUnitConverter(TemporalUnit unit) {
211-
this.unit = unit;
212-
}
213-
214-
public Duration convert(long value) {
215-
return Duration.of(value, unit);
216-
}
217-
218-
/**
219-
* @return Description of all allowed valued as a sequence of
220-
* double-quoted values separated by comma
221-
*/
222-
public static String descForAllowed() {
223-
return "\"" + PARSEABLE_UNITS.keySet().stream()
224-
.collect(Collectors.joining("\", \""))
225-
+"\"";
226-
}
227-
228-
static DurationUnitConverter from(String unit) {
229-
ChronoUnit chr = PARSEABLE_UNITS.get(unit);
230-
return (chr == null) ? null : new DurationUnitConverter(chr);
231-
}
232-
}
233189
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.fasterxml.jackson.datatype.jsr310.util;
2+
3+
import java.time.Duration;
4+
import java.time.temporal.ChronoUnit;
5+
import java.time.temporal.TemporalUnit;
6+
import java.util.LinkedHashMap;
7+
import java.util.Map;
8+
import java.util.function.Function;
9+
import java.util.stream.Collectors;
10+
11+
import static com.fasterxml.jackson.datatype.jsr310.util.DurationUnitConverter.DurationSerialization.deserializer;
12+
13+
14+
public class DurationUnitConverter {
15+
16+
protected static class DurationSerialization {
17+
final Function<Duration, Long> serializer;
18+
final Function<Long, Duration> deserializer;
19+
20+
DurationSerialization(
21+
Function<Duration, Long> serializer,
22+
Function<Long, Duration> deserializer) {
23+
this.serializer = serializer;
24+
this.deserializer = deserializer;
25+
}
26+
27+
static Function<Long, Duration> deserializer(TemporalUnit unit) {
28+
return v -> Duration.of(v, unit);
29+
}
30+
}
31+
32+
private final static Map<String, DurationSerialization> UNITS;
33+
34+
static {
35+
Map<String, DurationSerialization> units = new LinkedHashMap<>();
36+
units.put(ChronoUnit.NANOS.name(), new DurationSerialization(Duration::toNanos, deserializer(ChronoUnit.NANOS)));
37+
units.put(ChronoUnit.MICROS.name(), new DurationSerialization(d -> d.toNanos() / 1000, deserializer(ChronoUnit.MICROS)));
38+
units.put(ChronoUnit.MILLIS.name(), new DurationSerialization(Duration::toMillis, deserializer(ChronoUnit.MILLIS)));
39+
units.put(ChronoUnit.SECONDS.name(), new DurationSerialization(Duration::getSeconds, deserializer(ChronoUnit.SECONDS)));
40+
units.put(ChronoUnit.MINUTES.name(), new DurationSerialization(Duration::toMinutes, deserializer(ChronoUnit.MINUTES)));
41+
units.put(ChronoUnit.HOURS.name(), new DurationSerialization(Duration::toHours, deserializer(ChronoUnit.HOURS)));
42+
units.put(ChronoUnit.HALF_DAYS.name(), new DurationSerialization(d -> d.toHours() / 12, deserializer(ChronoUnit.HALF_DAYS)));
43+
units.put(ChronoUnit.DAYS.name(), new DurationSerialization(Duration::toDays, deserializer(ChronoUnit.DAYS)));
44+
UNITS = units;
45+
}
46+
47+
48+
final DurationSerialization serialization;
49+
50+
DurationUnitConverter(DurationSerialization serialization) {
51+
this.serialization = serialization;
52+
}
53+
54+
public Duration convert(long value) {
55+
return serialization.deserializer.apply(value);
56+
}
57+
58+
public long convert(Duration duration) {
59+
return serialization.serializer.apply(duration);
60+
}
61+
62+
/**
63+
* @return Description of all allowed valued as a sequence of
64+
* double-quoted values separated by comma
65+
*/
66+
public static String descForAllowed() {
67+
return "\"" + UNITS.keySet().stream()
68+
.collect(Collectors.joining("\", \""))
69+
+ "\"";
70+
}
71+
72+
public static DurationUnitConverter from(String unit) {
73+
DurationSerialization def = UNITS.get(unit);
74+
return (def == null) ? null : new DurationUnitConverter(def);
75+
}
76+
}

datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/deser/DurationUnitConverterTest.java renamed to datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/util/DurationUnitConverterTest.java

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
package com.fasterxml.jackson.datatype.jsr310.deser;
1+
package com.fasterxml.jackson.datatype.jsr310.util;
22

3-
import static org.junit.Assert.assertEquals;
43
import static org.junit.Assert.assertNotNull;
54
import static org.junit.Assert.assertNull;
65

@@ -9,7 +8,6 @@
98
import org.junit.Test;
109

1110
import com.fasterxml.jackson.datatype.jsr310.ModuleTestBase;
12-
import com.fasterxml.jackson.datatype.jsr310.deser.DurationDeserializer.DurationUnitConverter;
1311

1412
public class DurationUnitConverterTest
1513
extends ModuleTestBase
@@ -28,7 +26,6 @@ public void shouldMapToTemporalUnit() {
2826
}) {
2927
DurationUnitConverter conv = DurationUnitConverter.from(inputUnit.name());
3028
assertNotNull(conv);
31-
assertEquals(inputUnit, conv.unit);
3229
// is case-sensitive:
3330
assertNull(DurationUnitConverter.from(inputUnit.name().toLowerCase()));
3431
}

0 commit comments

Comments
 (0)