Skip to content

Commit

Permalink
experiment with alternative approach to handling unwrapped properties
Browse files Browse the repository at this point in the history
  • Loading branch information
fxshlein committed Jan 7, 2024
1 parent d65dfac commit 3bd10a0
Show file tree
Hide file tree
Showing 13 changed files with 320 additions and 102 deletions.
40 changes: 28 additions & 12 deletions src/main/java/com/fasterxml/jackson/databind/PropertyMetadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fasterxml.jackson.annotation.Nulls;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.util.NameTransformer;

/**
* Simple container class used for storing "additional" metadata about
Expand All @@ -17,13 +18,13 @@ public class PropertyMetadata
private static final long serialVersionUID = -1;

public final static PropertyMetadata STD_REQUIRED = new PropertyMetadata(Boolean.TRUE,
null, null, null, null, null, null);
null, null, null, null, null, null, null);

public final static PropertyMetadata STD_OPTIONAL = new PropertyMetadata(Boolean.FALSE,
null, null, null, null, null, null);
null, null, null, null, null, null, null);

public final static PropertyMetadata STD_REQUIRED_OR_OPTIONAL = new PropertyMetadata(null,
null, null, null, null, null, null);
null, null, null, null, null, null, null);

/**
* Helper class used for containing information about expected merge
Expand Down Expand Up @@ -108,6 +109,11 @@ public static MergeInfo createForPropertyOverride(AnnotatedMember getter) {
*/
protected Nulls _valueNulls, _contentNulls;

/**
* The {@link NameTransformer} used to unwrap the value of property. {@code null} if this property is not unwrapped.
*/
protected NameTransformer _unwrapper;

/*
/**********************************************************
/* Construction, configuration
Expand All @@ -118,7 +124,7 @@ public static MergeInfo createForPropertyOverride(AnnotatedMember getter) {
* @since 2.9
*/
protected PropertyMetadata(Boolean req, String desc, Integer index, String def,
MergeInfo mergeInfo, Nulls valueNulls, Nulls contentNulls)
MergeInfo mergeInfo, Nulls valueNulls, Nulls contentNulls, NameTransformer unwrapper)
{
_required = req;
_description = desc;
Expand All @@ -127,6 +133,7 @@ protected PropertyMetadata(Boolean req, String desc, Integer index, String def,
_mergeInfo = mergeInfo;
_valueNulls = valueNulls;
_contentNulls = contentNulls;
_unwrapper = unwrapper;
}

/**
Expand All @@ -136,7 +143,7 @@ public static PropertyMetadata construct(Boolean req, String desc, Integer index
String defaultValue) {
if ((desc != null) || (index != null) || (defaultValue != null)) {
return new PropertyMetadata(req, desc, index, defaultValue,
null, null, null);
null, null, null, null);
}
if (req == null) {
return STD_REQUIRED_OR_OPTIONAL;
Expand All @@ -149,7 +156,7 @@ public static PropertyMetadata construct(boolean req, String desc, Integer index
String defaultValue) {
if (desc != null || index != null || defaultValue != null) {
return new PropertyMetadata(req, desc, index, defaultValue,
null, null, null);
null, null, null, null);
}
return req ? STD_REQUIRED : STD_OPTIONAL;
}
Expand All @@ -173,15 +180,15 @@ protected Object readResolve()

public PropertyMetadata withDescription(String desc) {
return new PropertyMetadata(_required, desc, _index, _defaultValue,
_mergeInfo, _valueNulls, _contentNulls);
_mergeInfo, _valueNulls, _contentNulls, _unwrapper);
}

/**
* @since 2.9
*/
public PropertyMetadata withMergeInfo(MergeInfo mergeInfo) {
return new PropertyMetadata(_required, _description, _index, _defaultValue,
mergeInfo, _valueNulls, _contentNulls);
mergeInfo, _valueNulls, _contentNulls, _unwrapper);
}

/**
Expand All @@ -190,7 +197,12 @@ public PropertyMetadata withMergeInfo(MergeInfo mergeInfo) {
public PropertyMetadata withNulls(Nulls valueNulls,
Nulls contentNulls) {
return new PropertyMetadata(_required, _description, _index, _defaultValue,
_mergeInfo, valueNulls, contentNulls);
_mergeInfo, valueNulls, contentNulls, _unwrapper);
}

public PropertyMetadata withUnwrapper(NameTransformer unwrapper) {
return new PropertyMetadata(_required, _description, _index, _defaultValue,
_mergeInfo, _valueNulls, _contentNulls, unwrapper);
}

public PropertyMetadata withDefaultValue(String def) {
Expand All @@ -203,12 +215,12 @@ public PropertyMetadata withDefaultValue(String def) {
return this;
}
return new PropertyMetadata(_required, _description, _index, def,
_mergeInfo, _valueNulls, _contentNulls);
_mergeInfo, _valueNulls, _contentNulls, _unwrapper);
}

public PropertyMetadata withIndex(Integer index) {
return new PropertyMetadata(_required, _description, index, _defaultValue,
_mergeInfo, _valueNulls, _contentNulls);
_mergeInfo, _valueNulls, _contentNulls, _unwrapper);
}

public PropertyMetadata withRequired(Boolean b) {
Expand All @@ -220,7 +232,7 @@ public PropertyMetadata withRequired(Boolean b) {
return this;
}
return new PropertyMetadata(b, _description, _index, _defaultValue,
_mergeInfo, _valueNulls, _contentNulls);
_mergeInfo, _valueNulls, _contentNulls, _unwrapper);
}

/*
Expand Down Expand Up @@ -272,4 +284,8 @@ public PropertyMetadata withRequired(Boolean b) {
* @since 2.9
*/
public Nulls getContentNulls() { return _contentNulls; }

