Skip to content

Instantly share code, notes, and snippets.

@Piasy
Forked from JakeWharton/AutoGson.java
Last active August 29, 2015 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Piasy/fa507251da452d36b221 to your computer and use it in GitHub Desktop.
Save Piasy/fa507251da452d36b221 to your computer and use it in GitHub Desktop.
A Gson TypeAdapterFactory which allows serialization of @autovalue types. Apache 2 licensed.
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
public final class AutoGenTypeAdapterFactory implements TypeAdapterFactory {
@SuppressWarnings("unchecked")
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
Class<T> rawType = (Class<T>) type.getRawType();
AutoGson annotation = rawType.getAnnotation(AutoGson.class);
// Only deserialize classes decorated with @AutoGson.
if (annotation == null) {
return null;
}
return (TypeAdapter<T>) gson.getAdapter(annotation.autoClass());
}
}
import com.google.auto.value.AutoValue;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Marks an {@link AutoValue @AutoValue}/{@link AutoParcel @AutoParcel}-annotated type for proper Gson serialization.
* <p>
* This annotation is needed because the {@linkplain Retention retention} of {@code @AutoValue}/{@code @AutoParcel}
* does not allow reflection at runtime.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoGson {
// A reference to the Auto*-generated class (e.g. AutoValue_MyClass/AutoParcel_MyClass). This is
// necessary to handle obfuscation of the class names.
Class autoClass();
}
import auto.parcel.AutoParcel;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class Main {
public static void main(String... args) {
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(new AutoGenTypeAdapterFactory())
.create();
Test inTest = Test.of("John", "Doe", 100);
System.out.println("IN: " + inTest);
String json = gson.toJson(inTest);
System.out.println("JSON: " + json);
Test outTest = gson.fromJson(json, Test.class);
System.out.println("OUT: " + outTest);
}
@AutoParcel
@AutoGson(autoClass = AutoParcel_Main_Test.class)
public abstract static class Test {
public static Test of(String firstName, String lastName, int age) {
return new AutoParcel_Main_Test(firstName, lastName, age);
}
public abstract String firstName();
public abstract String lastName();
public abstract int age();
}
}
@Piasy
Copy link
Author

Piasy commented Aug 16, 2015

@AutoParcel annotated class with a List member, whose element type is also @AutoParcel annotated, won't work. The List member type will be deserialized as com.google.gson.internal.LinkedTreeMap.
Need to dig deeply later.

@Piasy
Copy link
Author

Piasy commented Aug 21, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment