Skip to content

Commit

Permalink
Remove usage of _neitherNull on findProperty (#1918)
Browse files Browse the repository at this point in the history
* Fix #1912

Remove usage of _neitherNull on findProperty to get custom property if possible.

* [#1912] add unit test
  • Loading branch information
deblockt authored and cowtowncoder committed Feb 5, 2018
1 parent ff83469 commit 8098ff3
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ protected BeanDeserializerBase(BeanDeserializerBase src, boolean ignoreAllUnknow

_vanillaProcessing = src._vanillaProcessing;
}

protected BeanDeserializerBase(BeanDeserializerBase src, NameTransformer unwrapper)
{
super(src._beanType);
Expand Down Expand Up @@ -415,7 +415,7 @@ public BeanDeserializerBase withBeanProperties(BeanPropertyMap props) {
* Fluent factory for creating a variant that can handle
* POJO output as a JSON Array. Implementations may ignore this request
* if no such input is possible.
*
*
* @since 2.1
*/
protected abstract BeanDeserializerBase asArrayDeserializer();
Expand Down Expand Up @@ -644,7 +644,7 @@ private JsonDeserializer<Object> _findDelegateDeserializer(DeserializationContex
*<p>
* NOTE: returned deserializer is NOT yet contextualized, caller needs to take
* care to do that.
*
*
* @since 2.2
*/
protected JsonDeserializer<Object> findConvertingDeserializer(DeserializationContext ctxt,
Expand All @@ -665,7 +665,7 @@ protected JsonDeserializer<Object> findConvertingDeserializer(DeserializationCon
}
return null;
}

/**
* Although most of post-processing is done in resolve(), we only get
* access to referring property's annotations here; and this is needed
Expand Down Expand Up @@ -1026,7 +1026,7 @@ public Iterator<SettableBeanProperty> properties()
* Accessor for finding properties that represents values to pass
* through property-based creator method (constructor or
* factory method)
*
*
* @since 2.0
*/
public Iterator<SettableBeanProperty> creatorProperties()
Expand All @@ -1047,14 +1047,14 @@ public SettableBeanProperty findProperty(PropertyName propertyName)
* Accessor for finding the property with given name, if POJO
* has one. Name used is the external name, i.e. name used
* in external data representation (JSON).
*
*
* @since 2.0
*/
public SettableBeanProperty findProperty(String propertyName)
{
SettableBeanProperty prop = (_beanProperties == null) ?
null : _beanProperties.find(propertyName);
if (_neitherNull(prop, _propertyBasedCreator)) {
if (prop == null && _propertyBasedCreator != null) {
prop = _propertyBasedCreator.findCreatorProperty(propertyName);
}
return prop;
Expand All @@ -1067,14 +1067,14 @@ public SettableBeanProperty findProperty(String propertyName)
* since properties are not directly indexable; however, for most
* instances difference is not significant as number of properties
* is low.
*
*
* @since 2.3
*/
public SettableBeanProperty findProperty(int propertyIndex)
{
SettableBeanProperty prop = (_beanProperties == null) ?
null : _beanProperties.find(propertyIndex);
if (_neitherNull(prop, _propertyBasedCreator)) {
if (prop == null && _propertyBasedCreator != null) {
prop = _propertyBasedCreator.findCreatorProperty(propertyIndex);
}
return prop;
Expand Down Expand Up @@ -1113,7 +1113,7 @@ public ValueInstantiator getValueInstantiator() {
*
* @param original Property to replace
* @param replacement Property to replace it with
*
*
* @since 2.1
*/
public void replaceProperty(SettableBeanProperty original,
Expand Down Expand Up @@ -1585,7 +1585,7 @@ protected void handleUnknownProperty(JsonParser p, DeserializationContext ctxt,
/**
* Method called when an explicitly ignored property (one specified with a
* name to match, either by property annotation or class annotation) is encountered.
*
*
* @since 2.3
*/
protected void handleIgnoredProperty(JsonParser p, DeserializationContext ctxt,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
import java.io.IOException;
import java.util.*;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.BeanDeserializer;
import com.fasterxml.jackson.databind.deser.BeanDeserializerBuilder;
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
Expand Down Expand Up @@ -139,7 +138,92 @@ public void setupModule(SetupContext context) {
context.addBeanDeserializerModifier(new Issue476DeserializerModifier());
}
}


public static class Issue1912Bean {
public Issue1912SubBean subBean;

@JsonCreator(mode = JsonCreator.Mode.PROPERTIES) // This is need to populate _propertyBasedCreator on BeanDeserializerBase
public Issue1912Bean(@JsonProperty("subBean") Issue1912SubBean subBean) {
this.subBean = subBean;
}
}
public static class Issue1912SubBean {
public String a;

public Issue1912SubBean() { }

public Issue1912SubBean(String a) {
this.a = a;
}
}

public static class Issue1912CustomBeanDeserializer extends JsonDeserializer<Issue1912Bean> {
private BeanDeserializer defaultDeserializer;

public Issue1912CustomBeanDeserializer(BeanDeserializer defaultDeserializer) {
this.defaultDeserializer = defaultDeserializer;
}

@Override
public Issue1912Bean deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
// this is need on some cases, this populate _propertyBasedCreator
defaultDeserializer.resolve(ctxt);

p.nextFieldName(); // read subBean
p.nextToken(); // read start object

Issue1912SubBean subBean = (Issue1912SubBean) defaultDeserializer.findProperty("subBean").deserialize(p, ctxt);

return new Issue1912Bean(subBean);
}
}

public static class Issue1912CustomPropertyDeserializer extends JsonDeserializer<Issue1912SubBean> {

@Override
public Issue1912SubBean deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
p.nextFieldName(); // read "a"
Issue1912SubBean object = new Issue1912SubBean(p.nextTextValue() + "_custom");
p.nextToken();
return object;
}
}
public static class Issue1912UseAddOrReplacePropertyDeserializerModifier extends BeanDeserializerModifier {

@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
if (beanDesc.getBeanClass() == Issue1912Bean.class) {
return new Issue1912CustomBeanDeserializer((BeanDeserializer) deserializer);
}
return super.modifyDeserializer(config, beanDesc, deserializer);
}

@Override
public BeanDeserializerBuilder updateBuilder(DeserializationConfig config, BeanDescription beanDesc, BeanDeserializerBuilder builder) {
if (beanDesc.getBeanClass() == Issue1912Bean.class) {
Iterator<SettableBeanProperty> props = builder.getProperties();
while (props.hasNext()) {
SettableBeanProperty prop = props.next();
SettableBeanProperty propWithCustomDeserializer = prop.withValueDeserializer(new Issue1912CustomPropertyDeserializer());
builder.addOrReplaceProperty(propWithCustomDeserializer, true);
}
}

return builder;
}
}
public class Issue1912Module extends SimpleModule {

public Issue1912Module() {
super("Issue1912Module", Version.unknownVersion());
}

@Override
public void setupModule(SetupContext context) {
context.addBeanDeserializerModifier(new Issue1912UseAddOrReplacePropertyDeserializerModifier());
}
}

// [Issue#121], arrays, collections, maps

enum EnumABC { A, B, C; }
Expand Down Expand Up @@ -380,4 +464,11 @@ public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config,
assertEquals("ABCDEF", result);
}

public void testAddOrReplacePropertyIsUsedOnDeserialization() throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Issue1912Module());

Issue1912Bean result = mapper.readValue("{\"subBean\": {\"a\":\"foo\"}}", Issue1912Bean.class);
assertEquals("foo_custom", result.subBean.a);
}
}

0 comments on commit 8098ff3

Please sign in to comment.