Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   package com.fasterxml.jackson.databind.deser;
   
   import java.io.IOException;
   import java.util.*;
   
  
  
Base class for BeanDeserializer.
  
  public abstract class BeanDeserializerBase
      extends StdDeserializer<Object>
          java.io.Serializable // since 2.1
  {
      private static final long serialVersionUID = 2960120955735322578L;
  
      protected final static PropertyName TEMP_PROPERTY_NAME = new PropertyName("#temporary-name");
  
      /*
      /**********************************************************
      /* Information regarding type being deserialized
      /**********************************************************
       */

    
Annotations from the bean class: used for accessing annotations during resolution (see resolve(com.fasterxml.jackson.databind.DeserializationContext)) and contextualization (see createContextual(com.fasterxml.jackson.databind.DeserializationContext,com.fasterxml.jackson.databind.BeanProperty))

Transient since annotations only used during construction.

  
      final private transient Annotations _classAnnotations;

    
Declared type of the bean this deserializer handles.
  
      final protected JavaType _beanType;

    
Requested shape from bean class annotations.
  
      final protected JsonFormat.Shape _serializationShape;
      
      /*
      /**********************************************************
      /* Configuration for creating value instance
      /**********************************************************
       */

    
Object that handles details of constructing initial bean value (to which bind data to), unless instance is passed (via updateValue())
  
      protected final ValueInstantiator _valueInstantiator;
    
    
Deserializer that is used iff delegate-based creator is to be used for deserializing from JSON Object.
  
      protected JsonDeserializer<Object_delegateDeserializer;
    
    
If the bean needs to be instantiated using constructor or factory method that takes one or more named properties as argument(s), this creator is used for instantiation. This value gets resolved during general resolution.
  
      protected PropertyBasedCreator _propertyBasedCreator;

    
Flag that is set to mark "non-standard" cases; where either we use one of non-default creators, or there are unwrapped values to consider.
  
      protected boolean _nonStandardCreation;

    
Flag that indicates that no "special features" whatsoever are enabled, so the simplest processing is possible.
 
     protected boolean _vanillaProcessing;
 
     /*
     /**********************************************************
     /* Property information, setters
     /**********************************************************
      */

    
Mapping of property names to properties, built when all properties to use have been successfully resolved.
 
     final protected BeanPropertyMap _beanProperties;
    
    
List of com.fasterxml.jackson.databind.deser.impl.ValueInjectors, if any injectable values are expected by the bean; otherwise null. This includes injectors used for injecting values via setters and fields, but not ones passed through constructor parameters.
 
     final protected ValueInjector[] _injectables;
    
    
Fallback setter used for handling any properties that are not mapped to regular setters. If setter is not null, it will be called once for each such property.
 
     protected SettableAnyProperty _anySetter;

    
In addition to properties that are set, we will also keep track of recognized but ignorable properties: these will be skipped without errors or warnings.
 
     final protected HashSet<String_ignorableProps;

    
Flag that can be set to ignore and skip unknown properties. If set, will not throw an exception for unknown properties.
 
     final protected boolean _ignoreAllUnknown;

    
Flag that indicates that some aspect of deserialization depends on active view used (if any)
 
     final protected boolean _needViewProcesing;
    
    
We may also have one or more back reference fields (usually zero or one).
 
     final protected Map<StringSettableBeanProperty_backRefs;
     
     /*
     /**********************************************************
     /* Related handlers
     /**********************************************************
      */

    
Lazily constructed map used to contain deserializers needed for polymorphic subtypes. Note that this is only needed for polymorphic types, that is, when the actual type is not statically known. For other types this remains null.
 
     protected transient HashMap<ClassKeyJsonDeserializer<Object>> _subDeserializers;

    
If one of properties has "unwrapped" value, we need separate helper object
 
Handler that we need iff any of properties uses external type id.
 
     protected ExternalTypeHandler _externalTypeIdHandler;

    
If an Object Id is to be used for value handled by this deserializer, this reader is used for handling.
 
     protected final ObjectIdReader _objectIdReader;
 
     /*
     /**********************************************************
     /* Life-cycle, construction, initialization
     /**********************************************************
      */

    
Constructor used when initially building a deserializer instance, given a BeanDeserializerBuilder that contains configuration.
 
     protected BeanDeserializerBase(BeanDeserializerBuilder builder,
             BeanDescription beanDesc,
             BeanPropertyMap propertiesMap<StringSettableBeanPropertybackRefs,
             HashSet<StringignorablePropsboolean ignoreAllUnknown,
             boolean hasViews)
     {
         super(beanDesc.getType());
 
         AnnotatedClass ac = beanDesc.getClassInfo();
          = ac.getAnnotations();       
          = beanDesc.getType();
          = builder.getValueInstantiator();
         
          = properties;
          = backRefs;
          = ignorableProps;
          = ignoreAllUnknown;
 
          = builder.getAnySetter();
         List<ValueInjectorinjectables = builder.getInjectables();
          = (injectables == null || injectables.isEmpty()) ? null
                 : injectables.toArray(new ValueInjector[injectables.size()]);
          = builder.getObjectIdReader();
          = ( != null)
             || .canCreateUsingDelegate()
             || .canCreateFromObjectWith()
             || !.canCreateUsingDefault()
             ;
 
         // Any transformation we may need to apply?
         JsonFormat.Value format = beanDesc.findExpectedFormat(null);
          = (format == null) ? null : format.getShape();
 
          = hasViews;
                 && ( == null)
                 && !
                 // also, may need to reorder stuff if we expect Object Id:
                 && ( == null)
                 ;
     }
 
     {
         this(srcsrc._ignoreAllUnknown);
     }
 
     protected BeanDeserializerBase(BeanDeserializerBase srcboolean ignoreAllUnknown)
     {
         super(src._beanType);
         
          = src._classAnnotations;
          = src._beanType;
         
          = src._valueInstantiator;
          = src._delegateDeserializer;
          = src._propertyBasedCreator;
         
          = src._beanProperties;
          = src._backRefs;
          = src._ignorableProps;
          = ignoreAllUnknown;
          = src._anySetter;
          = src._injectables;
          = src._objectIdReader;
         
          = src._nonStandardCreation;
          = src._unwrappedPropertyHandler;
          = src._needViewProcesing;
          = src._serializationShape;
 
          = src._vanillaProcessing;
     }
  
     protected BeanDeserializerBase(BeanDeserializerBase srcNameTransformer unwrapper)
     {
         super(src._beanType);
 
          = src._classAnnotations;
          = src._beanType;
         
          = src._valueInstantiator;
          = src._delegateDeserializer;
          = src._propertyBasedCreator;
 
          = src._backRefs;
          = src._ignorableProps;
          = (unwrapper != null) || src._ignoreAllUnknown;
          = src._anySetter;
          = src._injectables;
          = src._objectIdReader;
 
          = src._nonStandardCreation;
         UnwrappedPropertyHandler uph = src._unwrappedPropertyHandler;
 
         if (unwrapper != null) {
             // delegate further unwraps, if any
             if (uph != null) { // got handler, delegate
                 uph = uph.renameAll(unwrapper);
             }
             // and handle direct unwrapping as well:
              = src._beanProperties.renameAll(unwrapper);
         } else {
              = src._beanProperties;
         }
          = uph;
          = src._needViewProcesing;
          = src._serializationShape;
 
         // probably adds a twist, so:
          = false;
     }
 
     {
         super(src._beanType);
         
          = src._classAnnotations;
          = src._beanType;
         
          = src._valueInstantiator;
          = src._delegateDeserializer;
          = src._propertyBasedCreator;
         
          = src._backRefs;
          = src._ignorableProps;
          = src._ignoreAllUnknown;
          = src._anySetter;
          = src._injectables;
         
          = src._nonStandardCreation;
          = src._unwrappedPropertyHandler;
          = src._needViewProcesing;
          = src._serializationShape;
 
         // then actual changes:
          = oir;
 
         if (oir == null) {
              = src._beanProperties;
              = src._vanillaProcessing;
         } else {
             /* 18-Nov-2012, tatu: May or may not have annotations for id property;
              *   but no easy access. But hard to see id property being optional,
              *   so let's consider required at this point.
              */
             ObjectIdValueProperty idProp = new ObjectIdValueProperty(oir.);
              = src._beanProperties.withProperty(idProp);
              = false;
         }
     }
 
     public BeanDeserializerBase(BeanDeserializerBase srcHashSet<StringignorableProps)
     {
         super(src._beanType);
         
          = src._classAnnotations;
          = src._beanType;
         
          = src._valueInstantiator;
          = src._delegateDeserializer;
          = src._propertyBasedCreator;
         
          = src._backRefs;
          = ignorableProps;
          = src._ignoreAllUnknown;
          = src._anySetter;
          = src._injectables;
         
          = src._nonStandardCreation;
          = src._unwrappedPropertyHandler;
          = src._needViewProcesing;
          = src._serializationShape;
 
          = src._vanillaProcessing;
          = src._objectIdReader;
          = src._beanProperties;
     }
     
     @Override
     public abstract JsonDeserializer<ObjectunwrappingDeserializer(NameTransformer unwrapper);
 
     public abstract BeanDeserializerBase withObjectIdReader(ObjectIdReader oir);
 
     public abstract BeanDeserializerBase withIgnorableProperties(HashSet<StringignorableProps);

    
Fluent factory for creating a variant that can handle POJO output as a JSON Array. Implementations may ignore this request if no such input is possible.

Since:
2.1
 
     protected abstract BeanDeserializerBase asArrayDeserializer();
 
     /*
     /**********************************************************
     /* Validation, post-processing
     /**********************************************************
      */

    
Method called to finalize setup of this deserializer, after deserializer itself has been registered. This is needed to handle recursive and transitive dependencies.
 
     @Override
     public void resolve(DeserializationContext ctxt)
         throws JsonMappingException
     {
         ExternalTypeHandler.Builder extTypes = null;
         // if ValueInstantiator can use "creator" approach, need to resolve it here...
         if (.canCreateFromObjectWith()) {
             SettableBeanProperty[] creatorProps = .getFromObjectArguments(ctxt.getConfig());
              = PropertyBasedCreator.construct(ctxtcreatorProps);
             // also: need to try to resolve 'external' type ids...
             for (SettableBeanProperty prop : .properties()) {
                 if (prop.hasValueTypeDeserializer()) {
                     TypeDeserializer typeDeser = prop.getValueTypeDeserializer();
                     if (typeDeser.getTypeInclusion() == ..) {
                         if (extTypes == null) {
                             extTypes = new ExternalTypeHandler.Builder();
                         }
                         extTypes.addExternal(proptypeDeser);
                     }
                 }
             }
         }
 
         UnwrappedPropertyHandler unwrapped = null;
 
         for (SettableBeanProperty origProp : ) {
             SettableBeanProperty prop = origProp;
             // May already have deserializer from annotations, if so, skip:
             if (!prop.hasValueDeserializer()) {
                 // [Issue#125]: allow use of converters
                 JsonDeserializer<?> deser = findConvertingDeserializer(ctxtprop);
                 if (deser == null) {
                     deser = findDeserializer(ctxtprop.getType(), prop);
                 }
                 prop = prop.withValueDeserializer(deser);
             } else { // may need contextual version
                 JsonDeserializer<Objectdeser = prop.getValueDeserializer();
                 /* Important! This is the only place where actually handle "primary"
                  * property deserializers -- call is different from other places.
                  */
                 JsonDeserializer<?> cd = ctxt.handlePrimaryContextualization(deserprop);
                 if (cd != deser) {
                     prop = prop.withValueDeserializer(cd);
                 }
             }
             // [JACKSON-235]: need to link managed references with matching back references
             prop = _resolveManagedReferenceProperty(ctxtprop);
             // [JACKSON-132]: support unwrapped values (via @JsonUnwrapped)
             SettableBeanProperty u = _resolveUnwrappedProperty(ctxtprop);
             if (u != null) {
                 prop = u;
                 if (unwrapped == null) {
                     unwrapped = new UnwrappedPropertyHandler();
                 }
                 unwrapped.addProperty(prop);
                 continue;
             }
             // [JACKSON-594]: non-static inner classes too:
             prop = _resolveInnerClassValuedProperty(ctxtprop);
             if (prop != origProp) {
                 .replace(prop);
             }
             
             /* one more thing: if this property uses "external property" type inclusion
              * (see [JACKSON-453]), it needs different handling altogether
              */
             if (prop.hasValueTypeDeserializer()) {
                 TypeDeserializer typeDeser = prop.getValueTypeDeserializer();
                 if (typeDeser.getTypeInclusion() == ..) {
                     if (extTypes == null) {
                         extTypes = new ExternalTypeHandler.Builder();
                     }
                     extTypes.addExternal(proptypeDeser);
                     // In fact, remove from list of known properties to simplify later handling
                     .remove(prop);
                     continue;
                 }
             }
         }
 
         // "any setter" may also need to be resolved now
         if ( != null && !.hasValueDeserializer()) {
                     .getType(), .getProperty()));
         }
 
         // as well as delegate-based constructor:
         if (.canCreateUsingDelegate()) {
             JavaType delegateType = .getDelegateType(ctxt.getConfig());
             if (delegateType == null) {
                 throw new IllegalArgumentException("Invalid delegate-creator definition for "+
                         +": value instantiator ("+.getClass().getName()
                         +") returned true for 'canCreateUsingDelegate()', but null for 'getDelegateType()'");
             }
             AnnotatedWithParams delegateCreator = .getDelegateCreator();
             // Need to create a temporary property to allow contextual deserializers:
             BeanProperty.Std property = new BeanProperty.Std(,
                     delegateTypenulldelegateCreator,
                     .);
              = findDeserializer(ctxtdelegateTypeproperty);
         }
         
         if (extTypes != null) {
              = extTypes.build();
             // we consider this non-standard, to offline handling
              = true;
         }
         
          = unwrapped;
         if (unwrapped != null) { // we consider this non-standard, to offline handling
              = true;
         }
 
         // may need to disable vanilla processing, if unwrapped handling was enabled...
     }

    
