package com.fasterxml.jackson.datatype.eclipsecollections.ser.map;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.type.WritableTypeId;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.ContainerSerializer;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.impl.PropertySerializerMap;
import com.fasterxml.jackson.databind.type.TypeFactory;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.collections.api.map.MapIterable;
public final class RefRefMapSerializer extends ContainerSerializer<MapIterable<?, ?>> implements ContextualSerializer {
private final JavaType _type;
private final BeanProperty _property;
private final JsonSerializer<Object> _keySerializer;
private final TypeSerializer _valueTypeSerializer;
private final JsonSerializer<Object> _valueSerializer;
protected final Set<String> _ignoredEntries;
protected PropertySerializerMap _dynamicValueSerializers;
public RefRefMapSerializer(
JavaType type,
JsonSerializer<Object> keySerializer, TypeSerializer vts, JsonSerializer<Object> valueSerializer,
Set<String> ignoredEntries
) {
super(type.getRawClass(), false);
_type = type;
_property = null;
_keySerializer = keySerializer;
_valueTypeSerializer = vts;
_valueSerializer = valueSerializer;
_ignoredEntries = ignoredEntries;
_dynamicValueSerializers = PropertySerializerMap.emptyForProperties();
}
@SuppressWarnings("unchecked")
protected RefRefMapSerializer(
RefRefMapSerializer src, BeanProperty property,
JsonSerializer<?> keySerializer, TypeSerializer vts, JsonSerializer<?> valueSerializer,
Set<String> ignoredEntries
) {
super(src);
_type = src._type;
_property = property;
_keySerializer = (JsonSerializer<Object>) keySerializer;
_valueTypeSerializer = vts;
_valueSerializer = (JsonSerializer<Object>) valueSerializer;
_dynamicValueSerializers = src._dynamicValueSerializers;
_ignoredEntries = ignoredEntries;
}
protected RefRefMapSerializer withResolved(
BeanProperty property,
JsonSerializer<?> keySer, TypeSerializer vts, JsonSerializer<?> valueSer,
Set<String> ignored
) {
return new RefRefMapSerializer(this, property, keySer, vts, valueSer,
ignored);
}
@Override
protected ContainerSerializer<?> _withValueTypeSerializer(TypeSerializer typeSer) {
return new RefRefMapSerializer(this, _property, _keySerializer,
typeSer, _valueSerializer, _ignoredEntries);
}
@Override
public JsonSerializer<?> createContextual(
SerializerProvider provider,
BeanProperty property
) throws JsonMappingException {
JsonSerializer<?> valueSer = _valueSerializer;
if (valueSer == null) {
JavaType valueType = getContentType();
if (valueType.isFinal()) {
valueSer = provider.findValueSerializer(valueType, property);
}
} else if (valueSer instanceof ContextualSerializer) {
valueSer = ((ContextualSerializer) valueSer).createContextual(provider, property);
}
final AnnotationIntrospector intr = provider.getAnnotationIntrospector();
final AnnotatedMember propertyAcc = (property == null) ? null : property.getMember();
JsonSerializer<?> keySer = null;
if (propertyAcc != null && intr != null) {
Object serDef = intr.findKeySerializer(propertyAcc);
if (serDef != null) {
keySer = provider.serializerInstance(propertyAcc, serDef);
}
serDef = intr.findContentSerializer(propertyAcc);
if (serDef != null) {
valueSer = provider.serializerInstance(propertyAcc, serDef);
}
}
if (valueSer == null) {
valueSer = _valueSerializer;
}
valueSer = findContextualConvertingSerializer(provider, property, valueSer);
if (valueSer == null) {
JavaType valueType = getContentType();
if (valueType.useStaticType()) {
valueSer = provider.findValueSerializer(valueType, property);
}
} else {
valueSer = provider.handleSecondaryContextualization(valueSer, property);
}
if (keySer == null) {
keySer = _keySerializer;
}
if (keySer == null) {
keySer = provider.findKeySerializer(getKeyType(), property);
} else {
keySer = provider.handleSecondaryContextualization(keySer, property);
}
TypeSerializer typeSer = _valueTypeSerializer;
if (typeSer != null) {
typeSer = typeSer.forProperty(property);
}
Set<String> ignored = _ignoredEntries;
if (intr != null && propertyAcc != null) {
JsonIgnoreProperties.Value ignorals = intr.findPropertyIgnorals(propertyAcc);
if (ignorals != null) {
Set<String> newIgnored = ignorals.findIgnoredForSerialization();
if ((newIgnored != null) && !newIgnored.isEmpty()) {
ignored = (ignored == null) ? new HashSet<>() : new HashSet<>(ignored);
ignored.addAll(newIgnored);
}
}
}
return withResolved(property, keySer, typeSer, valueSer,
ignored);
}
@Override
public JsonSerializer<?> getContentSerializer() {
return _valueSerializer;
}
protected JavaType getKeyType() {
JavaType[] typeParameters = _type.findTypeParameters(MapIterable.class);
return typeParameters.length > 0 ? typeParameters[0] : TypeFactory.unknownType();
}
@Override
public JavaType getContentType() {
JavaType[] typeParameters = _type.findTypeParameters(MapIterable.class);
return typeParameters.length > 1 ? typeParameters[1] : TypeFactory.unknownType();
}
@Override
public boolean hasSingleElement(MapIterable<?, ?> map) {
return map.size() == 1;
}
@Override
public boolean isEmpty(SerializerProvider prov, MapIterable<?, ?> value) {
return value.isEmpty();
}
@Override
public void serialize(MapIterable<?, ?> value, JsonGenerator gen, SerializerProvider provider)
throws IOException {
gen.writeStartObject(value);
if (!value.isEmpty()) {
serializeFields(value, gen, provider);
}
gen.writeEndObject();
}
@Override
public void serializeWithType(
MapIterable<?, ?> value, JsonGenerator gen,
SerializerProvider provider, TypeSerializer typeSer
) throws IOException {
gen.setCurrentValue(value);
WritableTypeId typeIdDef = typeSer.writeTypePrefix(gen,
typeSer.typeId(value, JsonToken.START_OBJECT));
if (!value.isEmpty()) {
serializeFields(value, gen, provider);
}
typeSer.writeTypeSuffix(gen, typeIdDef);
}
private final void serializeFields(MapIterable<?, ?> mmap, JsonGenerator gen, SerializerProvider provider)
throws IOException {
Set<String> ignored = _ignoredEntries;
PropertySerializerMap serializers = _dynamicValueSerializers;
mmap.forEachKeyValue((key, v) -> {
try {
if ((ignored != null) && ignored.contains(key)) {
return;
}
if (key == null) {
provider.findNullKeySerializer(getKeyType(), _property)
.serialize(null, gen, provider);
} else {
_keySerializer.serialize(key, gen, provider);
}
if (v == null) {
provider.defaultSerializeNull(gen);
return;
}
JsonSerializer<Object> valueSer = _valueSerializer;
if (valueSer == null) {
Class<?> cc = v.getClass();
valueSer = serializers.serializerFor(cc);
if (valueSer == null) {
valueSer = _findAndAddDynamic(serializers, cc, provider);
}
}
if (_valueTypeSerializer == null) {
valueSer.serialize(v, gen, provider);
} else {
valueSer.serializeWithType(v, gen, provider, _valueTypeSerializer);
}
} catch (IOException e) {
PrimitiveMapSerializer.rethrowUnchecked(e);
}
});
}
protected final JsonSerializer<Object> _findAndAddDynamic(
PropertySerializerMap map,
Class<?> type, SerializerProvider provider
) throws JsonMappingException {
PropertySerializerMap.SerializerAndMapResult result =
map.findAndAddSecondarySerializer(type, provider, _property);
if (map != result.map) {
_dynamicValueSerializers = result.map;
}
return result.serializer;
}
}