/* * 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.smartandroid.sa.json; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Map; import java.util.Set; import com.smartandroid.sa.json.internal.$Gson$Types; /** * Default serialization and deserialization of a map type. This implementation * really only works well with simple primitive types as the map key. If the key * is not a simple primitive then the object is {@code toString}ed and that * value is used as its key. * * @author Joel Leitch */ @SuppressWarnings("unchecked") final class MapTypeAdapter extends BaseMapTypeAdapter { public JsonElement serialize(Map src, Type typeOfSrc, JsonSerializationContext context) { JsonObject map = new JsonObject(); Type childGenericType = null; if (typeOfSrc instanceof ParameterizedType) { Class<?> rawTypeOfSrc = $Gson$Types.getRawType(typeOfSrc); childGenericType = $Gson$Types.getMapKeyAndValueTypes(typeOfSrc, rawTypeOfSrc)[1]; } for (Map.Entry entry : (Set<Map.Entry>) src.entrySet()) { Object value = entry.getValue(); JsonElement valueElement; if (value == null) { valueElement = JsonNull.INSTANCE; } else { Type childType = (childGenericType == null) ? value.getClass() : childGenericType; valueElement = serialize(context, value, childType); } map.add(String.valueOf(entry.getKey()), valueElement); } return map; } public Map deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { // Use ObjectConstructor to create instance instead of hard-coding a // specific type. // This handles cases where users are using their own subclass of Map. Map<Object, Object> map = constructMapType(typeOfT, context); Type[] keyAndValueTypes = $Gson$Types.getMapKeyAndValueTypes(typeOfT, $Gson$Types.getRawType(typeOfT)); for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject() .entrySet()) { Object key = context.deserialize(new JsonPrimitive(entry.getKey()), keyAndValueTypes[0]); Object value = context.deserialize(entry.getValue(), keyAndValueTypes[1]); map.put(key, value); } return map; } @Override public String toString() { return MapTypeAdapter.class.getSimpleName(); } }