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.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.deser.SettableBeanProperty; import com.fasterxml.jackson.databind.introspect.AnnotatedMember; import com.fasterxml.jackson.databind.util.ClassUtil; /** * This sub-class is used to handle special case of value being a * non-static inner class. If so, we will have to use a special * alternative for default constructor; but otherwise can delegate * to regular implementation. */ public final class InnerClassProperty extends SettableBeanProperty { private static final long serialVersionUID = 1L; /** * Actual property that we use after value construction. */ protected final SettableBeanProperty _delegate; /** * Single-arg constructor we use for value instantiation. */ protected final Constructor<?> _creator; public InnerClassProperty(SettableBeanProperty delegate, Constructor<?> ctor) { super(delegate); _delegate = delegate; _creator = ctor; } protected InnerClassProperty(InnerClassProperty src, JsonDeserializer<?> deser) { super(src, deser); _delegate = src._delegate.withValueDeserializer(deser); _creator = src._creator; } protected InnerClassProperty(InnerClassProperty src, String newName) { super(src, newName); _delegate = src._delegate.withName(newName); _creator = src._creator; } @Override public InnerClassProperty withName(String newName) { return new InnerClassProperty(this, newName); } @Override public InnerClassProperty withValueDeserializer(JsonDeserializer<?> deser) { return new InnerClassProperty(this, deser); } // // // 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 /********************************************************** */ @Override public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt, Object bean) throws IOException, JsonProcessingException { JsonToken t = jp.getCurrentToken(); Object value; if (t == JsonToken.VALUE_NULL) { value = (_nullProvider == null) ? null : _nullProvider.nullValue(ctxt); } else if (_valueTypeDeserializer != null) { value = _valueDeserializer.deserializeWithType(jp, ctxt, _valueTypeDeserializer); } else { // the usual case try { value = _creator.newInstance(bean); } catch (Exception e) { ClassUtil.unwrapAndThrowAsIAE(e, "Failed to instantiate class "+_creator.getDeclaringClass().getName()+", problem: "+e.getMessage()); value = null; } _valueDeserializer.deserialize(jp, ctxt, value); } set(bean, value); } @Override public Object deserializeSetAndReturn(JsonParser jp, DeserializationContext ctxt, Object instance) throws IOException, JsonProcessingException { return setAndReturn(instance, deserialize(jp, ctxt)); } @Override public final void set(Object instance, Object value) throws IOException { _delegate.set(instance, value); } @Override public Object setAndReturn(Object instance, Object value) throws IOException { return _delegate.setAndReturn(instance, value); } }