2 * Copyright (C) 2011 Google Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com
.google
.gson
.internal
.bind
;
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
;
34 * Adapt a homogeneous collection of objects.
36 public final class CollectionTypeAdapterFactory
implements TypeAdapterFactory
{
37 private final ConstructorConstructor constructorConstructor
;
39 public CollectionTypeAdapterFactory(ConstructorConstructor constructorConstructor
) {
40 this.constructorConstructor
= constructorConstructor
;
43 public <T
> TypeAdapter
<T
> create(Gson gson
, TypeToken
<T
> typeToken
) {
44 Type type
= typeToken
.getType();
46 Class
<?
super T
> rawType
= typeToken
.getRawType();
47 if (!Collection
.class.isAssignableFrom(rawType
)) {
51 Type elementType
= $Gson$Types
.getCollectionElementType(type
, rawType
);
52 TypeAdapter
<?
> elementTypeAdapter
= gson
.getAdapter(TypeToken
.get(elementType
));
53 ObjectConstructor
<T
> constructor
= constructorConstructor
.get(typeToken
);
55 @SuppressWarnings({"unchecked", "rawtypes"}) // create() doesn't define a type parameter
56 TypeAdapter
<T
> result
= new Adapter(gson
, elementType
, elementTypeAdapter
, constructor
);
60 private static final class Adapter
<E
> extends TypeAdapter
<Collection
<E
>> {
61 private final TypeAdapter
<E
> elementTypeAdapter
;
62 private final ObjectConstructor
<?
extends Collection
<E
>> constructor
;
64 public Adapter(Gson context
, Type elementType
,
65 TypeAdapter
<E
> elementTypeAdapter
,
66 ObjectConstructor
<?
extends Collection
<E
>> constructor
) {
67 this.elementTypeAdapter
=
68 new TypeAdapterRuntimeTypeWrapper
<E
>(context
, elementTypeAdapter
, elementType
);
69 this.constructor
= constructor
;
72 public Collection
<E
> read(JsonReader in
) throws IOException
{
73 if (in
.peek() == JsonToken
.NULL
) {
78 Collection
<E
> collection
= constructor
.construct();
80 while (in
.hasNext()) {
81 E instance
= elementTypeAdapter
.read(in
);
82 collection
.add(instance
);
88 public void write(JsonWriter out
, Collection
<E
> collection
) throws IOException
{
89 if (collection
== null) {
95 for (E element
: collection
) {
96 elementTypeAdapter
.write(out
, element
);