All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fitbur.jackson.databind.JsonSerializer Maven / Gradle / Ivy

There is a newer version: 1.0.0
Show newest version
package com.fitbur.jackson.databind;

import java.io.IOException;
import java.util.Iterator;

import com.fitbur.jackson.core.*;

import com.fitbur.jackson.databind.jsonFormatVisitors.JsonFormatVisitable;
import com.fitbur.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fitbur.jackson.databind.jsontype.TypeSerializer;
import com.fitbur.jackson.databind.ser.PropertyWriter;
import com.fitbur.jackson.databind.util.ClassUtil;
import com.fitbur.jackson.databind.util.NameTransformer;

/**
 * Abstract class that defines API used by {@link ObjectMapper} (and
 * other chained {@link JsonSerializer}s too) to serialize Objects of
 * arbitrary types into JSON, using provided {@link JsonGenerator}.
 * {@link com.fitbur.jackson.databind.ser.std.StdSerializer} instead
 * of this class, since it will implement many of optional
 * methods of this class.
 *

* NOTE: various serialize methods are never (to be) called * with null values -- caller must handle null values, usually * by calling {@link SerializerProvider#findNullValueSerializer} to obtain * serializer to use. * This also means that custom serializers can not be directly used to change * the output to produce when serializing null values. *

* If serializer is an aggregate one -- meaning it delegates handling of some * of its contents by using other serializer(s) -- it typically also needs * to implement {@link com.fitbur.jackson.databind.ser.ResolvableSerializer}, * which can locate secondary serializers needed. This is important to allow dynamic * overrides of serializers; separate call interface is needed to separate * resolution of secondary serializers (which may have cyclic link back * to serializer itself, directly or indirectly). *

* In addition, to support per-property annotations (to configure aspects * of serialization on per-property basis), serializers may want * to implement * {@link com.fitbur.jackson.databind.ser.ContextualSerializer}, * which allows specialization of serializers: call to * {@link com.fitbur.jackson.databind.ser.ContextualSerializer#createContextual} * is passed information on property, and can create a newly configured * serializer for handling that particular property. *

* If both * {@link com.fitbur.jackson.databind.ser.ResolvableSerializer} and * {@link com.fitbur.jackson.databind.ser.ContextualSerializer} * are implemented, resolution of serializers occurs before * contextualization. */ public abstract class JsonSerializer implements JsonFormatVisitable // since 2.1 { /* /********************************************************** /* Fluent factory methods for constructing decorated versions /********************************************************** */ /** * Method that will return serializer instance that produces * "unwrapped" serialization, if applicable for type being * serialized (which is the case for some serializers * that produce JSON Objects as output). * If no unwrapped serializer can be constructed, will simply * return serializer as-is. *

