diff --git a/README.md b/README.md
index 8f98644..8fe01ac 100644
--- a/README.md
+++ b/README.md
@@ -72,7 +72,7 @@ Gson gson = builder.createGson();
### Expose your methods
-You can annotate methods to be automatically evaluated and serialized
+You can annotate methods to be automatically evaluated and serialized:
```java
@@ -92,8 +92,27 @@ GsonFireBuilder builder = new GsonFireBuilder()
```
+This works for deserialization as well:
+
+```java
+
+public void SomeClass{
+
+ @ExposeMethodParam("name")
+ public void setName(String name){
+ // Obviously, this is only useful on more complicated methods
+ this.name = name;
+ }
+}
+
+//Then
+GsonFireBuilder builder = new GsonFireBuilder()
+ .enableExposeMethodParam(); //This will make Gson to call all methods
+ //annotated with @ExposeMethodParam
+
+```
You can use ```GsonFireBuilder.addSerializationExclusionStrategy``` if you want to add custom exclusion strategies for
-some methods.
+some methods. You can also specify a `ConflictResolutionStrategy` if a method exposes a value with the same name as a field.
### Date format
@@ -129,6 +148,13 @@ public void SomeClass{
//this method will get invoked just before
//the class is serialized to gson
}
+
+ @PostSerialize
+ public void postSerializeLogic() {
+ //this method will get invoked after the class
+ //has been serialized to json, before all the hooks
+ //are run.
+ }
@PostDeserialize
public void postDeserializeLogic(){
@@ -148,7 +174,25 @@ Gson builder = new GsonFireBuilder()
Gson gson = builder.createGson();
```
-Any `Exception` thrown inside the hooks will be wrapped into a `HookInvocationException`
+Any `Exception` thrown inside the hooks will be wrapped into a `HookInvocationException`.
+
+The hook method can also be written as `preSerializeLogic(JsonElement src, Gson gson)`. As an example,
+using this, you can serialize `byte[]` fields to Base64 strings:
+
+```java
+@Exclude
+byte[] data;
+
+@PostSerialize
+private void postSerialize(JsonElement src, Gson gson) {
+ src.getAsJsonObject().addProperty("data", Base64.getEncoder().encodeToString(data));
+}
+
+@PostDeserialize
+private void postDeserialize(JsonElement src, Gson gson) {
+ data = Base64.getDecoder().decode(src.getAsJsonObject().getAsJsonPrimitive("data").getAsString());
+}
+```
### Iterable Serialization
@@ -175,6 +219,14 @@ for(Integer i: simpleIterable) {
```
+### Exclude fields
+
+Gson has an `Expose` annotation if you only want to serialize single fields. If you want to exclude single fields,
+you can make them `transient` and ignore them with `gsonBuilder.excludeFieldsWithModifiers(Modifier.TRANSIENT)`.
+This will have other implications on other Java serialization tools too. If you want to ignore specific fields, but
+only in Gson, annotate them with `Exclude`, `ExcludeSerialize` and `ExcludeDeserialize`. Enable this feature
+using `fireBuilder.enableExcludeByAnnotation()`.
+
### Excude fields depending on its value
Gson allows to define custom exclusion strategies for fields. However it is not possible to exclude a field depending
diff --git a/src/main/java/io/gsonfire/AnnotationExclusionStrategy.java b/src/main/java/io/gsonfire/AnnotationExclusionStrategy.java
new file mode 100644
index 0000000..4a19c75
--- /dev/null
+++ b/src/main/java/io/gsonfire/AnnotationExclusionStrategy.java
@@ -0,0 +1,35 @@
+package io.gsonfire;
+
+import java.lang.annotation.Annotation;
+import java.util.Objects;
+
+import com.google.gson.ExclusionStrategy;
+import com.google.gson.FieldAttributes;
+
+/**
+ * Exclude all fields annotated with a specific annotation.
+ *
+ * Forked from https://stackoverflow.com/a/27986860/6094756.
+ *
+ * @param T
+ * the type of the annotation class
+ * @author piegames
+ */
+public class AnnotationExclusionStrategy implements ExclusionStrategy {
+
+ private Class extends T> clazz;
+
+ public AnnotationExclusionStrategy(Class extends T> clazz) {
+ this.clazz = Objects.requireNonNull(clazz);
+ }
+
+ @Override
+ public boolean shouldSkipField(FieldAttributes f) {
+ return f.getAnnotation(clazz) != null;
+ }
+
+ @Override
+ public boolean shouldSkipClass(Class> clazz) {
+ return false;
+ }
+}
diff --git a/src/main/java/io/gsonfire/GsonFireBuilder.java b/src/main/java/io/gsonfire/GsonFireBuilder.java
index 2d96be6..571e0e4 100644
--- a/src/main/java/io/gsonfire/GsonFireBuilder.java
+++ b/src/main/java/io/gsonfire/GsonFireBuilder.java
@@ -1,9 +1,30 @@
package io.gsonfire;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TimeZone;
+import java.util.concurrent.ConcurrentHashMap;
+
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
-import io.gsonfire.gson.*;
+
+import io.gsonfire.annotations.Exclude;
+import io.gsonfire.annotations.ExcludeDeserialize;
+import io.gsonfire.annotations.ExcludeSerialize;
+import io.gsonfire.gson.EnumDefaultValueTypeAdapterFactory;
+import io.gsonfire.gson.ExcludeByValueTypeAdapterFactory;
+import io.gsonfire.gson.FireExclusionStrategy;
+import io.gsonfire.gson.FireExclusionStrategyComposite;
+import io.gsonfire.gson.HooksTypeAdapterFactory;
+import io.gsonfire.gson.SimpleIterableTypeAdapterFactory;
+import io.gsonfire.gson.TypeSelectorTypeAdapterFactory;
+import io.gsonfire.gson.WrapTypeAdapterFactory;
import io.gsonfire.postprocessors.MergeMapPostProcessor;
import io.gsonfire.postprocessors.methodinvoker.MethodInvokerPostProcessor;
import io.gsonfire.util.Mapper;
@@ -11,9 +32,6 @@
import io.gsonfire.util.reflection.Factory;
import io.gsonfire.util.reflection.FieldInspector;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-
/**
* @autor: julio
*/
@@ -31,6 +49,8 @@ public final class GsonFireBuilder {
private boolean dateDeserializationStrict = true;
private TimeZone serializeTimeZone = TimeZone.getDefault();
private boolean enableExposeMethodResults = false;
+ private boolean enableExposeMethodParams = false;
+ private boolean enableExcludeByAnnotation = false;
private boolean enableExclusionByValueStrategies = false;
private ClassConfig getClassConfig(Class clazz){
@@ -156,6 +176,37 @@ public GsonFireBuilder enableExposeMethodResult(){
return this;
}
+ /**
+ * By enabling this, all methods with the annotation {@link io.gsonfire.annotations.ExposeMethodParam} will be called with appropriate data
+ * parsed from the json tree.
+ *
+ * @return
+ */
+ public GsonFireBuilder enableExposeMethodParam() {
+ this.enableExposeMethodParams = true;
+ return this;
+ }
+
+ /**
+ * By enabling this, all fields with the annotation {@link io.gsonfire.annotations.Exclude},
+ * {@link io.gsonfire.annotations.ExcludeSerialize} and {@link io.gsonfire.annotations.ExcludeDeserialize} will be evaluated and it result
+ * will be excluded from serialization, deserialization and/or both.
+ *
+ * This is equivalent to calling
+ *
+ *
+ *
+ * @return
+ */
+ public GsonFireBuilder enableExcludeByAnnotation(){
+ this.enableExcludeByAnnotation = true;
+ return this;
+ }
+
/**
* By enabling this, all exclusion by value strategies specified with the annotation
* {@link io.gsonfire.annotations.ExcludeByValue} will be run to remove specific fields from the resulting json
@@ -228,15 +279,22 @@ public GsonBuilder createGsonBuilder(){
Set alreadyResolvedTypeTokensRegistry = Collections.newSetFromMap(new ConcurrentHashMap());
GsonBuilder builder = new GsonBuilder();
- if(enableExposeMethodResults) {
- FireExclusionStrategy compositeExclusionStrategy = new FireExclusionStrategyComposite(serializationExclusions);
- registerPostProcessor(Object.class, new MethodInvokerPostProcessor