Class<?> mapClass = type.getRawClass();
/* Ok, to resolve [JACKSON-167], we need to check class annotations
* (and later on, may need creator info too)
*/
BasicBeanDescription beanDesc = config.introspectForCreation(mapClass);
type = modifyTypeByAnnotation(config, beanDesc.getClassInfo(), type);
JavaType keyType = type.getKeyType();
JavaType contentType = type.getContentType();
// First: is there annotation-specified deserializer for values?
@SuppressWarnings("unchecked")
JsonDeserializer<Object> contentDeser = (JsonDeserializer<Object>) contentType.getHandler();
if (contentDeser == null) { // nope...
// 'null' -> maps have no referring fields
contentDeser = p.findValueDeserializer(config, contentType, type, null);
}
/* Value handling is identical for all,
* but EnumMap requires special handling for keys
*/
if (EnumMap.class.isAssignableFrom(mapClass)) {
return new EnumMapDeserializer(EnumResolver.constructUnsafe(keyType.getRawClass(), config.getAnnotationIntrospector()), contentDeser);
}
// Otherwise, generic handler works ok.
// Ok: need a key deserializer (null indicates 'default' here)
KeyDeserializer keyDes = (KeyDeserializer) keyType.getHandler();
if (keyDes == null) {
keyDes = (TYPE_STRING.equals(keyType)) ? null : p.findKeyDeserializer(config, keyType);
}
/* But there is one more twist: if we are being asked to instantiate
* an interface or abstract Map, we need to either find something
* that implements the thing, or give up.
*
* Note that we do NOT try to guess based on secondary interfaces
* here; that would probably not work correctly since casts would
* fail later on (as the primary type is not the interface we'd
* be implementing)
*/
if (type.isInterface() || type.isAbstract()) {
@SuppressWarnings("unchecked")
Class<? extends Map> fallback = _mapFallbacks.get(mapClass.getName());
if (fallback == null) {
throw new IllegalArgumentException("Can not find a deserializer for non-concrete Map type "+type);
}
mapClass = fallback;
// But if so, also need to re-check creators...
beanDesc = config.introspectForCreation(mapClass);
}
// [JACKSON-153]: allow use of @JsonCreator
boolean fixAccess = config.isEnabled(DeserializationConfig.Feature.CAN_OVERRIDE_ACCESS_MODIFIERS);
// First, locate the default constructor (if one available)
@SuppressWarnings("unchecked")
Constructor<Map<Object,Object>> defaultCtor = (Constructor<Map<Object,Object>>) beanDesc.findDefaultConstructor();
if (defaultCtor != null) {
if (fixAccess) {
ClassUtil.checkAndFixAccess(defaultCtor);
}
}