* Default implementation just returns serializer as-is, * indicating that no unwrapped variant exists * * @param unwrapper Name transformation to use to convert between names * of unwrapper properties */ public JsonSerializer unwrappingSerializer(NameTransformer unwrapper) { return this; } /** * Method that can be called to try to replace serializer this serializer * delegates calls to. If not supported (either this serializer does not * delegate anything; or it does not want any changes), should either * throw {@link UnsupportedOperationException} (if operation does not * make sense or is not allowed); or return this serializer as is. * * @since 2.1 */ public JsonSerializer replaceDelegatee(JsonSerializer delegatee) { throw new UnsupportedOperationException(); } /** * Mutant factory method that is called if contextual configuration indicates that * a specific filter (as specified by filterId) is to be used for * serialization. *

* Default implementation simply returns this; sub-classes that do support * filtering will need to create and return new instance if filter changes. * * @since 2.6 */ public JsonSerializer withFilterId(Object filterId) { return this; } /* /********************************************************** /* Serialization methods /********************************************************** */ /** * Method that can be called to ask implementation to serialize * values of type this serializer handles. * * @param value Value to serialize; can not be null. * @param gen Generator used to output resulting Json content * @param serializers Provider that can be used to get serializers for * serializing Objects value contains, if any. */ public abstract void serialize(T value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException; /** * Method that can be called to ask implementation to serialize * values of type this serializer handles, using specified type serializer * for embedding necessary type information. *

* Default implementation will throw {@link UnsupportedOperationException} * to indicate that proper type handling needs to be implemented. *

* For simple datatypes written as a single scalar value (JSON String, Number, Boolean), * implementation would look like: *

     *  // note: method to call depends on whether this type is serialized as JSON scalar, object or Array!
     *  typeSer.writeTypePrefixForScalar(value, gen);
     *  serialize(value, gen, provider);
     *  typeSer.writeTypeSuffixForScalar(value, gen);
     *
* and implementations for type serialized as JSON Arrays or Objects would differ slightly, * as START-ARRAY/END-ARRAY and * START-OBJECT/END-OBJECT pairs * need to be properly handled with respect to serializing of contents. * * @param value Value to serialize; can not be null. * @param gen Generator used to output resulting Json content * @param serializers Provider that can be used to get serializers for * serializing Objects value contains, if any. * @param typeSer Type serializer to use for including type information */ public void serializeWithType(T value, JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { Class clz = handledType(); if (clz == null) { clz = value.getClass(); } throw serializers.mappingException("Type id handling not implemented for type %s (by serializer of type %s)", clz.getName(), getClass().getName()); } /* /********************************************************** /* Other accessors /********************************************************** */ /** * Method for accessing type of Objects this serializer can handle. * Note that this information is not guaranteed to be exact -- it * may be a more generic (super-type) -- but it should not be * incorrect (return a non-related type). *

* Default implementation will return null, which essentially means * same as returning Object.class would; that is, that * nothing is known about handled type. *

*/ public Class handledType() { return null; } /** * Method called to check whether given serializable value is * considered "empty" value (for purposes of suppressing serialization * of empty values). *

* Default implementation will consider only null values to be empty. * * @since 2.0 * * @deprecated Since 2.5 Use {@link #isEmpty(SerializerProvider, Object)} instead; * will be removed from 2.8 */ @Deprecated public boolean isEmpty(T value) { return isEmpty(null, value); } /** * Method called to check whether given serializable value is * considered "empty" value (for purposes of suppressing serialization * of empty values). *

* Default implementation will consider only null values to be empty. *

* NOTE: replaces {@link #isEmpty(Object)}, deprecated in 2.5 * * @since 2.5 */ public boolean isEmpty(SerializerProvider provider, T value) { return (value == null); } /** * Method that can be called to see whether this serializer instance * will use Object Id to handle cyclic references. */ public boolean usesObjectId() { return false; } /** * Accessor for checking whether this serializer is an * "unwrapping" serializer; this is necessary to know since * it may also require caller to suppress writing of the * leading property name. */ public boolean isUnwrappingSerializer() { return false; } /** * Accessor that can be used to determine if this serializer uses * another serializer for actual serialization, by delegating * calls. If so, will return immediate delegate (which itself may * delegate to further serializers); otherwise will return null. * * @return Serializer this serializer delegates calls to, if null; * null otherwise. * * @since 2.1 */ public JsonSerializer getDelegatee() { return null; } /** * Accessor for iterating over logical properties that the type * handled by this serializer has, from serialization perspective. * Actual type of properties, if any, will be * {@link com.fitbur.jackson.databind.ser.BeanPropertyWriter}. * Of standard Jackson serializers, only {@link com.fitbur.jackson.databind.ser.BeanSerializer} * exposes properties. * * @since 2.6 */ public Iterator properties() { return ClassUtil.emptyIterator(); } /* /********************************************************** /* Default JsonFormatVisitable implementation /********************************************************** */ /** * Default implementation simply calls {@link JsonFormatVisitorWrapper#expectAnyFormat(JavaType)}. * * @since 2.1 */ @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType type) throws JsonMappingException { if (visitor != null) visitor.expectAnyFormat(type); } /* /********************************************************** /* Helper class(es) /********************************************************** */ /** * This marker class is only to be used with annotations, to * indicate that no serializer is configured. *

* Specifically, this class is to be used as the marker for * annotation {@link com.fitbur.jackson.databind.annotation.JsonSerialize}. */ public abstract static class None extends JsonSerializer { } }