001package io.avaje.json.core;
002
003import io.avaje.json.JsonAdapter;
004import io.avaje.json.JsonReader;
005import io.avaje.json.JsonWriter;
006
007import java.lang.reflect.Type;
008import java.util.List;
009import java.util.Map;
010import java.util.Set;
011import java.util.concurrent.ConcurrentHashMap;
012
013import static java.util.Objects.requireNonNull;
014
015/**
016 * Provides core JsonAdapter for common types.
017 * <p>
018 * Supports Boolean, Integer, Long, Double, Float, String.
019 */
020public final class CoreTypes {
021
022  private static final Map<Type, JsonAdapter<?>> adapterCache = new ConcurrentHashMap<>();
023  private static final NullPlaceholder NULL_PLACEHOLDER = new NullPlaceholder();
024
025  /**
026   * Return a core supported type adapter or null.
027   * <p>
028   * Supports Boolean, Integer, Long, Double, Float, String.
029   *
030   * @param type The type to get the adapter for.
031   * @return The JsonAdapter for the type or null.
032   */
033  @SuppressWarnings({"unchecked"})
034  public static <T> JsonAdapter<T> create(Type type) {
035    final JsonAdapter<?> adapter = adapterCache.computeIfAbsent(type, CoreTypes::createAdapter);
036    return adapter == NULL_PLACEHOLDER ? null : (JsonAdapter<T>) adapter;
037  }
038
039  /**
040   * Create a JsonAdapter for an Array of the given element type.
041   */
042  @SuppressWarnings("unchecked")
043  public static <T> JsonAdapter<T> createArray(Class<?> elementType) {
044    final JsonAdapter<Object> adapter = (JsonAdapter<Object>) createAdapter(elementType);
045    return createArray(elementType, adapter);
046  }
047
048  /**
049   * Create a JsonAdapter for an Array of the given type.
050   *
051   * @param elementType The element type of the array.
052   * @return The JsonAdapter for an Array of the given type.
053   */
054  @SuppressWarnings("unchecked")
055  public static <T> JsonAdapter<T> createArray(Class<?> elementType, JsonAdapter<Object> adapter) {
056    return (JsonAdapter<T>) ArrayAdapter.create(requireNonNull(elementType), requireNonNull(adapter));
057  }
058
059  /**
060   * Return a JsonAdapter for {@code byte[]}.
061   */
062  public static JsonAdapter<byte[]> byteArray() {
063    return ArrayAdapter.byteArray();
064  }
065
066  /**
067   * Create a JsonAdapter for a Map with a given adapter for the values.
068   *
069   * @param valueAdapter The JsonAdapter used for the values in the map.
070   * @return The JsonAdapter for the map.
071   */
072  public static <V> JsonAdapter<Map<String, V>> createMap(JsonAdapter<V> valueAdapter) {
073    return MapAdapter.create(valueAdapter);
074  }
075
076  /**
077   * Create a JsonAdapter for a List with a given adapter for the elements.
078   *
079   * @param elementAdapter The JsonAdapter used for the elements in the list.
080   * @return The JsonAdapter for the list.
081   */
082  public static <V> JsonAdapter<List<V>> createList(JsonAdapter<V> elementAdapter) {
083    return CollectionAdapter.createList(elementAdapter);
084  }
085
086  /**
087   * Create a JsonAdapter for a Set with a given adapter for the elements.
088   *
089   * @param elementAdapter The JsonAdapter used for the elements in the set.
090   * @return The JsonAdapter for the set.
091   */
092  public static <V> JsonAdapter<Set<V>> createSet(JsonAdapter<V> elementAdapter) {
093    return CollectionAdapter.createSet(elementAdapter);
094  }
095
096  /**
097   * Create a JsonAdapter that supports simple types including scalar
098   * types of: String, Integer, Long, Double, Boolean plus List and Map
099   * of those types.
100   */
101  public static CoreAdapters createCoreAdapters() {
102    return new BasicObjectAdapter();
103  }
104
105  private static JsonAdapter<?> createAdapter(Type type) {
106    final JsonAdapter<?> adapter = BaseAdapters.create(type);
107    if (adapter != null) {
108      return adapter;
109    }
110    return NULL_PLACEHOLDER;
111  }
112
113  static final class NullPlaceholder implements JsonAdapter<Void> {
114
115    @Override
116    public void toJson(JsonWriter writer, Void value) {
117      throw new UnsupportedOperationException();
118    }
119
120    @Override
121    public Void fromJson(JsonReader reader) {
122      throw new UnsupportedOperationException();
123    }
124  }
125
126  /**
127   * The basic JsonAdapter types.
128   */
129  public interface CoreAdapters {
130
131    /**
132     * Return the Object JsonAdapter.
133     */
134    JsonAdapter<Object> objectAdapter();
135
136    /**
137     * Return the List JsonAdapter.
138     */
139    JsonAdapter<List<Object>> listAdapter();
140
141    /**
142     * Return the Map JsonAdapter.
143     */
144    JsonAdapter<Map<String, Object>> mapAdapter();
145  }
146}