/**
   * Method called by {@link BeanDeserializerFactory} to see if there might be a standard
   * deserializer registered for given type.
   */
  @SuppressWarnings("unchecked")
  protected JsonDeserializer<Object> findStdDeserializer(
      DeserializationConfig config, JavaType type) throws JsonMappingException {
    Class<?> cls = type.getRawClass();
    // note: we do NOT check for custom deserializers here; that's for sub-class to do
    JsonDeserializer<Object> deser = _simpleDeserializers.get(new ClassKey(cls));
    if (deser != null) {
      return deser;
    }

    // [JACKSON-283]: AtomicReference is a rather special type...
    if (AtomicReference.class.isAssignableFrom(cls)) {
      // Must find parameterization
      TypeFactory tf = config.getTypeFactory();
      JavaType[] params = tf.findTypeParameters(type, AtomicReference.class);
      JavaType referencedType;
      if (params == null || params.length < 1) { // untyped (raw)
        referencedType = TypeFactory.unknownType();
      } else {
        referencedType = params[0];
      }

      JsonDeserializer<?> d2 = new JdkDeserializers.AtomicReferenceDeserializer(referencedType);
      return (JsonDeserializer<Object>) d2;
    }
    // [JACKSON-386]: External/optional type handlers are handled somewhat differently
    JsonDeserializer<?> d = optionalHandlers.findDeserializer(type, config);
    if (d != null) {
      return (JsonDeserializer<Object>) d;
    }
    return null;
  }
 protected boolean _useStatic(
     SerializerProvider provider, BeanProperty property, JavaType referredType) {
   // First: no serializer for `Object.class`, must be dynamic
   if (referredType.isJavaLangObject()) {
     return false;
   }
   // but if type is final, might as well fetch
   if (referredType.isFinal()) { // or should we allow annotation override? (only if requested...)
     return true;
   }
   // also: if indicated by typing, should be considered static
   if (referredType.useStaticType()) {
     return true;
   }
   // if neither, maybe explicit annotation?
   AnnotationIntrospector intr = provider.getAnnotationIntrospector();
   if ((intr != null) && (property != null)) {
     Annotated ann = property.getMember();
     if (ann != null) {
       JsonSerialize.Typing t = intr.findSerializationTyping(property.getMember());
       if (t == JsonSerialize.Typing.STATIC) {
         return true;
       }
       if (t == JsonSerialize.Typing.DYNAMIC) {
         return false;
       }
     }
   }
   // and finally, may be forced by global static typing (unlikely...)
   return provider.isEnabled(MapperFeature.USE_STATIC_TYPING);
 }
  protected BeanPropertyWriter _constructVirtualProperty(
      JsonAppend.Prop prop, MapperConfig<?> config, AnnotatedClass ac) {
    PropertyMetadata metadata =
        prop.required() ? PropertyMetadata.STD_REQUIRED : PropertyMetadata.STD_OPTIONAL;
    PropertyName propName = _propertyName(prop.name(), prop.namespace());
    JavaType type = config.constructType(prop.type());
    // now, then, we need a placeholder for member (no real Field/Method):
    AnnotatedMember member =
        new VirtualAnnotatedMember(
            ac, ac.getRawType(), propName.getSimpleName(), type.getRawClass());
    // and with that and property definition
    SimpleBeanPropertyDefinition propDef =
        SimpleBeanPropertyDefinition.construct(config, member, propName, metadata, prop.include());

    Class<?> implClass = prop.value();

    HandlerInstantiator hi = config.getHandlerInstantiator();
    VirtualBeanPropertyWriter bpw =
        (hi == null) ? null : hi.virtualPropertyWriterInstance(config, implClass);
    if (bpw == null) {
      bpw =
          (VirtualBeanPropertyWriter)
              ClassUtil.createInstance(implClass, config.canOverrideAccessModifiers());
    }

    // one more thing: give it necessary contextual information
    return bpw.withConfig(config, ac, propDef, type);
  }
 @Override
 public JsonArrayFormatVisitor expectArrayFormat(JavaType type) throws JsonMappingException {
   serializerProvider
       .findValueSerializer(type.getContentType())
       .acceptJsonFormatVisitor(createSubtraverser(baseName), type.getContentType());
   return new JsonArrayFormatVisitor.Base(serializerProvider);
 }
  /** Method that will construct a regular bean property setter using the given setter method. */
  protected SettableBeanProperty constructSetterlessProperty(
      DeserializationContext ctxt, BeanDescription beanDesc, BeanPropertyDefinition propDef)
      throws JsonMappingException {
    final AnnotatedMethod getter = propDef.getGetter();
    // need to ensure it is callable now:
    if (ctxt.canOverrideAccessModifiers()) {
      getter.fixAccess();
    }

    /* 26-Jan-2012, tatu: Alas, this complication is still needed to handle
     *   (or at least work around) local type declarations...
     */
    JavaType type = getter.getType(beanDesc.bindingsForBeanType());
    /* First: does the Method specify the deserializer to use?
     * If so, let's use it.
     */
    JsonDeserializer<Object> propDeser = findDeserializerFromAnnotation(ctxt, getter);
    type = modifyTypeByAnnotation(ctxt, getter, type);
    TypeDeserializer typeDeser = type.getTypeHandler();
    SettableBeanProperty prop =
        new SetterlessProperty(propDef, type, typeDeser, beanDesc.getClassAnnotations(), getter);
    if (propDeser != null) {
      prop = prop.withValueDeserializer(propDeser);
    }
    return prop;
  }
  public ValueInstantiator constructValueInstantiator(DeserializationConfig config) {
    JavaType delegateType;
    boolean maybeVanilla = !_hasNonDefaultCreator;

    if (maybeVanilla || (_creators[C_DELEGATE] == null)) {
      delegateType = null;
    } else {
      // need to find type...
      int ix = 0;
      if (_delegateArgs != null) {
        for (int i = 0, len = _delegateArgs.length; i < len; ++i) {
          if (_delegateArgs[i] == null) { // marker for delegate itself
            ix = i;
            break;
          }
        }
      }
      delegateType = _creators[C_DELEGATE].getParameterType(ix);
    }

    final JavaType type = _beanDesc.getType();

    // Any non-standard creator will prevent; with one exception: int-valued constructor
    // that standard containers have can be ignored
    maybeVanilla &= !_hasNonDefaultCreator;

    if (maybeVanilla) {
      /* 10-May-2014, tatu: If we have nothing special, and we are dealing with one
       *   of "well-known" types, can create a non-reflection-based instantiator.
       */
      final Class<?> rawType = type.getRawClass();
      if (rawType == Collection.class || rawType == List.class || rawType == ArrayList.class) {
        return new Vanilla(Vanilla.TYPE_COLLECTION);
      }
      if (rawType == Map.class || rawType == LinkedHashMap.class) {
        return new Vanilla(Vanilla.TYPE_MAP);
      }
      if (rawType == HashMap.class) {
        return new Vanilla(Vanilla.TYPE_HASH_MAP);
      }
    }

    StdValueInstantiator inst = new StdValueInstantiator(config, type);
    inst.configureFromObjectSettings(
        _creators[C_DEFAULT],
        _creators[C_DELEGATE],
        delegateType,
        _delegateArgs,
        _creators[C_PROPS],
        _propertyBasedArgs);
    inst.configureFromStringCreator(_creators[C_STRING]);
    inst.configureFromIntCreator(_creators[C_INT]);
    inst.configureFromLongCreator(_creators[C_LONG]);
    inst.configureFromDoubleCreator(_creators[C_DOUBLE]);
    inst.configureFromBooleanCreator(_creators[C_BOOLEAN]);
    inst.configureIncompleteParameter(_incompleteParameter);
    return inst;
  }
 @Override
 public JavaType widenContentsBy(Class<?> contentClass) {
   // Can do a quick check first:
   if (contentClass == _elementType.getRawClass()) {
     return this;
   }
   return new CollectionLikeType(
       _class, _elementType.widenBy(contentClass), _valueHandler, _typeHandler);
 }
  // [databind#938]
  public void testRecursivePair() throws Exception {
    JavaType t = MAPPER.constructType(ImmutablePair.class);

    assertNotNull(t);
    assertEquals(ImmutablePair.class, t.getRawClass());

    List<ImmutablePair<String, Double>> list = new ArrayList<ImmutablePair<String, Double>>();
    list.add(ImmutablePair.of("Hello World!", 123d));
    String json = MAPPER.writeValueAsString(list);

    assertNotNull(json);

    // can not deserialize with current definition, however
  }
 protected MinimalClassNameIdResolver(JavaType javatype, TypeFactory typefactory) {
   super(javatype, typefactory);
   javatype = javatype.getRawClass().getName();
   int i = javatype.lastIndexOf('.');
   if (i < 0) {
     _basePackageName = "";
     _basePackagePrefix = ".";
     return;
   } else {
     _basePackagePrefix = javatype.substring(0, i + 1);
     _basePackageName = javatype.substring(0, i);
     return;
   }
 }
 @Override
 public JavaType modifyType(
     JavaType type, Type jdkType, TypeBindings bindings, TypeFactory typeFactory) {
   final Class<?> raw = type.getRawClass();
   if (Seq.class.isAssignableFrom(raw) && CharSeq.class != raw) {
     return CollectionLikeType.construct(raw, type.containedTypeOrUnknown(0));
   }
   if (Set.class.isAssignableFrom(raw)) {
     return CollectionLikeType.construct(raw, type.containedTypeOrUnknown(0));
   }
   if (PriorityQueue.class.isAssignableFrom(raw)) {
     return CollectionLikeType.construct(raw, type.containedTypeOrUnknown(0));
   }
   return type;
 }
  /**
   * Method that will construct a regular bean property setter using the given setter method.
   *
   * @return Property constructed, if any; or null to indicate that there should be no property
   *     based on given definitions.
   */
  protected SettableBeanProperty constructSettableProperty(
      DeserializationContext ctxt,
      BeanDescription beanDesc,
      BeanPropertyDefinition propDef,
      Type jdkType)
      throws JsonMappingException {
    // need to ensure method is callable (for non-public)
    AnnotatedMember mutator = propDef.getMutator();
    if (ctxt.canOverrideAccessModifiers()) {
      mutator.fixAccess();
    }
    // note: this works since we know there's exactly one argument for methods
    JavaType t0 = beanDesc.resolveType(jdkType);

    BeanProperty.Std property =
        new BeanProperty.Std(propDef.getName(), t0, beanDesc.getClassAnnotations(), mutator);
    JavaType type = resolveType(ctxt, beanDesc, t0, mutator);
    // did type change?
    if (type != t0) {
      property = property.withType(type);
    }

    /* First: does the Method specify the deserializer to use?
     * If so, let's use it.
     */
    JsonDeserializer<Object> propDeser = findDeserializerFromAnnotation(ctxt, mutator);
    type = modifyTypeByAnnotation(ctxt, mutator, type);
    TypeDeserializer typeDeser = type.getTypeHandler();
    SettableBeanProperty prop;
    if (mutator instanceof AnnotatedMethod) {
      prop =
          new MethodProperty(
              propDef, type, typeDeser, beanDesc.getClassAnnotations(), (AnnotatedMethod) mutator);
    } else {
      prop =
          new FieldProperty(
              propDef, type, typeDeser, beanDesc.getClassAnnotations(), (AnnotatedField) mutator);
    }
    if (propDeser != null) {
      prop = prop.withValueDeserializer(propDeser);
    }
    // [JACKSON-235]: need to retain name of managed forward references:
    AnnotationIntrospector.ReferenceProperty ref = propDef.findReferenceType();
    if (ref != null && ref.isManagedReference()) {
      prop.setManagedReferenceName(ref.getName());
    }
    return prop;
  }
 /*
  * Enabled aggressive block sorting
  */
 @Override
 public Collection<NamedType> collectAndResolveSubtypes(AnnotatedMember object, MapperConfig<?> mapperConfig, AnnotationIntrospector annotationIntrospector, JavaType javaType) {
     void var4_6;
     if (javaType == null) {
         Class class_ = object.getRawType();
     } else {
         Class class_ = javaType.getRawClass();
     }
     HashMap<NamedType, NamedType> hashMap = new HashMap<NamedType, NamedType>();
     if (this._registeredSubtypes != null) {
         for (NamedType namedType : this._registeredSubtypes) {
             if (!var4_6.isAssignableFrom(namedType.getType())) continue;
             this._collectAndResolve(AnnotatedClass.constructWithoutSuperTypes(namedType.getType(), annotationIntrospector, mapperConfig), namedType, mapperConfig, annotationIntrospector, hashMap);
         }
     }
     if ((object = annotationIntrospector.findSubtypes((Annotated)object)) != null) {
         object = object.iterator();
         while (object.hasNext()) {
             NamedType namedType = (NamedType)object.next();
             this._collectAndResolve(AnnotatedClass.constructWithoutSuperTypes(namedType.getType(), annotationIntrospector, mapperConfig), namedType, mapperConfig, annotationIntrospector, hashMap);
         }
     }
     object = new NamedType(var4_6, null);
     this._collectAndResolve(AnnotatedClass.constructWithoutSuperTypes(var4_6, annotationIntrospector, mapperConfig), (NamedType)object, mapperConfig, annotationIntrospector, hashMap);
     return new ArrayList<NamedType>(hashMap.values());
 }
 @SuppressWarnings("unchecked")
 public static JsonSerializer<Object> getStdKeySerializer(JavaType keyType) {
   if (keyType == null) {
     return DEFAULT_KEY_SERIALIZER;
   }
   Class<?> cls = keyType.getRawClass();
   if (cls == String.class) {
     return DEFAULT_STRING_SERIALIZER;
   }
   if (cls == Object.class || cls.isPrimitive() || Number.class.isAssignableFrom(cls)) {
     return DEFAULT_KEY_SERIALIZER;
   }
   if (Date.class.isAssignableFrom(cls)) {
     return (JsonSerializer<Object>) DateKeySerializer.instance;
   }
   if (Calendar.class.isAssignableFrom(cls)) {
     return (JsonSerializer<Object>) CalendarKeySerializer.instance;
   }
   /* 14-Mar-2014, tatu: Should support @JsonValue, as per #47; but that
    *   requires extensive introspection, and passing in more information
    *   to this method.
    */
   // If no match, just use default one:
   return DEFAULT_KEY_SERIALIZER;
 }
  public JsonDeserializer<?> findDeserializer(
      JavaType type, DeserializationConfig config, BeanDescription beanDesc)
      throws JsonMappingException {
    final Class<?> rawType = type.getRawClass();

    if (_jdk7Helper != null) {
      JsonDeserializer<?> deser = _jdk7Helper.getDeserializerForJavaNioFilePath(rawType);
      if (deser != null) {
        return deser;
      }
    }
    if ((CLASS_DOM_NODE != null) && CLASS_DOM_NODE.isAssignableFrom(rawType)) {
      return (JsonDeserializer<?>) instantiate(DESERIALIZER_FOR_DOM_NODE);
    }
    if ((CLASS_DOM_DOCUMENT != null) && CLASS_DOM_DOCUMENT.isAssignableFrom(rawType)) {
      return (JsonDeserializer<?>) instantiate(DESERIALIZER_FOR_DOM_DOCUMENT);
    }
    String className = rawType.getName();
    String factoryName;
    if (className.startsWith(PACKAGE_PREFIX_JAVAX_XML)
        || hasSuperClassStartingWith(rawType, PACKAGE_PREFIX_JAVAX_XML)) {
      factoryName = DESERIALIZERS_FOR_JAVAX_XML;
    } else {
      return null;
    }
    Object ob = instantiate(factoryName);
    if (ob == null) { // could warn, if we had logging system (j.u.l?)
      return null;
    }
    return ((Deserializers) ob).findBeanDeserializer(type, config, beanDesc);
  }
  public JsonSerializer<?> findSerializer(
      SerializationConfig config, JavaType type, BeanDescription beanDesc) {
    final Class<?> rawType = type.getRawClass();

    if (_jdk7Helper != null) {
      Class<?> path = _jdk7Helper.getClassJavaNioFilePath();
      if (path.isAssignableFrom(rawType)) {
        return ToStringSerializer.instance;
      }
    }
    if ((CLASS_DOM_NODE != null) && CLASS_DOM_NODE.isAssignableFrom(rawType)) {
      return (JsonSerializer<?>) instantiate(SERIALIZER_FOR_DOM_NODE);
    }
    String className = rawType.getName();
    String factoryName;
    if (className.startsWith(PACKAGE_PREFIX_JAVAX_XML)
        || hasSuperClassStartingWith(rawType, PACKAGE_PREFIX_JAVAX_XML)) {
      factoryName = SERIALIZERS_FOR_JAVAX_XML;
    } else {
      return null;
    }

    Object ob = instantiate(factoryName);
    if (ob == null) { // could warn, if we had logging system (j.u.l?)
      return null;
    }
    return ((Serializers) ob).findSerializer(config, type, beanDesc);
  }
 @Override
 public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
     throws JsonMappingException {
   // May need to resolve types for delegate-based creators:
   JsonDeserializer<Object> delegate = null;
   if (_valueInstantiator != null) {
     AnnotatedWithParams delegateCreator = _valueInstantiator.getDelegateCreator();
     if (delegateCreator != null) {
       JavaType delegateType = _valueInstantiator.getDelegateType(ctxt.getConfig());
       delegate = findDeserializer(ctxt, delegateType, property);
     }
   }
   JsonDeserializer<?> valueDeser = _valueDeserializer;
   if (valueDeser == null) {
     // #125: May have a content converter
     valueDeser = findConvertingContentDeserializer(ctxt, property, valueDeser);
     if (valueDeser == null) {
       // And we may also need to get deserializer for String
       valueDeser =
           ctxt.findContextualValueDeserializer(_collectionType.getContentType(), property);
     }
   } else { // if directly assigned, probably not yet contextual, so:
     valueDeser = ctxt.handleSecondaryContextualization(valueDeser, property);
   }
   if (isDefaultDeserializer(valueDeser)) {
     valueDeser = null;
   }
   return withResolved(delegate, valueDeser);
 }
 public void acceptJsonFormatVisitor(
     JsonFormatVisitorWrapper paramJsonFormatVisitorWrapper, JavaType paramJavaType)
     throws JsonMappingException {
   JsonArrayFormatVisitor localJsonArrayFormatVisitor =
       paramJsonFormatVisitorWrapper.expectArrayFormat(paramJavaType);
   if (localJsonArrayFormatVisitor != null) {
     JavaType localJavaType =
         paramJsonFormatVisitorWrapper
             .getProvider()
             .getTypeFactory()
             .moreSpecificType(this._elementType, paramJavaType.getContentType());
     if (localJavaType == null) {
       throw new JsonMappingException("Could not resolve type");
     }
     JsonSerializer localJsonSerializer = this._elementSerializer;
     paramJavaType = localJsonSerializer;
     if (localJsonSerializer == null) {
       paramJavaType =
           paramJsonFormatVisitorWrapper
               .getProvider()
               .findValueSerializer(localJavaType, this._property);
     }
     localJsonArrayFormatVisitor.itemsFormat(paramJavaType, localJavaType);
   }
 }
 /**
  * Helper method used for figuring out if given raw type is a collection ("indexed") type; in
  * which case a wrapper element is typically added.
  */
 public static boolean isIndexedType(JavaType type) {
   if (type.isContainerType()) {
     Class<?> cls = type.getRawClass();
     // One special case; byte[] will be serialized as base64-encoded String, not real array, so:
     // (actually, ditto for char[]; thought to be a String)
     if (cls == byte[].class || cls == char[].class) {
       return false;
     }
     // issue#5: also, should not add wrapping for Maps
     if (Map.class.isAssignableFrom(cls)) {
       return false;
     }
     return true;
   }
   return false;
 }
 @Override
 public StringBuilder getGenericSignature(StringBuilder sb) {
   _classSignature(_class, sb, false);
   sb.append('<');
   _elementType.getGenericSignature(sb);
   sb.append(">;");
   return sb;
 }
 @Override
 public CollectionLikeType withStaticTyping() {
   if (_asStatic) {
     return this;
   }
   return new CollectionLikeType(
       _class, _elementType.withStaticTyping(), _valueHandler, _typeHandler, true);
 }
  /**
   * Method that {@link DeserializerCache}s call to create a new deserializer for types other than
   * Collections, Maps, arrays and enums.
   */
  @Override
  public JsonDeserializer<Object> createBeanDeserializer(
      DeserializationContext ctxt, JavaType type, BeanDescription beanDesc)
      throws JsonMappingException {
    final DeserializationConfig config = ctxt.getConfig();
    // We may also have custom overrides:
    JsonDeserializer<Object> custom = _findCustomBeanDeserializer(type, config, beanDesc);
    if (custom != null) {
      return custom;
    }
    /* One more thing to check: do we have an exception type
     * (Throwable or its sub-classes)? If so, need slightly
     * different handling.
     */
    if (type.isThrowable()) {
      return buildThrowableDeserializer(ctxt, type, beanDesc);
    }
    /* Or, for abstract types, may have alternate means for resolution
     * (defaulting, materialization)
     */
    if (type.isAbstract()) {
      // [JACKSON-41] (v1.6): Let's make it possible to materialize abstract types.
      JavaType concreteType = materializeAbstractType(config, beanDesc);
      if (concreteType != null) {
        /* important: introspect actual implementation (abstract class or
         * interface doesn't have constructors, for one)
         */
        beanDesc = config.introspect(concreteType);
        return buildBeanDeserializer(ctxt, concreteType, beanDesc);
      }
    }

    // Otherwise, may want to check handlers for standard types, from superclass:
    JsonDeserializer<Object> deser = findStdDeserializer(config, type);
    if (deser != null) {
      return deser;
    }

    // Otherwise: could the class be a Bean class? If not, bail out
    if (!isPotentialBeanType(type.getRawClass())) {
      return null;
    }
    // Use generic bean introspection to build deserializer
    return buildBeanDeserializer(ctxt, type, beanDesc);
  }
  @Override
  public boolean equals(Object o) {
    if (o == this) return true;
    if (o == null) return false;
    if (o.getClass() != getClass()) return false;

    CollectionLikeType other = (CollectionLikeType) o;
    return (_class == other._class) && _elementType.equals(other._elementType);
  }
  @Override
  protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage)
      throws IOException, HttpMessageNotWritableException {

    JsonEncoding encoding = getJsonEncoding(outputMessage.getHeaders().getContentType());
    JsonGenerator generator =
        this.objectMapper.getFactory().createGenerator(outputMessage.getBody(), encoding);
    try {
      writePrefix(generator, object);

      Class<?> serializationView = null;
      FilterProvider filters = null;
      Object value = object;
      JavaType javaType = null;
      if (object instanceof MappingJacksonValue) {
        MappingJacksonValue container = (MappingJacksonValue) object;
        value = container.getValue();
        serializationView = container.getSerializationView();
        filters = container.getFilters();
      }
      if (type != null && value != null && TypeUtils.isAssignable(type, value.getClass())) {
        javaType = getJavaType(type, null);
      }
      ObjectWriter objectWriter;
      if (serializationView != null) {
        objectWriter = this.objectMapper.writerWithView(serializationView);
      } else if (filters != null) {
        objectWriter = this.objectMapper.writer(filters);
      } else {
        objectWriter = this.objectMapper.writer();
      }
      if (javaType != null && javaType.isContainerType()) {
        objectWriter = objectWriter.forType(javaType);
      }
      objectWriter.writeValue(generator, value);

      writeSuffix(generator, object);
      generator.flush();

    } catch (JsonProcessingException ex) {
      throw new HttpMessageNotWritableException("Could not write content: " + ex.getMessage(), ex);
    }
  }
 @Override
 public TypeResolverBuilder<?> findPropertyTypeResolver(
     MapperConfig<?> config, AnnotatedMember am, JavaType baseType) {
   /* As per definition of @JsonTypeInfo, should only apply to contents of container
    * (collection, map) types, not container types themselves:
    */
   if (baseType.isContainerType()) return null;
   // No per-member type overrides (yet)
   return _findTypeResolver(config, am, baseType);
 }
 @Override
 protected String buildCanonicalName() {
   StringBuilder sb = new StringBuilder();
   sb.append(_class.getName());
   if (_elementType != null) {
     sb.append('<');
     sb.append(_elementType.toCanonical());
     sb.append('>');
   }
   return sb.toString();
 }
示例#26
0
  /** Method called to serialize fields, when the value type is not statically known. */
  public void serializeFields(Map<?, ?> value, JsonGenerator jgen, SerializerProvider provider)
      throws IOException, JsonGenerationException {
    // If value type needs polymorphic type handling, some more work needed:
    if (_valueTypeSerializer != null) {
      serializeTypedFields(value, jgen, provider);
      return;
    }
    final JsonSerializer<Object> keySerializer = _keySerializer;

    final HashSet<String> ignored = _ignoredEntries;
    final boolean skipNulls = !provider.isEnabled(SerializationFeature.WRITE_NULL_MAP_VALUES);

    PropertySerializerMap serializers = _dynamicValueSerializers;

    for (Map.Entry<?, ?> entry : value.entrySet()) {
      Object valueElem = entry.getValue();
      // First, serialize key
      Object keyElem = entry.getKey();
      if (keyElem == null) {
        provider.findNullKeySerializer(_keyType, _property).serialize(null, jgen, provider);
      } else {
        // [JACKSON-314] skip entries with null values?
        if (skipNulls && valueElem == null) continue;
        // One twist: is entry ignorable? If so, skip
        if (ignored != null && ignored.contains(keyElem)) continue;
        keySerializer.serialize(keyElem, jgen, provider);
      }

      // And then value
      if (valueElem == null) {
        provider.defaultSerializeNull(jgen);
      } else {
        Class<?> cc = valueElem.getClass();
        JsonSerializer<Object> serializer = serializers.serializerFor(cc);
        if (serializer == null) {
          if (_valueType.hasGenericTypes()) {
            serializer =
                _findAndAddDynamic(
                    serializers, provider.constructSpecializedType(_valueType, cc), provider);
          } else {
            serializer = _findAndAddDynamic(serializers, cc, provider);
          }
          serializers = _dynamicValueSerializers;
        }
        try {
          serializer.serialize(valueElem, jgen, provider);
        } catch (Exception e) {
          // [JACKSON-55] Need to add reference information
          String keyDesc = "" + keyElem;
          wrapAndThrow(provider, e, value, keyDesc);
        }
      }
    }
  }
  @Override
  public KeyDeserializer findKeyDeserializer(
      JavaType type, DeserializationConfig config, BeanDescription beanDesc)
      throws JsonMappingException {
    final Class<?> candidateTT = type.getRawClass();
    if (MetaTinyTypes.isTinyType(candidateTT)) {
      return new TinyTypesKeyDeserializer(candidateTT);
    }

    return null;
  }
 protected JsonDeserializer<Object> _handleUnknownValueDeserializer(JavaType type)
     throws JsonMappingException {
   /* Let's try to figure out the reason, to give better error
    * messages
    */
   Class<?> rawClass = type.getRawClass();
   if (!ClassUtil.isConcrete(rawClass)) {
     throw new JsonMappingException("Can not find a Value deserializer for abstract type " + type);
   }
   throw new JsonMappingException("Can not find a Value deserializer for type " + type);
 }
  /**
   * Method that does the heavy lifting of checking for per-type annotations, find out full type,
   * and figure out which actual factory method to call.
   */
  @SuppressWarnings("unchecked")
  protected JsonDeserializer<Object> _createDeserializer(
      DeserializationContext ctxt, DeserializerFactory factory, JavaType type)
      throws JsonMappingException {
    final DeserializationConfig config = ctxt.getConfig();

    // First things first: do we need to use abstract type mapping?
    if (type.isAbstract() || type.isMapLikeType() || type.isCollectionLikeType()) {
      type = factory.mapAbstractType(config, type);
    }
    BeanDescription beanDesc = config.introspect(type);
    // Then: does type define explicit deserializer to use, with annotation(s)?
    JsonDeserializer<Object> deser = findDeserializerFromAnnotation(ctxt, beanDesc.getClassInfo());
    if (deser != null) {
      return deser;
    }

    // If not, may have further type-modification annotations to check:
    JavaType newType = modifyTypeByAnnotation(ctxt, beanDesc.getClassInfo(), type);
    if (newType != type) {
      type = newType;
      beanDesc = config.introspect(newType);
    }

    // We may also have a Builder type to consider...
    Class<?> builder = beanDesc.findPOJOBuilder();
    if (builder != null) {
      return (JsonDeserializer<Object>)
          factory.createBuilderBasedDeserializer(ctxt, type, beanDesc, builder);
    }

    // Or perhaps a Converter?
    Converter<Object, Object> conv = beanDesc.findDeserializationConverter();
    if (conv == null) { // nope, just construct in normal way
      return (JsonDeserializer<Object>) _createDeserializer2(ctxt, factory, type, beanDesc);
    }
    // otherwise need to do bit of introspection
    JavaType delegateType = conv.getInputType(ctxt.getTypeFactory());
    return new StdDelegatingDeserializer<Object>(
        conv, delegateType, _createDeserializer2(ctxt, factory, delegateType, beanDesc));
  }
 public EnumMapDeserializer(
     JavaType mapType,
     KeyDeserializer keyDeserializer,
     JsonDeserializer<?> valueDeser,
     TypeDeserializer valueTypeDeser) {
   super(mapType);
   _mapType = mapType;
   _enumClass = mapType.getKeyType().getRawClass();
   _keyDeserializer = keyDeserializer;
   _valueDeserializer = (JsonDeserializer<Object>) valueDeser;
   _valueTypeDeserializer = valueTypeDeser;
 }