Skip to content

Commit 2e30184

Browse files
committed
Merge branch '2.19' of github.com:FasterXML/jackson-databind into 2.19
2 parents 40130ac + 1d30be6 commit 2e30184

File tree

10 files changed

+488
-40
lines changed

10 files changed

+488
-40
lines changed

src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -554,8 +554,10 @@ protected void _addFields(Map<String, POJOPropertyBuilder> props)
554554
_anySetterField = new LinkedList<>();
555555
}
556556
_anySetterField.add(f);
557+
// 07-Feb-2025: [databind#4775]: Skip the rest of processing, but only
558+
// for "any-setter', not any-getter
559+
continue;
557560
}
558-
continue;
559561
}
560562
String implName = ai.findImplicitPropertyName(f);
561563
if (implName == null) {
@@ -1125,18 +1127,19 @@ protected void _addGetterMethod(Map<String, POJOPropertyBuilder> props,
11251127
_anyGetters = new LinkedList<>();
11261128
}
11271129
_anyGetters.add(m);
1128-
return;
1130+
// 07-Feb-2025: [databind#4775] Do not stop processing here
1131+
// (used to return)
11291132
}
11301133
// @JsonKey?
1131-
if (Boolean.TRUE.equals(ai.hasAsKey(_config, m))) {
1134+
else if (Boolean.TRUE.equals(ai.hasAsKey(_config, m))) {
11321135
if (_jsonKeyAccessors == null) {
11331136
_jsonKeyAccessors = new LinkedList<>();
11341137
}
11351138
_jsonKeyAccessors.add(m);
11361139
return;
11371140
}
11381141
// @JsonValue?
1139-
if (Boolean.TRUE.equals(ai.hasAsValue(m))) {
1142+
else if (Boolean.TRUE.equals(ai.hasAsValue(m))) {
11401143
if (_jsonValueAccessors == null) {
11411144
_jsonValueAccessors = new LinkedList<>();
11421145
}

src/main/java/com/fasterxml/jackson/databind/ser/AnyGetterWriter.java

+27-3
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,31 @@
1212
* for serializing {@link com.fasterxml.jackson.annotation.JsonAnyGetter} annotated
1313
* (Map) properties
1414
*/
15-
public class AnyGetterWriter
15+
public class AnyGetterWriter extends BeanPropertyWriter
16+
implements java.io.Serializable // since 2.19
1617
{
18+
// As of 2.19
19+
private static final long serialVersionUID = 1L;
20+
1721
protected final BeanProperty _property;
1822

1923
/**
20-
* Method (or field) that represents the "any getter"
24+
* Method (or Field) that represents the "any getter"
2125
*/
2226
protected final AnnotatedMember _accessor;
2327

2428
protected JsonSerializer<Object> _serializer;
2529

2630
protected MapSerializer _mapSerializer;
2731

32+
/**
33+
* @since 2.19
34+
*/
2835
@SuppressWarnings("unchecked")
29-
public AnyGetterWriter(BeanProperty property,
36+
public AnyGetterWriter(BeanPropertyWriter parent, BeanProperty property,
3037
AnnotatedMember accessor, JsonSerializer<?> serializer)
3138
{
39+
super(parent);
3240
_accessor = accessor;
3341
_property = property;
3442
_serializer = (JsonSerializer<Object>) serializer;
@@ -37,9 +45,20 @@ public AnyGetterWriter(BeanProperty property,
3745
}
3846
}
3947

48+
/**
49+
* @deprecated Since 2.19, use one that takes {@link BeanPropertyWriter} instead.
50+
*/
51+
@Deprecated
52+
public AnyGetterWriter(BeanProperty property,
53+
AnnotatedMember accessor, JsonSerializer<?> serializer)
54+
{
55+
this(null, property, accessor, serializer);
56+
}
57+
4058
/**
4159
* @since 2.8.3
4260
*/
61+
@Override
4362
public void fixAccess(SerializationConfig config) {
4463
_accessor.fixAccess(
4564
config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
@@ -65,6 +84,11 @@ public void getAndSerialize(Object bean, JsonGenerator gen, SerializerProvider p
6584
_serializer.serialize(value, gen, provider);
6685
}
6786

87+
@Override
88+
public void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception {
89+
getAndSerialize(bean, gen, prov);
90+
}
91+
6892
/**
6993
* @since 2.3
7094
*/

src/main/java/com/fasterxml/jackson/databind/ser/BeanSerializer.java

-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@ protected BeanSerializerBase asArraySerializer()
147147
* - have per-property filters
148148
*/
149149
if ((_objectIdWriter == null)
150-
&& (_anyGetterWriter == null)
151150
&& (_propertyFilterId == null)
152151
) {
153152
return new BeanAsArraySerializer(this);

src/main/java/com/fasterxml/jackson/databind/ser/BeanSerializerFactory.java

+28-6
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,7 @@
2626
import com.fasterxml.jackson.databind.ser.std.StdDelegatingSerializer;
2727
import com.fasterxml.jackson.databind.ser.std.ToEmptyObjectSerializer;
2828
import com.fasterxml.jackson.databind.type.ReferenceType;
29-
import com.fasterxml.jackson.databind.util.BeanUtil;
30-
import com.fasterxml.jackson.databind.util.ClassUtil;
31-
import com.fasterxml.jackson.databind.util.Converter;
32-
import com.fasterxml.jackson.databind.util.IgnorePropertiesUtil;
33-
import com.fasterxml.jackson.databind.util.NativeImageUtil;
29+
import com.fasterxml.jackson.databind.util.*;
3430

3531
/**
3632
* Factory class that can provide serializers for any regular Java beans
@@ -464,7 +460,33 @@ protected JsonSerializer<Object> constructBeanOrAddOnSerializer(SerializerProvid
464460
PropertyName name = PropertyName.construct(anyGetter.getName());
465461
BeanProperty.Std anyProp = new BeanProperty.Std(name, valueType, null,
466462
anyGetter, PropertyMetadata.STD_OPTIONAL);
467-
builder.setAnyGetter(new AnyGetterWriter(anyProp, anyGetter, anySer));
463+
464+
// Check if there is an accessor exposed for the anyGetter
465+
BeanPropertyWriter anyGetterProp = null;
466+
int anyGetterIndex = -1;
467+
for (int i = 0; i < props.size(); i++) {
468+
BeanPropertyWriter prop = props.get(i);
469+
// Either any-getter as field...
470+
if (Objects.equals(prop.getName(), anyGetter.getName())
471+
// or as method
472+
|| Objects.equals(prop.getMember().getMember(), anyGetter.getMember()))
473+
{
474+
anyGetterProp = prop;
475+
anyGetterIndex = i;
476+
break;
477+
}
478+
}
479+
if (anyGetterIndex != -1) {
480+
// There is prop is already in place, just need to replace it
481+
AnyGetterWriter anyGetterWriter = new AnyGetterWriter(anyGetterProp, anyProp, anyGetter, anySer);
482+
props.set(anyGetterIndex, anyGetterWriter);
483+
} else {
484+
// Otherwise just add it at the end, but won't be sorted...
485+
// This is case where JsonAnyGetter is private/protected,
486+
BeanPropertyDefinition anyGetterPropDef = SimpleBeanPropertyDefinition.construct(config, anyGetter, name);
487+
BeanPropertyWriter anyPropWriter = _constructWriter(prov, anyGetterPropDef, new PropertyBuilder(config, beanDesc), staticTyping, anyGetter);
488+
props.add(new AnyGetterWriter(anyPropWriter, anyProp, anyGetter, anySer));
489+
}
468490
}
469491
// Next: need to gather view information, if any:
470492
processViews(config, builder);

src/main/java/com/fasterxml/jackson/databind/ser/impl/BeanAsArraySerializer.java

-4
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,6 @@ protected final void serializeAsArray(Object bean, JsonGenerator gen, Serializer
214214
prop.serializeAsElement(bean, gen, provider);
215215
}
216216
}
217-
// NOTE: any getters cannot be supported either
218-
//if (_anyGetterWriter != null) {
219-
// _anyGetterWriter.getAndSerialize(bean, gen, provider);
220-
//}
221217
} catch (Exception e) {
222218
wrapAndThrow(provider, e, bean, props[i].getName());
223219
} catch (StackOverflowError e) {

src/main/java/com/fasterxml/jackson/databind/ser/impl/SimpleBeanPropertyFilter.java

+2
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ public void serializeAsField(Object pojo, JsonGenerator jgen,
218218
writer.serializeAsField(pojo, jgen, provider);
219219
} else if (!jgen.canOmitFields()) { // since 2.3
220220
writer.serializeAsOmittedField(pojo, jgen, provider);
221+
} else if (writer instanceof AnyGetterWriter) {
222+
((AnyGetterWriter) writer).getAndFilter(pojo, jgen, provider, this);
221223
}
222224
}
223225

src/main/java/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java

+5-20
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,6 @@ public abstract class BeanSerializerBase
6565
*/
6666
final protected BeanPropertyWriter[] _filteredProps;
6767

68-
/**
69-
* Handler for {@link com.fasterxml.jackson.annotation.JsonAnyGetter}
70-
* annotated properties
71-
*/
72-
final protected AnyGetterWriter _anyGetterWriter;
73-
7468
/**
7569
* Id of the bean property filter to use, if any; null if none.
7670
*/
@@ -118,13 +112,11 @@ protected BeanSerializerBase(JavaType type, BeanSerializerBuilder builder,
118112
// 20-Sep-2019, tatu: Actually not just that but also "dummy" serializer for
119113
// case of no bean properties, too
120114
_typeId = null;
121-
_anyGetterWriter = null;
122115
_propertyFilterId = null;
123116
_objectIdWriter = null;
124117
_serializationShape = null;
125118
} else {
126119
_typeId = builder.getTypeId();
127-
_anyGetterWriter = builder.getAnyGetter();
128120
_propertyFilterId = builder.getFilterId();
129121
_objectIdWriter = builder.getObjectIdWriter();
130122
final JsonFormat.Value format = builder.getBeanDescription().findExpectedFormat();
@@ -141,7 +133,6 @@ protected BeanSerializerBase(BeanSerializerBase src,
141133
_filteredProps = filteredProperties;
142134

143135
_typeId = src._typeId;
144-
_anyGetterWriter = src._anyGetterWriter;
145136
_objectIdWriter = src._objectIdWriter;
146137
_propertyFilterId = src._propertyFilterId;
147138
_serializationShape = src._serializationShape;
@@ -165,7 +156,6 @@ protected BeanSerializerBase(BeanSerializerBase src,
165156
_filteredProps = src._filteredProps;
166157

167158
_typeId = src._typeId;
168-
_anyGetterWriter = src._anyGetterWriter;
169159
_objectIdWriter = objectIdWriter;
170160
_propertyFilterId = filterId;
171161
_serializationShape = src._serializationShape;
@@ -209,7 +199,6 @@ protected BeanSerializerBase(BeanSerializerBase src, Set<String> toIgnore, Set<S
209199
_filteredProps = (fpropsOut == null) ? null : fpropsOut.toArray(new BeanPropertyWriter[fpropsOut.size()]);
210200

211201
_typeId = src._typeId;
212-
_anyGetterWriter = src._anyGetterWriter;
213202
_objectIdWriter = src._objectIdWriter;
214203
_propertyFilterId = src._propertyFilterId;
215204
_serializationShape = src._serializationShape;
@@ -401,9 +390,11 @@ public void resolve(SerializerProvider provider)
401390
}
402391

403392
// also, any-getter may need to be resolved
404-
if (_anyGetterWriter != null) {
405-
// 23-Feb-2015, tatu: Misleading, as this actually triggers call to contextualization...
406-
_anyGetterWriter.resolve(provider);
393+
for (int i = 0; i < _props.length; i++) {
394+
BeanPropertyWriter prop = _props[i];
395+
if (prop instanceof AnyGetterWriter) {
396+
((AnyGetterWriter) prop).resolve(provider);
397+
}
407398
}
408399
}
409400

@@ -769,9 +760,6 @@ protected void serializeFields(Object bean, JsonGenerator gen, SerializerProvide
769760
prop.serializeAsField(bean, gen, provider);
770761
}
771762
}
772-
if (_anyGetterWriter != null) {
773-
_anyGetterWriter.getAndSerialize(bean, gen, provider);
774-
}
775763
} catch (Exception e) {
776764
String name = (i == props.length) ? "[anySetter]" : props[i].getName();
777765
wrapAndThrow(provider, e, bean, name);
@@ -820,9 +808,6 @@ protected void serializeFieldsFiltered(Object bean, JsonGenerator gen,
820808
filter.serializeAsField(bean, gen, provider, prop);
821809
}
822810
}
823-
if (_anyGetterWriter != null) {
824-
_anyGetterWriter.getAndFilter(bean, gen, provider, filter);
825-
}
826811
} catch (Exception e) {
827812
String name = (i == props.length) ? "[anySetter]" : props[i].getName();
828813
wrapAndThrow(provider, e, bean, name);

0 commit comments

Comments
 (0)