1 package com.fasterxml.jackson.databind.ser.std;
2
3 import java.io.IOException;
4 import java.lang.reflect.Type;
5 import java.math.BigDecimal;
6 import java.util.Map;
7
8 import com.fasterxml.jackson.annotation.JsonFormat;
9
10 import com.fasterxml.jackson.core.*;
11 import com.fasterxml.jackson.core.type.WritableTypeId;
12 import com.fasterxml.jackson.databind.*;
13 import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
14 import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
15 import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
16 import com.fasterxml.jackson.databind.ser.ContextualSerializer;
17
18
22 @SuppressWarnings("serial")
23 public class NumberSerializers {
24 protected NumberSerializers() { }
25
26 public static void addAll(Map<String, JsonSerializer<?>> allDeserializers) {
27 allDeserializers.put(Integer.class.getName(), new IntegerSerializer(Integer.class));
28 allDeserializers.put(Integer.TYPE.getName(), new IntegerSerializer(Integer.TYPE));
29 allDeserializers.put(Long.class.getName(), new LongSerializer(Long.class));
30 allDeserializers.put(Long.TYPE.getName(), new LongSerializer(Long.TYPE));
31
32 allDeserializers.put(Byte.class.getName(), IntLikeSerializer.instance);
33 allDeserializers.put(Byte.TYPE.getName(), IntLikeSerializer.instance);
34 allDeserializers.put(Short.class.getName(), ShortSerializer.instance);
35 allDeserializers.put(Short.TYPE.getName(), ShortSerializer.instance);
36
37
38 allDeserializers.put(Double.class.getName(), new DoubleSerializer(Double.class));
39 allDeserializers.put(Double.TYPE.getName(), new DoubleSerializer(Double.TYPE));
40 allDeserializers.put(Float.class.getName(), FloatSerializer.instance);
41 allDeserializers.put(Float.TYPE.getName(), FloatSerializer.instance);
42 }
43
44
49
50
60 public abstract static class Base<T> extends StdScalarSerializer<T>
61 implements ContextualSerializer
62 {
63 protected final JsonParser.NumberType _numberType;
64 protected final String _schemaType;
65 protected final boolean _isInt;
66
67 protected Base(Class<?> cls, JsonParser.NumberType numberType,
68 String schemaType) {
69 super(cls, false);
70 _numberType = numberType;
71 _schemaType = schemaType;
72 _isInt = (numberType == JsonParser.NumberType.INT)
73 || (numberType == JsonParser.NumberType.LONG)
74 || (numberType == JsonParser.NumberType.BIG_INTEGER);
75 }
76
77 @Override
78 public JsonNode getSchema(SerializerProvider provider, Type typeHint) {
79 return createSchemaNode(_schemaType, true);
80 }
81
82 @Override
83 public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor,
84 JavaType typeHint) throws JsonMappingException
85 {
86 if (_isInt) {
87 visitIntFormat(visitor, typeHint, _numberType);
88 } else {
89 visitFloatFormat(visitor, typeHint, _numberType);
90 }
91 }
92
93 @Override
94 public JsonSerializer<?> createContextual(SerializerProvider prov,
95 BeanProperty property) throws JsonMappingException
96 {
97 JsonFormat.Value format = findFormatOverrides(prov, property, handledType());
98 if (format != null) {
99 switch (format.getShape()) {
100 case STRING:
101 if (((Class<?>) handledType()) == BigDecimal.class) {
102 return NumberSerializer.bigDecimalAsStringSerializer();
103 }
104 return ToStringSerializer.instance;
105 default:
106 }
107 }
108 return this;
109 }
110 }
111
112
117
118 @JacksonStdImpl
119 public static class ShortSerializer extends Base<Object> {
120 final static ShortSerializer instance = new ShortSerializer();
121
122 public ShortSerializer() {
123 super(Short.class, JsonParser.NumberType.INT, "number");
124 }
125
126 @Override
127 public void serialize(Object value, JsonGenerator gen,
128 SerializerProvider provider) throws IOException {
129 gen.writeNumber(((Short) value).shortValue());
130 }
131 }
132
133
143 @JacksonStdImpl
144 public static class IntegerSerializer extends Base<Object> {
145 public IntegerSerializer(Class<?> type) {
146 super(type, JsonParser.NumberType.INT, "integer");
147 }
148
149 @Override
150 public void serialize(Object value, JsonGenerator gen,
151 SerializerProvider provider) throws IOException {
152 gen.writeNumber(((Integer) value).intValue());
153 }
154
155
156 @Override
157 public void serializeWithType(Object value, JsonGenerator gen,
158 SerializerProvider provider, TypeSerializer typeSer)
159 throws IOException {
160
161 serialize(value, gen, provider);
162 }
163 }
164
165
170 @JacksonStdImpl
171 public static class IntLikeSerializer extends Base<Object> {
172 final static IntLikeSerializer instance = new IntLikeSerializer();
173
174 public IntLikeSerializer() {
175 super(Number.class, JsonParser.NumberType.INT, "integer");
176 }
177
178 @Override
179 public void serialize(Object value, JsonGenerator gen,
180 SerializerProvider provider) throws IOException {
181 gen.writeNumber(((Number) value).intValue());
182 }
183 }
184
185 @JacksonStdImpl
186 public static class LongSerializer extends Base<Object> {
187 public LongSerializer(Class<?> cls) {
188 super(cls, JsonParser.NumberType.LONG, "number");
189 }
190
191 @Override
192 public void serialize(Object value, JsonGenerator gen,
193 SerializerProvider provider) throws IOException {
194 gen.writeNumber(((Long) value).longValue());
195 }
196 }
197
198 @JacksonStdImpl
199 public static class FloatSerializer extends Base<Object> {
200 final static FloatSerializer instance = new FloatSerializer();
201
202 public FloatSerializer() {
203 super(Float.class, JsonParser.NumberType.FLOAT, "number");
204 }
205
206 @Override
207 public void serialize(Object value, JsonGenerator gen,
208 SerializerProvider provider) throws IOException {
209 gen.writeNumber(((Float) value).floatValue());
210 }
211 }
212
213
220 @JacksonStdImpl
221 public static class DoubleSerializer extends Base<Object> {
222 public DoubleSerializer(Class<?> cls) {
223 super(cls, JsonParser.NumberType.DOUBLE, "number");
224 }
225
226 @Override
227 public void serialize(Object value, JsonGenerator gen,
228 SerializerProvider provider) throws IOException {
229 gen.writeNumber(((Double) value).doubleValue());
230 }
231
232
233 @Override
234 public void serializeWithType(Object value, JsonGenerator g,
235 SerializerProvider provider, TypeSerializer typeSer)
236 throws IOException {
237
238
239 Double d = (Double) value;
240 if (notFinite(d)) {
241 WritableTypeId typeIdDef = typeSer.writeTypePrefix(g,
242
243 typeSer.typeId(value, JsonToken.VALUE_NUMBER_FLOAT));
244 g.writeNumber(d);
245 typeSer.writeTypeSuffix(g, typeIdDef);
246 } else {
247 g.writeNumber(d);
248 }
249 }
250
251 public static boolean notFinite(double value) {
252
253 return Double.isNaN(value) || Double.isInfinite(value);
254 }
255 }
256 }
257