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

com.fasterxml.jackson.databind.ser.std.EnumSerializer Maven / Gradle / Ivy

There is a newer version: 2.17.0
Show newest version
package com.fasterxml.jackson.databind.ser.std;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.*;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonFormat.Shape;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.io.SerializedString;


import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonStringFormatVisitor;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.util.EnumValues;

/**
 * Standard serializer used for {@link java.lang.Enum} types.
 *

* Based on {@link StdScalarSerializer} since the JSON value is * scalar (String). * * @author tatu */ @JacksonStdImpl public class EnumSerializer extends StdScalarSerializer> implements ContextualSerializer { /** * This map contains pre-resolved values (since there are ways * to customize actual String constants to use) to use as * serializations. */ protected final EnumValues _values; /** * Flag that is set if we statically know serialization choice * between index and textual format (null if it needs to be dynamically * checked). * * @since 2.1 */ protected final Boolean _serializeAsIndex; /* /********************************************************** /* Construction, initialization /********************************************************** */ /** * @deprecated Since 2.1 */ @Deprecated public EnumSerializer(EnumValues v) { this(v, null); } public EnumSerializer(EnumValues v, Boolean serializeAsIndex) { super(Enum.class, false); _values = v; _serializeAsIndex = serializeAsIndex; } /** * Factory method used by {@link com.fasterxml.jackson.databind.ser.BasicSerializerFactory} * for constructing serializer instance of Enum types. * * @since 2.1 */ public static EnumSerializer construct(Class> enumClass, SerializationConfig config, BeanDescription beanDesc, JsonFormat.Value format) { // [JACKSON-212]: If toString() is to be used instead, leave EnumValues null AnnotationIntrospector intr = config.getAnnotationIntrospector(); EnumValues v = config.isEnabled(SerializationFeature.WRITE_ENUMS_USING_TO_STRING) ? EnumValues.constructFromToString(enumClass, intr) : EnumValues.constructFromName(enumClass, intr); Boolean serializeAsIndex = _isShapeWrittenUsingIndex(enumClass, format, true); return new EnumSerializer(v, serializeAsIndex); } /** * @deprecated Since 2.1 use the variant that takes in format argument. */ @Deprecated public static EnumSerializer construct(Class> enumClass, SerializationConfig config, BeanDescription beanDesc) { return construct(enumClass, config, beanDesc, beanDesc.findExpectedFormat(null)); } /** * To support some level of per-property configuration, we will need * to make things contextual. We are limited to "textual vs index" * choice here, however. */ public JsonSerializer createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { if (property != null) { JsonFormat.Value format = prov.getAnnotationIntrospector().findFormat((Annotated) property.getMember()); if (format != null) { Boolean serializeAsIndex = _isShapeWrittenUsingIndex(property.getType().getRawClass(), format, false); if (serializeAsIndex != _serializeAsIndex) { return new EnumSerializer(_values, serializeAsIndex); } } } return this; } /* /********************************************************** /* Extended API for Jackson databind core /********************************************************** */ public EnumValues getEnumValues() { return _values; } /* /********************************************************** /* Actual serialization /********************************************************** */ @Override public final void serialize(Enum en, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { // [JACKSON-684]: serialize as index? if (_serializeAsIndex(provider)) { jgen.writeNumber(en.ordinal()); return; } jgen.writeString(_values.serializedValueFor(en)); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { // [JACKSON-684]: serialize as index? if (_serializeAsIndex(provider)) { return createSchemaNode("integer", true); } ObjectNode objectNode = createSchemaNode("string", true); if (typeHint != null) { JavaType type = provider.constructType(typeHint); if (type.isEnumType()) { ArrayNode enumNode = objectNode.putArray("enum"); for (SerializedString value : _values.values()) { enumNode.add(value.getValue()); } } } return objectNode; } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) { // [JACKSON-684]: serialize as index? if (visitor.getProvider().isEnabled(SerializationFeature.WRITE_ENUMS_USING_INDEX)) { visitor.expectIntegerFormat(typeHint); } else { JsonStringFormatVisitor stringVisitor = visitor.expectStringFormat(typeHint); if (typeHint != null && visitor != null) { if (typeHint.isEnumType()) { // important: ensure that order is retained Set enums = new LinkedHashSet(); for (SerializedString value : _values.values()) { enums.add(value.getValue()); } stringVisitor.enumTypes(enums); } } } } /* /********************************************************** /* Helper methods /********************************************************** */ protected final boolean _serializeAsIndex(SerializerProvider provider) { if (_serializeAsIndex != null) { return _serializeAsIndex.booleanValue(); } return provider.isEnabled(SerializationFeature.WRITE_ENUMS_USING_INDEX); } /** * Helper method called to check whether */ protected static Boolean _isShapeWrittenUsingIndex(Class enumClass, JsonFormat.Value format, boolean fromClass) { JsonFormat.Shape shape = (format == null) ? null : format.getShape(); if (shape == null) { return null; } if (shape == Shape.ANY || shape == Shape.SCALAR) { // i.e. "default", check dynamically return null; } if (shape == Shape.STRING) { return Boolean.FALSE; } if (shape.isNumeric()) { return Boolean.TRUE; } throw new IllegalArgumentException("Unsupported serialization shape ("+shape+") for Enum "+enumClass.getName() +", not supported as " + (fromClass? "class" : "property") +" annotation"); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy