Subversion Repositories bacoAlunos

Rev

Blame | Last modification | View Log | RSS feed

package com.owlike.genson;

import java.io.*;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import com.owlike.genson.reflect.BeanDescriptor;
import com.owlike.genson.reflect.BeanDescriptorProvider;
import com.owlike.genson.reflect.RuntimePropertyFilter;
import com.owlike.genson.stream.*;

/**
 * <p/>
 * Main class of the library. Instances of Genson are thread safe and should be reused.
 * You can instantiate it multiple times but it is better to have an instance per configuration
 * so you can benefit of better performances.
 * <p/>
 * For more examples have a look at the <a
 * href="http://owlike.github.io/genson/">online documentation</a>.
 * <p/>
 * <p/>
 * To create a new instance of Genson you can use the default no arg constructor or the
 * {@link GensonBuilder} class to have control over Gensons configuration. <br>
 * A basic usage of Genson would be:
 * <p/>
 * <pre>
 * Genson genson = new Genson();
 * String json = genson.serialize(new int[] { 1, 2, 3 });
 * int[] arrayOfInt = genson.deserialize(json, int[].class);
 * // (multi-dimensional arrays are also supported)
 *
 * // genson can also deserialize primitive types without class information
 * Number[] arrayOfNumber = genson.deserialize(&quot;[1, 2.03, 8877463]&quot;, Number[].class);
 * // or even
 * Object[] arrayOfUnknownTypes = genson
 *              .deserialize(&quot;[1, false, null, 4.05, \&quot;hey this is a string!\&quot;]&quot;, Object[].class);
 * // it can also deserialize json objects of unknown types to standard java types such as Map, Array, Long etc.
 * Map&lt;String, Object&gt; map = (Map&lt;String, Object&gt;) genson.deserialize(&quot;{\&quot;foo\&quot;:1232}&quot;, Object.class);
 * </pre>
 * <p/>
 *
 * Every object serialized with Genson, can be deserialized back into its concrete type! Just enable
 * it via the builder {@link com.owlike.genson.GensonBuilder#useClassMetadata(boolean)}.
 *
 * You can also deserialize to objects that don't provide a default constructor with no arguments
 * {@link com.owlike.genson.GensonBuilder#useConstructorWithArguments(boolean)}.
 *
 * @author eugen
 */

public final class Genson {
  /**
   * Default genson configuration, the default configuration (sers, desers, etc) will be shared
   * accros all default Genson instances.
   */

  private final static Genson _default = new GensonBuilder().create();
  private final static 1.5.0/docs/api/java/nio/charset/Charset.html">Charset UTF8_CHARSET = 1.5.0/docs/api/java/nio/charset/Charset.html">Charset.forName("UTF-8");

  private final ConcurrentHashMap<Type, Converter<?>> converterCache = new ConcurrentHashMap<Type, Converter<?>>();
  private final Factory<Converter<?>> converterFactory;
  private final BeanDescriptorProvider beanDescriptorFactory;
  private final Map<Class<?>, String> classAliasMap;
  private final Map<String, Class<?>> aliasClassMap;
  private final boolean skipNull;
  private final boolean htmlSafe;
  private final boolean withClassMetadata;
  private final boolean withMetadata;
  private final boolean strictDoubleParse;
  private final boolean indent;
  private final boolean failOnMissingProperty;
  private final EncodingAwareReaderFactory readerFactory = new EncodingAwareReaderFactory();
  private final Map<Class<?>, Object> defaultValues;
  private final RuntimePropertyFilter runtimePropertyFilter;

  /**
   * The default constructor will use the default configuration provided by the {@link GensonBuilder}.
   * In most cases using this default constructor will suffice.
   */

  public Genson() {
    this(_default.converterFactory, _default.beanDescriptorFactory,
      _default.skipNull, _default.htmlSafe, _default.aliasClassMap,
      _default.withClassMetadata, _default.strictDoubleParse, _default.indent,
      _default.withMetadata, _default.failOnMissingProperty, _default.defaultValues, _default.runtimePropertyFilter);
  }

