Created
February 22, 2016 05:24
-
-
Save elucash/955499dc6569669434df to your computer and use it in GitHub Desktop.
Creating intercepting wrappers for type adapters
This file contains hidden or 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 abc; | |
import com.google.common.base.Function; | |
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.util.Optional; | |
import java.util.ServiceLoader; | |
import javax.annotation.Nullable; | |
import org.immutables.mongo.Mongo; | |
import org.immutables.mongo.types.TimeInstant; | |
import org.immutables.value.Value; | |
interface WithModifiedOn { | |
WithModifiedOn withModifiedOn(TimeInstant timestamp); | |
Optional<TimeInstant> modifiedOn(); | |
} | |
@Mongo.Repository | |
@Value.Immutable | |
@org.immutables.gson.Gson.TypeAdapters | |
interface SampleDocument extends WithModifiedOn { | |
String field1(); | |
String field2(); | |
} | |
class SerializeInterceptor<T> { | |
private final Class<T> interceptedRawType; | |
private final Function<T, T> transformation; | |
SerializeInterceptor(Class<T> interceptedRawType, Function<T, T> transformation) { | |
this.interceptedRawType = interceptedRawType; | |
this.transformation = transformation; | |
} | |
TypeAdapterFactory wrap(TypeAdapterFactory factory) { | |
return new TypeAdapterFactory() { | |
@Override | |
public <X> TypeAdapter<X> create(Gson gson, TypeToken<X> type) { | |
@Nullable TypeAdapter<X> delegateAdapter = factory.create(gson, type); | |
if (delegateAdapter != null) { | |
if (interceptedRawType.isAssignableFrom(type.getRawType())) { | |
return wrapAdapter(delegateAdapter); | |
} | |
return delegateAdapter; | |
} | |
return null; | |
} | |
}; | |
} | |
<X> TypeAdapter<X> wrapAdapter(TypeAdapter<X> adapter) { | |
return new TypeAdapter<X>() { | |
// safe unchecked: checked in runtime using Class.isAssignableFrom | |
@SuppressWarnings("unchecked") | |
@Override | |
public void write(JsonWriter out, X value) throws IOException { | |
X transformedValue = (X) transformation.apply((T) value); | |
adapter.write(out, transformedValue); | |
} | |
@Override | |
public X read(JsonReader in) throws IOException { | |
return adapter.read(in); | |
} | |
}; | |
} | |
public static void main(String... args) { | |
GsonBuilder gsonBuilder = new GsonBuilder(); | |
SerializeInterceptor<WithModifiedOn> interceptor = | |
new SerializeInterceptor<>(WithModifiedOn.class, new Function<WithModifiedOn, WithModifiedOn>() { | |
@Override | |
public WithModifiedOn apply(WithModifiedOn input) { | |
return input.withModifiedOn(TimeInstant.of(System.currentTimeMillis())); | |
} | |
}); | |
for (TypeAdapterFactory factory : ServiceLoader.load(TypeAdapterFactory.class)) { | |
gsonBuilder.registerTypeAdapterFactory(interceptor.wrap(factory)); | |
} | |
Gson gson = gsonBuilder.create(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment