diff --git a/extras/pom.xml b/extras/pom.xml
index 41e6c9c9..1c5e76c3 100644
--- a/extras/pom.xml
+++ b/extras/pom.xml
@@ -40,9 +40,14 @@
com.google.code.gson
gson
- 2.3.1
+ 2.7
compile
+
+ javax.annotation
+ jsr250-api
+ 1.0
+
junit
junit
@@ -86,16 +91,16 @@
org.apache.maven.plugins
maven-compiler-plugin
- 3.2
+ 3.5.1
-
- 1.5
+
+ 1.6
org.apache.maven.plugins
maven-jar-plugin
- 2.5
+ 3.0.2
package
@@ -113,7 +118,7 @@
org.apache.maven.plugins
maven-source-plugin
- 2.4
+ 3.0.1
attach-sources
@@ -127,7 +132,7 @@
org.apache.maven.plugins
maven-javadoc-plugin
- 2.10.1
+ 2.10.4
attach-javadocs
@@ -147,7 +152,7 @@
org.apache.maven.plugins
maven-eclipse-plugin
- 2.9
+ 2.10
true
true
diff --git a/extras/src/main/java/com/google/gson/typeadapters/PostConstructAdapterFactory.java b/extras/src/main/java/com/google/gson/typeadapters/PostConstructAdapterFactory.java
new file mode 100644
index 00000000..6d02b958
--- /dev/null
+++ b/extras/src/main/java/com/google/gson/typeadapters/PostConstructAdapterFactory.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 Gson Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.gson.typeadapters;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import javax.annotation.PostConstruct;
+
+import com.google.gson.Gson;
+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;
+
+public class PostConstructAdapterFactory implements TypeAdapterFactory {
+ // copied from https://gist.github.com/swankjesse/20df26adaf639ed7fd160f145a0b661a
+ @Override
+ public TypeAdapter create(Gson gson, TypeToken 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 delegate = gson.getDelegateAdapter(this, type);
+ return new PostConstructAdapter(delegate, m);
+ }
+ }
+ }
+ return null;
+ }
+
+ final static class PostConstructAdapter extends TypeAdapter {
+ private final TypeAdapter delegate;
+ private final Method method;
+
+ public PostConstructAdapter(TypeAdapter 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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/extras/src/test/java/com/google/gson/typeadapters/PostConstructAdapterFactoryTest.java b/extras/src/test/java/com/google/gson/typeadapters/PostConstructAdapterFactoryTest.java
new file mode 100644
index 00000000..1c934b11
--- /dev/null
+++ b/extras/src/test/java/com/google/gson/typeadapters/PostConstructAdapterFactoryTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 Gson Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.gson.typeadapters;
+
+import javax.annotation.PostConstruct;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import junit.framework.TestCase;
+
+public class PostConstructAdapterFactoryTest extends TestCase {
+ public void test() throws Exception {
+ Gson gson = new GsonBuilder()
+ .registerTypeAdapterFactory(new PostConstructAdapterFactory())
+ .create();
+ gson.fromJson("{\"bread\": \"white\", \"cheese\": \"cheddar\"}", Sandwich.class);
+ try {
+ gson.fromJson("{\"bread\": \"cheesey bread\", \"cheese\": \"swiss\"}", Sandwich.class);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ assertEquals("too cheesey", expected.getMessage());
+ }
+ }
+
+ static class Sandwich {
+ String bread;
+ String cheese;
+
+ @PostConstruct void validate() {
+ if (bread.equals("cheesey bread") && cheese != null) {
+ throw new IllegalArgumentException("too cheesey");
+ }
+ }
+ }
+}