/**
   * 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);
 }