Skip to content

Commit

Permalink
Fixed #383
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Mar 26, 2017
1 parent 4b880d2 commit 0e373fa
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 26 deletions.
2 changes: 2 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ Project: jackson-databind
(reported by Starkom@github)
#357: StackOverflowError with contentConverter that returns array type
(reported by Florian S)
#383: Recursive `@JsonUnwrapped` (`child` with same type) fail: "No _valueDeserializer assigned"
(reported by tdavis@github)
#403: Make FAIL_ON_NULL_FOR_PRIMITIVES apply to primitive arrays and other types that wrap primitives
(reported by Harleen S)
#476: Allow "Serialize as POJO" using `@JsonFormat(shape=Shape.OBJECT)` class annotation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,8 @@ public JsonSerializer<Object> findValueSerializer(Class<?> valueType, BeanProper
* full generics-aware type instead of raw class.
* This is necessary for accurate handling of external type information,
* to handle polymorphic types.
*<p>
* Note: this call will also contextualize serializer before returning it.
*
* @param property When creating secondary serializers, property for which
* serializer is needed: annotations of the property (or bean that contains it)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ public class BeanDeserializer
*/
protected transient Exception _nullFromCreator;

/**
* State marker we need in order to avoid infinite recursion for some cases
* (not very clean, alas, but has to do for now)
*
* @since 2.9
*/
private volatile transient NameTransformer _currentlyTransforming;

/*
/**********************************************************
/* Life-cycle, construction, initialization
Expand Down Expand Up @@ -86,18 +94,22 @@ public BeanDeserializer(BeanDeserializerBase src, BeanPropertyMap props) {
}

@Override
public JsonDeserializer<Object> unwrappingDeserializer(NameTransformer unwrapper)
public JsonDeserializer<Object> unwrappingDeserializer(NameTransformer transformer)
{
// bit kludgy but we don't want to accidentally change type; sub-classes
// MUST override this method to support unwrapped properties...
if (getClass() != BeanDeserializer.class) {
return this;
}
/* main thing really is to just enforce ignoring of unknown
* properties; since there may be multiple unwrapped values
* and properties for all may be interleaved...
*/
return new BeanDeserializer(this, unwrapper);
// 25-Mar-2017, tatu: Not clean at all, but for [databind#383] we do need
// to keep track of accidental recursion...
if (_currentlyTransforming == transformer) {
return this;
}
_currentlyTransforming = transformer;
try {
return new BeanDeserializer(this, transformer);
} finally { _currentlyTransforming = null; }
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -478,18 +478,23 @@ public void resolve(DeserializationContext ctxt)
prop = _resolvedObjectIdProperty(ctxt, prop);
}
// Support unwrapped values (via @JsonUnwrapped)
SettableBeanProperty u = _resolveUnwrappedProperty(ctxt, prop);
if (u != null) {
prop = u;
if (unwrapped == null) {
unwrapped = new UnwrappedPropertyHandler();
NameTransformer xform = _findPropertyUnwrapper(ctxt, prop);
if (xform != null) {
JsonDeserializer<Object> orig = prop.getValueDeserializer();
JsonDeserializer<Object> unwrapping = orig.unwrappingDeserializer(xform);
if (unwrapping != orig && unwrapping != null) {
prop = prop.withValueDeserializer(unwrapping);
if (unwrapped == null) {
unwrapped = new UnwrappedPropertyHandler();
}
unwrapped.addProperty(prop);
// 12-Dec-2014, tatu: As per [databind#647], we will have problems if
// the original property is left in place. So let's remove it now.
// 25-Mar-2017, tatu: Wonder if this could be problematic wrt creators?
// (that is, should be remove it from creator too)
_beanProperties.remove(prop);
continue;
}
unwrapped.addProperty(prop);
// 12-Dec-2014, tatu: As per [databind#647], we will have problems if
// the original property is left in place. So let's remove it now.
// 25-Mar-2017, tatu: Wonder if this could be problematic wrt creators?
_beanProperties.remove(prop);
continue;
}

// 26-Oct-2016, tatu: Need to have access to value deserializer to know if
Expand Down Expand Up @@ -796,7 +801,7 @@ protected SettableBeanProperty _resolvedObjectIdProperty(DeserializationContext
* Helper method called to see if given property might be so-called unwrapped
* property: these require special handling.
*/
protected SettableBeanProperty _resolveUnwrappedProperty(DeserializationContext ctxt,
protected NameTransformer _findPropertyUnwrapper(DeserializationContext ctxt,
SettableBeanProperty prop)
throws JsonMappingException
{
Expand All @@ -811,13 +816,7 @@ protected SettableBeanProperty _resolveUnwrappedProperty(DeserializationContext
"Can not define Creator property \"%s\" as `@JsonUnwrapped`: combination not yet supported",
prop.getName()));
}

JsonDeserializer<Object> orig = prop.getValueDeserializer();
JsonDeserializer<Object> unwrapping = orig.unwrappingDeserializer(unwrapper);
if (unwrapping != orig && unwrapping != null) {
// might be cleaner to create new instance; but difficult to do reliably, so:
return prop.withValueDeserializer(unwrapping);
}
return unwrapper;
}
}
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.fasterxml.jackson.failing;
package com.fasterxml.jackson.databind.struct;

import com.fasterxml.jackson.annotation.*;

Expand Down

0 comments on commit 0e373fa

Please sign in to comment.