Add event basic tab. work in progress
[unical.git] / gson / com / google / gson / internal / bind / TypeAdapterRuntimeTypeWrapper.java
CommitLineData
cfd903b6
MG
1/*\r
2 * Copyright (C) 2011 Google Inc.\r
3 *\r
4 * Licensed under the Apache License, Version 2.0 (the "License");\r
5 * you may not use this file except in compliance with the License.\r
6 * You may obtain a copy of the License at\r
7 *\r
8 * http://www.apache.org/licenses/LICENSE-2.0\r
9 *\r
10 * Unless required by applicable law or agreed to in writing, software\r
11 * distributed under the License is distributed on an "AS IS" BASIS,\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13 * See the License for the specific language governing permissions and\r
14 * limitations under the License.\r
15 */\r
16package com.google.gson.internal.bind;\r
17\r
18import com.google.gson.Gson;\r
19import com.google.gson.TypeAdapter;\r
20import com.google.gson.reflect.TypeToken;\r
21import com.google.gson.stream.JsonReader;\r
22import com.google.gson.stream.JsonWriter;\r
23import java.io.IOException;\r
24import java.lang.reflect.Type;\r
25import java.lang.reflect.TypeVariable;\r
26\r
27final class TypeAdapterRuntimeTypeWrapper<T> extends TypeAdapter<T> {\r
28 private final Gson context;\r
29 private final TypeAdapter<T> delegate;\r
30 private final Type type;\r
31\r
32 TypeAdapterRuntimeTypeWrapper(Gson context, TypeAdapter<T> delegate, Type type) {\r
33 this.context = context;\r
34 this.delegate = delegate;\r
35 this.type = type;\r
36 }\r
37\r
38 @Override\r
39 public T read(JsonReader in) throws IOException {\r
40 return delegate.read(in);\r
41 }\r
42\r
43 @SuppressWarnings({"rawtypes", "unchecked"})\r
44 @Override\r
45 public void write(JsonWriter out, T value) throws IOException {\r
46 // Order of preference for choosing type adapters\r
47 // First preference: a type adapter registered for the runtime type\r
48 // Second preference: a type adapter registered for the declared type\r
49 // Third preference: reflective type adapter for the runtime type (if it is a sub class of the declared type)\r
50 // Fourth preference: reflective type adapter for the declared type\r
51\r
52 TypeAdapter chosen = delegate;\r
53 Type runtimeType = getRuntimeTypeIfMoreSpecific(type, value);\r
54 if (runtimeType != type) {\r
55 TypeAdapter runtimeTypeAdapter = context.getAdapter(TypeToken.get(runtimeType));\r
56 if (!(runtimeTypeAdapter instanceof ReflectiveTypeAdapterFactory.Adapter)) {\r
57 // The user registered a type adapter for the runtime type, so we will use that\r
58 chosen = runtimeTypeAdapter;\r
59 } else if (!(delegate instanceof ReflectiveTypeAdapterFactory.Adapter)) {\r
60 // The user registered a type adapter for Base class, so we prefer it over the\r
61 // reflective type adapter for the runtime type\r
62 chosen = delegate;\r
63 } else {\r
64 // Use the type adapter for runtime type\r
65 chosen = runtimeTypeAdapter;\r
66 }\r
67 }\r
68 chosen.write(out, value);\r
69 }\r
70\r
71 /**\r
72 * Finds a compatible runtime type if it is more specific\r
73 */\r
74 private Type getRuntimeTypeIfMoreSpecific(Type type, Object value) {\r
75 if (value != null\r
76 && (type == Object.class || type instanceof TypeVariable<?> || type instanceof Class<?>)) {\r
77 type = value.getClass();\r
78 }\r
79 return type;\r
80 }\r
81}\r
This page took 0.013622 seconds and 4 git commands to generate.