Helper method that can be used to see if specified property is annotated to indicate use of a converter for property value (in case of container types, it is container type itself, not key or content type).

Since:
2.2
 
             SettableBeanProperty prop)
         throws JsonMappingException
     {
         final AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
         if (intr != null) {
             Object convDef = intr.findDeserializationConverter(prop.getMember());
             if (convDef != null) {
                 Converter<Object,Objectconv = ctxt.converterInstance(prop.getMember(), convDef);
                 JavaType delegateType = conv.getInputType(ctxt.getTypeFactory());
                 JsonDeserializer<?> ser = ctxt.findContextualValueDeserializer(delegateTypeprop);
                 return new StdDelegatingDeserializer<Object>(convdelegateTypeser);
             }
         }
         return null;
     }
    
    
Although most of post-processing is done in resolve(), we only get access to referring property's annotations here; and this is needed to support per-property ObjectIds. We will also consider Shape transformations (read from Array) at this point, since it may come from either Class definition or property.
 
     @Override
             BeanProperty propertythrows JsonMappingException
     {
         ObjectIdReader oir = ;
         String[] ignorals = null;
         
         // First: may have an override for Object Id:
         final AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
         final AnnotatedMember accessor = (property == null || intr == null)
                 ? null : property.getMember();
         if (property != null && intr != null) {
             ignorals = intr.findPropertiesToIgnore(accessor);
             ObjectIdInfo objectIdInfo = intr.findObjectIdInfo(accessor);
             if (objectIdInfo != null) { // some code duplication here as well (from BeanDeserializerFactory)
                 // 2.1: allow modifications by "id ref" annotations as well:
                 objectIdInfo = intr.findObjectReferenceInfo(accessorobjectIdInfo);
                 
                 Class<?> implClass = objectIdInfo.getGeneratorType();
                 // Property-based generator is trickier
                 JavaType idType;
                 SettableBeanProperty idProp;
                 ObjectIdGenerator<?> idGen;
                 if (implClass == ObjectIdGenerators.PropertyGenerator.class) {
                     PropertyName propName = objectIdInfo.getPropertyName();
                     idProp = findProperty(propName);
                     if (idProp == null) {
                         throw new IllegalArgumentException("Invalid Object Id definition for "
                                 +handledType().getName()+": can not find property with name '"+propName+"'");
                     }
                     idType = idProp.getType();
                     idGen = new PropertyBasedObjectIdGenerator(objectIdInfo.getScope());
                 } else { // other types need to be simpler
                     JavaType type = ctxt.constructType(implClass);
                     idType = ctxt.getTypeFactory().findTypeParameters(typeObjectIdGenerator.class)[0];
                     idProp = null;
                     idGen = ctxt.objectIdGeneratorInstance(accessorobjectIdInfo);
                 }
                 JsonDeserializer<?> deser = ctxt.findRootValueDeserializer(idType);
                 oir = ObjectIdReader.construct(idTypeobjectIdInfo.getPropertyName(),
                 		idGendeseridProp);
             }
         }
         // either way, need to resolve serializer:
         BeanDeserializerBase contextual = this;
         if (oir != null && oir != ) {
             contextual = contextual.withObjectIdReader(oir);
         }
         // And possibly add more properties to ignore
         if (ignorals != null && ignorals.length != 0) {
             HashSet<StringnewIgnored = ArrayBuilders.setAndArray(contextual._ignorablePropsignorals);
             contextual = contextual.withIgnorableProperties(newIgnored);
         }
 
         // One more thing: are we asked to serialize POJO as array?
         JsonFormat.Shape shape = null;
         if (accessor != null) {
             JsonFormat.Value format = intr.findFormat((Annotatedaccessor);
 
             if (format != null) {
                 shape = format.getShape();
             }
         }
         if (shape == null) {
             shape = ;
         }
         if (shape == ..) {
             contextual = contextual.asArrayDeserializer();
         }
         return contextual;
     }

    
Helper method called to see if given property is part of 'managed' property pair (managed + back reference), and if so, handle resolution details.
 
             SettableBeanProperty prop)
     {
         String refName = prop.getManagedReferenceName();
         if (refName == null) {
             return prop;
         }
         JsonDeserializer<?> valueDeser = prop.getValueDeserializer();
         SettableBeanProperty backProp = valueDeser.findBackReference(refName);
         if (backProp == null) {
             throw new IllegalArgumentException("Can not handle managed/back reference '"+refName+"': no back reference property found from type "
                     +prop.getType());
         }
         // also: verify that type is compatible
         JavaType referredType = ;
         JavaType backRefType = backProp.getType();
         boolean isContainer = prop.getType().isContainerType();
         if (!backRefType.getRawClass().isAssignableFrom(referredType.getRawClass())) {
             throw new IllegalArgumentException("Can not handle managed/back reference '"+refName+"': back reference type ("
                     +backRefType.getRawClass().getName()+") not compatible with managed type ("
                     +referredType.getRawClass().getName()+")");
         }
         return new ManagedReferenceProperty(proprefNamebackProp,
                 isContainer);
     }

    
