package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.BeanDeserializer;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
import com.fasterxml.jackson.databind.util.NameTransformer;
public class ThrowableDeserializer
extends BeanDeserializer
{
private static final long serialVersionUID = 1L;
protected final static String PROP_NAME_MESSAGE = "message";
protected final static String PROP_NAME_SUPPRESSED = "suppressed";
public ThrowableDeserializer(BeanDeserializer baseDeserializer) {
super(baseDeserializer);
_vanillaProcessing = false;
}
protected ThrowableDeserializer(BeanDeserializer src, NameTransformer unwrapper) {
super(src, unwrapper);
}
@Override
public JsonDeserializer<Object> unwrappingDeserializer(NameTransformer unwrapper) {
if (getClass() != ThrowableDeserializer.class) {
return this;
}
return new ThrowableDeserializer(this, unwrapper);
}
@Override
public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) throws IOException
{
if (_propertyBasedCreator != null) {
return _deserializeUsingPropertyBased(p, ctxt);
}
if (_delegateDeserializer != null) {
return _valueInstantiator.createUsingDelegate(ctxt,
_delegateDeserializer.deserialize(p, ctxt));
}
if (_beanType.isAbstract()) {
return ctxt.handleMissingInstantiator(handledType(), getValueInstantiator(), p,
"abstract type (need to add/enable type information?)");
}
boolean hasStringCreator = _valueInstantiator.canCreateFromString();
boolean hasDefaultCtor = _valueInstantiator.canCreateUsingDefault();
if (!hasStringCreator && !hasDefaultCtor) {
return ctxt.handleMissingInstantiator(handledType(), getValueInstantiator(), p,
"Throwable needs a default constructor, a single-String-arg constructor; or explicit @JsonCreator");
}
Throwable throwable = null;
Object[] pending = null;
Throwable[] suppressed = null;
int pendingIx = 0;
for (; !p.hasToken(JsonToken.END_OBJECT); p.nextToken()) {
String propName = p.currentName();
SettableBeanProperty prop = _beanProperties.find(propName);
p.nextToken();
if (prop != null) {
if (throwable != null) {
prop.deserializeAndSet(p, ctxt, throwable);
continue;
}
if (pending == null) {
int len = _beanProperties.size();
pending = new Object[len + len];
}
pending[pendingIx++] = prop;
pending[pendingIx++] = prop.deserialize(p, ctxt);
continue;
}
if (PROP_NAME_MESSAGE.equals(propName)) {
if (hasStringCreator) {
throwable = (Throwable) _valueInstantiator.createFromString(ctxt, p.getValueAsString());
continue;
}
} else if (PROP_NAME_SUPPRESSED.equals(propName)) {
suppressed = ctxt.readValue(p, Throwable[].class);
continue;
}
if ((_ignorableProps != null) && _ignorableProps.contains(propName)) {
p.skipChildren();
continue;
}
if (_anySetter != null) {
_anySetter.deserializeAndSet(p, ctxt, throwable, propName);
continue;
}
handleUnknownProperty(p, ctxt, throwable, propName);
}
if (throwable == null) {
if (hasStringCreator) {
throwable = (Throwable) _valueInstantiator.createFromString(ctxt, null);
} else {
throwable = (Throwable) _valueInstantiator.createUsingDefault(ctxt);
}
}
if (pending != null) {
for (int i = 0, len = pendingIx; i < len; i += 2) {
SettableBeanProperty prop = (SettableBeanProperty)pending[i];
prop.set(throwable, pending[i+1]);
}
}
if (suppressed != null) {
for (Throwable s : suppressed) {
throwable.addSuppressed(s);
}
}
return throwable;
}
}