  /**
   * Instead of using this constructor you should use {@link GensonBuilder}.
   * @param converterFactory  providing instance of converters.
   * @param beanDescProvider  providing instance of {@link BeanDescriptor
   *                          BeanDescriptor} used during bean serialization and deserialization.
   * @param skipNull          indicates whether null values should be serialized. False by default, null values
*                          will be serialized.
   * @param htmlSafe          indicates whether \,<,>,&,= characters should be replaced by their Unicode
*                          representation.
   * @param classAliases      association map between classes and their aliases, used if withClassMetadata is
*                          true.
   * @param withClassMetadata indicates whether class name should be serialized and used during deserialization
*                          to determine the type. False by default.
   * @param strictDoubleParse indicates whether to use or not double approximation. If false (by default) it
*                          enables Genson custom double parsing algorithm, that is an approximation of
*                          Double.parse but is a lot faster. If true, Double.parse method will be usead
*                          instead. In most cases you should be fine with Genson algorithm, but if for some
*                          reason you need to have 100% match with Double.parse, then enable strict parsing.
   * @param indent            true if outputed json must be indented (pretty printed).
   * @param withMetadata      true if ObjectReader instances must be configured with metadata feature enabled.
*                          if withClassMetadata is true withMetadata will be automatically true.
   * @param failOnMissingProperty throw a JsonBindingException when a key in the json stream does not match a property in the Java Class.
   * @param defaultValues contains a mapping from the raw class to the default value that should be used when the property is missing.
   * @param runtimePropertyFilter is used to define what bean properties should be excluded from ser/de at runtime.
   */

  public Genson(Factory<Converter<?>> converterFactory, BeanDescriptorProvider beanDescProvider,
                boolean skipNull, boolean htmlSafe, Map<String, Class<?>> classAliases, boolean withClassMetadata,
                boolean strictDoubleParse, boolean indent, boolean withMetadata, boolean failOnMissingProperty,
                Map<Class<?>, Object> defaultValues, RuntimePropertyFilter runtimePropertyFilter) {
    this.converterFactory = converterFactory;
    this.beanDescriptorFactory = beanDescProvider;
    this.skipNull = skipNull;
    this.htmlSafe = htmlSafe;
    this.aliasClassMap = classAliases;
    this.withClassMetadata = withClassMetadata;
    this.defaultValues = defaultValues;
    this.runtimePropertyFilter = runtimePropertyFilter;
    this.classAliasMap = new HashMap<Class<?>, String>(classAliases.size());
    for (1.5.0/docs/api/java/util/Map.html">Map.Entry<String, Class<?>> entry : classAliases.entrySet()) {
      classAliasMap.put(entry.getValue(), entry.getKey());
    }
    this.strictDoubleParse = strictDoubleParse;
    this.indent = indent;
    this.withMetadata = withClassMetadata || withMetadata;
    this.failOnMissingProperty = failOnMissingProperty;
  }

  /**
   * Provides an instance of Converter capable of handling objects of type forType.
   *
   * @param forType the type for which a converter is needed.
   * @return the converter instance.
   * @throws com.owlike.genson.JsonBindingException if a problem occurs during converters lookup/construction.
   */

