diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java index 5c4df4efe5..9df98f52e2 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java @@ -836,7 +836,7 @@ protected SettableBeanProperty _resolveUnwrappedProperty(DeserializationContext } return null; } - + /** * Helper method that will handle gruesome details of dealing with properties * that have non-static inner class as value... @@ -856,10 +856,10 @@ protected SettableBeanProperty _resolveInnerClassValuedProperty(DeserializationC Class valueClass = prop.getType().getRawClass(); Class enclosing = ClassUtil.getOuterClass(valueClass); // and is inner class of the bean class... - if (enclosing != null && enclosing == _beanType.getRawClass()) { + if ((enclosing != null) && (enclosing == _beanType.getRawClass())) { for (Constructor ctor : valueClass.getConstructors()) { Class[] paramTypes = ctor.getParameterTypes(); - if (paramTypes.length == 1 && paramTypes[0] == enclosing) { + if ((paramTypes.length == 1) && (paramTypes[0] == enclosing)) { if (ctxt.canOverrideAccessModifiers()) { ClassUtil.checkAndFixAccess(ctor, ctxt.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS)); } diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/SettableBeanProperty.java b/src/main/java/com/fasterxml/jackson/databind/deser/SettableBeanProperty.java index e886d1dd12..da9d439c7a 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/SettableBeanProperty.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/SettableBeanProperty.java @@ -666,7 +666,7 @@ public void fixAccess(DeserializationConfig config) { @Override public int getCreatorIndex() { return delegate.getCreatorIndex(); } - + @Override public Object getInjectableValueId() { return delegate.getInjectableValueId(); } @@ -685,7 +685,7 @@ public A getAnnotation(Class acls) { /* Actual mutators /********************************************************** */ - + @Override public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object instance) throws IOException { diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/impl/InnerClassProperty.java b/src/main/java/com/fasterxml/jackson/databind/deser/impl/InnerClassProperty.java index 1fa76fef05..68a2e68ce8 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/impl/InnerClassProperty.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/impl/InnerClassProperty.java @@ -1,10 +1,10 @@ package com.fasterxml.jackson.databind.deser.impl; import java.io.IOException; -import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import com.fasterxml.jackson.core.*; + import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.deser.SettableBeanProperty; import com.fasterxml.jackson.databind.introspect.*; @@ -17,15 +17,10 @@ * to regular implementation. */ public final class InnerClassProperty - extends SettableBeanProperty + extends SettableBeanProperty.Delegating { private static final long serialVersionUID = 1L; - /** - * Actual property that we use after value construction. - */ - protected final SettableBeanProperty _delegate; - /** * Constructor used when deserializing this property. * Transient since there is no need to persist; only needed during @@ -42,7 +37,6 @@ public InnerClassProperty(SettableBeanProperty delegate, Constructor ctor) { super(delegate); - _delegate = delegate; _creator = ctor; } @@ -50,54 +44,21 @@ public InnerClassProperty(SettableBeanProperty delegate, * Constructor used with JDK Serialization; needed to handle transient * Constructor, wrap/unwrap in/out-of Annotated variant. */ - protected InnerClassProperty(InnerClassProperty src, AnnotatedConstructor ann) + protected InnerClassProperty(SettableBeanProperty src, AnnotatedConstructor ann) { super(src); - _delegate = src._delegate; _annotated = ann; _creator = (_annotated == null) ? null : _annotated.getAnnotated(); if (_creator == null) { throw new IllegalArgumentException("Missing constructor (broken JDK (de)serialization?)"); } } - - protected InnerClassProperty(InnerClassProperty src, JsonDeserializer deser) - { - super(src, deser); - _delegate = src._delegate.withValueDeserializer(deser); - _creator = src._creator; - } - - protected InnerClassProperty(InnerClassProperty src, PropertyName newName) { - super(src, newName); - _delegate = src._delegate.withName(newName); - _creator = src._creator; - } @Override - public InnerClassProperty withName(PropertyName newName) { - return new InnerClassProperty(this, newName); + protected SettableBeanProperty withDelegate(SettableBeanProperty d) { + return new InnerClassProperty(d, _creator); } - @Override - public InnerClassProperty withValueDeserializer(JsonDeserializer deser) { - return new InnerClassProperty(this, deser); - } - - @Override - public void fixAccess(DeserializationConfig config) { - _delegate.fixAccess(config); - } - - // // // BeanProperty impl - - @Override - public A getAnnotation(Class acls) { - return _delegate.getAnnotation(acls); - } - - @Override public AnnotatedMember getMember() { return _delegate.getMember(); } - /* /********************************************************** /* Deserialization methods @@ -105,15 +66,15 @@ public A getAnnotation(Class acls) { */ @Override - public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt, Object bean) + public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object bean) throws IOException { - JsonToken t = jp.getCurrentToken(); + JsonToken t = p.getCurrentToken(); Object value; if (t == JsonToken.VALUE_NULL) { value = _valueDeserializer.getNullValue(ctxt); } else if (_valueTypeDeserializer != null) { - value = _valueDeserializer.deserializeWithType(jp, ctxt, _valueTypeDeserializer); + value = _valueDeserializer.deserializeWithType(p, ctxt, _valueTypeDeserializer); } else { // the usual case try { value = _creator.newInstance(bean); @@ -121,28 +82,21 @@ public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt, Object ClassUtil.unwrapAndThrowAsIAE(e, "Failed to instantiate class "+_creator.getDeclaringClass().getName()+", problem: "+e.getMessage()); value = null; } - _valueDeserializer.deserialize(jp, ctxt, value); + _valueDeserializer.deserialize(p, ctxt, value); } set(bean, value); } @Override - public Object deserializeSetAndReturn(JsonParser jp, - DeserializationContext ctxt, Object instance) + public Object deserializeSetAndReturn(JsonParser p, DeserializationContext ctxt, Object instance) throws IOException { - return setAndReturn(instance, deserialize(jp, ctxt)); - } - - @Override - public final void set(Object instance, Object value) throws IOException { - _delegate.set(instance, value); + return setAndReturn(instance, deserialize(p, ctxt)); } - @Override - public Object setAndReturn(Object instance, Object value) throws IOException { - return _delegate.setAndReturn(instance, value); - } +// these are fine with defaults +// public final void set(Object instance, Object value) throws IOException { } +// public Object setAndReturn(Object instance, Object value) throws IOException { } /* /********************************************************** @@ -157,9 +111,9 @@ Object readResolve() { Object writeReplace() { // need to construct a fake instance to support serialization - if (_annotated != null) { - return this; + if (_annotated == null) { + return new InnerClassProperty(this, new AnnotatedConstructor(null, _creator, null, null)); } - return new InnerClassProperty(this, new AnnotatedConstructor(null, _creator, null, null)); + return this; } -} \ No newline at end of file +} diff --git a/src/test/java/com/fasterxml/jackson/databind/deser/TestInnerClass.java b/src/test/java/com/fasterxml/jackson/databind/deser/TestInnerClass.java index 4be0a6372e..556e996d68 100644 --- a/src/test/java/com/fasterxml/jackson/databind/deser/TestInnerClass.java +++ b/src/test/java/com/fasterxml/jackson/databind/deser/TestInnerClass.java @@ -1,10 +1,10 @@ package com.fasterxml.jackson.databind.deser; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.*; public class TestInnerClass extends BaseMapTest { - // [JACKSON-594] static class Dog { public String name; @@ -16,9 +16,10 @@ public Dog(String n, boolean thinking) { brain = new Brain(); brain.isThinking = thinking; } - + // note: non-static public class Brain { + @JsonProperty("brainiac") public boolean isThinking; public String parentName() { return name; } @@ -45,5 +46,11 @@ public void testSimpleNonStaticInner() throws Exception assertEquals("Smurf", output.brain.parentName()); output.name = "Foo"; assertEquals("Foo", output.brain.parentName()); + + // also, null handling + input.brain = null; + + output = mapper.readValue(mapper.writeValueAsString(input), Dog.class); + assertNull(output.brain); } }