Remove trailing whitespace
[unical.git] / gson / com / google / gson / internal / bind / TypeAdapterRuntimeTypeWrapper.java
CommitLineData
070d3ab2
MG
1/*
2 * Copyright (C) 2011 Google Inc.
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16package com.google.gson.internal.bind;
17
18import com.google.gson.Gson;
19import com.google.gson.TypeAdapter;
20import com.google.gson.reflect.TypeToken;
21import com.google.gson.stream.JsonReader;
22import com.google.gson.stream.JsonWriter;
23import java.io.IOException;
24import java.lang.reflect.Type;
25import java.lang.reflect.TypeVariable;
26
27final class TypeAdapterRuntimeTypeWrapper<T> extends TypeAdapter<T> {
28 private final Gson context;
29 private final TypeAdapter<T> delegate;
30 private final Type type;
31
32 TypeAdapterRuntimeTypeWrapper(Gson context, TypeAdapter<T> delegate, Type type) {
33 this.context = context;
34 this.delegate = delegate;
35 this.type = type;
36 }
37
38 @Override
39 public T read(JsonReader in) throws IOException {
40 return delegate.read(in);
41 }
42
43 @SuppressWarnings({"rawtypes", "unchecked"})
44 @Override
45 public void write(JsonWriter out, T value) throws IOException {
46 // Order of preference for choosing type adapters
47 // First preference: a type adapter registered for the runtime type
48 // Second preference: a type adapter registered for the declared type
49 // Third preference: reflective type adapter for the runtime type (if it is a sub class of the declared type)
50 // Fourth preference: reflective type adapter for the declared type
51
52 TypeAdapter chosen = delegate;
53 Type runtimeType = getRuntimeTypeIfMoreSpecific(type, value);
54 if (runtimeType != type) {
55 TypeAdapter runtimeTypeAdapter = context.getAdapter(TypeToken.get(runtimeType));
56 if (!(runtimeTypeAdapter instanceof ReflectiveTypeAdapterFactory.Adapter)) {
57 // The user registered a type adapter for the runtime type, so we will use that
58 chosen = runtimeTypeAdapter;
59 } else if (!(delegate instanceof ReflectiveTypeAdapterFactory.Adapter)) {
60 // The user registered a type adapter for Base class, so we prefer it over the
61 // reflective type adapter for the runtime type
62 chosen = delegate;
63 } else {
64 // Use the type adapter for runtime type
65 chosen = runtimeTypeAdapter;
66 }
67 }
68 chosen.write(out, value);
69 }
70
71 /**
72 * Finds a compatible runtime type if it is more specific
73 */
74 private Type getRuntimeTypeIfMoreSpecific(Type type, Object value) {
75 if (value != null
76 && (type == Object.class || type instanceof TypeVariable<?> || type instanceof Class<?>)) {
77 type = value.getClass();
78 }
79 return type;
80 }
81}
This page took 0.0139 seconds and 4 git commands to generate.