/**
* Copyright (c) 2010 Darmstadt University of Technology.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Johannes Lerch - initial API and implementation.
*/
package org.eclipse.recommenders.utils.gson;
import static org.eclipse.recommenders.utils.Checks.*;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
@SuppressWarnings({ "rawtypes", "unchecked" })
public class MultimapTypeAdapter implements JsonSerializer<Multimap>, JsonDeserializer<Multimap> {
@Override
public JsonElement serialize(final Multimap src, final Type typeOfSrc, final JsonSerializationContext context) {
return context.serialize(src.asMap(), createMapType(typeOfSrc));
}
@Override
public Multimap deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context)
throws JsonParseException {
final Multimap multimap = HashMultimap.create();
final Map<Object, Collection> map = context.deserialize(json, createMapType(typeOfT));
for (Entry<Object, Collection> entry : map.entrySet()) {
multimap.putAll(entry.getKey(), entry.getValue());
}
return multimap;
}
private Type createMapType(final Type multimapType) {
final ParameterizedType paramType = ensureIsInstanceOf(multimapType, ParameterizedType.class);
final Type[] typeArguments = paramType.getActualTypeArguments();
ensureEquals(2, typeArguments.length, "Type must contain exactly 2 type arguments.");
final ParameterizedTypeImpl valueType = new ParameterizedTypeImpl(Collection.class, null, typeArguments[1]);
return new ParameterizedTypeImpl(Map.class, null, typeArguments[0], valueType);
}
}