Java tutorial
package com.fasterxml.jackson.datatype.guava; import java.lang.reflect.Type; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.type.TypeBindings; import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.databind.type.TypeModifier; import com.google.common.collect.FluentIterable; import com.google.common.collect.Multimap; public class GuavaTypeModifier extends TypeModifier { @Override public JavaType modifyType(JavaType type, Type jdkType, TypeBindings context, TypeFactory typeFactory) { final Class<?> raw = type.getRawClass(); if (Multimap.class.isAssignableFrom(raw)) { JavaType keyType = type.containedType(0); JavaType contentType = type.containedType(1); if (keyType == null) { keyType = TypeFactory.unknownType(); } if (contentType == null) { contentType = TypeFactory.unknownType(); } return typeFactory.constructMapLikeType(type.getRawClass(), keyType, contentType); } /* Guava 12 changed the implementation of their {@link FluentIterable} to include a method named "isEmpty." This method * causes Jackson to treat FluentIterables as a Bean instead of an {@link Iterable}. Serialization of FluentIterables by * default result in a string like "{\"empty\":true}." This module modifies the JavaType of FluentIterable to be * the same as Iterable. */ /* Hmmh. This won't work too well for deserialization. But I guess it'll * have to do for now... */ if (FluentIterable.class.isAssignableFrom(raw)) { JavaType[] types = typeFactory.findTypeParameters(type, Iterable.class); JavaType elemType = (types == null || types.length < 1) ? null : types[0]; if (elemType == null) { elemType = TypeFactory.unknownType(); } return typeFactory.constructParametricType(Iterable.class, elemType); } return type; } }