001package arez.persist.runtime;
002
003import java.util.Map;
004import java.util.Objects;
005import javax.annotation.Nonnull;
006import javax.annotation.Nullable;
007
008/**
009 * A converter that encodes properties for a specific type.
010 */
011@SuppressWarnings( { "rawtypes", "unchecked" } )
012public final class TypeConverter
013{
014  /**
015   * A map of property names to converters.
016   */
017  @Nonnull
018  private final Map<String, Converter> _converters;
019
020  public TypeConverter( @Nonnull final Map<String, Converter> converters )
021  {
022    _converters = Objects.requireNonNull( converters );
023  }
024
025  /**
026   * Decode encoded value into form used by the application.
027   *
028   * @param key   the property name.
029   * @param encoded the encoded form of the value.
030   * @return the value.
031   * @param <A> the type of the value.
032   * @param <E> the type of the encoded value.
033   */
034  public <A, E> A decode( @Nonnull final String key, @Nullable E encoded )
035  {
036    if ( null == encoded )
037    {
038      return null;
039    }
040    else
041    {
042      final Converter converter = _converters.get( key );
043      return (A) ( null == converter ? encoded : converter.decode( encoded ) );
044    }
045  }
046
047  /**
048   * Encode value into form used by the storage system.
049   *
050   * @param key   the property name.
051   * @param value the decoded value.
052   * @return the encoded form of the value.
053   * @param <A> the type of the value.
054   * @param <E> the type of the encoded value.
055   */
056  public <A, E> E encode( @Nonnull final String key, @Nullable A value )
057  {
058    if ( null == value )
059    {
060      return null;
061    }
062    else
063    {
064      final Converter converter = _converters.get( key );
065      return (E) ( null == converter ? value : converter.encode( value ) );
066    }
067  }
068}