-
Notifications
You must be signed in to change notification settings - Fork 94
/
AbstractDateTimeDeserializer.java
138 lines (124 loc) · 5.16 KB
/
AbstractDateTimeDeserializer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
* Copyright (c) 2016, 2019 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.yasson.internal.serializer;
import java.lang.reflect.Type;
import java.time.DateTimeException;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import javax.json.bind.JsonbException;
import javax.json.bind.annotation.JsonbDateFormat;
import org.eclipse.yasson.internal.JsonbContext;
import org.eclipse.yasson.internal.Unmarshaller;
import org.eclipse.yasson.internal.model.customization.Customization;
import org.eclipse.yasson.internal.properties.MessageKeys;
import org.eclipse.yasson.internal.properties.Messages;
/**
* Abstract class for converting date objects from {@link java.time}.
*
* @param <T> date type
*/
public abstract class AbstractDateTimeDeserializer<T> extends AbstractValueTypeDeserializer<T> {
/**
* Default zone id.
*/
public static final ZoneId UTC = ZoneId.of("UTC");
/**
* Creates an instance.
*
* @param clazz Class to create deserializer for.
* @param customization Model customization.
*/
public AbstractDateTimeDeserializer(Class<T> clazz, Customization customization) {
super(clazz, customization);
}
@Override
public T deserialize(String jsonValue, Unmarshaller unmarshaller, Type rtType) {
final JsonbDateFormatter formatter = getJsonbDateFormatter(unmarshaller.getJsonbContext());
if (JsonbDateFormat.TIME_IN_MILLIS.equals(formatter.getFormat())) {
return fromInstant(Instant.ofEpochMilli(Long.parseLong(jsonValue)));
} else if (formatter.getDateTimeFormatter() != null) {
return parseWithFormatterInternal(jsonValue, formatter.getDateTimeFormatter());
} else {
DateTimeFormatter configDateTimeFormatter = unmarshaller.getJsonbContext().getConfigProperties()
.getConfigDateFormatter().getDateTimeFormatter();
if (configDateTimeFormatter != null) {
return parseWithFormatterInternal(jsonValue, configDateTimeFormatter);
}
}
final boolean strictIJson = unmarshaller.getJsonbContext().getConfigProperties().isStrictIJson();
if (strictIJson) {
return parseWithFormatterInternal(jsonValue, JsonbDateFormatter.IJSON_DATE_FORMATTER);
}
try {
return parseDefault(jsonValue, unmarshaller.getJsonbContext().getConfigProperties().getLocale(formatter.getLocale()));
} catch (DateTimeException e) {
throw new JsonbException(Messages.getMessage(MessageKeys.DATE_PARSE_ERROR, jsonValue, getPropertyType()), e);
}
}
/**
* Returns registered deserialization jsonb date formatter.
*
* @param context context
* @return date formatter
*/
protected JsonbDateFormatter getJsonbDateFormatter(JsonbContext context) {
if (getCustomization() != null && getCustomization().getDeserializeDateFormatter() != null) {
return getCustomization().getDeserializeDateFormatter();
}
return context.getConfigProperties().getConfigDateFormatter();
}
/**
* Append UTC zone in case zone is not set on formatter.
*
* @param formatter formatter
* @return zoned formatter
*/
protected DateTimeFormatter getZonedFormatter(DateTimeFormatter formatter) {
return formatter.getZone() != null
? formatter
: formatter.withZone(UTC);
}
/**
* Construct date object from an instant containing epoch millisecond.
* If date object supports zone offset / zone id, system default is used and warning is logged.
*
* @param instant instant to construct from
* @return date object
*/
protected abstract T fromInstant(Instant instant);
/**
* Parse {@link java.time} date object with default formatter.
* Different default formatter for each date object type is used.
*
* @param jsonValue string value to parse from
* @param locale annotated locale or default
* @return parsed date object
*/
protected abstract T parseDefault(String jsonValue, Locale locale);
/**
* Parse {@link java.time} date object with provided formatter.
*
* @param jsonValue string value to parse from
* @param formatter a formatter to use
* @return parsed date object
*/
protected abstract T parseWithFormatter(String jsonValue, DateTimeFormatter formatter);
private T parseWithFormatterInternal(String jsonValue, DateTimeFormatter formatter) {
try {
return parseWithFormatter(jsonValue, formatter);
} catch (DateTimeException e) {
throw new JsonbException(Messages.getMessage(MessageKeys.DATE_PARSE_ERROR, jsonValue, getPropertyType()), e);
}
}
}