Skip to content

Commit

Permalink
...
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Oct 21, 2016
1 parent db974eb commit 9cf32e2
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 71 deletions.
Expand Up @@ -836,7 +836,7 @@ protected SettableBeanProperty _resolveUnwrappedProperty(DeserializationContext
} }
return null; return null;
} }

/** /**
* Helper method that will handle gruesome details of dealing with properties * Helper method that will handle gruesome details of dealing with properties
* that have non-static inner class as value... * that have non-static inner class as value...
Expand All @@ -856,10 +856,10 @@ protected SettableBeanProperty _resolveInnerClassValuedProperty(DeserializationC
Class<?> valueClass = prop.getType().getRawClass(); Class<?> valueClass = prop.getType().getRawClass();
Class<?> enclosing = ClassUtil.getOuterClass(valueClass); Class<?> enclosing = ClassUtil.getOuterClass(valueClass);
// and is inner class of the bean class... // 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()) { for (Constructor<?> ctor : valueClass.getConstructors()) {
Class<?>[] paramTypes = ctor.getParameterTypes(); Class<?>[] paramTypes = ctor.getParameterTypes();
if (paramTypes.length == 1 && paramTypes[0] == enclosing) { if ((paramTypes.length == 1) && (paramTypes[0] == enclosing)) {
if (ctxt.canOverrideAccessModifiers()) { if (ctxt.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(ctor, ctxt.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS)); ClassUtil.checkAndFixAccess(ctor, ctxt.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
} }
Expand Down
Expand Up @@ -666,7 +666,7 @@ public void fixAccess(DeserializationConfig config) {


@Override @Override
public int getCreatorIndex() { return delegate.getCreatorIndex(); } public int getCreatorIndex() { return delegate.getCreatorIndex(); }

@Override @Override
public Object getInjectableValueId() { return delegate.getInjectableValueId(); } public Object getInjectableValueId() { return delegate.getInjectableValueId(); }


Expand All @@ -685,7 +685,7 @@ public <A extends Annotation> A getAnnotation(Class<A> acls) {
/* Actual mutators /* Actual mutators
/********************************************************** /**********************************************************
*/ */

