/** * 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 Type for purpose of locating a serializer; usually dynamic runtime type, but * can also be static declared type, depending on configuration * @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( Class<?> 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, _config.constructType(valueType)); if (typeSer != null) { typeSer = typeSer.forProperty(property); ser = new TypeWrappedSerializer(typeSer, ser); } if (cache) { _serializerCache.addTypedSerializer(valueType, ser); } return ser; }
/** * 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 that will try to construct a value serializer; and if one is successfully created, cache * it for reuse. */ protected JsonSerializer<Object> _createAndCacheUntypedSerializer(Class<?> rawType) throws JsonMappingException { JavaType type = _config.constructType(rawType); JsonSerializer<Object> ser; try { ser = _createUntypedSerializer(type); } catch (IllegalArgumentException iae) { /* We better only expose checked exceptions, since those * are what caller is expected to handle */ throw JsonMappingException.from(this, iae.getMessage(), iae); } if (ser != null) { _serializerCache.addAndResolveNonTypedSerializer(type, ser, this); } 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(Class<?> 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 = _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; }
/** @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); }
/** @since 2.7 */ public JsonSerializer<Object> findKeySerializer(Class<?> rawKeyType, BeanProperty property) throws JsonMappingException { return findKeySerializer(_config.constructType(rawKeyType), property); }