1
16
17 package com.fasterxml.jackson.datatype.jsr310.ser;
18
19 import java.io.IOException;
20 import java.time.LocalTime;
21 import java.time.format.DateTimeFormatter;
22 import java.time.temporal.ChronoField;
23
24 import com.fasterxml.jackson.annotation.JsonFormat;
25 import com.fasterxml.jackson.core.JsonGenerator;
26 import com.fasterxml.jackson.core.JsonToken;
27 import com.fasterxml.jackson.core.type.WritableTypeId;
28 import com.fasterxml.jackson.databind.JavaType;
29 import com.fasterxml.jackson.databind.JsonMappingException;
30 import com.fasterxml.jackson.databind.SerializerProvider;
31 import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
32 import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonStringFormatVisitor;
33 import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonValueFormat;
34 import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
35
41 public class LocalTimeSerializer extends JSR310FormattedSerializerBase<LocalTime>
42 {
43 private static final long serialVersionUID = 1L;
44
45 public static final LocalTimeSerializer INSTANCE = new LocalTimeSerializer();
46
47 protected LocalTimeSerializer() {
48 this(null);
49 }
50
51 public LocalTimeSerializer(DateTimeFormatter formatter) {
52 super(LocalTime.class, formatter);
53 }
54
55 protected LocalTimeSerializer(LocalTimeSerializer base, Boolean useTimestamp, DateTimeFormatter formatter) {
56 this(base, useTimestamp, null, formatter);
57 }
58
59 protected LocalTimeSerializer(LocalTimeSerializer base, Boolean useTimestamp, Boolean useNanoseconds, DateTimeFormatter formatter) {
60 super(base, useTimestamp, useNanoseconds, formatter, null);
61 }
62
63 @Override
64 protected JSR310FormattedSerializerBase<LocalTime> withFormat(Boolean useTimestamp, DateTimeFormatter dtf, JsonFormat.Shape shape) {
65 return new LocalTimeSerializer(this, useTimestamp, dtf);
66 }
67
68
69 protected DateTimeFormatter _defaultFormatter() {
70 return DateTimeFormatter.ISO_LOCAL_TIME;
71 }
72
73 @Override
74 public void serialize(LocalTime value, JsonGenerator g, SerializerProvider provider)
75 throws IOException
76 {
77 if (useTimestamp(provider)) {
78 g.writeStartArray();
79 _serializeAsArrayContents(value, g, provider);
80 g.writeEndArray();
81 } else {
82 DateTimeFormatter dtf = _formatter;
83 if (dtf == null) {
84 dtf = _defaultFormatter();
85 }
86 g.writeString(value.format(dtf));
87 }
88 }
89
90 @Override
91 public void serializeWithType(LocalTime value, JsonGenerator g,
92 SerializerProvider provider, TypeSerializer typeSer) throws IOException
93 {
94 WritableTypeId typeIdDef = typeSer.writeTypePrefix(g,
95 typeSer.typeId(value, serializationShape(provider)));
96
97 if (typeIdDef.valueShape == JsonToken.START_ARRAY) {
98 _serializeAsArrayContents(value, g, provider);
99 } else {
100 DateTimeFormatter dtf = _formatter;
101 if (dtf == null) {
102 dtf = _defaultFormatter();
103 }
104 g.writeString(value.format(dtf));
105 }
106 typeSer.writeTypeSuffix(g, typeIdDef);
107 }
108
109 private final void _serializeAsArrayContents(LocalTime value, JsonGenerator g,
110 SerializerProvider provider) throws IOException
111 {
112 g.writeNumber(value.getHour());
113 g.writeNumber(value.getMinute());
114 int secs = value.getSecond();
115 int nanos = value.getNano();
116 if ((secs > 0) || (nanos > 0))
117 {
118 g.writeNumber(secs);
119 if (nanos > 0) {
120 if (useNanoseconds(provider)) {
121 g.writeNumber(nanos);
122 } else {
123 g.writeNumber(value.get(ChronoField.MILLI_OF_SECOND));
124 }
125 }
126 }
127 }
128
129 @Override
130 protected JsonToken serializationShape(SerializerProvider provider) {
131 return useTimestamp(provider) ? JsonToken.START_ARRAY : JsonToken.VALUE_STRING;
132 }
133
134 @Override
135 protected JSR310FormattedSerializerBase<?> withFeatures(Boolean writeZoneId, Boolean writeNanoseconds) {
136 return new LocalTimeSerializer(this, _useTimestamp, writeNanoseconds, _formatter);
137 }
138
139
140 @Override
141 public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
142 throws JsonMappingException
143 {
144 if (useTimestamp(visitor.getProvider())) {
145 _acceptTimestampVisitor(visitor, typeHint);
146 } else {
147 JsonStringFormatVisitor v2 = visitor.expectStringFormat(typeHint);
148 if (v2 != null) {
149 v2.format(JsonValueFormat.TIME);
150 }
151 }
152 }
153 }
154