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; }
@Override public EnumMap<?, ?> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_OBJECT if (jp.getCurrentToken() != JsonToken.START_OBJECT) { return _deserializeFromEmpty(jp, ctxt); } EnumMap result = constructMap(); final JsonDeserializer<Object> valueDes = _valueDeserializer; final TypeDeserializer typeDeser = _valueTypeDeserializer; while ((jp.nextToken()) == JsonToken.FIELD_NAME) { String keyName = jp.getCurrentName(); // just for error message // but we need to let key deserializer handle it separately, nonetheless Enum<?> key = (Enum<?>) _keyDeserializer.deserializeKey(keyName, ctxt); if (key == null) { if (!ctxt.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) { throw ctxt.weirdStringException( keyName, _enumClass, "value not one of declared Enum instance names for " + _mapType.getKeyType()); } /* 24-Mar-2012, tatu: Null won't work as a key anyway, so let's * just skip the entry then. But we must skip the value as well, if so. */ jp.nextToken(); jp.skipChildren(); continue; } // And then the value... JsonToken t = jp.nextToken(); /* note: MUST check for nulls separately: deserializers will * not handle them (and maybe fail or return bogus data) */ Object value; try { if (t == JsonToken.VALUE_NULL) { value = valueDes.getNullValue(ctxt); } else if (typeDeser == null) { value = valueDes.deserialize(jp, ctxt); } else { value = valueDes.deserializeWithType(jp, ctxt, typeDeser); } } catch (Exception e) { wrapAndThrow(e, result, keyName); return null; } result.put(key, value); } return result; }
/** @since 2.8 */ public static MapSerializer construct( Set<String> ignoredEntries, JavaType mapType, boolean staticValueType, TypeSerializer vts, JsonSerializer<Object> keySerializer, JsonSerializer<Object> valueSerializer, Object filterId) { JavaType keyType, valueType; if (mapType == null) { keyType = valueType = UNSPECIFIED_TYPE; } else { keyType = mapType.getKeyType(); valueType = mapType.getContentType(); } // If value type is final, it's same as forcing static value typing: if (!staticValueType) { staticValueType = (valueType != null && valueType.isFinal()); } else { // also: Object.class can not be handled as static, ever if (valueType.getRawClass() == Object.class) { staticValueType = false; } } MapSerializer ser = new MapSerializer( ignoredEntries, keyType, valueType, staticValueType, vts, keySerializer, valueSerializer); if (filterId != null) { ser = ser.withFilterId(filterId); } return ser; }
/** * Method called to finalize setup of this deserializer, when it is known for which property * deserializer is needed for. */ @Override public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException { // note: instead of finding key deserializer, with enums we actually // work with regular deserializers (less code duplication; but not // quite as clean as it ought to be) KeyDeserializer kd = _keyDeserializer; if (kd == null) { kd = ctxt.findKeyDeserializer(_mapType.getKeyType(), property); } JsonDeserializer<?> vd = _valueDeserializer; final JavaType vt = _mapType.getContentType(); if (vd == null) { vd = ctxt.findContextualValueDeserializer(vt, property); } else { // if directly assigned, probably not yet contextual, so: vd = ctxt.handleSecondaryContextualization(vd, property, vt); } TypeDeserializer vtd = _valueTypeDeserializer; if (vtd != null) { vtd = vtd.forProperty(property); } return withResolved(kd, vd, vtd); }
public static MapSerializer construct( String[] ignoredList, JavaType mapType, boolean staticValueType, TypeSerializer vts, JsonSerializer<Object> keySerializer, JsonSerializer<Object> valueSerializer) { HashSet<String> ignoredEntries = toSet(ignoredList); JavaType keyType, valueType; if (mapType == null) { keyType = valueType = UNSPECIFIED_TYPE; } else { keyType = mapType.getKeyType(); valueType = mapType.getContentType(); } // If value type is final, it's same as forcing static value typing: if (!staticValueType) { staticValueType = (valueType != null && valueType.isFinal()); } return new MapSerializer( ignoredEntries, keyType, valueType, staticValueType, vts, keySerializer, valueSerializer); }