Skip to content

Instantly share code, notes, and snippets.

@swankjesse
Created July 28, 2016 02:24
Show Gist options
  • Save swankjesse/20df26adaf639ed7fd160f145a0b661a to your computer and use it in GitHub Desktop.
Save swankjesse/20df26adaf639ed7fd160f145a0b661a to your computer and use it in GitHub Desktop.
package com.google.gson.functional;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
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.InvocationTargetException;
import java.lang.reflect.Method;
import javax.annotation.PostConstruct;
import junit.framework.TestCase;
public class PostConstructTest extends TestCase {
public void test() throws Exception {
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(new PostConstructFactory())
.create();
gson.fromJson("{\"bread\": \"white\", \"cheese\": \"cheddar\"}", Sandwich.class);
gson.fromJson("{\"bread\": \"cheesey bread\", \"cheese\": \"swiss\"}", Sandwich.class);
}
static class Sandwich {
String bread;
String cheese;
@PostConstruct void validate() {
if (bread.equals("cheesey bread") && cheese != null) {
throw new IllegalArgumentException("too cheesey");
}
}
}
static class PostConstructFactory implements TypeAdapterFactory {
@Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
for (Class<?> t = type.getRawType(); t != Object.class; t = t.getSuperclass()) {
for (Method m : t.getDeclaredMethods()) {
if (m.isAnnotationPresent(PostConstruct.class)) {
m.setAccessible(true);
TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
return new PostConstructAdapter<T>(delegate, m);
}
}
}
return null;
}
}
static class PostConstructAdapter<T> extends TypeAdapter<T> {
private final TypeAdapter<T> delegate;
private final Method method;
public PostConstructAdapter(TypeAdapter<T> delegate, Method method) {
this.delegate = delegate;
this.method = method;
}
@Override public T read(JsonReader in) throws IOException {
T result = delegate.read(in);
if (result != null) {
try {
method.invoke(result);
} catch (IllegalAccessException e) {
throw new AssertionError();
} catch (InvocationTargetException e) {
if (e.getCause() instanceof RuntimeException) throw (RuntimeException) e.getCause();
throw new RuntimeException(e.getCause());
}
}
return result;
}
@Override public void write(JsonWriter out, T value) throws IOException {
delegate.write(out, value);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment