/** * Method called to get hold of a serializer for a value of given type; or if no such serializer * can be found, a default handler (which may do a best-effort generic serialization or just * simply throw an exception when invoked). * * <p>Note: this method is only called for non-null values; not for keys or null values. For * these, check out other accessor methods. * * <p>Note that serializers produced should NOT handle polymorphic serialization aspects; separate * {@link TypeSerializer} is to be constructed by caller if and as necessary. * * @throws JsonMappingException if there are fatal problems with accessing suitable serializer; * including that of not finding any serializer */ @SuppressWarnings("unchecked") public JsonSerializer<Object> findValueSerializer(Class<?> valueType, BeanProperty property) throws JsonMappingException { // Fast lookup from local lookup thingy works? JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType); if (ser == null) { // If not, maybe shared map already has it? ser = _serializerCache.untypedValueSerializer(valueType); if (ser == null) { // ... possibly as fully typed? ser = _serializerCache.untypedValueSerializer(_config.constructType(valueType)); if (ser == null) { // If neither, must create ser = _createAndCacheUntypedSerializer(valueType); // Not found? Must use the unknown type serializer, which will report error later on if (ser == null) { ser = getUnknownTypeSerializer(valueType); // Should this be added to lookups? if (CACHE_UNKNOWN_MAPPINGS) { _serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this); } return ser; } } } } // at this point, resolution has occured, but not contextualization return (JsonSerializer<Object>) handleSecondaryContextualization(ser, property); }
/** * Method called to locate regular serializer, matching type serializer, and if both found, wrap * them in a serializer that calls both in correct sequence. This method is currently only used * for root-level serializer handling to allow for simpler caching. A call can always be replaced * by equivalent calls to access serializer and type serializer separately. * * @param valueType Declared type of value being serialized (which may not be actual runtime * type); used for finding both value serializer and type serializer to use for adding * polymorphic type (if any) * @param cache Whether resulting value serializer should be cached or not; this is just a hint * @param property When creating secondary serializers, property for which serializer is needed: * annotations of the property (or bean that contains it) may be checked to create contextual * serializers. */ public JsonSerializer<Object> findTypedValueSerializer( JavaType valueType, boolean cache, BeanProperty property) throws JsonMappingException { // Two-phase lookups; local non-shared cache, then shared: JsonSerializer<Object> ser = _knownSerializers.typedValueSerializer(valueType); if (ser != null) { return ser; } // If not, maybe shared map already has it? ser = _serializerCache.typedValueSerializer(valueType); if (ser != null) { return ser; } // Well, let's just compose from pieces: ser = findValueSerializer(valueType, property); TypeSerializer typeSer = _serializerFactory.createTypeSerializer(_config, valueType); if (typeSer != null) { typeSer = typeSer.forProperty(property); ser = new TypeWrappedSerializer(typeSer, ser); } if (cache) { _serializerCache.addTypedSerializer(valueType, ser); } return ser; }
/** * Method variant used when we do NOT want contextualization to happen; it will need to be handled * at a later point, but caller wants to be able to do that as needed; sometimes to avoid infinite * loops * * @since 2.5 */ public JsonSerializer<Object> findValueSerializer(JavaType valueType) throws JsonMappingException { // (see comments from above method) JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType); if (ser == null) { ser = _serializerCache.untypedValueSerializer(valueType); if (ser == null) { ser = _createAndCacheUntypedSerializer(valueType); if (ser == null) { ser = getUnknownTypeSerializer(valueType.getRawClass()); if (CACHE_UNKNOWN_MAPPINGS) { _serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this); } } } } return ser; }
/** * Similar to {@link #findValueSerializer(JavaType, BeanProperty)}, but used when finding * "primary" property value serializer (one directly handling value of the property). Difference * has to do with contextual resolution, and method(s) called: this method should only be called * when caller is certain that this is the primary property value serializer. * * @param property Property that is being handled; will never be null, and its type has to match * <code>valueType</code> parameter. * @since 2.3 */ @SuppressWarnings("unchecked") public JsonSerializer<Object> findPrimaryPropertySerializer( JavaType valueType, BeanProperty property) throws JsonMappingException { JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType); if (ser == null) { ser = _serializerCache.untypedValueSerializer(valueType); if (ser == null) { ser = _createAndCacheUntypedSerializer(valueType); if (ser == null) { ser = getUnknownTypeSerializer(valueType.getRawClass()); // Should this be added to lookups? if (CACHE_UNKNOWN_MAPPINGS) { _serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this); } return ser; } } } return (JsonSerializer<Object>) handlePrimaryContextualization(ser, property); }
/** * Similar to {@link #findValueSerializer(Class,BeanProperty)}, but takes full generics-aware type * instead of raw class. This is necessary for accurate handling of external type information, to * handle polymorphic types. * * @param property When creating secondary serializers, property for which serializer is needed: * annotations of the property (or bean that contains it) may be checked to create contextual * serializers. */ @SuppressWarnings("unchecked") public JsonSerializer<Object> findValueSerializer(JavaType valueType, BeanProperty property) throws JsonMappingException { // (see comments from above method) JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType); if (ser == null) { ser = _serializerCache.untypedValueSerializer(valueType); if (ser == null) { ser = _createAndCacheUntypedSerializer(valueType); if (ser == null) { ser = getUnknownTypeSerializer(valueType.getRawClass()); if (CACHE_UNKNOWN_MAPPINGS) { _serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this); } return ser; } } } return (JsonSerializer<Object>) handleSecondaryContextualization(ser, property); }
/** * Method that will try to find a serializer, either from cache or by constructing one; but will * not return an "unknown" serializer if this can not be done but rather returns null. * * @return Serializer if one can be found, null if not. */ protected JsonSerializer<Object> _findExplicitUntypedSerializer(Class<?> runtimeType) throws JsonMappingException { // Fast lookup from local lookup thingy works? JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(runtimeType); if (ser == null) { // If not, maybe shared map already has it? ser = _serializerCache.untypedValueSerializer(runtimeType); if (ser == null) { ser = _createAndCacheUntypedSerializer(runtimeType); } } /* 18-Sep-2014, tatu: This is unfortunate patch over related change * that pushes creation of "unknown type" serializer deeper down * in BeanSerializerFactory; as a result, we need to "undo" creation * here. */ if (isUnknownTypeSerializer(ser)) { return null; } return ser; }
/** @since 2.3 */ @SuppressWarnings("unchecked") public JsonSerializer<Object> findPrimaryPropertySerializer( Class<?> valueType, BeanProperty property) throws JsonMappingException { JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType); if (ser == null) { ser = _serializerCache.untypedValueSerializer(valueType); if (ser == null) { ser = _serializerCache.untypedValueSerializer(_config.constructType(valueType)); if (ser == null) { ser = _createAndCacheUntypedSerializer(valueType); if (ser == null) { ser = getUnknownTypeSerializer(valueType); if (CACHE_UNKNOWN_MAPPINGS) { _serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this); } return ser; } } } } return (JsonSerializer<Object>) handlePrimaryContextualization(ser, property); }