public ObjectArrayDeserializer(JavaType arrayType, JsonDeserializer<Object> elemDeser, TypeDeserializer elemTypeDeser) { super(arrayType, null, null); _elementClass = arrayType.getContentType().getRawClass(); _untyped = (_elementClass == Object.class); _elementDeserializer = elemDeser; _elementTypeDeserializer = elemTypeDeser; }
@Override public TypeResolverBuilder<?> findPropertyContentTypeResolver(MapperConfig<?> config, AnnotatedMember am, JavaType containerType) { /* First: let's ensure property is a container type: caller should have * verified but just to be sure */ if (containerType.getContentType() == null) { throw new IllegalArgumentException("Must call method with a container or reference type (got "+containerType+")"); } return _findTypeResolver(config, am, containerType); }
/** * Accessor for declared type of contained value elements; either exact * type, or one of its supertypes. */ public JavaType getContentType() { if (_containerType == null) { return TypeFactory.unknownType(); // should never occur but... } return _containerType.getContentType(); }
@Override public JavaType withHandlersFrom(JavaType src) { JavaType type = super.withHandlersFrom(src); JavaType srcCt = src.getContentType(); if (srcCt != null) { JavaType ct = _elementType.withHandlersFrom(srcCt); if (ct != _elementType) { type = type.withContentType(ct); } } return type; }
/** * Method for constructing a {@link CollectionType}. *<p> * NOTE: type modifiers are NOT called on Collection type itself; but are called * for contained types. */ public CollectionType constructCollectionType(Class<? extends Collection> collectionClass, JavaType elementType) { TypeBindings bindings = TypeBindings.createIfNeeded(collectionClass, elementType); CollectionType result = (CollectionType) _fromClass(null, collectionClass, bindings); // 17-May-2017, tatu: As per [databind#1415], we better verify bound values if (but only if) // type being resolved was non-generic (i.e.element type was ignored) if (bindings.isEmpty() && (elementType != null)) { JavaType t = result.findSuperType(Collection.class); JavaType realET = t.getContentType(); if (!realET.equals(elementType)) { throw new IllegalArgumentException(String.format( "Non-generic Collection class %s did not resolve to something with element type %s but %s ", ClassUtil.nameOf(collectionClass), elementType, realET)); } } return result; }
/** * Method for constructing a {@link MapType} instance *<p> * NOTE: type modifiers are NOT called on constructed type itself; but are called * for contained types. */ public MapType constructMapType(Class<? extends Map> mapClass, JavaType keyType, JavaType valueType) { TypeBindings bindings = TypeBindings.createIfNeeded(mapClass, new JavaType[] { keyType, valueType }); MapType result = (MapType) _fromClass(null, mapClass, bindings); // 17-May-2017, tatu: As per [databind#1415], we better verify bound values if (but only if) // type being resolved was non-generic (i.e.element type was ignored) if (bindings.isEmpty()) { JavaType t = result.findSuperType(Map.class); JavaType realKT = t.getKeyType(); if (!realKT.equals(keyType)) { throw new IllegalArgumentException(String.format( "Non-generic Map class %s did not resolve to something with key type %s but %s ", ClassUtil.nameOf(mapClass), keyType, realKT)); } JavaType realVT = t.getContentType(); if (!realVT.equals(valueType)) { throw new IllegalArgumentException(String.format( "Non-generic Map class %s did not resolve to something with value type %s but %s ", ClassUtil.nameOf(mapClass), valueType, realVT)); } } return result; }
public boolean useForType(JavaType t) { switch (_appliesFor) { case NON_CONCRETE_AND_ARRAYS: while (t.isArrayType()) { t = t.getContentType(); } // fall through case OBJECT_AND_NON_CONCRETE: return (t.getRawClass() == Object.class) || !t.isConcrete(); case NON_FINAL: while (t.isArrayType()) { t = t.getContentType(); } // to fix problem with wrong long to int conversion if (t.getRawClass() == Long.class) { return true; } if (t.getRawClass() == XMLGregorianCalendar.class) { return false; } return !t.isFinal(); // includes Object.class default: // case JAVA_LANG_OBJECT: return (t.getRawClass() == Object.class); } } };
public boolean useForType(JavaType t) { switch (_appliesFor) { case NON_CONCRETE_AND_ARRAYS: while (t.isArrayType()) { t = t.getContentType(); } // fall through case OBJECT_AND_NON_CONCRETE: return (t.getRawClass() == Object.class) || !t.isConcrete(); case NON_FINAL: while (t.isArrayType()) { t = t.getContentType(); } // to fix problem with wrong long to int conversion if (t.getRawClass() == Long.class) { return true; } if (t.getRawClass() == XMLGregorianCalendar.class) { return false; } return !t.isFinal(); // includes Object.class default: // case JAVA_LANG_OBJECT: return (t.getRawClass() == Object.class); } } };
} else { keyType = mapType.getKeyType(); valueType = mapType.getContentType();
@Override public JavaType withHandlersFrom(JavaType src) { JavaType type = super.withHandlersFrom(src); JavaType srcKeyType = src.getKeyType(); // "withKeyType()" not part of JavaType, hence must verify: if (type instanceof MapLikeType) { if (srcKeyType != null) { JavaType ct = _keyType.withHandlersFrom(srcKeyType); if (ct != _keyType) { type = ((MapLikeType) type).withKeyType(ct); } } } JavaType srcCt = src.getContentType(); if (srcCt != null) { JavaType ct = _valueType.withHandlersFrom(srcCt); if (ct != _valueType) { type = type.withContentType(ct); } } return type; }
case NON_CONCRETE_AND_ARRAYS: while (t.isArrayType()) { t = t.getContentType(); t = t.getContentType();
/** * Helper method used to prevent both caching and cache lookups for structured * types that have custom value handlers * * @since 2.8.11 */ private boolean _hasCustomHandlers(JavaType t) { if (t.isContainerType()) { // First: value types may have both value and type handlers JavaType ct = t.getContentType(); if (ct != null) { if ((ct.getValueHandler() != null) || (ct.getTypeHandler() != null)) { return true; } } // Second: map(-like) types may have value handler for key (but not type; keys are untyped) if (t.isMapLikeType()) { JavaType kt = t.getKeyType(); if (kt.getValueHandler() != null) { return true; } } } return false; }
/** * Method called to find and create a type information deserializer for values of * given container (list, array, map) property, if one is needed. * If not needed (no polymorphic handling configured for property), should return null. *<p> * Note that this method is only called for container bean properties, * and not for values in container types or root values (or non-container properties) * * @param containerType Type of property; must be a container type * @param propertyEntity Field or method that contains container property */ public TypeDeserializer findPropertyContentTypeDeserializer(DeserializationConfig config, JavaType containerType, AnnotatedMember propertyEntity) throws JsonMappingException { AnnotationIntrospector ai = config.getAnnotationIntrospector(); TypeResolverBuilder<?> b = ai.findPropertyContentTypeResolver(config, propertyEntity, containerType); JavaType contentType = containerType.getContentType(); // Defaulting: if no annotations on member, check class if (b == null) { return findTypeDeserializer(config, contentType); } // but if annotations found, may need to resolve subtypes: Collection<NamedType> subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByTypeId( config, propertyEntity, contentType); return b.buildTypeDeserializer(config, contentType, subtypes); }
/** * Method called to create a type information serializer for values of given * container property * if one is needed. If not needed (no polymorphic handling configured), should * return null. * * @param containerType Declared type of the container to use as the base type for type information serializer * * @return Type serializer to use for property value contents, if one is needed; null if not. */ public TypeSerializer findPropertyContentTypeSerializer(JavaType containerType, SerializationConfig config, AnnotatedMember accessor) throws JsonMappingException { JavaType contentType = containerType.getContentType(); AnnotationIntrospector ai = config.getAnnotationIntrospector(); TypeResolverBuilder<?> b = ai.findPropertyContentTypeResolver(config, accessor, containerType); TypeSerializer typeSer; // Defaulting: if no annotations on member, check value class if (b == null) { typeSer = createTypeSerializer(config, contentType); } else { Collection<NamedType> subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByClass(config, accessor, contentType); typeSer = b.buildTypeSerializer(config, contentType, subtypes); } return typeSer; }
valueDeser = findConvertingContentDeserializer(ctxt, property, valueDeser); final JavaType vt = _containerType.getContentType(); if (valueDeser == null) { valueDeser = ctxt.findContextualValueDeserializer(vt, property);
JavaType contentType = type.getContentType(); if (contentType != null) { // collection[like], map[like], array, reference
/** * 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 keyDeser = _keyDeserializer; if (keyDeser == null) { keyDeser = ctxt.findKeyDeserializer(_containerType.getKeyType(), property); } JsonDeserializer<?> valueDeser = _valueDeserializer; final JavaType vt = _containerType.getContentType(); if (valueDeser == null) { valueDeser = ctxt.findContextualValueDeserializer(vt, property); } else { // if directly assigned, probably not yet contextual, so: valueDeser = ctxt.handleSecondaryContextualization(valueDeser, property, vt); } TypeDeserializer vtd = _valueTypeDeserializer; if (vtd != null) { vtd = vtd.forProperty(property); } return withResolved(keyDeser, valueDeser, vtd, findContentNullProvider(ctxt, property, valueDeser)); }
@Override public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException { JsonDeserializer<?> valueDeser = _elementDeserializer; Boolean unwrapSingle = findFormatFeature(ctxt, property, _containerType.getRawClass(), JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY); // May have a content converter valueDeser = findConvertingContentDeserializer(ctxt, property, valueDeser); final JavaType vt = _containerType.getContentType(); if (valueDeser == null) { valueDeser = ctxt.findContextualValueDeserializer(vt, property); } else { // if directly assigned, probably not yet contextual, so: valueDeser = ctxt.handleSecondaryContextualization(valueDeser, property, vt); } TypeDeserializer elemTypeDeser = _elementTypeDeserializer; if (elemTypeDeser != null) { elemTypeDeser = elemTypeDeser.forProperty(property); } NullValueProvider nuller = findContentNullProvider(ctxt, property, valueDeser); return withResolved(elemTypeDeser, valueDeser, nuller, unwrapSingle); }
final TypeDeserializer typeDeser = _valueTypeDeserializer; CollectionReferringAccumulator referringAccumulator = new CollectionReferringAccumulator(_containerType.getContentType().getRawClass(), result);
final JavaType valueType = _containerType.getContentType(); if (valueDeser == null) {