  @1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings("unchecked")
  public <T> Converter<T> provideConverter(1.5.0/docs/api/java/lang/reflect/Type.html">Type forType) {
    if (1.5.0/docs/api/java/lang/Boolean.html">Boolean.TRUE.equals(ThreadLocalHolder.get("__GENSON$DO_NOT_CACHE_CONVERTER", 1.5.0/docs/api/java/lang/Boolean.html">Boolean.class))) {
      return (Converter<T>) converterFactory.create(forType, this);
    } else {
      Converter<T> converter = (Converter<T>) converterCache.get(forType);
      if (converter == null) {
        converter = (Converter<T>) converterFactory.create(forType, this);
        if (converter == null)
          throw new JsonBindingException("No converter found for type " + forType);
        converterCache.putIfAbsent(forType, converter);
      }
      return converter;
    }
  }

  /**
   * Serializes the object into a json string.
   *
   * @param object object to be serialized.
   * @return the serialized object as a string.
   * @throws com.owlike.genson.JsonBindingException if there was any kind of error during serialization.
   * @throws JsonStreamException                    if there was a problem during writing of the object to the output.
   */

  public 1.5.0/docs/api/java/lang/String.html">String serialize(5+0%2Fdocs%2Fapi+Object">Object object) {
    1.5.0/docs/api/java/io/StringWriter.html">StringWriter sw = new 1.5.0/docs/api/java/io/StringWriter.html">StringWriter();
    ObjectWriter writer = createWriter(sw);

    if (object == null) serializeNull(writer);
    else serialize(object, object.getClass(), writer, new 5+0%2Fdocs%2Fapi+Context">Context(this));

    return sw.toString();
  }

  /**
   * Serializes the object using the type of GenericType instead of using its runtime type.
   *
   * @param object object to be serialized.
   * @param type   the type of the object to be serialized.
   * @return json string representation.
   * @throws com.owlike.genson.JsonBindingException
   * @throws JsonStreamException
   */

  public 1.5.0/docs/api/java/lang/String.html">String serialize(5+0%2Fdocs%2Fapi+Object">Object object, GenericType<?> type) {
    1.5.0/docs/api/java/io/StringWriter.html">StringWriter sw = new 1.5.0/docs/api/java/io/StringWriter.html">StringWriter();
    ObjectWriter writer = createWriter(sw);

    if (object == null) serializeNull(writer);
    else serialize(object, type.getType(), writer, new 5+0%2Fdocs%2Fapi+Context">Context(this));

    return sw.toString();
  }

  /**
   * Serializes the object using the specified BeanViews.
   *
   * @param object
   * @param withViews the BeanViews to apply during this serialization.
   * @return the json string representing this object
   * @throws com.owlike.genson.JsonBindingException
   * @throws com.owlike.genson.stream.JsonStreamException
   * @see BeanView
   */

  public 1.5.0/docs/api/java/lang/String.html">String serialize(5+0%2Fdocs%2Fapi+Object">Object object, Class<? extends BeanView<?>> firstView, Class<? extends BeanView<?>>... withViews) {
    1.5.0/docs/api/java/io/StringWriter.html">StringWriter sw = new 1.5.0/docs/api/java/io/StringWriter.html">StringWriter();
    ObjectWriter writer = createWriter(sw);

    List<Class<? extends BeanView<?>>> views = new 1.5.0/docs/api/java/util/ArrayList.html">ArrayList(withViews.length);
    for (Class<? extends BeanView<?>> view : withViews) views.add(view);
    views.add(firstView);

    if (object == null) serializeNull(writer);
    else serialize(object, object.getClass(), writer, new 5+0%2Fdocs%2Fapi+Context">Context(this, views));

    return sw.toString();
  }

  /**
   * Serializes this object to the passed Writer, as Genson did not instantiate it, you are
   * responsible of calling close on it.
   */

  public void serialize(5+0%2Fdocs%2Fapi+Object">Object object, 1.5.0/docs/api/java/io/Writer.html">Writer writer) {
    ObjectWriter objectWriter = createWriter(writer);

    if (object == null) serializeNull(objectWriter);
    else serialize(object, object.getClass(), objectWriter, new 5+0%2Fdocs%2Fapi+Context">Context(this));
  }

  /**
   * Serializes this object to the passed OutputStream, as Genson did not instantiate it, you are
   * responsible of calling close on it.
   */

  public void serialize(5+0%2Fdocs%2Fapi+Object">Object object, 5+0%2Fdocs%2Fapi+OutputStream">OutputStream output) {
    ObjectWriter objectWriter = createWriter(output);

    if (object == null) serializeNull(objectWriter);
    else serialize(object, object.getClass(), objectWriter, new 5+0%2Fdocs%2Fapi+Context">Context(this));
  }

  /**
   * Serializes this object to its json form in a byte array.
   */

  public byte[] serializeBytes(5+0%2Fdocs%2Fapi+Object">Object object) {
    1.5.0/docs/api/java/io/ByteArrayOutputStream.html">ByteArrayOutputStream baos = new 1.5.0/docs/api/java/io/ByteArrayOutputStream.html">ByteArrayOutputStream();
    ObjectWriter objectWriter = createWriter(baos);

    if (object == null) serializeNull(objectWriter);
    else serialize(object, object.getClass(), objectWriter, new 5+0%2Fdocs%2Fapi+Context">Context(this));

    return baos.toByteArray();
  }

  /**
   * Serializes this object and writes its representation to writer. As you are providing the
   * writer instance you also must ensure to call flush and close on it when you are done.
   *
   * @param object
   * @param writer into which to write the serialized object.
   * @throws com.owlike.genson.JsonBindingException
   * @throws JsonStreamException
   */

  public void serialize(5+0%2Fdocs%2Fapi+Object">Object object, ObjectWriter writer, 5+0%2Fdocs%2Fapi+Context">Context ctx) {
    if (object == null) serializeNull(writer);
    else serialize(object, object.getClass(), writer, ctx);
  }

  /**
   * Serializes this object and writes its representation to writer. As you are providing the
   * writer instance you also must ensure to call close on it when you are done.
   */

  public void serialize(5+0%2Fdocs%2Fapi+Object">Object object, 1.5.0/docs/api/java/lang/reflect/Type.html">Type type, ObjectWriter writer, 5+0%2Fdocs%2Fapi+Context">Context ctx) {
    Serializer<Object> ser = provideConverter(type);
    try {
      ser.serialize(object, writer, ctx);
      writer.flush();
    } catch (1.5.0/docs/api/java/lang/Exception.html">Exception e) {
      throw new JsonBindingException("Failed to serialize object of type " + type, e);
    }
  }

  private void serializeNull(ObjectWriter writer) {
    try {
      writer.writeNull();
      writer.flush();
    } catch (1.5.0/docs/api/java/lang/Exception.html">Exception e) {
      throw new JsonBindingException("Could not serialize null value.", e);
    }
  }

  /**
   * Deserializes fromSource String into an instance of toClass.
   *
   * @param fromSource source from which to deserialize.
   * @param toClass    type into which to deserialize.
   * @throws com.owlike.genson.JsonBindingException
   * @throws JsonStreamException
   */

  public <T> T deserialize(1.5.0/docs/api/java/lang/String.html">String fromSource, Class<T> toClass) {
    return deserialize(GenericType.of(toClass), createReader(new 1.5.0/docs/api/java/io/StringReader.html">StringReader(fromSource)),
      new 5+0%2Fdocs%2Fapi+Context">Context(this));
  }

  /**
   * Deserializes to an instance of T. GenericType is useful when you want to deserialize to a
   * list or map (or any other type with generics).
   *
   * @param fromSource
   * @param toType
   * @throws com.owlike.genson.JsonBindingException
   * @throws JsonStreamException
   * @see GenericType
   */

  public <T> T deserialize(1.5.0/docs/api/java/lang/String.html">String fromSource, GenericType<T> toType) {
    return deserialize(toType, createReader(new 1.5.0/docs/api/java/io/StringReader.html">StringReader(fromSource)), new 5+0%2Fdocs%2Fapi+Context">Context(this));
  }

  /**
   * Deserializes the incoming json stream into an instance of T.
   * Genson did not create the instance of Reader so it will not be closed
   */

  public <T> T deserialize(1.5.0/docs/api/java/io/Reader.html">Reader reader, GenericType<T> toType) {
    return deserialize(toType, createReader(reader), new 5+0%2Fdocs%2Fapi+Context">Context(this));
  }

  /**
   * Deserializes the incoming json stream into an instance of T.
   * Genson did not create the instance of Reader so it will not be closed
   */

  public <T> T deserialize(1.5.0/docs/api/java/io/Reader.html">Reader reader, Class<T> toType) {
    return deserialize(GenericType.of(toType), createReader(reader), new 5+0%2Fdocs%2Fapi+Context">Context(this));
  }

  /**
   * Deserializes the incoming json stream into an instance of T.
   * Genson did not create the instance of InputStream so it will not be closed
   */

  public <T> T deserialize(5+0%2Fdocs%2Fapi+InputStream">InputStream input, Class<T> toType) {
    return deserialize(GenericType.of(toType), createReader(input), new 5+0%2Fdocs%2Fapi+Context">Context(this));
  }

  /**
   * Deserializes the incoming json stream into an instance of T.
   * Genson did not create the instance of InputStream so it will not be closed.
   */

  public <T> T deserialize(5+0%2Fdocs%2Fapi+InputStream">InputStream input, GenericType<T> toType) {
    return deserialize(toType, createReader(input), new 5+0%2Fdocs%2Fapi+Context">Context(this));
  }

  /**
   * Deserializes the incoming json byte array into an instance of T.
   */

  public <T> T deserialize(byte[] input, Class<T> toType) {
    return deserialize(GenericType.of(toType), createReader(input), new 5+0%2Fdocs%2Fapi+Context">Context(this));
  }

  /**
   * Deserializes the incoming json byte array into an instance of T.
   */

  public <T> T deserialize(byte[] input, GenericType<T> toType) {
    return deserialize(toType, createReader(input), new 5+0%2Fdocs%2Fapi+Context">Context(this));
  }

  public <T> T deserialize(1.5.0/docs/api/java/lang/String.html">String fromSource, GenericType<T> toType, Class<? extends BeanView<?>>... withViews) {
    1.5.0/docs/api/java/io/StringReader.html">StringReader reader = new 1.5.0/docs/api/java/io/StringReader.html">StringReader(fromSource);
    return deserialize(toType, createReader(reader),
      new 5+0%2Fdocs%2Fapi+Context">Context(this, 1.5.0/docs/api/java/util/Arrays.html">Arrays.asList(withViews)));
  }

  public <T> T deserialize(1.5.0/docs/api/java/lang/String.html">String fromSource, Class<T> toType, Class<? extends BeanView<?>>... withViews) {
    1.5.0/docs/api/java/io/StringReader.html">StringReader reader = new 1.5.0/docs/api/java/io/StringReader.html">StringReader(fromSource);
    return deserialize(GenericType.of(toType), createReader(reader),
      new 5+0%2Fdocs%2Fapi+Context">Context(this, 1.5.0/docs/api/java/util/Arrays.html">Arrays.asList(withViews)));
  }

  public <T> T deserialize(GenericType<T> type, 1.5.0/docs/api/java/io/Reader.html">Reader reader, Class<? extends BeanView<?>>... withViews) {
    return deserialize(type, createReader(reader), new 5+0%2Fdocs%2Fapi+Context">Context(this, 1.5.0/docs/api/java/util/Arrays.html">Arrays.asList(withViews)));
  }

  public <T> T deserialize(GenericType<T> type, ObjectReader reader, 5+0%2Fdocs%2Fapi+Context">Context ctx) {
    Deserializer<T> deser = provideConverter(type.getType());
    try {
      return deser.deserialize(reader, ctx);
    } catch (1.5.0/docs/api/java/lang/Exception.html">Exception e) {
      throw new JsonBindingException("Could not deserialize to type " + type.getRawClass(), e);
    }
  }

  /**
   * @see #deserializeInto(com.owlike.genson.stream.ObjectReader, Object, Context)
   */

  public <T> T deserializeInto(1.5.0/docs/api/java/lang/String.html">String json, T object) {
    return deserializeInto(createReader(new 1.5.0/docs/api/java/io/StringReader.html">StringReader(json)), object, new 5+0%2Fdocs%2Fapi+Context">Context(this));
  }

  /**
   * @see #deserializeInto(com.owlike.genson.stream.ObjectReader, Object, Context)
   */

  public <T> T deserializeInto(byte[] jsonBytes, T object) {
    return deserializeInto(createReader(jsonBytes), object, new 5+0%2Fdocs%2Fapi+Context">Context(this));
  }

  /**
   * @see #deserializeInto(com.owlike.genson.stream.ObjectReader, Object, Context)
   */

  public <T> T deserializeInto(5+0%2Fdocs%2Fapi+InputStream">InputStream is, T object) {
    return deserializeInto(createReader(is), object, new 5+0%2Fdocs%2Fapi+Context">Context(this));
  }

  /**
   * @see #deserializeInto(com.owlike.genson.stream.ObjectReader, Object, Context)
   */

  public <T> T deserializeInto(1.5.0/docs/api/java/io/Reader.html">Reader reader, T object) {
    return deserializeInto(createReader(reader), object, new 5+0%2Fdocs%2Fapi+Context">Context(this));
  }

  /**
   * Deserializes the stream in the existing object. Note however that this works only for Pojos
   * and doesn't handle nested objects (will be overridden by the values from the stream).
   *
   * @return the object enriched with the properties from the stream.
   */

  public <T> T deserializeInto(ObjectReader reader, T object, 5+0%2Fdocs%2Fapi+Context">Context ctx) {
    BeanDescriptor<T> bd = (BeanDescriptor<T>) getBeanDescriptorProvider().provide(object.getClass(), this);
    bd.deserialize(object, reader, ctx);
    return object;
  }

  /**
   * @see #deserializeValues(com.owlike.genson.stream.ObjectReader, GenericType)
   */

  public <T> Iterator<T> deserializeValues(final 5+0%2Fdocs%2Fapi+InputStream">InputStream is, final Class<T> type) {
    return deserializeValues(createReader(is), GenericType.of(type));
  }

  /**
   * This can be used to deserialize in an efficient streaming fashion a sequence of objects.
   * Note that you can use this method when your values are wrapped in an array (valid json) but also
   * when they all are root values (not enclosed in an array). For example:
   *
   * <pre>
   *   Genson genson = new Genson();
   *   ObjectReader reader = genson.createReader(json);
   *
   *   for (Iterator&lt;LogEntry> it = genson.deserializeValues(reader, GenericType.of(LogEntry.class));
   *    it.hasNext(); ) {
   *      // do something
   *      LogEntry p = it.next();
   *   }
   * </pre>
   * @param reader an instance of the ObjectReader to use (obtained with genson.createReader(...) for ex.),
   *               note that you are responsible of closing it.
   * @param type to deserialize to
   * @param <T>
   * @return an iterator of T
   */

  public <T> Iterator<T> deserializeValues(final ObjectReader reader, final GenericType<T> type) {
    final boolean isArray = reader.getValueType() == ValueType.ARRAY;
    if (isArray == true) {
      reader.beginArray();
    }

    return new Iterator<T>() {
      final Converter<T> converter = provideConverter(type.getType());
      final 5+0%2Fdocs%2Fapi+Context">Context ctx = new 5+0%2Fdocs%2Fapi+Context">Context(Genson.this);

      @1.5.0/docs/api/java/lang/Override.html">Override
      public boolean hasNext() {
        boolean hasMore = reader.hasNext();
        if (isArray && !hasMore) reader.endArray();
        return hasMore;
      }

      @1.5.0/docs/api/java/lang/Override.html">Override
      public T next() {
        if (!hasNext()) throw new 1.5.0/docs/api/java/util/NoSuchElementException.html">NoSuchElementException();
        reader.next();
        try {
          return converter.deserialize(reader, ctx);
        } catch (1.5.0/docs/api/java/lang/Exception.html">Exception e) {
          throw new JsonBindingException("Could not deserialize to type " + type.getRawClass(), e);
        }
      }

      @1.5.0/docs/api/java/lang/Override.html">Override
      public void remove() {
        throw new 1.5.0/docs/api/java/lang/UnsupportedOperationException.html">UnsupportedOperationException();
      }
    };
  }

    /**
     * Searches if an alias has been registered for clazz. If not will take the class full name and
     * use it as alias. This method never returns null.
     */

  public <T> 1.5.0/docs/api/java/lang/String.html">String aliasFor(Class<T> clazz) {
    1.5.0/docs/api/java/lang/String.html">String alias = classAliasMap.get(clazz);
    if (alias == null) {
      alias = clazz.getName();
      classAliasMap.put(clazz, alias);
    }
    return alias;
  }

  /**
   * Searches for the class matching this alias, if none will try to use the alias as the class
   * name.
   *
   * @param alias
   * @return The class matching this alias.
   * @throws ClassNotFoundException thrown if no class has been registered for this alias and the alias it self does
   *                                not correspond to the full name of a class.
   */

  public Class<?> classFor(1.5.0/docs/api/java/lang/String.html">String alias) throws 1.5.0/docs/api/java/lang/ClassNotFoundException.html">ClassNotFoundException {
    Class<?> clazz = aliasClassMap.get(alias);
    if (clazz == null) {
      clazz = 1.5.0/docs/api/java/lang/Class.html">Class.forName(alias);
      aliasClassMap.put(alias, clazz);
    }
    return clazz;
  }

  /**
   * Creates a new ObjectWriter with this Genson instance configuration and default encoding to
   * UTF8.
   */

  public ObjectWriter createWriter(5+0%2Fdocs%2Fapi+OutputStream">OutputStream os) {
    return new JsonWriter(new 1.5.0/docs/api/java/io/OutputStreamWriter.html">OutputStreamWriter(os, UTF8_CHARSET), skipNull, htmlSafe, indent);
  }

  /**
   * Creates a new ObjectWriter with this Genson instance configuration.
   */

  public ObjectWriter createWriter(5+0%2Fdocs%2Fapi+OutputStream">OutputStream os, 1.5.0/docs/api/java/nio/charset/Charset.html">Charset charset) {
    return createWriter(new 1.5.0/docs/api/java/io/OutputStreamWriter.html">OutputStreamWriter(os, charset));
  }

  /**
   * Creates a new ObjectWriter with this Genson instance configuration.
   */

  public ObjectWriter createWriter(1.5.0/docs/api/java/io/Writer.html">Writer writer) {
    return new JsonWriter(writer, skipNull, htmlSafe, indent);
  }

  /**
   * @see #createReader(java.io.InputStream)
   */

  public ObjectReader createReader(byte[] in) {
    try {
      return createReader(readerFactory.createReader(new 1.5.0/docs/api/java/io/ByteArrayInputStream.html">ByteArrayInputStream(in)));
    } catch (1.5.0/docs/api/java/io/IOException.html">IOException e) {
      throw new JsonStreamException("Failed to detect encoding.", e);
    }
  }

  /**
   * Creates a new ObjectReader with this Genson instance configuration and tries to detect the encoding
   * from the stream content.
   */

  public ObjectReader createReader(5+0%2Fdocs%2Fapi+InputStream">InputStream is) {
    try {
      return createReader(readerFactory.createReader(is));
    } catch (1.5.0/docs/api/java/io/IOException.html">IOException e) {
      throw new JsonStreamException("Failed to detect encoding.", e);
    }
  }

  /**
   * Creates a new ObjectReader with this Genson instance configuration.
   */

  public ObjectReader createReader(5+0%2Fdocs%2Fapi+InputStream">InputStream is, 1.5.0/docs/api/java/nio/charset/Charset.html">Charset charset) {
    return createReader(new 1.5.0/docs/api/java/io/InputStreamReader.html">InputStreamReader(is, charset));
  }

  /**
   * Creates a new ObjectReader with this Genson instance configuration.
   */

  public ObjectReader createReader(1.5.0/docs/api/java/io/Reader.html">Reader reader) {
    return new JsonReader(reader, strictDoubleParse, withMetadata);
  }

  public boolean isSkipNull() {
    return skipNull;
  }

  public boolean isHtmlSafe() {
    return htmlSafe;
  }

  public boolean isWithClassMetadata() {
    return withClassMetadata;
  }

  public BeanDescriptorProvider getBeanDescriptorProvider() {
    return beanDescriptorFactory;
  }

  public boolean failOnMissingProperty() {
    return this.failOnMissingProperty;
  }

  /**
   * @return the defined default value for type clazz or null if none is defined. Intended for internal use.
   */

  public <T> T defaultValue(Class<T> clazz) {
    return (T) defaultValues.get(clazz);
  }

  public RuntimePropertyFilter runtimePropertyFilter() {
    return runtimePropertyFilter;
  }

  /**
   * @deprecated use GensonBuilder
   */

  @1.5.0/docs/api/java/lang/Deprecated.html">Deprecated
  public static class Builder extends GensonBuilder {

  }
}