Skip to content

Commit

Permalink
A further tweak to handle a corner case of FasterXML#3647
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Oct 1, 2023
1 parent 09166a0 commit b2ab29c
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ public JsonSerializer<Object> createKeySerializer(SerializerProvider ctxt,
config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
}
// null -> no TypeSerializer for key-serializer use case
ser = new JsonValueSerializer(acc, null, delegate);
ser = JsonValueSerializer.construct(config, acc, null, delegate);
} else {
ser = StdKeySerializers.getFallbackKeySerializer(config, keyType.getRawClass(),
beanDesc.getClassInfo());
Expand Down Expand Up @@ -405,7 +405,8 @@ protected final JsonSerializer<?> findSerializerByAnnotations(SerializerProvider
if (typeSerializer == null) {
typeSerializer = createTypeSerializer(prov.getConfig(), valueType);
}
return new JsonValueSerializer(valueAccessor, typeSerializer, valueSerializer);
return JsonValueSerializer.construct(prov.getConfig(), valueAccessor,
typeSerializer, valueSerializer);
}
// No well-known annotations...
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;

Expand Down Expand Up @@ -73,6 +74,14 @@ public class JsonValueSerializer
*/
protected final boolean _forceTypeInformation;

/**
* Names of properties to ignore from Value class accessed using
* accessor.
*
* @since 2.16
*/
protected final Set<String> _ignoredProperties;

/**
* If value type cannot be statically determined, mapping from
* runtime value types to serializers are cached in this object.
Expand All @@ -97,7 +106,8 @@ public class JsonValueSerializer
*/
@SuppressWarnings("unchecked")
public JsonValueSerializer(AnnotatedMember accessor,
TypeSerializer vts, JsonSerializer<?> ser)
TypeSerializer vts, JsonSerializer<?> ser,
Set<String> ignoredProperties)
{
super(accessor.getType());
_accessor = accessor;
Expand All @@ -106,15 +116,23 @@ public JsonValueSerializer(AnnotatedMember accessor,
_valueSerializer = (JsonSerializer<Object>) ser;
_property = null;
_forceTypeInformation = true; // gets reconsidered when we are contextualized
_ignoredProperties = ignoredProperties;
_dynamicSerializers = PropertySerializerMap.emptyForProperties();
}

@Deprecated // since 2.16
public JsonValueSerializer(AnnotatedMember accessor,
TypeSerializer vts, JsonSerializer<?> ser)
{
this(accessor, vts, ser, Collections.emptySet());
}

/**
* @deprecated Since 2.12
*/
@Deprecated
public JsonValueSerializer(AnnotatedMember accessor, JsonSerializer<?> ser) {
this(accessor, null, ser);
this(accessor, null, ser, Collections.emptySet());
}

// @since 2.12
Expand All @@ -129,9 +147,24 @@ public JsonValueSerializer(JsonValueSerializer src, BeanProperty property,
_valueSerializer = (JsonSerializer<Object>) ser;
_property = property;
_forceTypeInformation = forceTypeInfo;
_ignoredProperties = src._ignoredProperties;
_dynamicSerializers = PropertySerializerMap.emptyForProperties();
}

/**
* @since 2.16
*/
public static JsonValueSerializer construct(SerializationConfig config,
AnnotatedMember accessor,
TypeSerializer vts, JsonSerializer<?> ser)
{
JsonIgnoreProperties.Value ignorals = config.getAnnotationIntrospector()
.findPropertyIgnoralByName(config, accessor);
final Set<String> ignoredProperties = ignorals.findIgnoredForSerialization();
ser = _withIgnoreProperties(ser, ignoredProperties);
return new JsonValueSerializer(accessor, vts, ser, ignoredProperties);
}

@SuppressWarnings("unchecked")
private final static Class<Object> _notNullClass(Class<?> cls) {
return (cls == null) ? Object.class : (Class<Object>) cls;
Expand Down Expand Up @@ -205,6 +238,8 @@ public JsonSerializer<?> createContextual(SerializerProvider ctxt,
*/
// 05-Sep-2013, tatu: I _think_ this can be considered a primary property...
ser = ctxt.findPrimaryPropertySerializer(_valueType, property);
ser = _withIgnoreProperties(ser, _ignoredProperties);

/* 09-Dec-2010, tatu: Turns out we must add special handling for
* cases where "native" (aka "natural") type is being serialized,
* using standard serializer
Expand Down Expand Up @@ -416,12 +451,13 @@ protected JsonSerializer<Object> _findDynamicSerializer(SerializerProvider ctxt,
if (_valueType.hasGenericTypes()) {
final JavaType fullType = ctxt.constructSpecializedType(_valueType, valueClass);
serializer = ctxt.findPrimaryPropertySerializer(fullType, _property);
serializer = _withIgnoreProperties(serializer, _ignoredProperties);
PropertySerializerMap.SerializerAndMapResult result = _dynamicSerializers.addSerializer(fullType, serializer);
_dynamicSerializers = result.map;
} else {
serializer = ctxt.findPrimaryPropertySerializer(valueClass, _property);
// [databind#3647] : Support `@JsonIgnoreProperties` to work with `@JsonValue`
serializer = (JsonSerializer<Object>) _withIgnoreProperties(ctxt, serializer);
serializer = _withIgnoreProperties(serializer, _ignoredProperties);
PropertySerializerMap.SerializerAndMapResult result = _dynamicSerializers.addSerializer(valueClass, serializer);
_dynamicSerializers = result.map;
}
Expand Down Expand Up @@ -451,18 +487,17 @@ protected JsonSerializer<Object> _findDynamicSerializer(SerializerProvider ctxt,
/**
* Internal helper that configures the provided {@code ser} to ignore properties specified by {@link JsonIgnoreProperties}.
*
* @param ctxt For introspection.
* @param ser Serializer to be configured
* @return Configured serializer with specified properties ignored
* @since 2.16
*/
@SuppressWarnings("unchecked")
protected JsonSerializer<Object> _withIgnoreProperties(SerializerProvider ctxt, JsonSerializer<?> ser) {
JsonIgnoreProperties.Value ignorals = ctxt.getAnnotationIntrospector()
.findPropertyIgnoralByName(ctxt.getConfig(), _accessor);
Set<String> ignored = ignorals.findIgnoredForSerialization();
if (!ignored.isEmpty()) {
ser = ser.withIgnoredProperties(ignored);
protected static JsonSerializer<Object> _withIgnoreProperties(JsonSerializer<?> ser,
Set<String> ignoredProperties) {
if (ser != null) {
if (!ignoredProperties.isEmpty()) {
ser = ser.withIgnoredProperties(ignoredProperties);
}
}
return (JsonSerializer<Object>) ser;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// [databind#3647] : Support @JsonIgnoreProperties to work with @JsonValue
public class JsonValueIgnore3647Test extends BaseMapTest
{
static class Foo3647 {
final static class Foo3647 {
public String p1 = "hello";
public String p2 = "world";
}
Expand Down

0 comments on commit b2ab29c

Please sign in to comment.