package com.fasterxml.jackson.databind.deser;
import java.io.
IOException;
import java.util.*;
import com.fasterxml.jackson.
core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.
impl.*;
import com.fasterxml.jackson.databind.
util.
NameTransformer;
import com.fasterxml.jackson.databind.
util.
TokenBuffer;
/**
* Deserializer class that can deserialize instances of
* arbitrary bean objects, usually from JSON Object structs,
* but possibly also from simple types like String values.
*/
public class
BeanDeserializer
extends
BeanDeserializerBase
implements java.io.
Serializable
{
private static final long
serialVersionUID = 1L;
/*
/**********************************************************
/* Life-cycle, construction, initialization
/**********************************************************
*/
/**
* Constructor used by {@link BeanDeserializerBuilder}.
*/
public
BeanDeserializer(
BeanDeserializerBuilder builder,
BeanDescription beanDesc,
BeanPropertyMap properties,
Map<
String,
SettableBeanProperty>
backRefs,
HashSet<
String>
ignorableProps, boolean
ignoreAllUnknown,
boolean
hasViews)
{
super(
builder,
beanDesc,
properties,
backRefs,
ignorableProps,
ignoreAllUnknown,
hasViews);
}
/**
* Copy-constructor that can be used by sub-classes to allow
* copy-on-write style copying of settings of an existing instance.
*/
protected
BeanDeserializer(
BeanDeserializerBase src) {
super(
src,
src.
_ignoreAllUnknown);
}
protected
BeanDeserializer(
BeanDeserializerBase src, boolean
ignoreAllUnknown) {
super(
src,
ignoreAllUnknown);
}
protected
BeanDeserializer(
BeanDeserializerBase src,
NameTransformer unwrapper) {
super(
src,
unwrapper);
}
public
BeanDeserializer(
BeanDeserializerBase src,
ObjectIdReader oir) {
super(
src,
oir);
}
public
BeanDeserializer(
BeanDeserializerBase src,
HashSet<
String>
ignorableProps) {
super(
src,
ignorableProps);
}
@
Override
public
JsonDeserializer<
Object> unwrappingDeserializer(
NameTransformer unwrapper)
{
/* bit kludgy but we don't want to accidentally change type; sub-classes
* MUST override this method to support unwrapped properties...
*/
if (
getClass() !=
BeanDeserializer.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
BeanDeserializer(this,
unwrapper);
}
@
Override
public
BeanDeserializer withObjectIdReader(
ObjectIdReader oir) {
return new
BeanDeserializer(this,
oir);
}
@
Override
public
BeanDeserializer withIgnorableProperties(
HashSet<
String>
ignorableProps) {
return new
BeanDeserializer(this,
ignorableProps);
}
@
Override
protected
BeanDeserializerBase asArrayDeserializer() {
SettableBeanProperty[]
props =
_beanProperties.
getPropertiesInInsertionOrder();
return new
BeanAsArrayDeserializer(this,
props);
}
/*
/**********************************************************
/* JsonDeserializer implementation
/**********************************************************
*/
/**
* Main deserialization method for bean-based objects (POJOs).
*<p>
* NOTE: was declared 'final' in 2.2; should NOT be to let extensions
* like Afterburner change definition.
*/
@
Override
public
Object deserialize(
JsonParser jp,
DeserializationContext ctxt)
throws
IOException,
JsonProcessingException
{
JsonToken t =
jp.
getCurrentToken();
// common case first:
if (
t ==
JsonToken.
START_OBJECT) {
if (
_vanillaProcessing) {
return
vanillaDeserialize(
jp,
ctxt,
jp.
nextToken());
}
jp.
nextToken();
if (
_objectIdReader != null) {
return
deserializeWithObjectId(
jp,
ctxt);
}
return
deserializeFromObject(
jp,
ctxt);
}
return
_deserializeOther(
jp,
ctxt,
t);
}
protected final
Object _deserializeOther(
JsonParser jp,
DeserializationContext ctxt,
JsonToken t)
throws
IOException,
JsonProcessingException
{
if (
t == null) {
return
_missingToken(
jp,
ctxt);
}
// and then others, generally requiring use of @JsonCreator
switch (
t) {
case
VALUE_STRING:
return
deserializeFromString(
jp,
ctxt);
case
VALUE_NUMBER_INT:
return
deserializeFromNumber(
jp,
ctxt);
case
VALUE_NUMBER_FLOAT:
return
deserializeFromDouble(
jp,
ctxt);
case
VALUE_EMBEDDED_OBJECT:
return
jp.
getEmbeddedObject();
case
VALUE_TRUE:
case
VALUE_FALSE:
return
deserializeFromBoolean(
jp,
ctxt);
case
START_ARRAY:
// these only work if there's a (delegating) creator...
return
deserializeFromArray(
jp,
ctxt);
case
FIELD_NAME:
case
END_OBJECT: // added to resolve [JACKSON-319], possible related issues
if (
_vanillaProcessing) {
return
vanillaDeserialize(
jp,
ctxt,
t);
}
if (
_objectIdReader != null) {
return
deserializeWithObjectId(
jp,
ctxt);
}
return
deserializeFromObject(
jp,
ctxt);
default:
throw
ctxt.
mappingException(
handledType());
}
}
protected
Object _missingToken(
JsonParser jp,
DeserializationContext ctxt)
throws
JsonProcessingException
{
throw
ctxt.
endOfInputException(
handledType());
}
/**
* Secondary deserialization method, called in cases where POJO
* instance is created as part of deserialization, potentially
* after collecting some or all of the properties to set.
*/
@
Override
public
Object deserialize(
JsonParser jp,
DeserializationContext ctxt,
Object bean)
throws
IOException,
JsonProcessingException
{
if (
_injectables != null) {
injectValues(
ctxt,
bean);
}
if (
_unwrappedPropertyHandler != null) {
return
deserializeWithUnwrapped(
jp,
ctxt,
bean);
}
if (
_externalTypeIdHandler != null) {
return
deserializeWithExternalTypeId(
jp,
ctxt,
bean);
}
JsonToken t =
jp.
getCurrentToken();
// 23-Mar-2010, tatu: In some cases, we start with full JSON object too...
if (
t ==
JsonToken.
START_OBJECT) {
t =
jp.
nextToken();
}
if (
_needViewProcesing) {
Class<?>
view =
ctxt.
getActiveView();
if (
view != null) {
return
deserializeWithView(
jp,
ctxt,
bean,
view);
}
}
for (;
t ==
JsonToken.
FIELD_NAME;
t =
jp.
nextToken()) {
String propName =
jp.
getCurrentName();
// Skip field name:
jp.
nextToken();
SettableBeanProperty prop =
_beanProperties.
find(
propName);
if (
prop != null) { // normal case
try {
prop.
deserializeAndSet(
jp,
ctxt,
bean);
} catch (
Exception e) {
wrapAndThrow(
e,
bean,
propName,
ctxt);
}
continue;
}
handleUnknownVanilla(
jp,
ctxt,
bean,
propName);
}
return
bean;
}
/*
/**********************************************************
/* Concrete deserialization methods
/**********************************************************
*/
/**
* Streamlined version that is only used when no "special"
* features are enabled.
*/
private final
Object vanillaDeserialize(
JsonParser jp,
DeserializationContext ctxt,
JsonToken t)
throws
IOException,
JsonProcessingException
{
final
Object bean =
_valueInstantiator.
createUsingDefault(
ctxt);
for (;
jp.
getCurrentToken() !=
JsonToken.
END_OBJECT;
jp.
nextToken()) {
String propName =
jp.
getCurrentName();
// Skip field name:
jp.
nextToken();
SettableBeanProperty prop =
_beanProperties.
find(
propName);
if (
prop != null) { // normal case
try {
prop.
deserializeAndSet(
jp,
ctxt,
bean);
} catch (
Exception e) {
wrapAndThrow(
e,
bean,
propName,
ctxt);
}
} else {
handleUnknownVanilla(
jp,
ctxt,
bean,
propName);
}
}
return
bean;
}
/**
* General version used when handling needs more advanced
* features.
*/
@
Override
public
Object deserializeFromObject(
JsonParser jp,
DeserializationContext ctxt)
throws
IOException,
JsonProcessingException
{
if (
_nonStandardCreation) {
if (
_unwrappedPropertyHandler != null) {
return
deserializeWithUnwrapped(
jp,
ctxt);
}
if (
_externalTypeIdHandler != null) {
return
deserializeWithExternalTypeId(
jp,
ctxt);
}
return
deserializeFromObjectUsingNonDefault(
jp,
ctxt);
}
final
Object bean =
_valueInstantiator.
createUsingDefault(
ctxt);
if (
jp.
canReadObjectId()) {
Object id =
jp.
getObjectId();
if (
id != null) {
_handleTypedObjectId(
jp,
ctxt,
bean,
id);
}
}
if (
_injectables != null) {
injectValues(
ctxt,
bean);
}
if (
_needViewProcesing) {
Class<?>
view =
ctxt.
getActiveView();
if (
view != null) {
return
deserializeWithView(
jp,
ctxt,
bean,
view);
}
}
for (;
jp.
getCurrentToken() !=
JsonToken.
END_OBJECT;
jp.
nextToken()) {
String propName =
jp.
getCurrentName();
// Skip field name:
jp.
nextToken();
SettableBeanProperty prop =
_beanProperties.
find(
propName);
if (
prop != null) { // normal case
try {
prop.
deserializeAndSet(
jp,
ctxt,
bean);
} catch (
Exception e) {
wrapAndThrow(
e,
bean,
propName,
ctxt);
}
continue;
}
handleUnknownVanilla(
jp,
ctxt,
bean,
propName);
}
return
bean;
}
/**
* Method called to deserialize bean using "property-based creator":
* this means that a non-default constructor or factory method is
* called, and then possibly other setters. The trick is that
* values for creator method need to be buffered, first; and
* due to non-guaranteed ordering possibly some other properties
* as well.
*/
@
Override
@
SuppressWarnings("resource")
protected
Object _deserializeUsingPropertyBased(final
JsonParser jp, final
DeserializationContext ctxt)
throws
IOException,
JsonProcessingException
{
final
PropertyBasedCreator creator =
_propertyBasedCreator;
PropertyValueBuffer buffer =
creator.
startBuilding(
jp,
ctxt,
_objectIdReader);
// 04-Jan-2010, tatu: May need to collect unknown properties for polymorphic cases
TokenBuffer unknown = null;
JsonToken t =
jp.
getCurrentToken();
for (;
t ==
JsonToken.
FIELD_NAME;
t =
jp.
nextToken()) {
String propName =
jp.
getCurrentName();
jp.
nextToken(); // to point to value
// creator property?
SettableBeanProperty creatorProp =
creator.
findCreatorProperty(
propName);
if (
creatorProp != null) {
// Last creator property to set?
Object value =
creatorProp.
deserialize(
jp,
ctxt);
if (
buffer.
assignParameter(
creatorProp.
getCreatorIndex(),
value)) {
jp.
nextToken(); // to move to following FIELD_NAME/END_OBJECT
Object bean;
try {
bean =
creator.
build(
ctxt,
buffer);
} catch (
Exception e) {
wrapAndThrow(
e,
_beanType.
getRawClass(),
propName,
ctxt);
bean = null; // never gets here
}
// polymorphic?
if (
bean.
getClass() !=
_beanType.
getRawClass()) {
return
handlePolymorphic(
jp,
ctxt,
bean,
unknown);
}
if (
unknown != null) { // nope, just extra unknown stuff...
bean =
handleUnknownProperties(
ctxt,
bean,
unknown);
}
// or just clean?
return
deserialize(
jp,
ctxt,
bean);
}
continue;
}
// Object Id property?
if (
buffer.
readIdProperty(
propName)) {
continue;
}
// regular property? needs buffering
SettableBeanProperty prop =
_beanProperties.
find(
propName);
if (
prop != null) {
buffer.
bufferProperty(
prop,
prop.
deserialize(
jp,
ctxt));
continue;
}
// As per [JACKSON-313], things marked as ignorable should not be
// passed to any setter
if (
_ignorableProps != null &&
_ignorableProps.
contains(
propName)) {
handleIgnoredProperty(
jp,
ctxt,
handledType(),
propName);
continue;
}
// "any property"?
if (
_anySetter != null) {
buffer.
bufferAnyProperty(
_anySetter,
propName,
_anySetter.
deserialize(
jp,
ctxt));
continue;
}
// Ok then, let's collect the whole field; name and value
if (
unknown == null) {
unknown = new
TokenBuffer(
jp);
}
unknown.
writeFieldName(
propName);
unknown.
copyCurrentStructure(
jp);
}
// We hit END_OBJECT, so:
Object bean;
try {
bean =
creator.
build(
ctxt,
buffer);
} catch (
Exception e) {
wrapInstantiationProblem(
e,
ctxt);
bean = null; // never gets here
}
if (
unknown != null) {
// polymorphic?
if (
bean.
getClass() !=
_beanType.
getRawClass()) {
return
handlePolymorphic(null,
ctxt,
bean,
unknown);
}
// no, just some extra unknown properties
return
handleUnknownProperties(
ctxt,
bean,
unknown);
}
return
bean;
}
/*
/**********************************************************
/* Deserializing when we have to consider an active View
/**********************************************************
*/
protected final
Object deserializeWithView(
JsonParser jp,
DeserializationContext ctxt,
Object bean,
Class<?>
activeView)
throws
IOException,
JsonProcessingException
{
JsonToken t =
jp.
getCurrentToken();
for (;
t ==
JsonToken.
FIELD_NAME;
t =
jp.
nextToken()) {
String propName =
jp.
getCurrentName();
// Skip field name:
jp.
nextToken();
SettableBeanProperty prop =
_beanProperties.
find(
propName);
if (
prop != null) {
if (!
prop.
visibleInView(
activeView)) {
jp.
skipChildren();
continue;
}
try {
prop.
deserializeAndSet(
jp,
ctxt,
bean);
} catch (
Exception e) {
wrapAndThrow(
e,
bean,
propName,
ctxt);
}
continue;
}
handleUnknownVanilla(
jp,
ctxt,
bean,
propName);
}
return
bean;
}
/*
/**********************************************************
/* Handling for cases where we have "unwrapped" values
/**********************************************************
*/
/**
* Method called when there are declared "unwrapped" properties
* which need special handling
*/
@
SuppressWarnings("resource")
protected
Object deserializeWithUnwrapped(
JsonParser jp,
DeserializationContext ctxt)
throws
IOException,
JsonProcessingException
{
if (
_delegateDeserializer != null) {
return
_valueInstantiator.
createUsingDelegate(
ctxt,
_delegateDeserializer.
deserialize(
jp,
ctxt));
}
if (
_propertyBasedCreator != null) {
return
deserializeUsingPropertyBasedWithUnwrapped(
jp,
ctxt);
}
TokenBuffer tokens = new
TokenBuffer(
jp);
tokens.
writeStartObject();
final
Object bean =
_valueInstantiator.
createUsingDefault(
ctxt);
if (
_injectables != null) {
injectValues(
ctxt,
bean);
}
final
Class<?>
activeView =
_needViewProcesing ?
ctxt.
getActiveView() : null;
for (;
jp.
getCurrentToken() !=
JsonToken.
END_OBJECT;
jp.
nextToken()) {
String propName =
jp.
getCurrentName();
jp.
nextToken();
SettableBeanProperty prop =
_beanProperties.
find(
propName);
if (
prop != null) { // normal case
if (
activeView != null && !
prop.
visibleInView(
activeView)) {
jp.
skipChildren();
continue;
}
try {
prop.
deserializeAndSet(
jp,
ctxt,
bean);
} catch (
Exception e) {
wrapAndThrow(
e,
bean,
propName,
ctxt);
}
continue;
}
// ignorable things should be ignored
if (
_ignorableProps != null &&
_ignorableProps.
contains(
propName)) {
handleIgnoredProperty(
jp,
ctxt,
bean,
propName);
continue;
}
// but... others should be passed to unwrapped property deserializers
tokens.
writeFieldName(
propName);
tokens.
copyCurrentStructure(
jp);
// how about any setter? We'll get copies but...
if (
_anySetter != null) {
try {
_anySetter.
deserializeAndSet(
jp,
ctxt,
bean,
propName);
} catch (
Exception e) {
wrapAndThrow(
e,
bean,
propName,
ctxt);
}
continue;
}
}
tokens.
writeEndObject();
_unwrappedPropertyHandler.
processUnwrapped(
jp,
ctxt,
bean,
tokens);
return
bean;
}
@
SuppressWarnings("resource")
protected
Object deserializeWithUnwrapped(
JsonParser jp,
DeserializationContext ctxt,
Object bean)
throws
IOException,
JsonProcessingException
{
JsonToken t =
jp.
getCurrentToken();
if (
t ==
JsonToken.
START_OBJECT) {
t =
jp.
nextToken();
}
TokenBuffer tokens = new
TokenBuffer(
jp);
tokens.
writeStartObject();
final
Class<?>
activeView =
_needViewProcesing ?
ctxt.
getActiveView() : null;
for (;
t ==
JsonToken.
FIELD_NAME;
t =
jp.
nextToken()) {
String propName =
jp.
getCurrentName();
SettableBeanProperty prop =
_beanProperties.
find(
propName);
jp.
nextToken();
if (
prop != null) { // normal case
if (
activeView != null && !
prop.
visibleInView(
activeView)) {
jp.
skipChildren();
continue;
}
try {
prop.
deserializeAndSet(
jp,
ctxt,
bean);
} catch (
Exception e) {
wrapAndThrow(
e,
bean,
propName,
ctxt);
}
continue;
}
if (
_ignorableProps != null &&
_ignorableProps.
contains(
propName)) {
handleIgnoredProperty(
jp,
ctxt,
bean,
propName);
continue;
}
// but... others should be passed to unwrapped property deserializers
tokens.
writeFieldName(
propName);
tokens.
copyCurrentStructure(
jp);
// how about any setter? We'll get copies but...
if (
_anySetter != null) {
_anySetter.
deserializeAndSet(
jp,
ctxt,
bean,
propName);
}
}
tokens.
writeEndObject();
_unwrappedPropertyHandler.
processUnwrapped(
jp,
ctxt,
bean,
tokens);
return
bean;
}
@
SuppressWarnings("resource")
protected
Object deserializeUsingPropertyBasedWithUnwrapped(
JsonParser jp,
DeserializationContext ctxt)
throws
IOException,
JsonProcessingException
{
final
PropertyBasedCreator creator =
_propertyBasedCreator;
PropertyValueBuffer buffer =
creator.
startBuilding(
jp,
ctxt,
_objectIdReader);
TokenBuffer tokens = new
TokenBuffer(
jp);
tokens.
writeStartObject();
JsonToken t =
jp.
getCurrentToken();
for (;
t ==
JsonToken.
FIELD_NAME;
t =
jp.
nextToken()) {
String propName =
jp.
getCurrentName();
jp.
nextToken(); // to point to value
// creator property?
SettableBeanProperty creatorProp =
creator.
findCreatorProperty(
propName);
if (
creatorProp != null) {
// Last creator property to set?
Object value =
creatorProp.
deserialize(
jp,
ctxt);
if (
buffer.
assignParameter(
creatorProp.
getCreatorIndex(),
value)) {
t =
jp.
nextToken(); // to move to following FIELD_NAME/END_OBJECT
Object bean;
try {
bean =
creator.
build(
ctxt,
buffer);
} catch (
Exception e) {
wrapAndThrow(
e,
_beanType.
getRawClass(),
propName,
ctxt);
continue; // never gets here
}
// if so, need to copy all remaining tokens into buffer
while (
t ==
JsonToken.
FIELD_NAME) {
jp.
nextToken(); // to skip name
tokens.
copyCurrentStructure(
jp);
t =
jp.
nextToken();
}
tokens.
writeEndObject();
if (
bean.
getClass() !=
_beanType.
getRawClass()) {
// !!! 08-Jul-2011, tatu: Could probably support; but for now
// it's too complicated, so bail out
tokens.
close();
throw
ctxt.
mappingException("Can not create polymorphic instances with unwrapped values");
}
return
_unwrappedPropertyHandler.
processUnwrapped(
jp,
ctxt,
bean,
tokens);
}
continue;
}
// Object Id property?
if (
buffer.
readIdProperty(
propName)) {
continue;
}
// regular property? needs buffering
SettableBeanProperty prop =
_beanProperties.
find(
propName);
if (
prop != null) {
buffer.
bufferProperty(
prop,
prop.
deserialize(
jp,
ctxt));
continue;
}
/* As per [JACKSON-313], things marked as ignorable should not be
* passed to any setter
*/
if (
_ignorableProps != null &&
_ignorableProps.
contains(
propName)) {
handleIgnoredProperty(
jp,
ctxt,
handledType(),
propName);
continue;
}
tokens.
writeFieldName(
propName);
tokens.
copyCurrentStructure(
jp);
// "any property"?
if (
_anySetter != null) {
buffer.
bufferAnyProperty(
_anySetter,
propName,
_anySetter.
deserialize(
jp,
ctxt));
}
}
// We hit END_OBJECT, so:
Object bean;
try {
bean =
creator.
build(
ctxt,
buffer);
} catch (
Exception e) {
wrapInstantiationProblem(
e,
ctxt);
return null; // never gets here
}
return
_unwrappedPropertyHandler.
processUnwrapped(
jp,
ctxt,
bean,
tokens);
}
/*
/**********************************************************
/* Handling for cases where we have property/-ies with
/* external type id
/**********************************************************
*/
protected
Object deserializeWithExternalTypeId(
JsonParser jp,
DeserializationContext ctxt)
throws
IOException,
JsonProcessingException
{
if (
_propertyBasedCreator != null) {
return
deserializeUsingPropertyBasedWithExternalTypeId(
jp,
ctxt);
}
return
deserializeWithExternalTypeId(
jp,
ctxt,
_valueInstantiator.
createUsingDefault(
ctxt));
}
protected
Object deserializeWithExternalTypeId(
JsonParser jp,
DeserializationContext ctxt,
Object bean)
throws
IOException,
JsonProcessingException
{
final
Class<?>
activeView =
_needViewProcesing ?
ctxt.
getActiveView() : null;
final
ExternalTypeHandler ext =
_externalTypeIdHandler.
start();
for (;
jp.
getCurrentToken() !=
JsonToken.
END_OBJECT;
jp.
nextToken()) {
String propName =
jp.
getCurrentName();
jp.
nextToken();
SettableBeanProperty prop =
_beanProperties.
find(
propName);
if (
prop != null) { // normal case
// [JACKSON-831]: may have property AND be used as external type id:
if (
jp.
getCurrentToken().
isScalarValue()) {
ext.
handleTypePropertyValue(
jp,
ctxt,
propName,
bean);
}
if (
activeView != null && !
prop.
visibleInView(
activeView)) {
jp.
skipChildren();
continue;
}
try {
prop.
deserializeAndSet(
jp,
ctxt,
bean);
} catch (
Exception e) {
wrapAndThrow(
e,
bean,
propName,
ctxt);
}
continue;
}
// ignorable things should be ignored
if (
_ignorableProps != null &&
_ignorableProps.
contains(
propName)) {
handleIgnoredProperty(
jp,
ctxt,
bean,
propName);
continue;
}
// but others are likely to be part of external type id thingy...
if (
ext.
handlePropertyValue(
jp,
ctxt,
propName,
bean)) {
continue;
}
// if not, the usual fallback handling:
if (
_anySetter != null) {
try {
_anySetter.
deserializeAndSet(
jp,
ctxt,
bean,
propName);
} catch (
Exception e) {
wrapAndThrow(
e,
bean,
propName,
ctxt);
}
continue;
}
// Unknown: let's call handler method
handleUnknownProperty(
jp,
ctxt,
bean,
propName);
}
// and when we get this far, let's try finalizing the deal:
return
ext.
complete(
jp,
ctxt,
bean);
}
@
SuppressWarnings("resource")
protected
Object deserializeUsingPropertyBasedWithExternalTypeId(
JsonParser jp,
DeserializationContext ctxt)
throws
IOException,
JsonProcessingException
{
final
ExternalTypeHandler ext =
_externalTypeIdHandler.
start();
final
PropertyBasedCreator creator =
_propertyBasedCreator;
PropertyValueBuffer buffer =
creator.
startBuilding(
jp,
ctxt,
_objectIdReader);
TokenBuffer tokens = new
TokenBuffer(
jp);
tokens.
writeStartObject();
JsonToken t =
jp.
getCurrentToken();
for (;
t ==
JsonToken.
FIELD_NAME;
t =
jp.
nextToken()) {
String propName =
jp.
getCurrentName();
jp.
nextToken(); // to point to value
// creator property?
SettableBeanProperty creatorProp =
creator.
findCreatorProperty(
propName);
if (
creatorProp != null) {
// first: let's check to see if this might be part of value with external type id:
if (
ext.
handlePropertyValue(
jp,
ctxt,
propName,
buffer)) {
;
} else {
// Last creator property to set?
Object value =
creatorProp.
deserialize(
jp,
ctxt);
if (
buffer.
assignParameter(
creatorProp.
getCreatorIndex(),
value)) {
t =
jp.
nextToken(); // to move to following FIELD_NAME/END_OBJECT
Object bean;
try {
bean =
creator.
build(
ctxt,
buffer);
} catch (
Exception e) {
wrapAndThrow(
e,
_beanType.
getRawClass(),
propName,
ctxt);
continue; // never gets here
}
// if so, need to copy all remaining tokens into buffer
while (
t ==
JsonToken.
FIELD_NAME) {
jp.
nextToken(); // to skip name
tokens.
copyCurrentStructure(
jp);
t =
jp.
nextToken();
}
if (
bean.
getClass() !=
_beanType.
getRawClass()) {
// !!! 08-Jul-2011, tatu: Could probably support; but for now
// it's too complicated, so bail out
throw
ctxt.
mappingException("Can not create polymorphic instances with unwrapped values");
}
return
ext.
complete(
jp,
ctxt,
bean);
}
}
continue;
}
// Object Id property?
if (
buffer.
readIdProperty(
propName)) {
continue;
}
// regular property? needs buffering
SettableBeanProperty prop =
_beanProperties.
find(
propName);
if (
prop != null) {
buffer.
bufferProperty(
prop,
prop.
deserialize(
jp,
ctxt));
continue;
}
// external type id (or property that depends on it)?
if (
ext.
handlePropertyValue(
jp,
ctxt,
propName, null)) {
continue;
}
/* As per [JACKSON-313], things marked as ignorable should not be
* passed to any setter
*/
if (
_ignorableProps != null &&
_ignorableProps.
contains(
propName)) {
handleIgnoredProperty(
jp,
ctxt,
handledType(),
propName);
continue;
}
// "any property"?
if (
_anySetter != null) {
buffer.
bufferAnyProperty(
_anySetter,
propName,
_anySetter.
deserialize(
jp,
ctxt));
}
}
// We hit END_OBJECT; resolve the pieces:
try {
return
ext.
complete(
jp,
ctxt,
buffer,
creator);
} catch (
Exception e) {
wrapInstantiationProblem(
e,
ctxt);
return null; // never gets here
}
}
}