public boolean isUnwrapped() { return _unwrapper != null; }

public NameTransformer getUnwrapper() { return _unwrapper; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ protected void _addImplicitConstructorCreators(DeserializationContext ctxt,
}
NameTransformer unwrapper = intr.findUnwrappingNameTransformer(param);
if (unwrapper != null) {
properties[i] = constructCreatorProperty(ctxt, beanDesc, UnwrappedPropertyHandler.UNWRAPPED_CREATOR_PARAM_NAME, i, param, null);
properties[i] = constructCreatorProperty(ctxt, beanDesc, UnwrappedPropertyHandler.creatorParameterName(i), i, param, null);
++explicitNameCount;
continue;
}
Expand Down Expand Up @@ -730,7 +730,7 @@ protected void _addImplicitFactoryCreators(DeserializationContext ctxt,
}
NameTransformer unwrapper = intr.findUnwrappingNameTransformer(param);
if (unwrapper != null) {
properties[i] = constructCreatorProperty(ctxt, beanDesc, UnwrappedPropertyHandler.UNWRAPPED_CREATOR_PARAM_NAME, i, param, null);
properties[i] = constructCreatorProperty(ctxt, beanDesc, UnwrappedPropertyHandler.creatorParameterName(i), i, param, null);
++implicitNameCount;
continue;
}
Expand Down Expand Up @@ -861,7 +861,7 @@ protected void _addExplicitPropertyCreator(DeserializationContext ctxt,
// as that will not work with Creators well at all
NameTransformer unwrapper = ctxt.getAnnotationIntrospector().findUnwrappingNameTransformer(param);
if (unwrapper != null) {
properties[i] = constructCreatorProperty(ctxt, beanDesc, UnwrappedPropertyHandler.UNWRAPPED_CREATOR_PARAM_NAME, i, param, null);
properties[i] = constructCreatorProperty(ctxt, beanDesc, UnwrappedPropertyHandler.creatorParameterName(i), i, param, null);
continue;
}
name = candidate.findImplicitParamName(i);
Expand Down Expand Up @@ -1195,6 +1195,7 @@ protected SettableBeanProperty constructCreatorProperty(DeserializationContext c
// 22-Sep-2019, tatu: for [databind#2458] need more work on getting metadata
// about SetterInfo, mergeability
metadata = _getSetterInfo(ctxt, property, metadata);
metadata = _getPropertyUnwrapper(ctxt, property, metadata);

// Note: contextualization of typeDeser _should_ occur in constructor of CreatorProperty
// so it is not called directly here
Expand Down Expand Up @@ -1294,6 +1295,22 @@ protected PropertyMetadata _getSetterInfo(DeserializationContext ctxt,
return metadata;
}

/**
* Helper method that, if present, adds the {@link NameTransformer}
* for unwrapping the given property to the metadata.
*/
protected PropertyMetadata _getPropertyUnwrapper(DeserializationContext ctxt, BeanProperty prop, PropertyMetadata metadata)
{
AnnotatedMember am = prop.getMember();
if (am != null) {
NameTransformer unwrapper = ctxt.getAnnotationIntrospector().findUnwrappingNameTransformer(am);
if (unwrapper != null) {
metadata = metadata.withUnwrapper(unwrapper);
}
}
return metadata;
}

/*
/**********************************************************
/* DeserializerFactory impl: array deserializers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,12 @@ public class BeanDeserializer
public BeanDeserializer(BeanDeserializerBuilder builder, BeanDescription beanDesc,
BeanPropertyMap properties, Map<String, SettableBeanProperty> backRefs,
HashSet<String> ignorableProps, boolean ignoreAllUnknown,
UnwrappedPropertyHandler unwrappedPropertyHandler,
boolean hasViews)
{
super(builder, beanDesc, properties, backRefs,
ignorableProps, ignoreAllUnknown, null, hasViews);
ignorableProps, ignoreAllUnknown, null,
unwrappedPropertyHandler, hasViews);
}

/**
Expand All @@ -68,10 +70,12 @@ public BeanDeserializer(BeanDeserializerBuilder builder, BeanDescription beanDes
public BeanDeserializer(BeanDeserializerBuilder builder, BeanDescription beanDesc,
BeanPropertyMap properties, Map<String, SettableBeanProperty> backRefs,
HashSet<String> ignorableProps, boolean ignoreAllUnknown, Set<String> includableProps,
UnwrappedPropertyHandler unwrappedPropertyHandler,
boolean hasViews)
{
super(builder, beanDesc, properties, backRefs,
ignorableProps, ignoreAllUnknown, includableProps, hasViews);
ignorableProps, ignoreAllUnknown, includableProps,
unwrappedPropertyHandler, hasViews);
}

/**
Expand Down Expand Up @@ -835,10 +839,6 @@ protected Object deserializeWithUnwrapped(JsonParser p, DeserializationContext c
protected Object deserializeUsingPropertyBasedWithUnwrapped(JsonParser p, DeserializationContext ctxt)
throws IOException
{
// 01-Dec-2016, tatu: Note: This IS legal to call, but only when unwrapped
// value itself is NOT passed via `CreatorProperty` (which isn't supported).
// Ok however to pass via setter or field.

final PropertyBasedCreator creator = _propertyBasedCreator;
PropertyValueBuffer buffer = creator.startBuilding(p, ctxt, _objectIdReader);

Expand Down
Loading

0 comments on commit 3bd10a0

Please sign in to comment.