@Override @Override
public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, public void deserializeAndSet(JsonParser p, DeserializationContext ctxt,
Object instance) throws IOException { Object instance) throws IOException {
Expand Down
@@ -1,10 +1,10 @@
package com.fasterxml.jackson.databind.deser.impl; package com.fasterxml.jackson.databind.deser.impl;


import java.io.IOException; import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;


import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.core.*;

import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty; import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
import com.fasterxml.jackson.databind.introspect.*; import com.fasterxml.jackson.databind.introspect.*;
Expand All @@ -17,15 +17,10 @@
* to regular implementation. * to regular implementation.
*/ */
public final class InnerClassProperty public final class InnerClassProperty
extends SettableBeanProperty extends SettableBeanProperty.Delegating
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;


/**
* Actual property that we use after value construction.
*/
protected final SettableBeanProperty _delegate;

/** /**
* Constructor used when deserializing this property. * Constructor used when deserializing this property.
* Transient since there is no need to persist; only needed during * Transient since there is no need to persist; only needed during
Expand All @@ -42,107 +37,66 @@ public InnerClassProperty(SettableBeanProperty delegate,
Constructor<?> ctor) Constructor<?> ctor)
{ {
super(delegate); super(delegate);
_delegate = delegate;
_creator = ctor; _creator = ctor;
} }


/** /**
* Constructor used with JDK Serialization; needed to handle transient * Constructor used with JDK Serialization; needed to handle transient
* Constructor, wrap/unwrap in/out-of Annotated variant. * Constructor, wrap/unwrap in/out-of Annotated variant.
*/ */
protected InnerClassProperty(InnerClassProperty src, AnnotatedConstructor ann) protected InnerClassProperty(SettableBeanProperty src, AnnotatedConstructor ann)
{ {
super(src); super(src);
_delegate = src._delegate;
_annotated = ann; _annotated = ann;
_creator = (_annotated == null) ? null : _annotated.getAnnotated(); _creator = (_annotated == null) ? null : _annotated.getAnnotated();
if (_creator == null) { if (_creator == null) {
throw new IllegalArgumentException("Missing constructor (broken JDK (de)serialization?)"); 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 @Override
public InnerClassProperty withName(PropertyName newName) { protected SettableBeanProperty withDelegate(SettableBeanProperty d) {
return new InnerClassProperty(this, newName); 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 extends Annotation> A getAnnotation(Class<A> acls) {
return _delegate.getAnnotation(acls);
}

@Override public AnnotatedMember getMember() { return _delegate.getMember(); }

/* /*
/********************************************************** /**********************************************************
/* Deserialization methods /* Deserialization methods
/********************************************************** /**********************************************************
*/ */


@Override @Override
public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt, Object bean) public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object bean)
throws IOException throws IOException
{ {
JsonToken t = jp.getCurrentToken(); JsonToken t = p.getCurrentToken();
Object value; Object value;
if (t == JsonToken.VALUE_NULL) { if (t == JsonToken.VALUE_NULL) {
value = _valueDeserializer.getNullValue(ctxt); value = _valueDeserializer.getNullValue(ctxt);
} else if (_valueTypeDeserializer != null) { } else if (_valueTypeDeserializer != null) {
value = _valueDeserializer.deserializeWithType(jp, ctxt, _valueTypeDeserializer); value = _valueDeserializer.deserializeWithType(p, ctxt, _valueTypeDeserializer);
} else { // the usual case } else { // the usual case
try { try {
value = _creator.newInstance(bean); value = _creator.newInstance(bean);
} catch (Exception e) { } catch (Exception e) {
ClassUtil.unwrapAndThrowAsIAE(e, "Failed to instantiate class "+_creator.getDeclaringClass().getName()+", problem: "+e.getMessage()); ClassUtil.unwrapAndThrowAsIAE(e, "Failed to instantiate class "+_creator.getDeclaringClass().getName()+", problem: "+e.getMessage());
value = null; value = null;
} }
_valueDeserializer.deserialize(jp, ctxt, value); _valueDeserializer.deserialize(p, ctxt, value);
} }
set(bean, value); set(bean, value);
} }


@Override @Override
public Object deserializeSetAndReturn(JsonParser jp, public Object deserializeSetAndReturn(JsonParser p, DeserializationContext ctxt, Object instance)
DeserializationContext ctxt, Object instance)
throws IOException throws IOException
{ {
return setAndReturn(instance, deserialize(jp, ctxt)); return setAndReturn(instance, deserialize(p, ctxt));
}

@Override
public final void set(Object instance, Object value) throws IOException {
_delegate.set(instance, value);
} }


@Override // these are fine with defaults
public Object setAndReturn(Object instance, Object value) throws IOException { // public final void set(Object instance, Object value) throws IOException { }
return _delegate.setAndReturn(instance, value); // public Object setAndReturn(Object instance, Object value) throws IOException { }
}


/* /*
/********************************************************** /**********************************************************
Expand All @@ -157,9 +111,9 @@ Object readResolve() {


Object writeReplace() { Object writeReplace() {
// need to construct a fake instance to support serialization // need to construct a fake instance to support serialization
if (_annotated != null) { if (_annotated == null) {
return this; return new InnerClassProperty(this, new AnnotatedConstructor(null, _creator, null, null));
} }
return new InnerClassProperty(this, new AnnotatedConstructor(null, _creator, null, null)); return this;
} }
} }
@@ -1,10 +1,10 @@
package com.fasterxml.jackson.databind.deser; package com.fasterxml.jackson.databind.deser;


import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.*;


public class TestInnerClass extends BaseMapTest public class TestInnerClass extends BaseMapTest
{ {
// [JACKSON-594]
static class Dog static class Dog
{ {
public String name; public String name;
Expand All @@ -16,9 +16,10 @@ public Dog(String n, boolean thinking) {
brain = new Brain(); brain = new Brain();
brain.isThinking = thinking; brain.isThinking = thinking;
} }

// note: non-static // note: non-static
public class Brain { public class Brain {
@JsonProperty("brainiac")
public boolean isThinking; public boolean isThinking;


public String parentName() { return name; } public String parentName() { return name; }
Expand All @@ -45,5 +46,11 @@ public void testSimpleNonStaticInner() throws Exception
assertEquals("Smurf", output.brain.parentName()); assertEquals("Smurf", output.brain.parentName());
output.name = "Foo"; output.name = "Foo";
assertEquals("Foo", output.brain.parentName()); assertEquals("Foo", output.brain.parentName());

// also, null handling
input.brain = null;

output = mapper.readValue(mapper.writeValueAsString(input), Dog.class);
assertNull(output.brain);
} }
} }

0 comments on commit 9cf32e2

Please sign in to comment.