-
-
Save schlan/a51bda942ca600da9e8cb1b406079fea to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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