1
16
17 package com.google.gson.internal.bind;
18
19 import com.google.gson.Gson;
20 import com.google.gson.TypeAdapter;
21 import com.google.gson.TypeAdapterFactory;
22 import com.google.gson.internal.$Gson$Types;
23 import com.google.gson.internal.ConstructorConstructor;
24 import com.google.gson.internal.ObjectConstructor;
25 import com.google.gson.reflect.TypeToken;
26 import com.google.gson.stream.JsonReader;
27 import com.google.gson.stream.JsonToken;
28 import com.google.gson.stream.JsonWriter;
29 import java.io.IOException;
30 import java.lang.reflect.Type;
31 import java.util.Collection;
32
33
36 public final class CollectionTypeAdapterFactory implements TypeAdapterFactory {
37 private final ConstructorConstructor constructorConstructor;
38
39 public CollectionTypeAdapterFactory(ConstructorConstructor constructorConstructor) {
40 this.constructorConstructor = constructorConstructor;
41 }
42
43 @Override
44 public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
45 Type type = typeToken.getType();
46
47 Class<? super T> rawType = typeToken.getRawType();
48 if (!Collection.class.isAssignableFrom(rawType)) {
49 return null;
50 }
51
52 Type elementType = $Gson$Types.getCollectionElementType(type, rawType);
53 TypeAdapter<?> elementTypeAdapter = gson.getAdapter(TypeToken.get(elementType));
54 ObjectConstructor<T> constructor = constructorConstructor.get(typeToken);
55
56 @SuppressWarnings({"unchecked", "rawtypes"})
57 TypeAdapter<T> result = new Adapter(gson, elementType, elementTypeAdapter, constructor);
58 return result;
59 }
60
61 private static final class Adapter<E> extends TypeAdapter<Collection<E>> {
62 private final TypeAdapter<E> elementTypeAdapter;
63 private final ObjectConstructor<? extends Collection<E>> constructor;
64
65 public Adapter(Gson context, Type elementType,
66 TypeAdapter<E> elementTypeAdapter,
67 ObjectConstructor<? extends Collection<E>> constructor) {
68 this.elementTypeAdapter =
69 new TypeAdapterRuntimeTypeWrapper<E>(context, elementTypeAdapter, elementType);
70 this.constructor = constructor;
71 }
72
73 @Override public Collection<E> read(JsonReader in) throws IOException {
74 if (in.peek() == JsonToken.NULL) {
75 in.nextNull();
76 return null;
77 }
78
79 Collection<E> collection = constructor.construct();
80 in.beginArray();
81 while (in.hasNext()) {
82 E instance = elementTypeAdapter.read(in);
83 collection.add(instance);
84 }
85 in.endArray();
86 return collection;
87 }
88
89 @Override public void write(JsonWriter out, Collection<E> collection) throws IOException {
90 if (collection == null) {
91 out.nullValue();
92 return;
93 }
94
95 out.beginArray();
96 for (E element : collection) {
97 elementTypeAdapter.write(out, element);
98 }
99 out.endArray();
100 }
101 }
102 }
103