Helper method called to see if given property might be so-called unwrapped property: these require special handling.
 
             SettableBeanProperty prop)
     {
         AnnotatedMember am = prop.getMember();
         if (am != null) {
             NameTransformer unwrapper = ctxt.getAnnotationIntrospector().findUnwrappingNameTransformer(am);
             if (unwrapper != null) {
                 JsonDeserializer<Objectorig = prop.getValueDeserializer();
                 JsonDeserializer<Objectunwrapping = orig.unwrappingDeserializer(unwrapper);
                 if (unwrapping != orig && unwrapping != null) {
                     // might be cleaner to create new instance; but difficult to do reliably, so:
                     return prop.withValueDeserializer(unwrapping);
                 }
             }
         }
         return null;
     }
    
    
Helper method that will handle gruesome details of dealing with properties that have non-static inner class as value...
 
             SettableBeanProperty prop)
     {            
         /* Should we encounter a property that has non-static inner-class
          * as value, we need to add some more magic to find the "hidden" constructor...
          */
         JsonDeserializer<Objectdeser = prop.getValueDeserializer();
         // ideally wouldn't rely on it being BeanDeserializerBase; but for now it'll have to do
         if (deser instanceof BeanDeserializerBase) {
             BeanDeserializerBase bd = (BeanDeserializerBasedeser;
             ValueInstantiator vi = bd.getValueInstantiator();
             if (!vi.canCreateUsingDefault()) { // no default constructor
                 Class<?> valueClass = prop.getType().getRawClass();
                 Class<?> enclosing = ClassUtil.getOuterClass(valueClass);
                 // and is inner class of the bean class...
                 if (enclosing != null && enclosing == .getRawClass()) {
                     for (Constructor<?> ctor : valueClass.getConstructors()) {
                         Class<?>[] paramTypes = ctor.getParameterTypes();
                         if (paramTypes.length == 1 && paramTypes[0] == enclosing) {
                             if (ctxt.getConfig().canOverrideAccessModifiers()) {
                                 ClassUtil.checkAndFixAccess(ctor);
                             }
                             return new InnerClassProperty(propctor);
                         }
                     }
                 }
             }
         }
         return prop;
     }
 
     /*
     /**********************************************************
     /* Public accessors
     /**********************************************************
      */
 
     @Override
     public boolean isCachable() { return true; }
 
     @Override
     public Class<?> handledType() {
         return .getRawClass();
     }
    
    
Overridden to return true for those instances that are handling value for which Object Identity handling is enabled (either via value type or referring property).
 
     @Override
     public ObjectIdReader getObjectIdReader() {
         return ;
     }
     
     public boolean hasProperty(String propertyName) {
         return .find(propertyName) != null;
     }
 
     public boolean hasViews() {
         return ;
     }
    
    
Accessor for checking number of deserialized properties.
 
     public int getPropertyCount() { 
         return .size();
     }
 
     @Override
     public Collection<ObjectgetKnownPropertyNames() {
         ArrayList<Objectnames = new ArrayList<Object>();
         for (SettableBeanProperty prop : ) {
             names.add(prop.getName());
         }
         return names;
     }

    

Deprecated:
Since 2.3, use handledType() instead
 
     @Deprecated
     public final Class<?> getBeanClass() { return .getRawClass(); }
 
     @Override
     public JavaType getValueType() { return ; }

    
Accessor for iterating over properties this deserializer uses; with the exception that properties passed via Creator methods (specifically, "property-based constructor") are not included, but can be accessed separate by calling creatorProperties()
 
     {
         if ( == null) {
             throw new IllegalStateException("Can only call after BeanDeserializer has been resolved");
         }
         return .iterator();
     }

    
Accessor for finding properties that represents values to pass through property-based creator method (constructor or factory method)

Since:
2.0
 
     {
         if ( == null) {
             return Collections.<SettableBeanProperty>emptyList().iterator();
         }
         return .properties().iterator();
     }
 
     public SettableBeanProperty findProperty(PropertyName propertyName)
     {
         // TODO: start matching full name?
         return findProperty(propertyName.getSimpleName());
     }
    
    
Accessor for finding the property with given name, if POJO has one. Name used is the external name, i.e. name used in external data representation (JSON).

Since:
2.0
 
     public SettableBeanProperty findProperty(String propertyName)
     {
         SettableBeanProperty prop = ( == null) ?
                 null : .find(propertyName);
         if (prop == null &&  != null) {
             prop = .findCreatorProperty(propertyName);
         }
         return prop;
     }

    
Alternate find method that tries to locate a property with given property index. Note that access by index is not necessarily faster than by name, since properties are not directly indexable; however, for most instances difference is not significant as number of properties is low.

Since:
2.3
 
     public SettableBeanProperty findProperty(int propertyIndex)
     {
         SettableBeanProperty prop = ( == null) ?
                 null : .find(propertyIndex);
         if (prop == null &&  != null) {
             prop = .findCreatorProperty(propertyIndex);
         }
         return prop;
     }
    
    
Method needed by BeanDeserializerFactory to properly link managed- and back-reference pairs.
 
     @Override
     public SettableBeanProperty findBackReference(String logicalName)
     {
         if ( == null) {
             return null;
         }
         return .get(logicalName);
     }
 
         return ;
     }
 
     /*
     /**********************************************************
     /* Mutators
     /**********************************************************
      */

    
