Skip to content

Commit 2b1a8fd

Browse files
authored
More follow-up work wrt #4907 (#5173)
1 parent 649744e commit 2b1a8fd

13 files changed

+110
-106
lines changed

src/main/java/tools/jackson/databind/BeanDescription.java

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.fasterxml.jackson.annotation.JsonFormat;
77
import com.fasterxml.jackson.annotation.JsonInclude;
88

9+
import tools.jackson.databind.cfg.MapperConfig;
910
import tools.jackson.databind.introspect.*;
1011
import tools.jackson.databind.util.Annotations;
1112

@@ -34,8 +35,8 @@ protected BeanDescription(JavaType type) {
3435
_type = type;
3536
}
3637

37-
public BeanDescription.Supplier supplier() {
38-
return new EagerSupplier(this);
38+
public BeanDescription.Supplier supplier(MapperConfig<?> config) {
39+
return new EagerSupplier(config, this);
3940
}
4041

4142
/*
@@ -226,12 +227,6 @@ public AnnotatedMember findJsonKeyAccessor() {
226227
*/
227228
public abstract JsonInclude.Value findPropertyInclusion(JsonInclude.Value defValue);
228229

229-
/**
230-
* Method for checking what is the expected format for POJO, as
231-
* defined by possible annotations and possible per-type config overrides.
232-
*/
233-
public abstract JsonFormat.Value findExpectedFormat(Class<?> baseType);
234-
235230
/*
236231
/**********************************************************************
237232
/* Basic API, other
@@ -280,21 +275,23 @@ public interface Supplier extends java.util.function.Supplier<BeanDescription>
280275
JavaType getType();
281276

282277
boolean isRecordType();
278+
279+
JsonFormat.Value findExpectedFormat(Class<?> baseType);
283280
}
284281

285-
/**
286-
* Partial implementation for lazily-constructed suppliers for {@link BeanDescription} instances.
287-
*/
288-
public static abstract class LazySupplier implements Supplier
282+
protected static abstract class SupplierBase implements Supplier
289283
{
284+
protected final MapperConfig<?> _config;
290285
protected final JavaType _type;
291286

292-
protected transient AnnotatedClass _classDesc;
287+
/**
288+
* Format definitions lazily introspected from class annotations
289+
*/
290+
protected transient JsonFormat.Value _classFormat;
293291

294-
protected transient BeanDescription _beanDesc;
295-
296-
protected LazySupplier(JavaType type) {
297-
_type = type;
292+
protected SupplierBase(MapperConfig<?> config, JavaType type) {
293+
_config = config;
294+
_type = type;
298295
}
299296

300297
// // Simple accessors:
@@ -308,6 +305,41 @@ protected LazySupplier(JavaType type) {
308305
@Override
309306
public boolean isRecordType() { return _type.isRecordType(); }
310307

308+
// // // Introspection
309+
310+
@Override
311+
public JsonFormat.Value findExpectedFormat(Class<?> baseType)
312+
{
313+
JsonFormat.Value v0 = _classFormat;
314+
if (v0 == null) { // copied from above
315+
v0 = _config.getAnnotationIntrospector().findFormat(_config,
316+
getClassInfo());
317+
if (v0 == null) {
318+
v0 = JsonFormat.Value.empty();
319+
}
320+
_classFormat = v0;
321+
}
322+
JsonFormat.Value v1 = _config.getDefaultPropertyFormat(baseType);
323+
if (v1 == null) {
324+
return v0;
325+
}
326+
return JsonFormat.Value.merge(v0, v1);
327+
}
328+
}
329+
330+
/**
331+
* Partial implementation for lazily-constructed suppliers for {@link BeanDescription} instances.
332+
*/
333+
public static abstract class LazySupplier extends SupplierBase
334+
{
335+
protected transient AnnotatedClass _classDesc;
336+
337+
protected transient BeanDescription _beanDesc;
338+
339+
protected LazySupplier(MapperConfig<?> config, JavaType type) {
340+
super(config, type);
341+
}
342+
311343
// // Entity accessors:
312344

313345
@Override
@@ -334,6 +366,8 @@ public BeanDescription get() {
334366
return _beanDesc;
335367
}
336368

369+
// // // Internal factory methods
370+
337371
protected abstract AnnotatedClass _introspect(JavaType forType);
338372

339373
protected abstract BeanDescription _construct(JavaType forType, AnnotatedClass ac);
@@ -343,23 +377,15 @@ public BeanDescription get() {
343377
* Simple {@link Supplier} implementation that just returns pre-constructed
344378
* {@link BeanDescription} instance.
345379
*/
346-
public static class EagerSupplier implements Supplier
380+
public static class EagerSupplier extends SupplierBase
347381
{
348382
protected final BeanDescription _beanDesc;
349383

350-
public EagerSupplier(BeanDescription beanDesc) {
351-
_beanDesc = Objects.requireNonNull(beanDesc);
384+
public EagerSupplier(MapperConfig<?> config, BeanDescription beanDesc) {
385+
super(config, beanDesc.getType());
386+
_beanDesc = beanDesc;
352387
}
353388

354-
@Override
355-
public Class<?> getBeanClass() { return _beanDesc.getBeanClass(); }
356-
357-
@Override
358-
public boolean isRecordType() { return getType().isRecordType(); }
359-
360-
@Override
361-
public JavaType getType() { return _beanDesc.getType(); }
362-
363389
@Override
364390
public BeanDescription get() { return _beanDesc; }
365391

src/main/java/tools/jackson/databind/DatabindContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ public abstract BeanDescription introspectBeanDescription(JavaType type,
319319
AnnotatedClass classDef);
320320

321321
public BeanDescription.Supplier lazyIntrospectBeanDescription(JavaType type) {
322-
return new BeanDescription.LazySupplier(type) {
322+
return new BeanDescription.LazySupplier(getConfig(), type) {
323323
@Override
324324
protected BeanDescription _construct(JavaType forType, AnnotatedClass ac) {
325325
// System.out.println("lazyIntrospectBeanDescription.beanDesc("+forType+")");

src/main/java/tools/jackson/databind/DeserializationContext.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ public BeanDescription introspectBeanDescriptionForCreation(JavaType type, Annot
537537
}
538538

539539
public BeanDescription.Supplier lazyIntrospectBeanDescriptionForCreation(JavaType type) {
540-
return new BeanDescription.LazySupplier(type) {
540+
return new BeanDescription.LazySupplier(getConfig(), type) {
541541
@Override
542542
protected BeanDescription _construct(JavaType forType, AnnotatedClass ac) {
543543
return introspectBeanDescriptionForCreation(forType, ac);
@@ -558,7 +558,7 @@ public BeanDescription introspectBeanDescriptionForBuilder(JavaType builderType,
558558

559559
public BeanDescription.Supplier lazyIntrospectBeanDescriptionForBuilder(final JavaType builderType,
560560
final BeanDescription valueTypeDesc) {
561-
return new BeanDescription.LazySupplier(builderType) {
561+
return new BeanDescription.LazySupplier(getConfig(), builderType) {
562562
@Override
563563
protected BeanDescription _construct(JavaType forType, AnnotatedClass ac) {
564564
return introspectBeanDescriptionForBuilder(forType, valueTypeDesc);

src/main/java/tools/jackson/databind/deser/BeanDeserializerBuilder.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ public class BeanDeserializerBuilder
127127
/**********************************************************************
128128
*/
129129

130-
public BeanDeserializerBuilder(BeanDescription.Supplier beanDescRef,
131-
DeserializationContext ctxt)
130+
public BeanDeserializerBuilder(DeserializationContext ctxt,
131+
BeanDescription.Supplier beanDescRef)
132132
{
133133
_beanDescRef = beanDescRef;
134134
_context = ctxt;
@@ -584,7 +584,7 @@ protected BeanPropertyMap _constructPropMap(Collection<SettableBeanProperty> pro
584584
{
585585
// 07-May-2020, tatu: First find combination of per-type config overrides (higher
586586
// precedence) and per-type annotations (lower):
587-
JsonFormat.Value format = _beanDescRef.get().findExpectedFormat(null);
587+
JsonFormat.Value format = _beanDescRef.findExpectedFormat(null);
588588
// and see if any of those has explicit definition; if not, use global baseline default
589589
Boolean B = format.getFeature(JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES);
590590
boolean caseInsensitive = (B == null)

src/main/java/tools/jackson/databind/deser/BeanDeserializerFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ public ValueDeserializer<Object> buildThrowableDeserializer(DeserializationConte
492492
*/
493493
protected BeanDeserializerBuilder constructBeanDeserializerBuilder(DeserializationContext ctxt,
494494
BeanDescription.Supplier beanDescRef) {
495-
return new BeanDeserializerBuilder(beanDescRef, ctxt);
495+
return new BeanDeserializerBuilder(ctxt, beanDescRef);
496496
}
497497

498498
/**

src/main/java/tools/jackson/databind/deser/DeserializerCache.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -378,11 +378,11 @@ protected ValueDeserializer<?> _createDeserializer2(DeserializationContext ctxt,
378378
}
379379
if (type.isMapLikeType()) {
380380
// 11-Mar-2017, tatu: As per [databind#1554], also need to block
381-
// handling as Map if overriden with "as POJO" option.
381+
// handling as Map if overridden with "as POJO" option.
382382
// Ideally we'd determine it bit later on (to allow custom handler checks)
383383
// but that won't work for other reasons. So do it here.
384384
// (read: rewrite for 3.0)
385-
JsonFormat.Value format = beanDescRef.get().findExpectedFormat(type.getRawClass());
385+
JsonFormat.Value format = beanDescRef.findExpectedFormat(type.getRawClass());
386386
if (format.getShape() != JsonFormat.Shape.POJO) {
387387
MapLikeType mlt = (MapLikeType) type;
388388
if (mlt instanceof MapType) {
@@ -392,11 +392,10 @@ protected ValueDeserializer<?> _createDeserializer2(DeserializationContext ctxt,
392392
}
393393
}
394394
if (type.isCollectionLikeType()) {
395-
/* One exception is if shape is to be Shape.POJO (or, as alias, OBJECT).
396-
* Ideally we'd determine it bit later on (to allow custom handler checks),
397-
* but that won't work for other reasons. So do it here.
398-
*/
399-
JsonFormat.Value format = beanDescRef.get().findExpectedFormat(type.getRawClass());
395+
// One exception is if shape is to be Shape.POJO (or, as alias, OBJECT).
396+
// Ideally we'd determine it bit later on (to allow custom handler checks),
397+
// but that won't work for other reasons. So do it here.
398+
JsonFormat.Value format = beanDescRef.findExpectedFormat(type.getRawClass());
400399
if (format.getShape() != JsonFormat.Shape.POJO) {
401400
CollectionLikeType clt = (CollectionLikeType) type;
402401
if (clt instanceof CollectionType) {

src/main/java/tools/jackson/databind/deser/bean/BeanDeserializerBase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ protected BeanDeserializerBase(BeanDeserializerBuilder builder,
247247
;
248248

249249
// Any transformation we may need to apply?
250-
_serializationShape = beanDescRef.get().findExpectedFormat(_beanType.getRawClass()).getShape();
250+
_serializationShape = beanDescRef.findExpectedFormat(_beanType.getRawClass()).getShape();
251251

252252
_needViewProcesing = hasViews;
253253
_vanillaProcessing = !_nonStandardCreation

src/main/java/tools/jackson/databind/introspect/BasicBeanDescription.java

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -371,28 +371,6 @@ public AnnotatedMethod findMethod(String name, Class<?>[] paramTypes) {
371371
/**********************************************************************
372372
*/
373373

374-
@Override
375-
public JsonFormat.Value findExpectedFormat(Class<?> baseType)
376-
{
377-
JsonFormat.Value v0 = _classFormat;
378-
if (v0 == null) { // copied from above
379-
// 18-Apr-2018, tatu: Bit unclean but apparently `_config` is `null` for
380-
// a small set of pre-discovered simple types that `BasicClassIntrospector`
381-
// may expose. If so, nothing we can do
382-
v0 = (_config == null) ? null
383-
: _intr.findFormat(_config, _classInfo);
384-
if (v0 == null) {
385-
v0 = JsonFormat.Value.empty();
386-
}
387-
_classFormat = v0;
388-
}
389-
JsonFormat.Value v1 = _config.getDefaultPropertyFormat(baseType);
390-
if (v1 == null) {
391-
return v0;
392-
}
393-
return JsonFormat.Value.merge(v0, v1);
394-
}
395-
396374
@Override
397375
public Class<?>[] findDefaultViews()
398376
{

src/main/java/tools/jackson/databind/ser/BasicSerializerFactory.java

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,7 @@
1717
import tools.jackson.databind.annotation.JsonSerialize;
1818
import tools.jackson.databind.cfg.SerializerFactoryConfig;
1919
import tools.jackson.databind.ext.OptionalHandlerFactory;
20-
import tools.jackson.databind.ext.jdk8.DoubleStreamSerializer;
21-
import tools.jackson.databind.ext.jdk8.IntStreamSerializer;
22-
import tools.jackson.databind.ext.jdk8.Jdk8OptionalSerializer;
23-
import tools.jackson.databind.ext.jdk8.Jdk8StreamSerializer;
24-
import tools.jackson.databind.ext.jdk8.LongStreamSerializer;
25-
import tools.jackson.databind.ext.jdk8.OptionalDoubleSerializer;
26-
import tools.jackson.databind.ext.jdk8.OptionalIntSerializer;
27-
import tools.jackson.databind.ext.jdk8.OptionalLongSerializer;
20+
import tools.jackson.databind.ext.jdk8.*;
2821
import tools.jackson.databind.introspect.*;
2922
import tools.jackson.databind.jsontype.TypeSerializer;
3023
import tools.jackson.databind.ser.jackson.JacksonSerializableSerializer;
@@ -319,7 +312,8 @@ protected final ValueSerializer<?> findSerializerByPrimaryType(SerializationCont
319312
}
320313

321314
if (type.isTypeOrSubTypeOf(Number.class)) {
322-
JsonFormat.Value format = _calculateEffectiveFormat(beanDescRef, Number.class, formatOverrides);
315+
JsonFormat.Value format = _calculateEffectiveFormat(ctxt,
316+
beanDescRef, Number.class, formatOverrides);
323317

324318
// 21-May-2014, tatu: Couple of alternatives actually
325319
switch (format.getShape()) {
@@ -338,7 +332,7 @@ protected final ValueSerializer<?> findSerializerByPrimaryType(SerializationCont
338332
JavaType kt = mapEntryType.containedTypeOrUnknown(0);
339333
JavaType vt = mapEntryType.containedTypeOrUnknown(1);
340334
return buildMapEntrySerializer(ctxt, type, beanDescRef,
341-
_calculateEffectiveFormat(beanDescRef, Map.Entry.class, formatOverrides),
335+
_calculateEffectiveFormat(ctxt, beanDescRef, Map.Entry.class, formatOverrides),
342336
staticTyping, kt, vt);
343337
}
344338
if (ByteBuffer.class.isAssignableFrom(raw)) {
@@ -580,7 +574,8 @@ protected ValueSerializer<?> buildCollectionSerializer(SerializationContext ctxt
580574
}
581575
}
582576

583-
JsonFormat.Value format = _calculateEffectiveFormat(beanDescRef, Collection.class, formatOverrides);
577+
JsonFormat.Value format = _calculateEffectiveFormat(ctxt,
578+
beanDescRef, Collection.class, formatOverrides);
584579
if (ser == null) {
585580
ser = findSerializerByAnnotations(ctxt, type, beanDescRef); // (2) Annotations
586581
if (ser == null) {
@@ -672,7 +667,8 @@ protected ValueSerializer<?> buildMapSerializer(SerializationContext ctxt,
672667
boolean staticTyping, ValueSerializer<Object> keySerializer,
673668
TypeSerializer elementTypeSerializer, ValueSerializer<Object> elementValueSerializer)
674669
{
675-
JsonFormat.Value format = _calculateEffectiveFormat(beanDescRef, Map.class, formatOverrides);
670+
JsonFormat.Value format = _calculateEffectiveFormat(ctxt,
671+
beanDescRef, Map.class, formatOverrides);
676672

677673
// [databind#467]: This is where we could allow serialization "as POJO": But! It's
678674
// nasty to undo, and does not apply on per-property basis. So, hardly optimal
@@ -1135,10 +1131,11 @@ private void _removeEnumSelfReferences(BeanDescription beanDesc) {
11351131
*
11361132
* @since 3.0
11371133
*/
1138-
protected JsonFormat.Value _calculateEffectiveFormat(BeanDescription.Supplier beanDescRef,
1134+
protected JsonFormat.Value _calculateEffectiveFormat(SerializationContext ctxt,
1135+
BeanDescription.Supplier beanDescRef,
11391136
Class<?> baseType, JsonFormat.Value formatOverrides)
11401137
{
1141-
JsonFormat.Value fromType = beanDescRef.get().findExpectedFormat(baseType);
1138+
JsonFormat.Value fromType = beanDescRef.findExpectedFormat(baseType);
11421139
if (formatOverrides == null) {
11431140
return fromType;
11441141
}

0 commit comments

Comments
 (0)