1
16
17 package com.google.gson.internal.bind;
18
19 import com.google.gson.Gson;
20 import com.google.gson.JsonDeserializer;
21 import com.google.gson.JsonSerializer;
22 import com.google.gson.TypeAdapter;
23 import com.google.gson.TypeAdapterFactory;
24 import com.google.gson.annotations.JsonAdapter;
25 import com.google.gson.internal.ConstructorConstructor;
26 import com.google.gson.reflect.TypeToken;
27
28
34 public final class JsonAdapterAnnotationTypeAdapterFactory implements TypeAdapterFactory {
35 private final ConstructorConstructor constructorConstructor;
36
37 public JsonAdapterAnnotationTypeAdapterFactory(ConstructorConstructor constructorConstructor) {
38 this.constructorConstructor = constructorConstructor;
39 }
40
41 @SuppressWarnings("unchecked")
42 @Override
43 public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> targetType) {
44 Class<? super T> rawType = targetType.getRawType();
45 JsonAdapter annotation = rawType.getAnnotation(JsonAdapter.class);
46 if (annotation == null) {
47 return null;
48 }
49 return (TypeAdapter<T>) getTypeAdapter(constructorConstructor, gson, targetType, annotation);
50 }
51
52 @SuppressWarnings({ "unchecked", "rawtypes" })
53 TypeAdapter<?> getTypeAdapter(ConstructorConstructor constructorConstructor, Gson gson,
54 TypeToken<?> type, JsonAdapter annotation) {
55 Object instance = constructorConstructor.get(TypeToken.get(annotation.value())).construct();
56
57 TypeAdapter<?> typeAdapter;
58 if (instance instanceof TypeAdapter) {
59 typeAdapter = (TypeAdapter<?>) instance;
60 } else if (instance instanceof TypeAdapterFactory) {
61 typeAdapter = ((TypeAdapterFactory) instance).create(gson, type);
62 } else if (instance instanceof JsonSerializer || instance instanceof JsonDeserializer) {
63 JsonSerializer<?> serializer = instance instanceof JsonSerializer
64 ? (JsonSerializer) instance
65 : null;
66 JsonDeserializer<?> deserializer = instance instanceof JsonDeserializer
67 ? (JsonDeserializer) instance
68 : null;
69 typeAdapter = new TreeTypeAdapter(serializer, deserializer, gson, type, null);
70 } else {
71 throw new IllegalArgumentException("Invalid attempt to bind an instance of "
72 + instance.getClass().getName() + " as a @JsonAdapter for " + type.toString()
73 + ". @JsonAdapter value must be a TypeAdapter, TypeAdapterFactory,"
74 + " JsonSerializer or JsonDeserializer.");
75 }
76
77 if (typeAdapter != null && annotation.nullSafe()) {
78 typeAdapter = typeAdapter.nullSafe();
79 }
80
81 return typeAdapter;
82 }
83 }
84