X-Git-Url: http://git.ieval.ro/?a=blobdiff_plain;f=gson%2Fcom%2Fgoogle%2Fgson%2Finternal%2Fbind%2FTypeAdapterRuntimeTypeWrapper.java;fp=gson%2Fcom%2Fgoogle%2Fgson%2Finternal%2Fbind%2FTypeAdapterRuntimeTypeWrapper.java;h=7e52c27d271f3840dfa6b2dbbe615b0ff9c05f6b;hb=5c86ae2f45d293408d98a291e826948052d207bc;hp=0000000000000000000000000000000000000000;hpb=5cf4714f0675349ed599707e024cf0e70fe114b2;p=unical.git diff --git a/gson/com/google/gson/internal/bind/TypeAdapterRuntimeTypeWrapper.java b/gson/com/google/gson/internal/bind/TypeAdapterRuntimeTypeWrapper.java new file mode 100644 index 0000000..7e52c27 --- /dev/null +++ b/gson/com/google/gson/internal/bind/TypeAdapterRuntimeTypeWrapper.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.gson.internal.bind; + +import com.google.gson.Gson; +import com.google.gson.TypeAdapter; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; + +final class TypeAdapterRuntimeTypeWrapper extends TypeAdapter { + private final Gson context; + private final TypeAdapter delegate; + private final Type type; + + TypeAdapterRuntimeTypeWrapper(Gson context, TypeAdapter delegate, Type type) { + this.context = context; + this.delegate = delegate; + this.type = type; + } + + @Override + public T read(JsonReader in) throws IOException { + return delegate.read(in); + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + @Override + public void write(JsonWriter out, T value) throws IOException { + // Order of preference for choosing type adapters + // First preference: a type adapter registered for the runtime type + // Second preference: a type adapter registered for the declared type + // Third preference: reflective type adapter for the runtime type (if it is a sub class of the declared type) + // Fourth preference: reflective type adapter for the declared type + + TypeAdapter chosen = delegate; + Type runtimeType = getRuntimeTypeIfMoreSpecific(type, value); + if (runtimeType != type) { + TypeAdapter runtimeTypeAdapter = context.getAdapter(TypeToken.get(runtimeType)); + if (!(runtimeTypeAdapter instanceof ReflectiveTypeAdapterFactory.Adapter)) { + // The user registered a type adapter for the runtime type, so we will use that + chosen = runtimeTypeAdapter; + } else if (!(delegate instanceof ReflectiveTypeAdapterFactory.Adapter)) { + // The user registered a type adapter for Base class, so we prefer it over the + // reflective type adapter for the runtime type + chosen = delegate; + } else { + // Use the type adapter for runtime type + chosen = runtimeTypeAdapter; + } + } + chosen.write(out, value); + } + + /** + * Finds a compatible runtime type if it is more specific + */ + private Type getRuntimeTypeIfMoreSpecific(Type type, Object value) { + if (value != null + && (type == Object.class || type instanceof TypeVariable || type instanceof Class)) { + type = value.getClass(); + } + return type; + } +}