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