1 package org.oxerr.commons.ws.rs.provider;
2
3 import java.lang.annotation.Annotation;
4 import java.lang.reflect.Type;
5 import java.math.BigDecimal;
6 import java.time.Instant;
7 import java.time.format.DateTimeParseException;
8
9 import javax.inject.Singleton;
10 import javax.ws.rs.ProcessingException;
11 import javax.ws.rs.ext.ParamConverter;
12 import javax.ws.rs.ext.ParamConverterProvider;
13 import javax.ws.rs.ext.Provider;
14
15 import com.fasterxml.jackson.datatype.jsr310.DecimalUtils;
16
17
18
19
20
21 @Provider
22 @Singleton
23 public class InstantProvider implements ParamConverterProvider {
24
25
26
27
28 @Override
29 public <T> ParamConverter<T> getConverter(Class<T> rawType,
30 Type genericType, Annotation[] annotations) {
31 return (rawType != Instant.class) ? null : new ParamConverter<T>() {
32
33 @Override
34 public T fromString(final String value) {
35 return rawType.cast(InstantProvider.fromString(value));
36 }
37
38 @Override
39 public String toString(final T value) throws IllegalArgumentException {
40 return InstantProvider.<T>toString(value);
41 }
42 };
43 }
44
45 public static Instant fromString(final String value) {
46 if (value == null) {
47 throw new IllegalArgumentException("value cannot be null");
48 }
49
50 try {
51 final BigDecimal d = new BigDecimal(value);
52 long seconds = d.longValue();
53 int nanoseconds = DecimalUtils.extractNanosecondDecimal(d, seconds);
54 return Instant.ofEpochSecond(seconds, nanoseconds);
55 } catch (Exception e) {
56
57 }
58
59 try {
60 return Instant.parse(value);
61 } catch (DateTimeParseException ex) {
62 throw new ProcessingException(ex);
63 }
64 }
65
66 public static <T> String toString(final T value)
67 throws IllegalArgumentException {
68 if (value == null) {
69 throw new IllegalArgumentException("value cannot be null.");
70 }
71 return value.toString();
72 }
73
74 }