1
16
17 package com.fasterxml.jackson.datatype.jsr310.deser;
18
19 import java.io.IOException;
20 import java.time.DateTimeException;
21 import java.time.OffsetTime;
22 import java.time.ZoneOffset;
23 import java.time.format.DateTimeFormatter;
24
25 import com.fasterxml.jackson.annotation.JsonFormat;
26 import com.fasterxml.jackson.core.*;
27 import com.fasterxml.jackson.databind.*;
28
29
34 public class OffsetTimeDeserializer extends JSR310DateTimeDeserializerBase<OffsetTime>
35 {
36 private static final long serialVersionUID = 1L;
37
38 public static final OffsetTimeDeserializer INSTANCE = new OffsetTimeDeserializer();
39
40 private OffsetTimeDeserializer() {
41 this(DateTimeFormatter.ISO_OFFSET_TIME);
42 }
43
44 protected OffsetTimeDeserializer(DateTimeFormatter dtf) {
45 super(OffsetTime.class, dtf);
46 }
47
48
51 protected OffsetTimeDeserializer(OffsetTimeDeserializer base, Boolean leniency) {
52 super(base, leniency);
53 }
54
55 @Override
56 protected OffsetTimeDeserializer withDateFormat(DateTimeFormatter dtf) {
57 return new OffsetTimeDeserializer(dtf);
58 }
59
60 @Override
61 protected OffsetTimeDeserializer withLeniency(Boolean leniency) {
62 return new OffsetTimeDeserializer(this, leniency);
63 }
64
65 @Override
66 protected OffsetTimeDeserializer withShape(JsonFormat.Shape shape) { return this; }
67
68 @Override
69 public OffsetTime deserialize(JsonParser parser, DeserializationContext context) throws IOException
70 {
71 if (parser.hasToken(JsonToken.VALUE_STRING)) {
72 String string = parser.getText().trim();
73 if (string.length() == 0) {
74 if (!isLenient()) {
75 return _failForNotLenient(parser, context, JsonToken.VALUE_STRING);
76 }
77 return null;
78 }
79 try {
80 return OffsetTime.parse(string, _formatter);
81 } catch (DateTimeException e) {
82 return _handleDateTimeException(context, e, string);
83 }
84 }
85 if (!parser.isExpectedStartArrayToken()) {
86 if (parser.hasToken(JsonToken.VALUE_EMBEDDED_OBJECT)) {
87 return (OffsetTime) parser.getEmbeddedObject();
88 }
89 if (parser.hasToken(JsonToken.VALUE_NUMBER_INT)) {
90 _throwNoNumericTimestampNeedTimeZone(parser, context);
91 }
92 throw context.wrongTokenException(parser, handledType(), JsonToken.START_ARRAY,
93 "Expected array or string.");
94 }
95 JsonToken t = parser.nextToken();
96 if (t != JsonToken.VALUE_NUMBER_INT) {
97 if (t == JsonToken.END_ARRAY) {
98 return null;
99 }
100 if ((t == JsonToken.VALUE_STRING || t == JsonToken.VALUE_EMBEDDED_OBJECT)
101 && context.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
102 final OffsetTime parsed = deserialize(parser, context);
103 if (parser.nextToken() != JsonToken.END_ARRAY) {
104 handleMissingEndArrayForSingle(parser, context);
105 }
106 return parsed;
107 }
108 context.reportInputMismatch(handledType(),
109 "Unexpected token (%s) within Array, expected VALUE_NUMBER_INT",
110 t);
111 }
112 int hour = parser.getIntValue();
113 int minute = parser.nextIntValue(-1);
114 if (minute == -1) {
115 t = parser.getCurrentToken();
116 if (t == JsonToken.END_ARRAY) {
117 return null;
118 }
119 if (t != JsonToken.VALUE_NUMBER_INT) {
120 _reportWrongToken(context, JsonToken.VALUE_NUMBER_INT, "minutes");
121 }
122 minute = parser.getIntValue();
123 }
124 int partialSecond = 0;
125 int second = 0;
126 if (parser.nextToken() == JsonToken.VALUE_NUMBER_INT) {
127 second = parser.getIntValue();
128 if (parser.nextToken() == JsonToken.VALUE_NUMBER_INT) {
129 partialSecond = parser.getIntValue();
130 if (partialSecond < 1_000 &&
131 !context.isEnabled(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS)) {
132 partialSecond *= 1_000_000;
133 }
134 parser.nextToken();
135 }
136 }
137 if (parser.getCurrentToken() == JsonToken.VALUE_STRING) {
138 OffsetTime result = OffsetTime.of(hour, minute, second, partialSecond, ZoneOffset.of(parser.getText()));
139 if (parser.nextToken() != JsonToken.END_ARRAY) {
140 _reportWrongToken(context, JsonToken.END_ARRAY, "timezone");
141 }
142 return result;
143 }
144 throw context.wrongTokenException(parser, handledType(), JsonToken.VALUE_STRING,
145 "Expected string for TimeZone after numeric values");
146 }
147 }
148