1 /*
2  * Copyright 2013 FasterXML.com
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may
5  * not use this file except in compliance with the License. You may obtain
6  * a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the license for the specific language governing permissions and
14  * limitations under the license.
15  */

16
17 package com.fasterxml.jackson.datatype.jsr310.ser;
18
19 import com.fasterxml.jackson.annotation.JsonFormat;
20 import com.fasterxml.jackson.core.JsonGenerator;
21 import com.fasterxml.jackson.core.JsonToken;
22 import com.fasterxml.jackson.core.type.WritableTypeId;
23 import com.fasterxml.jackson.databind.SerializerProvider;
24 import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
25
26 import java.io.IOException;
27 import java.time.OffsetTime;
28 import java.time.format.DateTimeFormatter;
29 import java.time.temporal.ChronoField;
30
31 /**
32  * Serializer for Java 8 temporal {@link OffsetTime}s.
33  *
34  * @author Nick Williams
35  * @since 2.2
36  */

37 public class OffsetTimeSerializer extends JSR310FormattedSerializerBase<OffsetTime>
38 {
39     private static final long serialVersionUID = 1L;
40
41     public static final OffsetTimeSerializer INSTANCE = new OffsetTimeSerializer();
42
43     protected OffsetTimeSerializer() {
44         super(OffsetTime.class);
45     }
46
47     protected OffsetTimeSerializer(OffsetTimeSerializer base,
48             Boolean useTimestamp, DateTimeFormatter dtf) {
49         this(base, useTimestamp, null, dtf);
50     }
51
52     protected OffsetTimeSerializer(OffsetTimeSerializer base,
53             Boolean useTimestamp, Boolean useNanoseconds, DateTimeFormatter dtf) {
54         super(base, useTimestamp, useNanoseconds, dtf, null);
55     }
56
57     @Override
58     protected OffsetTimeSerializer withFormat(Boolean useTimestamp, DateTimeFormatter dtf, JsonFormat.Shape shape) {
59         return new OffsetTimeSerializer(this, useTimestamp, dtf);
60     }
61
62     @Override
63     public void serialize(OffsetTime time, JsonGenerator g, SerializerProvider provider) throws IOException
64     {
65         if (useTimestamp(provider)) {
66             g.writeStartArray();
67             _serializeAsArrayContents(time, g, provider);
68             g.writeEndArray();
69         } else {
70             String str = (_formatter == null) ? time.toString() : time.format(_formatter);
71             g.writeString(str);
72         }
73     }
74
75     @Override
76     public void serializeWithType(OffsetTime value, JsonGenerator g, SerializerProvider provider,
77             TypeSerializer typeSer) throws IOException
78     {
79         WritableTypeId typeIdDef = typeSer.writeTypePrefix(g,
80                 typeSer.typeId(value, serializationShape(provider)));
81         // need to write out to avoid double-writing array markers
82         if (typeIdDef.valueShape == JsonToken.START_ARRAY) {
83             _serializeAsArrayContents(value, g, provider);
84         } else {
85             String str = (_formatter == null) ? value.toString() : value.format(_formatter);
86             g.writeString(str);
87         }
88         typeSer.writeTypeSuffix(g, typeIdDef);
89     }
90
91     private final void _serializeAsArrayContents(OffsetTime value, JsonGenerator g,
92             SerializerProvider provider) throws IOException
93     {
94         g.writeNumber(value.getHour());
95         g.writeNumber(value.getMinute());
96         final int secs = value.getSecond();
97         final int nanos = value.getNano();
98         if ((secs > 0) || (nanos > 0)) {
99             g.writeNumber(secs);
100             if (nanos > 0) {
101                 if(useNanoseconds(provider)) {
102                     g.writeNumber(nanos);
103                 } else {
104                     g.writeNumber(value.get(ChronoField.MILLI_OF_SECOND));
105                 }
106             }
107         }
108         g.writeString(value.getOffset().toString());
109     }
110     
111     @Override // since 2.9
112     protected JsonToken serializationShape(SerializerProvider provider) {
113         return useTimestamp(provider) ? JsonToken.START_ARRAY : JsonToken.VALUE_STRING;
114     }
115
116     @Override
117     protected JSR310FormattedSerializerBase<?> withFeatures(Boolean writeZoneId, Boolean writeNanoseconds) {
118         return new OffsetTimeSerializer(this, _useTimestamp, writeNanoseconds, _formatter);
119     }
120 }
121