Skip to content
18 changes: 18 additions & 0 deletions src/main/java/tools/jackson/databind/SerializationFeature.java
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,24 @@ public enum SerializationFeature implements ConfigFeature
*/
FAIL_ON_ORDER_MAP_BY_INCOMPARABLE_KEY(false),

/**
* Feature that determines whether {@code JsonInclude#content()} is also
* applied to values inside {@link java.util.Collection} properties.
* <p>
* By default, {@code content()} inclusion rules are only applied to
* {@code Map} values and reference types, and are ignored for
* {@code Collection} element values.
* <p>
* When this feature is enabled, {@code JsonInclude#content()} rules
* are evaluated for {@code Collection} elements during serialization.
* <p>
* This feature is <b>disabled by default</b> for backwards
* compatibility.
*
* @since 3.1
*/
APPLY_JSON_INCLUDE_FOR_COLLECTIONS(false),

/*
/**********************************************************************
/* Other
Expand Down
101 changes: 90 additions & 11 deletions src/main/java/tools/jackson/databind/ser/jdk/CollectionSerializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,21 @@ public CollectionSerializer(JavaType elemType, boolean staticTyping, TypeSeriali
_maybeEnumSet = elemType.isEnumType() || elemType.isJavaLangObject();
}

@Deprecated // since 3.1.0
protected CollectionSerializer(CollectionSerializer src,
TypeSerializer vts, ValueSerializer<?> valueSerializer,
Boolean unwrapSingle, BeanProperty property) {
super(src, vts, valueSerializer, unwrapSingle, property);
this(src, vts, valueSerializer, unwrapSingle, property, null, false);
}

/**
* @since 3.1.0
*/
protected CollectionSerializer(CollectionSerializer src,
TypeSerializer vts, ValueSerializer<?> valueSerializer,
Boolean unwrapSingle, BeanProperty property,
Object suppressableValue, boolean suppressNulls) {
super(src, vts, valueSerializer, unwrapSingle, property, suppressableValue, suppressNulls);
_maybeEnumSet = src._maybeEnumSet;
}

Expand All @@ -63,7 +74,15 @@ protected StdContainerSerializer<?> _withValueTypeSerializer(TypeSerializer vts)
protected CollectionSerializer withResolved(BeanProperty property,
TypeSerializer vts, ValueSerializer<?> elementSerializer,
Boolean unwrapSingle) {
return new CollectionSerializer(this, vts, elementSerializer, unwrapSingle, property);
return withResolved(property, vts, elementSerializer, unwrapSingle, null, false);
}

// @since 3.1.0
@Override
protected CollectionSerializer withResolved(BeanProperty property,
TypeSerializer vts, ValueSerializer<?> elementSerializer,
Boolean unwrapSingle, Object suppressableValue, boolean suppressNulls) {
return new CollectionSerializer(this, vts, elementSerializer, unwrapSingle, property, suppressableValue, suppressNulls);
}

