All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.jackson.map.deser.std.ThrowableDeserializer Maven / Gradle / Ivy

Go to download

Data Mapper package is a high-performance data binding package built on Jackson JSON processor

There is a newer version: 1.9.13
Show newest version
package org.codehaus.jackson.map.deser.std;

import java.io.IOException;

import org.codehaus.jackson.*;
import org.codehaus.jackson.map.*;
import org.codehaus.jackson.map.deser.BeanDeserializer;
import org.codehaus.jackson.map.deser.SettableBeanProperty;

/**
 * Deserializer that builds on basic {@link BeanDeserializer} but
 * override some aspects like instance construction.
 *

* Note that this deserializer was significantly changed in Jackson 1.7 * (due to massive changes in {@link BeanDeserializer}). * * @since 1.9 (renamed from 'org.codehaus.jackson.map.deser.ThrowableDeserializer') */ public class ThrowableDeserializer extends BeanDeserializer { protected final static String PROP_NAME_MESSAGE = "message"; /* /************************************************************ /* Construction /************************************************************ */ public ThrowableDeserializer(BeanDeserializer baseDeserializer) { super(baseDeserializer); } /** * Alternative constructor used when creating "unwrapping" deserializers * * @since 1.9 */ protected ThrowableDeserializer(BeanDeserializer src, boolean ignoreAllUnknown) { super(src, ignoreAllUnknown); } @Override public JsonDeserializer unwrappingDeserializer() { if (getClass() != ThrowableDeserializer.class) { return this; } /* main thing really is to just enforce ignoring of unknown * properties; since there may be multiple unwrapped values * and properties for all may be interleaved... */ return new ThrowableDeserializer(this, true); } /* /************************************************************ /* Overridden methods /************************************************************ */ @Override public Object deserializeFromObject(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { // 30-Sep-2010, tatu: Need to allow use of @JsonCreator, so: if (_propertyBasedCreator != null) { // proper @JsonCreator return _deserializeUsingPropertyBased(jp, ctxt); } if (_delegateDeserializer != null) { return _valueInstantiator.createUsingDelegate(_delegateDeserializer.deserialize(jp, ctxt)); } if (_beanType.isAbstract()) { // for good measure, check this too throw JsonMappingException.from(jp, "Can not instantiate abstract type "+_beanType +" (need to add/enable type information?)"); } boolean hasStringCreator = _valueInstantiator.canCreateFromString(); boolean hasDefaultCtor = _valueInstantiator.canCreateUsingDefault(); // and finally, verify we do have single-String arg constructor (if no @JsonCreator) if (!hasStringCreator && !hasDefaultCtor) { throw new JsonMappingException("Can not deserialize Throwable of type "+_beanType +" without having a default contructor, a single-String-arg constructor; or explicit @JsonCreator"); } Object throwable = null; Object[] pending = null; int pendingIx = 0; for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) { String propName = jp.getCurrentName(); SettableBeanProperty prop = _beanProperties.find(propName); jp.nextToken(); // to point to field value if (prop != null) { // normal case if (throwable != null) { prop.deserializeAndSet(jp, ctxt, throwable); continue; } // nope; need to defer if (pending == null) { int len = _beanProperties.size(); pending = new Object[len + len]; } pending[pendingIx++] = prop; pending[pendingIx++] = prop.deserialize(jp, ctxt); continue; } // Maybe it's "message"? if (PROP_NAME_MESSAGE.equals(propName)) { if (hasStringCreator) { throwable = _valueInstantiator.createFromString(jp.getText()); // any pending values? if (pending != null) { for (int i = 0, len = pendingIx; i < len; i += 2) { prop = (SettableBeanProperty)pending[i]; prop.set(throwable, pending[i+1]); } pending = null; } continue; } } /* As per [JACKSON-313], things marked as ignorable should not be * passed to any setter */ if (_ignorableProps != null && _ignorableProps.contains(propName)) { jp.skipChildren(); continue; } if (_anySetter != null) { _anySetter.deserializeAndSet(jp, ctxt, throwable, propName); continue; } // Unknown: let's call handler method handleUnknownProperty(jp, ctxt, throwable, propName); } // Sanity check: did we find "message"? if (throwable == null) { /* 15-Oct-2010, tatu: Can't assume missing message is an error, since it may be * suppressed during serialization, as per [JACKSON-388]. * * Should probably allow use of default constructor, too... */ //throw new JsonMappingException("No 'message' property found: could not deserialize "+_beanType); if (hasStringCreator) { throwable = _valueInstantiator.createFromString(null); } else { throwable = _valueInstantiator.createUsingDefault(); } // any pending values? if (pending != null) { for (int i = 0, len = pendingIx; i < len; i += 2) { SettableBeanProperty prop = (SettableBeanProperty)pending[i]; prop.set(throwable, pending[i+1]); } } } return throwable; } }