• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind;
2 
3 import java.io.IOException;
4 import java.util.Iterator;
5 
6 import com.fasterxml.jackson.core.*;
7 
8 import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitable;
9 import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
10 import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
11 import com.fasterxml.jackson.databind.ser.PropertyWriter;
12 import com.fasterxml.jackson.databind.util.ClassUtil;
13 import com.fasterxml.jackson.databind.util.NameTransformer;
14 
15 /**
16  * Abstract class that defines API used by {@link ObjectMapper} (and
17  * other chained {@link JsonSerializer}s too) to serialize Objects of
18  * arbitrary types into JSON, using provided {@link JsonGenerator}.
19  * {@link com.fasterxml.jackson.databind.ser.std.StdSerializer} instead
20  * of this class, since it will implement many of optional
21  * methods of this class.
22  *<p>
23  * NOTE: various <code>serialize</code> methods are never (to be) called
24  * with null values -- caller <b>must</b> handle null values, usually
25  * by calling {@link SerializerProvider#findNullValueSerializer} to obtain
26  * serializer to use.
27  * This also means that custom serializers cannot be directly used to change
28  * the output to produce when serializing null values.
29  *<p>
30  * If serializer is an aggregate one -- meaning it delegates handling of some
31  * of its contents by using other serializer(s) -- it typically also needs
32  * to implement {@link com.fasterxml.jackson.databind.ser.ResolvableSerializer},
33  * which can locate secondary serializers needed. This is important to allow dynamic
34  * overrides of serializers; separate call interface is needed to separate
35  * resolution of secondary serializers (which may have cyclic link back
36  * to serializer itself, directly or indirectly).
37  *<p>
38  * In addition, to support per-property annotations (to configure aspects
39  * of serialization on per-property basis), serializers may want
40  * to implement
41  * {@link com.fasterxml.jackson.databind.ser.ContextualSerializer},
42  * which allows specialization of serializers: call to
43  * {@link com.fasterxml.jackson.databind.ser.ContextualSerializer#createContextual}
44  * is passed information on property, and can create a newly configured
45  * serializer for handling that particular property.
46  *<p>
47  * If both
48  * {@link com.fasterxml.jackson.databind.ser.ResolvableSerializer} and
49  * {@link com.fasterxml.jackson.databind.ser.ContextualSerializer}
50  * are implemented, resolution of serializers occurs before
51  * contextualization.
52  */
53 public abstract class JsonSerializer<T>
54     implements JsonFormatVisitable // since 2.1
55 {
56     /*
57     /**********************************************************
58     /* Fluent factory methods for constructing decorated versions
59     /**********************************************************
60      */
61 
62     /**
63      * Method that will return serializer instance that produces
64      * "unwrapped" serialization, if applicable for type being
65      * serialized (which is the case for some serializers
66      * that produce JSON Objects as output).
67      * If no unwrapped serializer can be constructed, will simply
68      * return serializer as-is.
69      *<p>
70      * Default implementation just returns serializer as-is,
71      * indicating that no unwrapped variant exists
72      *
73      * @param unwrapper Name transformation to use to convert between names
74      *   of unwrapper properties
75      */
unwrappingSerializer(NameTransformer unwrapper)76     public JsonSerializer<T> unwrappingSerializer(NameTransformer unwrapper) {
77         return this;
78     }
79 
80     /**
81      * Method that can be called to try to replace serializer this serializer
82      * delegates calls to. If not supported (either this serializer does not
83      * delegate anything; or it does not want any changes), should either
84      * throw {@link UnsupportedOperationException} (if operation does not
85      * make sense or is not allowed); or return this serializer as is.
86      *
87      * @since 2.1
88      */
replaceDelegatee(JsonSerializer<?> delegatee)89     public JsonSerializer<T> replaceDelegatee(JsonSerializer<?> delegatee) {
90         throw new UnsupportedOperationException();
91     }
92 
93     /**
94      * Mutant factory method that is called if contextual configuration indicates that
95      * a specific filter (as specified by <code>filterId</code>) is to be used for
96      * serialization.
97      *<p>
98      * Default implementation simply returns <code>this</code>; sub-classes that do support
99      * filtering will need to create and return new instance if filter changes.
100      *
101      * @since 2.6
102      */
withFilterId(Object filterId)103     public JsonSerializer<?> withFilterId(Object filterId) {
104         return this;
105     }
106 
107     /*
108     /**********************************************************
109     /* Serialization methods
110     /**********************************************************
111      */
112 
113     /**
114      * Method that can be called to ask implementation to serialize
115      * values of type this serializer handles.
116      *
117      * @param value Value to serialize; can <b>not</b> be null.
118      * @param gen Generator used to output resulting Json content
119      * @param serializers Provider that can be used to get serializers for
120      *   serializing Objects value contains, if any.
121      */
serialize(T value, JsonGenerator gen, SerializerProvider serializers)122     public abstract void serialize(T value, JsonGenerator gen, SerializerProvider serializers)
123         throws IOException;
124 
125     /**
126      * Method that can be called to ask implementation to serialize
127      * values of type this serializer handles, using specified type serializer
128      * for embedding necessary type information.
129      *<p>
130      * Default implementation will throw {@link UnsupportedOperationException}
131      * to indicate that proper type handling needs to be implemented.
132      *<p>
133      * For simple datatypes written as a single scalar value (JSON String, Number, Boolean),
134      * implementation would look like:
135      *<pre>
136      *  // note: method to call depends on whether this type is serialized as JSON scalar, object or Array!
137      *  typeSer.writeTypePrefixForScalar(value, gen);
138      *  serialize(value, gen, provider);
139      *  typeSer.writeTypeSuffixForScalar(value, gen);
140      *</pre>
141      * and implementations for type serialized as JSON Arrays or Objects would differ slightly,
142      * as <code>START-ARRAY</code>/<code>END-ARRAY</code> and
143      * <code>START-OBJECT</code>/<code>END-OBJECT</code> pairs
144      * need to be properly handled with respect to serializing of contents.
145      *
146      * @param value Value to serialize; can <b>not</b> be null.
147      * @param gen Generator used to output resulting Json content
148      * @param serializers Provider that can be used to get serializers for
149      *   serializing Objects value contains, if any.
150      * @param typeSer Type serializer to use for including type information
151      */
serializeWithType(T value, JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer)152     public void serializeWithType(T value, JsonGenerator gen, SerializerProvider serializers,
153             TypeSerializer typeSer)
154         throws IOException
155     {
156         Class<?> clz = handledType();
157         if (clz == null) {
158             clz = value.getClass();
159         }
160         serializers.reportBadDefinition(clz, String.format(
161                 "Type id handling not implemented for type %s (by serializer of type %s)",
162                 clz.getName(), getClass().getName()));
163     }
164 
165     /*
166     /**********************************************************
167     /* Other accessors
168     /**********************************************************
169      */
170 
171     /**
172      * Method for accessing type of Objects this serializer can handle.
173      * Note that this information is not guaranteed to be exact -- it
174      * may be a more generic (super-type) -- but it should not be
175      * incorrect (return a non-related type).
176      *<p>
177      * Default implementation will return null, which essentially means
178      * same as returning <code>Object.class</code> would; that is, that
179      * nothing is known about handled type.
180      *<p>
181      */
handledType()182     public Class<T> handledType() { return null; }
183 
184     /**
185      * Method called to check whether given serializable value is
186      * considered "empty" value (for purposes of suppressing serialization
187      * of empty values).
188      *<p>
189      * Default implementation will consider only null values to be empty.
190      *
191      * @deprecated Since 2.5 Use {@link #isEmpty(SerializerProvider, Object)} instead;
192      *   will be removed from 3.0
193      */
194     @Deprecated
isEmpty(T value)195     public boolean isEmpty(T value) {
196         return isEmpty(null, value);
197     }
198 
199     /**
200      * Method called to check whether given serializable value is
201      * considered "empty" value (for purposes of suppressing serialization
202      * of empty values).
203      *<p>
204      * Default implementation will consider only null values to be empty.
205      *<p>
206      * NOTE: replaces {@link #isEmpty(Object)}, which was deprecated in 2.5
207      *
208      * @since 2.5
209      */
isEmpty(SerializerProvider provider, T value)210     public boolean isEmpty(SerializerProvider provider, T value) {
211         return (value == null);
212     }
213 
214     /**
215      * Method that can be called to see whether this serializer instance
216      * will use Object Id to handle cyclic references.
217      */
usesObjectId()218     public boolean usesObjectId() {
219         return false;
220     }
221 
222     /**
223      * Accessor for checking whether this serializer is an
224      * "unwrapping" serializer; this is necessary to know since
225      * it may also require caller to suppress writing of the
226      * leading property name.
227      */
isUnwrappingSerializer()228     public boolean isUnwrappingSerializer() {
229         return false;
230     }
231 
232     /**
233      * Accessor that can be used to determine if this serializer uses
234      * another serializer for actual serialization, by delegating
235      * calls. If so, will return immediate delegate (which itself may
236      * delegate to further serializers); otherwise will return null.
237      *
238      * @return Serializer this serializer delegates calls to, if null;
239      *   null otherwise.
240      *
241      * @since 2.1
242      */
getDelegatee()243     public JsonSerializer<?> getDelegatee() {
244         return null;
245     }
246 
247     /**
248      * Accessor for iterating over logical properties that the type
249      * handled by this serializer has, from serialization perspective.
250      * Actual type of properties, if any, will be
251      * {@link com.fasterxml.jackson.databind.ser.BeanPropertyWriter}.
252      * Of standard Jackson serializers, only {@link com.fasterxml.jackson.databind.ser.BeanSerializer}
253      * exposes properties.
254      *
255      * @since 2.6
256      */
properties()257     public Iterator<PropertyWriter> properties() {
258         return ClassUtil.emptyIterator();
259     }
260 
261     /*
262     /**********************************************************
263     /* Default JsonFormatVisitable implementation
264     /**********************************************************
265      */
266 
267     /**
268      * Default implementation simply calls {@link JsonFormatVisitorWrapper#expectAnyFormat(JavaType)}.
269      *
270      * @since 2.1
271      */
272     @Override
acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType type)273     public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType type)
274         throws JsonMappingException
275     {
276         visitor.expectAnyFormat(type);
277     }
278 
279     /*
280     /**********************************************************
281     /* Helper class(es)
282     /**********************************************************
283      */
284 
285     /**
286      * This marker class is only to be used with annotations, to
287      * indicate that <b>no serializer is configured</b>.
288      *<p>
289      * Specifically, this class is to be used as the marker for
290      * annotation {@link com.fasterxml.jackson.databind.annotation.JsonSerialize}.
291      */
292     public abstract static class None
293         extends JsonSerializer<Object> { }
294 }
295