/*
Expand Down Expand Up @@ -97,21 +116,49 @@ public final void serialize(Collection<?> value, JsonGenerator g, SerializationC
if (((_unwrapSingle == null) &&
provider.isEnabled(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED))
|| (_unwrapSingle == Boolean.TRUE)) {
serializeContents(value, g, provider);
if (provider.isEnabled(SerializationFeature.APPLY_JSON_INCLUDE_FOR_COLLECTIONS)
&& ((_suppressableValue != null) || _suppressNulls)
) {
serializeFilteredContents(value, g, provider);
} else {
serializeContents(value, g, provider);
}
return;
}
}
g.writeStartArray(value, len);
serializeContents(value, g, provider);
if (provider.isEnabled(SerializationFeature.APPLY_JSON_INCLUDE_FOR_COLLECTIONS)
&& ((_suppressableValue != null) || _suppressNulls)
) {
serializeFilteredContents(value, g, provider);
} else {
serializeContents(value, g, provider);
}
g.writeEndArray();
}

@Override
public void serializeContents(Collection<?> value, JsonGenerator g, SerializationContext ctxt)
throws JacksonException
{
serializeContentsImpl(value, g, ctxt,
false);
}

@Override
protected void serializeFilteredContents(Collection<?> value, JsonGenerator g, SerializationContext ctxt) throws JacksonException
{
serializeContentsImpl(value, g, ctxt,
ctxt.isEnabled(SerializationFeature.APPLY_JSON_INCLUDE_FOR_COLLECTIONS));
}

private void serializeContentsImpl(Collection<?> value, JsonGenerator g, SerializationContext ctxt, boolean filtered) throws JacksonException
{
if (_elementSerializer != null) {
serializeContentsUsing(value, g, ctxt, _elementSerializer);
if (filtered) {
serializeFilteredContentsUsing(value, g, ctxt, _elementSerializer);
} else {
serializeContentsUsing(value, g, ctxt, _elementSerializer);
}
return;
}
Iterator<?> it = value.iterator();
Expand All @@ -128,6 +175,10 @@ public void serializeContents(Collection<?> value, JsonGenerator g, Serializatio
do {
Object elem = it.next();
if (elem == null) {
if (filtered && _suppressNulls) {
++i;
continue;
}
ctxt.defaultSerializeNullValue(g);
} else {
Class<?> cc = elem.getClass();
Expand All @@ -140,6 +191,11 @@ public void serializeContents(Collection<?> value, JsonGenerator g, Serializatio
}
serializers = _dynamicValueSerializers;
}
// Check if this element should be suppressed (only in filtered mode)
if (filtered && !_shouldSerializeElement(elem, serializer, ctxt)) {
++i;
continue;
}
if (typeSer == null) {
serializer.serialize(elem, g, ctxt);
} else {
Expand All @@ -153,9 +209,23 @@ public void serializeContents(Collection<?> value, JsonGenerator g, Serializatio
}
}

public void serializeContentsUsing(Collection<?> value, JsonGenerator g, SerializationContext provider,
public void serializeContentsUsing(Collection<?> value, JsonGenerator g, SerializationContext ctxt,
ValueSerializer<Object> ser)
throws JacksonException
{
serializeContentsUsingImpl(value, g, ctxt, ser,
false);
}

private void serializeFilteredContentsUsing(Collection<?> value, JsonGenerator g, SerializationContext ctxt,
ValueSerializer<Object> ser) throws JacksonException
{
serializeContentsUsingImpl(value, g, ctxt, ser,
ctxt.isEnabled(SerializationFeature.APPLY_JSON_INCLUDE_FOR_COLLECTIONS));
}

private void serializeContentsUsingImpl(Collection<?> value, JsonGenerator g, SerializationContext ctxt,
ValueSerializer<Object> ser, boolean filtered) throws JacksonException
{
Iterator<?> it = value.iterator();
if (it.hasNext()) {
Expand All @@ -167,17 +237,26 @@ public void serializeContentsUsing(Collection<?> value, JsonGenerator g, Seriali
Object elem = it.next();
try {
if (elem == null) {
provider.defaultSerializeNullValue(g);
if (filtered && _suppressNulls) {
++i;
continue;
}
ctxt.defaultSerializeNullValue(g);
} else {
// Check if this element should be suppressed (only in filtered mode)
if (filtered && !_shouldSerializeElement(elem, ser, ctxt)) {
++i;
continue;
}
if (typeSer == null) {
ser.serialize(elem, g, provider);
ser.serialize(elem, g, ctxt);
} else {
ser.serializeWithType(elem, g, provider, typeSer);
ser.serializeWithType(elem, g, ctxt, typeSer);
}
}
++i;
} catch (Exception e) {
wrapAndThrow(provider, e, value, i);
wrapAndThrow(ctxt, e, value, i);
}
} while (it.hasNext());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,21 @@ public EnumSetSerializer(JavaType elemType) {
super(EnumSet.class, elemType, true, null, null);
}

@Deprecated // since 3.1.0
public EnumSetSerializer(EnumSetSerializer src,
TypeSerializer vts, ValueSerializer<?> valueSerializer,
Boolean unwrapSingle, BeanProperty property) {
super(src, vts, valueSerializer, unwrapSingle, property);
this(src, vts, valueSerializer, unwrapSingle, property, null, false);
}

/**
* @since 3.1.0
*/
public EnumSetSerializer(EnumSetSerializer src,
TypeSerializer vts, ValueSerializer<?> valueSerializer,
Boolean unwrapSingle, BeanProperty property,
Object suppressableValue, boolean suppressNulls) {
super(src, vts, valueSerializer, unwrapSingle, property, suppressableValue, suppressNulls);
}

@Override
Expand All @@ -30,7 +41,14 @@ protected EnumSetSerializer _withValueTypeSerializer(TypeSerializer vts) {
protected EnumSetSerializer withResolved(BeanProperty property,
TypeSerializer vts, ValueSerializer<?> elementSerializer,
Boolean unwrapSingle) {
return new EnumSetSerializer(this, vts, elementSerializer, unwrapSingle, property);
return new EnumSetSerializer(this, vts, elementSerializer, unwrapSingle, property, null, false);
}

@Override
public EnumSetSerializer withResolved(BeanProperty property,
TypeSerializer vts, ValueSerializer<?> elementSerializer,
Boolean unwrapSingle, Object suppressableValue, boolean suppressNulls) {
return new EnumSetSerializer(this, vts, elementSerializer, unwrapSingle, property, suppressableValue, suppressNulls);
}

@Override
Expand Down Expand Up @@ -80,4 +98,5 @@ public void serializeContents(EnumSet<? extends Enum<?>> value, JsonGenerator ge
enumSer.serialize(en, gen, ctxt);
}
}

}
Loading
Loading