Method that can be used to replace an existing property with a modified one.

NOTE: only ever use this method if you know what you are doing; incorrect usage can break deserializer.

Parameters:
original Property to replace
replacement Property to replace it with
Since:
2.1
 
     public void replaceProperty(SettableBeanProperty original,
             SettableBeanProperty replacement)
     {
         .replace(replacement);
     }
 
     /*
     /**********************************************************
     /* Partial deserializer implementation
     /**********************************************************
      */

    
General version used when handling needs more advanced features.
 
     public abstract Object deserializeFromObject(JsonParser jpDeserializationContext ctxt)
         throws IOExceptionJsonProcessingException;
 
     @Override
     public final Object deserializeWithType(JsonParser jpDeserializationContext ctxt,
             TypeDeserializer typeDeserializer)
         throws IOExceptionJsonProcessingException
     {
         // 16-Feb-2012, tatu: ObjectId may be used as well... need to check that first
         if ( != null) {
             // 05-Aug-2013, tatu: May use native Object Id
             if (jp.canReadObjectId()) {
                 Object id = jp.getObjectId();
                 if (id != null) {
                     Object ob = typeDeserializer.deserializeTypedFromObject(jpctxt);
                     return _handleTypedObjectId(jpctxtobid);
                 }
             }
             // or, Object Ids Jackson explicitly sets
             JsonToken t = jp.getCurrentToken();
             // for now (2.2.x) we only allow scalar types (Strings, integral numbers):
             // NOTE: may  need to allow handling of structured values in future for JSOG
             if (t != null && t.isScalarValue()) {
                 return deserializeFromObjectId(jpctxt);
             }
         }
         // In future could check current token... for now this should be enough:
         return typeDeserializer.deserializeTypedFromObject(jpctxt);
     }

    
Offlined method called to handle "native" Object Id that has been read and known to be associated with given deserialized POJO.

Since:
2.3
 
             Object pojoObject rawId)
         throws IOExceptionJsonProcessingException
     {
         /* 07-Aug-2013, tatu: One more challenge: type of id may not be type
          *   of property we are expecting later on; specifically, numeric ids
          *   vs Strings.
          */
         JsonDeserializer<ObjectidDeser = .getDeserializer();
         final Object id;
 
         // Ok, this is bit ridiculous; let's see if conversion is needed:
         if (idDeser.handledType() == rawId.getClass()) {
             // nope: already same type
             id = rawId;
         } else {
             id = _convertObjectId(jpctxtrawIdidDeser);
         }
 
         ReadableObjectId roid = ctxt.findObjectId(id.);
         roid.bindItem(pojo);
         // also: may need to set a property value as well
         SettableBeanProperty idProp = .;
         if (idProp != null) {
             return idProp.setAndReturn(pojoid);
         }
         return pojo;
     }

    
Helper method we need to do necessary conversion from whatever native object id type is, into declared type that Jackson internals expect. This may be simple cast (for String ids), or something more complicated; in latter case we may need to create bogus content buffer to allow use of id deserializer.

Since:
2.3
 
     @SuppressWarnings("resource"// TokenBuffers don't need close, nor parser thereof
     protected Object _convertObjectId(JsonParser jpDeserializationContext ctxt,
             Object rawIdJsonDeserializer<ObjectidDeser)
         throws IOExceptionJsonProcessingException
     {
         TokenBuffer buf = new TokenBuffer(jp);
         if (rawId instanceof String) {
             buf.writeString((StringrawId);
         } else if (rawId instanceof Long) {
             buf.writeNumber(((LongrawId).longValue());
         } else if (rawId instanceof Integer) {
             buf.writeNumber(((IntegerrawId).intValue());
         } else {
             // should we worry about UUIDs? They should be fine, right?
             buf.writeObject(rawId);
         }
         JsonParser bufParser = buf.asParser();
         bufParser.nextToken();
         return idDeser.deserialize(bufParserctxt);
     }
 
     // NOTE: currently only used by standard BeanDeserializer (not Builder-based)
     
Alternative deserialization method used when we expect to see Object Id; if so, we will need to ensure that the Id is seen before anything else, to ensure that it is available for solving references, even if JSON itself is not ordered that way. This may require buffering in some cases, but usually just a simple lookup to ensure that ordering is correct.
 
     @SuppressWarnings("resource")
            throws IOExceptionJsonProcessingException
    {
        final String idPropName = ..getSimpleName();
        // First, the simple case: we point to the Object Id property
        if (idPropName.equals(jp.getCurrentName())
                // 05-Aug-2013, tatu: Or might point to a native Object Id
                || jp.canReadObjectId()) {
            return deserializeFromObject(jpctxt);
        }
        // otherwise need to reorder things
        TokenBuffer tmpBuffer = new TokenBuffer(jp);
        TokenBuffer mergedBuffer = null;
        for (; jp.getCurrentToken() != .jp.nextToken()) {
            String propName = jp.getCurrentName();
            // when we match the id property, can start merging
            if (mergedBuffer == null) {
                if (idPropName.equals(propName)) {
                    mergedBuffer = new TokenBuffer(jp);
                    mergedBuffer.writeFieldName(propName);
                    jp.nextToken();
                    mergedBuffer.copyCurrentStructure(jp);
                    mergedBuffer.append(tmpBuffer);
                    tmpBuffer = null;
                } else {
                    tmpBuffer.writeFieldName(propName);
                    jp.nextToken();
                    tmpBuffer.copyCurrentStructure(jp);
                }
            } else {
                mergedBuffer.writeFieldName(propName);
                jp.nextToken();
                mergedBuffer.copyCurrentStructure(jp);
            }
        }
        // note: we really should get merged buffer (and if not, that is likely error), but
        // for now let's allow missing case as well. Will be caught be a later stage...
        TokenBuffer buffer = (mergedBuffer == null) ? tmpBuffer : mergedBuffer;
        buffer.writeEndObject();
        // important: need to advance to point to first FIELD_NAME:
        JsonParser mergedParser = buffer.asParser();
        mergedParser.nextToken();
        return deserializeFromObject(mergedParserctxt);
    }
    
    
Method called in cases where it looks like we got an Object Id to parse and use as a reference.
        throws IOExceptionJsonProcessingException
    {
        Object id = .readObjectReference(jpctxt);
        ReadableObjectId roid = ctxt.findObjectId(id.);
        // do we have it resolved?
        Object pojo = roid.item;
        if (pojo == null) { // not yet; should wait...
            throw new IllegalStateException("Could not resolve Object Id ["+id+"] (for "
                    ++") -- unresolved forward-reference?");
        }
        return pojo;
    }
            DeserializationContext ctxt)
        throws IOExceptionJsonProcessingException
    {        
        if ( != null) {
            return .createUsingDelegate(ctxt,
                    .deserialize(jpctxt));
        }
        if ( != null) {
            return _deserializeUsingPropertyBased(jpctxt);
        }
        // should only occur for abstract types...
        if (.isAbstract()) {
            throw JsonMappingException.from(jp"Can not instantiate abstract type "+
                    +" (need to add/enable type information?)");
        }
        throw JsonMappingException.from(jp"No suitable constructor found for type "
                ++": can not instantiate from JSON object (need to add/enable type information?)");
    }
    protected abstract Object _deserializeUsingPropertyBased(final JsonParser jp,
            final DeserializationContext ctxt)
        throws IOExceptionJsonProcessingException;
    @SuppressWarnings("incomplete-switch")
        throws IOExceptionJsonProcessingException
    {
        // First things first: id Object Id is used, most likely that's it
        if ( != null) {
            return deserializeFromObjectId(jpctxt);
        }
        switch (jp.getNumberType()) {
        case :
            if ( != null) {
                if (!.canCreateFromInt()) {
                    Object bean = .createUsingDelegate(ctxt.deserialize(jpctxt));
                    if ( != null) {
                        injectValues(ctxtbean);
                    }
                    return bean;
                }
            }
            return .createFromInt(ctxtjp.getIntValue());
        case :
            if ( != null) {
                if (!.canCreateFromInt()) {
                    Object bean = .createUsingDelegate(ctxt.deserialize(jpctxt));
                    if ( != null) {
                        injectValues(ctxtbean);
                    }
                    return bean;
                }
            }
            return .createFromLong(ctxtjp.getLongValue());
        }
        // actually, could also be BigInteger, so:
        if ( != null) {
            Object bean = .createUsingDelegate(ctxt.deserialize(jpctxt));
            if ( != null) {
                injectValues(ctxtbean);
            }
            return bean;
        }
        throw ctxt.instantiationException(getBeanClass(), "no suitable creator method found to deserialize from JSON integer number");
    }
        throws IOExceptionJsonProcessingException
    {
        // First things first: id Object Id is used, most likely that's it
        if ( != null) {
            return deserializeFromObjectId(jpctxt);
        }
        
        /* Bit complicated if we have delegating creator; may need to use it,
         * or might not...
         */
        if ( != null) {
            if (!.canCreateFromString()) {
                Object bean = .createUsingDelegate(ctxt.deserialize(jpctxt));
                if ( != null) {
                    injectValues(ctxtbean);
                }
                return bean;
            }
        }
        return .createFromString(ctxtjp.getText());
    }

    
Method called to deserialize POJO value from a JSON floating-point number.
    @SuppressWarnings("incomplete-switch")
        throws IOExceptionJsonProcessingException
    {
        switch (jp.getNumberType()) {
        case // no separate methods for taking float...
        case :
            if ( != null) {
                if (!.canCreateFromDouble()) {
                    Object bean = .createUsingDelegate(ctxt.deserialize(jpctxt));
                    if ( != null) {
                        injectValues(ctxtbean);
                    }
                    return bean;
                }
            }
            return .createFromDouble(ctxtjp.getDoubleValue());
        }
        // actually, could also be BigDecimal, so:
        if ( != null) {