Java 类com.fasterxml.jackson.databind.deser.std.DelegatingDeserializer 实例源码

项目:codec    文件:CodecTypeDeserializer.java   
private boolean handleDefaultsAndImplicitPrimary(ObjectNode fieldValues,
                                                 ConfigObject aliasDefaults,
                                                 JsonDeserializer<?> deserializer,
                                                 DeserializationContext ctxt) throws JsonMappingException {
    if (!aliasDefaults.isEmpty()) {
        if (deserializer instanceof DelegatingDeserializer) {
            deserializer = ((DelegatingDeserializer) deserializer).getDelegatee();
        }
        if ((deserializer instanceof BeanDeserializerBase) && (aliasDefaults.get("_primary") != null)) {
            BeanDeserializerBase beanDeserializer = (BeanDeserializerBase) deserializer;
            String primaryField = (String) aliasDefaults.get("_primary").unwrapped();
            if (!fieldValues.has(primaryField)) {
                // user has not explicitly set a value where _primary points, see if _primary is a plugin type
                SettableBeanProperty primaryProperty = beanDeserializer.findProperty(primaryField);
                if ((primaryProperty != null) && primaryProperty.hasValueTypeDeserializer()) {
                    TypeDeserializer primaryTypeDeserializer = primaryProperty.getValueTypeDeserializer();
                    if (primaryTypeDeserializer instanceof CodecTypeDeserializer) {
                        CodecTypeIdResolver primaryPropertyTypeIdResolver =
                                ((CodecTypeDeserializer) primaryTypeDeserializer).idRes;
                        String possibleInlinedPrimary = null;
                        Iterator<String> fieldNames = fieldValues.fieldNames();
                        while (fieldNames.hasNext()) {
                            String fieldName = fieldNames.next();
                            if ((fieldName.charAt(0) != '_') && !beanDeserializer.hasProperty(fieldName)) {
                                if (primaryPropertyTypeIdResolver.isValidTypeId(fieldName)) {
                                    if (possibleInlinedPrimary == null) {
                                        possibleInlinedPrimary = fieldName;
                                    } else {
                                        String message = String.format(
                                                "%s and %s are both otherwise unknown properties that "
                                                + "could be types for the _primary property %s whose category is "
                                                + "%s. This is too ambiguous to resolve.",
                                                possibleInlinedPrimary, fieldName, primaryField,
                                                ((CodecTypeDeserializer) primaryTypeDeserializer)
                                                        .pluginMap.category());
                                        JsonMappingException ex =
                                                ctxt.instantiationException(_baseType.getRawClass(), message);
                                        ex.prependPath(beanDeserializer.getValueType(), fieldName);
                                        throw ex;
                                    }
                                }
                            }
                        }
                        // did we find a good candidate?
                        if (possibleInlinedPrimary != null) {
                            // then wrap the value with its key (its type), and stash it in our primary field
                            JsonNode inlinedPrimaryValue = fieldValues.remove(possibleInlinedPrimary);
                            fieldValues.with(primaryField).set(possibleInlinedPrimary, inlinedPrimaryValue);
                            Jackson.merge(fieldValues, Jackson.configConverter(aliasDefaults));
                            return true;
                        }
                    }
                }
            }
        }
        // merge alias defaults here since we check for empty etc anyway
        Jackson.merge(fieldValues, Jackson.configConverter(aliasDefaults));
    }
    return false;
}