1 package com.fasterxml.jackson.databind.ser.std;
2 
3 import java.io.IOException;
4 import java.net.InetAddress;
5 
6 import com.fasterxml.jackson.annotation.JsonFormat;
7 import com.fasterxml.jackson.core.*;
8 import com.fasterxml.jackson.core.type.WritableTypeId;
9 import com.fasterxml.jackson.databind.BeanProperty;
10 import com.fasterxml.jackson.databind.JsonMappingException;
11 import com.fasterxml.jackson.databind.JsonSerializer;
12 import com.fasterxml.jackson.databind.SerializerProvider;
13 import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
14 import com.fasterxml.jackson.databind.ser.ContextualSerializer;
15 
16 /**
17  * Simple serializer for {@link java.net.InetAddress}. Main complexity is
18  * with registration, since same serializer is to be used for sub-classes.
19  *<p>
20  * Since 2.9 allows use of {@link JsonFormat} configuration (annotation,
21  * per-type defaulting) so that if <code>JsonFormat.Shape.NUMBER</code>
22  * (or <code>ARRAY</code>) is used, will serialize as "host address"
23  * (dotted numbers) instead of simple conversion.
24  */
25 @SuppressWarnings("serial")
26 public class InetAddressSerializer
27     extends StdScalarSerializer<InetAddress>
28     implements ContextualSerializer
29 {
30     /**
31      * @since 2.9
32      */
33     protected final boolean _asNumeric;
34 
InetAddressSerializer()35     public InetAddressSerializer() {
36         this(false);
37     }
38 
39     /**
40      * @since 2.9
41      */
InetAddressSerializer(boolean asNumeric)42     public InetAddressSerializer(boolean asNumeric) {
43         super(InetAddress.class);
44         _asNumeric = asNumeric;
45     }
46 
47     @Override
createContextual(SerializerProvider serializers, BeanProperty property)48     public JsonSerializer<?> createContextual(SerializerProvider serializers,
49             BeanProperty property) throws JsonMappingException
50     {
51         JsonFormat.Value format = findFormatOverrides(serializers,
52                 property, handledType());
53         boolean asNumeric = false;
54         if (format != null) {
55             JsonFormat.Shape shape = format.getShape();
56             if (shape.isNumeric() || shape == JsonFormat.Shape.ARRAY) {
57                 asNumeric = true;
58             }
59         }
60         if (asNumeric != _asNumeric) {
61             return new InetAddressSerializer(asNumeric);
62         }
63         return this;
64     }
65 
66     @Override
serialize(InetAddress value, JsonGenerator g, SerializerProvider provider)67     public void serialize(InetAddress value, JsonGenerator g, SerializerProvider provider) throws IOException
68     {
69         String str;
70 
71         if (_asNumeric) { // since 2.9
72             str = value.getHostAddress();
73         } else {
74             // Ok: get textual description; choose "more specific" part
75             str = value.toString().trim();
76             int ix = str.indexOf('/');
77             if (ix >= 0) {
78                 if (ix == 0) { // missing host name; use address
79                     str = str.substring(1);
80                 } else { // otherwise use name
81                     str = str.substring(0, ix);
82                 }
83             }
84         }
85         g.writeString(str);
86     }
87 
88     @Override
serializeWithType(InetAddress value, JsonGenerator g, SerializerProvider provider, TypeSerializer typeSer)89     public void serializeWithType(InetAddress value, JsonGenerator g,
90             SerializerProvider provider, TypeSerializer typeSer) throws IOException
91     {
92         // Better ensure we don't use specific sub-classes...
93         WritableTypeId typeIdDef = typeSer.writeTypePrefix(g,
94                 typeSer.typeId(value, InetAddress.class, JsonToken.VALUE_STRING));
95         serialize(value, g, provider);
96         typeSer.writeTypeSuffix(g, typeIdDef);
97     }
98 }
99