1 package com.fasterxml.jackson.databind.module;
2
3 import java.util.*;
4
5
6 import com.fasterxml.jackson.databind.*;
7 import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
8 import com.fasterxml.jackson.databind.ser.Serializers;
9 import com.fasterxml.jackson.databind.type.ArrayType;
10 import com.fasterxml.jackson.databind.type.ClassKey;
11 import com.fasterxml.jackson.databind.type.CollectionLikeType;
12 import com.fasterxml.jackson.databind.type.CollectionType;
13 import com.fasterxml.jackson.databind.type.MapLikeType;
14 import com.fasterxml.jackson.databind.type.MapType;
15
16
27 public class SimpleSerializers
28 extends Serializers.Base
29 implements java.io.Serializable
30 {
31 private static final long serialVersionUID = 3L;
32
33
37 protected HashMap<ClassKey,JsonSerializer<?>> _classMappings = null;
38
39
42 protected HashMap<ClassKey,JsonSerializer<?>> _interfaceMappings = null;
43
44
49 protected boolean _hasEnumSerializer = false;
50
51
56
57 public SimpleSerializers() { }
58
59
62 public SimpleSerializers(List<JsonSerializer<?>> sers) {
63 addSerializers(sers);
64 }
65
66
75 public void addSerializer(JsonSerializer<?> ser)
76 {
77
78 Class<?> cls = ser.handledType();
79 if (cls == null || cls == Object.class) {
80 throw new IllegalArgumentException("JsonSerializer of type "+ser.getClass().getName()
81 +" does not define valid handledType() -- must either register with method that takes type argument "
82 +" or make serializer extend 'com.fasterxml.jackson.databind.ser.std.StdSerializer'");
83 }
84 _addSerializer(cls, ser);
85 }
86
87 public <T> void addSerializer(Class<? extends T> type, JsonSerializer<T> ser)
88 {
89 _addSerializer(type, ser);
90 }
91
92
95 public void addSerializers(List<JsonSerializer<?>> sers) {
96 for (JsonSerializer<?> ser : sers) {
97 addSerializer(ser);
98 }
99 }
100
101
106
107 @Override
108 public JsonSerializer<?> findSerializer(SerializationConfig config,
109 JavaType type, BeanDescription beanDesc)
110 {
111 Class<?> cls = type.getRawClass();
112 ClassKey key = new ClassKey(cls);
113 JsonSerializer<?> ser = null;
114
115
116 if (cls.isInterface()) {
117 if (_interfaceMappings != null) {
118 ser = _interfaceMappings.get(key);
119 if (ser != null) {
120 return ser;
121 }
122 }
123 } else {
124 if (_classMappings != null) {
125 ser = _classMappings.get(key);
126 if (ser != null) {
127 return ser;
128 }
129
130
131 if (_hasEnumSerializer && type.isEnumType()) {
132 key.reset(Enum.class);
133 ser = _classMappings.get(key);
134 if (ser != null) {
135 return ser;
136 }
137 }
138
139
140 for (Class<?> curr = cls; (curr != null); curr = curr.getSuperclass()) {
141 key.reset(curr);
142 ser = _classMappings.get(key);
143 if (ser != null) {
144 return ser;
145 }
146 }
147 }
148 }
149
150 if (_interfaceMappings != null) {
151 ser = _findInterfaceMapping(cls, key);
152 if (ser != null) {
153 return ser;
154 }
155
156 if (!cls.isInterface()) {
157 while ((cls = cls.getSuperclass()) != null) {
158 ser = _findInterfaceMapping(cls, key);
159 if (ser != null) {
160 return ser;
161 }
162 }
163 }
164 }
165 return null;
166 }
167
168 @Override
169 public JsonSerializer<?> findArraySerializer(SerializationConfig config,
170 ArrayType type, BeanDescription beanDesc,
171 TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer) {
172 return findSerializer(config, type, beanDesc);
173 }
174
175 @Override
176 public JsonSerializer<?> findCollectionSerializer(SerializationConfig config,
177 CollectionType type, BeanDescription beanDesc,
178 TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer) {
179 return findSerializer(config, type, beanDesc);
180 }
181
182 @Override
183 public JsonSerializer<?> findCollectionLikeSerializer(SerializationConfig config,
184 CollectionLikeType type, BeanDescription beanDesc,
185 TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer) {
186 return findSerializer(config, type, beanDesc);
187 }
188
189 @Override
190 public JsonSerializer<?> findMapSerializer(SerializationConfig config,
191 MapType type, BeanDescription beanDesc,
192 JsonSerializer<Object> keySerializer,
193 TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer) {
194 return findSerializer(config, type, beanDesc);
195 }
196
197 @Override
198 public JsonSerializer<?> findMapLikeSerializer(SerializationConfig config,
199 MapLikeType type, BeanDescription beanDesc,
200 JsonSerializer<Object> keySerializer,
201 TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer) {
202 return findSerializer(config, type, beanDesc);
203 }
204
205
210
211 protected JsonSerializer<?> _findInterfaceMapping(Class<?> cls, ClassKey key)
212 {
213 for (Class<?> iface : cls.getInterfaces()) {
214 key.reset(iface);
215 JsonSerializer<?> ser = _interfaceMappings.get(key);
216 if (ser != null) {
217 return ser;
218 }
219 ser = _findInterfaceMapping(iface, key);
220 if (ser != null) {
221 return ser;
222 }
223 }
224 return null;
225 }
226
227 protected void _addSerializer(Class<?> cls, JsonSerializer<?> ser)
228 {
229 ClassKey key = new ClassKey(cls);
230
231 if (cls.isInterface()) {
232 if (_interfaceMappings == null) {
233 _interfaceMappings = new HashMap<ClassKey,JsonSerializer<?>>();
234 }
235 _interfaceMappings.put(key, ser);
236 } else {
237 if (_classMappings == null) {
238 _classMappings = new HashMap<ClassKey,JsonSerializer<?>>();
239 }
240 _classMappings.put(key, ser);
241 if (cls == Enum.class) {
242 _hasEnumSerializer = true;
243 }
244 }
245 }
246 }
247