/** * 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 configure the generator as necessary and then call write functionality */ protected final void _configAndWriteValue(JsonGenerator jgen, Object value) throws IOException, JsonGenerationException, JsonMappingException { _configureJsonGenerator(jgen); // [JACKSON-282]: consider Closeable if (_config.isEnabled(SerializationFeature.CLOSE_CLOSEABLE) && (value instanceof Closeable)) { _writeCloseable(jgen, value, _config); return; } boolean closed = false; try { if (_rootType == null) { _serializerProvider(_config).serializeValue(jgen, value); } else { _serializerProvider(_config).serializeValue(jgen, value, _rootType, _rootSerializer); } closed = true; jgen.close(); } finally { /* won't try to close twice; also, must catch exception (so it * will not mask exception that is pending) */ if (!closed) { try { jgen.close(); } catch (IOException ioe) { } } } }
/** * 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 can be used to serialize any Java value as JSON output, using provided {@link * JsonGenerator}. */ public void writeValue(JsonGenerator jgen, Object value) throws IOException, JsonGenerationException, JsonMappingException { // 10-Aug-2012, tatu: As per [Issue#12], may need to force PrettyPrinter settings, so: _configureJsonGenerator(jgen); if (_config.isEnabled(SerializationFeature.CLOSE_CLOSEABLE) && (value instanceof Closeable)) { _writeCloseableValue(jgen, value, _config); } else { if (_rootType == null) { _serializerProvider(_config).serializeValue(jgen, value); } else { _serializerProvider(_config).serializeValue(jgen, value, _rootType, _rootSerializer); } if (_config.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) { jgen.flush(); } } }
/** * Method called to locate (root) serializer ahead of time, if permitted by configuration. Method * also is NOT to throw an exception if access fails. */ protected final JsonSerializer<Object> _prefetchRootSerializer( SerializationConfig config, JavaType valueType) { if (valueType == null || !_config.isEnabled(SerializationFeature.EAGER_SERIALIZER_FETCH)) { return null; } try { return _serializerProvider(config).findTypedValueSerializer(valueType, true, null); } catch (JsonProcessingException e) { // need to swallow? return null; } }
// Test to ensure that we can check property ordering defaults... public void testConfigForPropertySorting() throws Exception { ObjectMapper m = new ObjectMapper(); // sort-alphabetically is disabled by default: assertFalse(m.isEnabled(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY)); SerializationConfig sc = m.getSerializationConfig(); assertFalse(sc.isEnabled(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY)); assertFalse(sc.shouldSortPropertiesAlphabetically()); DeserializationConfig dc = m.getDeserializationConfig(); assertFalse(dc.shouldSortPropertiesAlphabetically()); // but when enabled, should be visible: m.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY); sc = m.getSerializationConfig(); assertTrue(sc.isEnabled(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY)); assertTrue(sc.shouldSortPropertiesAlphabetically()); dc = m.getDeserializationConfig(); // and not just via SerializationConfig, but also via DeserializationConfig assertTrue(dc.isEnabled(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY)); assertTrue(dc.shouldSortPropertiesAlphabetically()); }
/** * "Copy-constructor", used by sub-classes when creating actual non-blueprint instances to use. * * @param src Blueprint object used as the baseline for this instance */ protected SerializerProvider( SerializerProvider src, SerializationConfig config, SerializerFactory f) { if (config == null) { throw new NullPointerException(); } _serializerFactory = f; _config = config; _serializerCache = src._serializerCache; _unknownTypeSerializer = src._unknownTypeSerializer; _keySerializer = src._keySerializer; _nullValueSerializer = src._nullValueSerializer; _nullKeySerializer = src._nullKeySerializer; _stdNullValueSerializer = (_nullValueSerializer == DEFAULT_NULL_KEY_SERIALIZER); _serializationView = config.getActiveView(); _attributes = config.getAttributes(); /* Non-blueprint instances do have a read-only map; one that doesn't * need synchronization for lookups. */ _knownSerializers = _serializerCache.getReadOnlyLookupMap(); }
/** * 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; }
protected final DateFormat _dateFormat() { if (_dateFormat != null) { return _dateFormat; } /* At this point, all timezone configuration should have occured, with respect * to default dateformat configuration. But we still better clone * an instance as formatters are stateful, not thread-safe. */ DateFormat df = _config.getDateFormat(); _dateFormat = df = (DateFormat) df.clone(); // [databind#939]: 26-Sep-2015, tatu: With 2.6, formatter has been (pre)configured // with TimeZone, so we should NOT try overriding it unlike with earlier versions /* TimeZone tz = getTimeZone(); if (tz != df.getTimeZone()) { df.setTimeZone(tz); } */ return df; }
/** * 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; }
/** * Helper method called to set or override settings of passed-in {@link JsonGenerator} * * @since 2.1 */ private final void _configureJsonGenerator(JsonGenerator jgen) { if (_prettyPrinter != null) { PrettyPrinter pp = _prettyPrinter; if (pp == NULL_PRETTY_PRINTER) { jgen.setPrettyPrinter(null); } else { /* [JACKSON-851]: Better take care of stateful PrettyPrinters... * like the DefaultPrettyPrinter. */ if (pp instanceof Instantiatable<?>) { pp = (PrettyPrinter) ((Instantiatable<?>) pp).createInstance(); } jgen.setPrettyPrinter(pp); } } else if (_config.isEnabled(SerializationFeature.INDENT_OUTPUT)) { jgen.useDefaultPrettyPrinter(); } // [JACKSON-520]: add support for pass-through schema: if (_schema != null) { jgen.setSchema(_schema); } }
/** @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); }
/** * Helper method used when value to serialize is {@link Closeable} and its <code>close()</code> * method is to be called right after serialization has been called */ private final void _writeCloseableValue(JsonGenerator jgen, Object value, SerializationConfig cfg) throws IOException, JsonGenerationException, JsonMappingException { Closeable toClose = (Closeable) value; try { if (_rootType == null) { _serializerProvider(cfg).serializeValue(jgen, value); } else { _serializerProvider(cfg).serializeValue(jgen, value, _rootType, _rootSerializer); } if (_config.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) { jgen.flush(); } Closeable tmpToClose = toClose; toClose = null; tmpToClose.close(); } finally { if (toClose != null) { try { toClose.close(); } catch (IOException ioe) { } } } }
/** * Convenience method for accessing provider to find serialization filters used, equivalent to * calling: * * <pre> * getConfig().getFilterProvider(); * </pre> */ public final FilterProvider getFilterProvider() { return _config.getFilterProvider(); }
@Override public final boolean canOverrideAccessModifiers() { return _config.canOverrideAccessModifiers(); }
/** * Convenience method for checking whether specified serialization feature is enabled or not. * Shortcut for: * * <pre> * getConfig().isEnabled(feature); * </pre> */ public final boolean isEnabled(SerializationFeature feature) { return _config.isEnabled(feature); }
/** * "Bulk" access method for checking that all features specified by mask are enabled. * * @since 2.3 */ public final boolean hasSerializationFeatures(int featureMask) { return _config.hasSerializationFeatures(featureMask); }
/** * Method for accessing default Locale to use: convenience method for * * <pre> * getConfig().getLocale(); * </pre> */ @Override public Locale getLocale() { return _config.getLocale(); }
/** * Method for accessing default TimeZone to use: convenience method for * * <pre> * getConfig().getTimeZone(); * </pre> */ @Override public TimeZone getTimeZone() { return _config.getTimeZone(); }
@Override public final JsonFormat.Value getDefaultPropertyFormat(Class<?> baseType) { return _config.getDefaultPropertyFormat(baseType); }
/** @since 2.8 */ public final JsonInclude.Value getDefaultPropertyInclusion(Class<?> baseType) { return _config.getDefaultPropertyInclusion(); }
@Override public final boolean isEnabled(MapperFeature feature) { return _config.isEnabled(feature); }
public TypeFactory getTypeFactory() { return _config.getTypeFactory(); }
/** * Method that will construct a new instance that uses specified default {@link Base64Variant} for * base64 encoding * * @since 2.1 */ public ObjectWriter with(Base64Variant b64variant) { SerializationConfig newConfig = _config.with(b64variant); return (newConfig == _config) ? this : new ObjectWriter(this, newConfig); }
public boolean isEnabled(SerializationFeature f) { return _config.isEnabled(f); }
public boolean isEnabled(MapperFeature f) { return _config.isEnabled(f); }
@Override public final AnnotationIntrospector getAnnotationIntrospector() { return _config.getAnnotationIntrospector(); }
@Override public final TypeFactory getTypeFactory() { return _config.getTypeFactory(); }
/** @since 2.7 */ public JsonSerializer<Object> findKeySerializer(Class<?> rawKeyType, BeanProperty property) throws JsonMappingException { return findKeySerializer(_config.constructType(rawKeyType), property); }
public ObjectWriter with(TimeZone tz) { SerializationConfig newConfig = _config.with(tz); return (newConfig == _config) ? this : new ObjectWriter(this, newConfig); }