1
16 package com.squareup.moshi;
17
18 import java.io.IOException;
19 import java.lang.annotation.Annotation;
20 import java.lang.reflect.Type;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.LinkedHashSet;
24 import java.util.List;
25 import java.util.Set;
26 import javax.annotation.Nullable;
27
28
29 abstract class CollectionJsonAdapter<C extends Collection<T>, T> extends JsonAdapter<C> {
30 public static final JsonAdapter.Factory FACTORY = new JsonAdapter.Factory() {
31 @Override public @Nullable JsonAdapter<?> create(
32 Type type, Set<? extends Annotation> annotations, Moshi moshi) {
33 Class<?> rawType = Types.getRawType(type);
34 if (!annotations.isEmpty()) return null;
35 if (rawType == List.class || rawType == Collection.class) {
36 return newArrayListAdapter(type, moshi).nullSafe();
37 } else if (rawType == Set.class) {
38 return newLinkedHashSetAdapter(type, moshi).nullSafe();
39 }
40 return null;
41 }
42 };
43
44 private final JsonAdapter<T> elementAdapter;
45
46 private CollectionJsonAdapter(JsonAdapter<T> elementAdapter) {
47 this.elementAdapter = elementAdapter;
48 }
49
50 static <T> JsonAdapter<Collection<T>> newArrayListAdapter(Type type, Moshi moshi) {
51 Type elementType = Types.collectionElementType(type, Collection.class);
52 JsonAdapter<T> elementAdapter = moshi.adapter(elementType);
53 return new CollectionJsonAdapter<Collection<T>, T>(elementAdapter) {
54 @Override Collection<T> newCollection() {
55 return new ArrayList<>();
56 }
57 };
58 }
59
60 static <T> JsonAdapter<Set<T>> newLinkedHashSetAdapter(Type type, Moshi moshi) {
61 Type elementType = Types.collectionElementType(type, Collection.class);
62 JsonAdapter<T> elementAdapter = moshi.adapter(elementType);
63 return new CollectionJsonAdapter<Set<T>, T>(elementAdapter) {
64 @Override Set<T> newCollection() {
65 return new LinkedHashSet<>();
66 }
67 };
68 }
69
70 abstract C newCollection();
71
72 @Override public C fromJson(JsonReader reader) throws IOException {
73 C result = newCollection();
74 reader.beginArray();
75 while (reader.hasNext()) {
76 result.add(elementAdapter.fromJson(reader));
77 }
78 reader.endArray();
79 return result;
80 }
81
82 @Override public void toJson(JsonWriter writer, C value) throws IOException {
83 writer.beginArray();
84 for (T element : value) {
85 elementAdapter.toJson(writer, element);
86 }
87 writer.endArray();
88 }
89
90 @Override public String toString() {
91 return elementAdapter + ".collection()";
92 }
93 }
94