All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.gsonfire.GsonFireBuilder Maven / Gradle / Ivy

Go to download

A java library that adds some very useful features to Gson, like Date serializing to unix timestamp or RFC3339, method (getter) serialization, pre and post processors and many more. Check out the documentation to learn how to use it!

There is a newer version: 1.9.0
Show newest version
package io.gsonfire;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.gsonfire.gson.*;
import io.gsonfire.postprocessors.MergeMapPostProcessor;
import io.gsonfire.postprocessors.methodinvoker.MethodInvokerPostProcessor;
import io.gsonfire.util.Mapper;
import io.gsonfire.util.reflection.FieldInspector;

import java.util.*;

/**
 * @autor: julio
 */
public final class GsonFireBuilder {

    private final Map classConfigMap = new HashMap();
    private final Map wrappedClasses = new HashMap();
    private final List orderedClasses = new ArrayList();
    private final List serializationExclusions = new ArrayList();
    private final FieldInspector fieldInspector = new FieldInspector();
    private final Map enumDefaultValues = new HashMap();

    private DateSerializationPolicy dateSerializationPolicy;
    private boolean dateDeserializationStrict = true;
    private TimeZone serializeTimeZone = TimeZone.getDefault();
    private boolean enableExposeMethodResults = false;
    private boolean enableExclusionByValueStrategies = false;

    private ClassConfig getClassConfig(Class clazz){
        ClassConfig result = classConfigMap.get(clazz);
        if(result == null){
            result = new ClassConfig(clazz);
            classConfigMap.put(clazz, result);
            insertOrdered(orderedClasses, clazz);
        }
        return result;
    }

    private static void insertOrdered(List classes, Class clazz) {
        for(int i = classes.size() - 1; i >= 0; i--) {
            Class current = classes.get(i);
            if(current.isAssignableFrom(clazz)) {
                classes.add(i + 1, clazz);
                return;
            }
        }
        classes.add(0, clazz);
    }

    /**
     * Registers a Type selector for the Class specified. 
* A type selector is in charge of deciding which sub class to use when converting a json * into an object.
* See docs and example * @param clazz * @param factory * @param * @return */ public GsonFireBuilder registerTypeSelector(Class clazz, TypeSelector factory){ ClassConfig config = getClassConfig(clazz); config.setTypeSelector(factory); return this; } /** * Registers a Post processor for the Class specified.
* A post processor is a class that will add new fields to a generated json just after generation, or that * will prepare a class just created from a json.
* See docs and example * * @param clazz * @param postProcessor * @param * @return */ public GsonFireBuilder registerPostProcessor(Class clazz, PostProcessor postProcessor){ ClassConfig config = getClassConfig(clazz); config.getPostProcessors().add(postProcessor); return this; } /** * Registers a pre processor for the Class specified.
* A pre processor is a class that will be given the gson to be deserialized in case it wants to change it before * it actually gets deserialized into a class * See docs and example * * @param clazz * @param preProcessor * @param * @return */ public GsonFireBuilder registerPreProcessor(Class clazz, PreProcessor preProcessor){ ClassConfig config = getClassConfig(clazz); config.getPreProcessors().add(preProcessor); return this; } /** * Configures the resulting Gson to serialize/unserialize Date instances with a policy * @param policy * @return */ public GsonFireBuilder dateSerializationPolicy(DateSerializationPolicy policy){ dateSerializationPolicy = policy; return this; } /** * A given class will be wrapped/unwrapped with a given string * during serialization/deserialization. * * @param clazz * @param * @return */ public GsonFireBuilder wrap(final Class clazz, final String name) { wrap(clazz, new Mapper() { @Override public String map(Object from) { return name; } }); return this; } /** * A given class will be wrapped/unwrapped with a string generated by a mapper * during serialization/deserialization. * * @param clazz * @param mapper * @param * @return */ public GsonFireBuilder wrap(Class clazz, Mapper mapper) { wrappedClasses.put(clazz, mapper); return this; } /** * By enabling this, all methods with the annotation {@link io.gsonfire.annotations.ExposeMethodResult} will * be evaluated and it result will be added to the resulting json * @return */ public GsonFireBuilder enableExposeMethodResult(){ this.enableExposeMethodResults = 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 * @return */ public GsonFireBuilder enableExclusionByValue(){ this.enableExclusionByValueStrategies = true; return this; } /** * By enabling this, all methods with the annotation {@link io.gsonfire.annotations.ExposeMethodResult} will * be evaluated and it result will be added to the resulting json * @return */ public GsonFireBuilder enableHooks(Class clazz){ ClassConfig config = getClassConfig(clazz); config.setHooksEnabled(true); return this; } /** * By enabling this, when a class is being converted to Json and it contains a {@link java.util.Map} class * annotated with {@link io.gsonfire.annotations.MergeMap}, the map will be walked and merged * with the resulting json object. * * This method has been deprecated and a {@link io.gsonfire.PostProcessor} should be used instead * @return */ @Deprecated public GsonFireBuilder enableMergeMaps(Class clazz){ registerPostProcessor(clazz, new MergeMapPostProcessor(fieldInspector)); return this; } /** * Sets the serialization TimeZone. This will affect only values that depend on the TimeZone, for example rfc3339 * dates. * @param timeZone * @return */ public GsonFireBuilder serializeTimeZone(TimeZone timeZone) { this.serializeTimeZone = timeZone; return this; } /** * Makes Gson not to throw an Exception when an enum cannot be parsed because its String representation does not match * any of the enum values. Instead, the defaultValue specified as parameter will be used. * The defaultValue can be null. * @param enumClass * @param defaultValue * @param * @return */ public GsonFireBuilder softEnum(Class enumClass, T defaultValue) { this.enumDefaultValues.put(enumClass, defaultValue); return this; } public GsonFireBuilder addSerializationExclusionStrategy(FireExclusionStrategy exclusionStrategy) { this.serializationExclusions.add(exclusionStrategy); return this; } /** * Returns a new instance of the good old {@link GsonBuilder} * @return */ public GsonBuilder createGsonBuilder(){ GsonBuilder builder = new GsonBuilder(); if(enableExposeMethodResults) { FireExclusionStrategy compositeExclusionStrategy = new FireExclusionStrategyComposite(serializationExclusions); registerPostProcessor(Object.class, new MethodInvokerPostProcessor(compositeExclusionStrategy)); } if(enableExclusionByValueStrategies) { builder.registerTypeAdapterFactory(new ExcludeByValueTypeAdapterFactory(fieldInspector)); } for(Class clazz: orderedClasses){ ClassConfig config = classConfigMap.get(clazz); if(config.getTypeSelector() != null) { builder.registerTypeAdapterFactory(new TypeSelectorTypeAdapterFactory(config)); } builder.registerTypeAdapterFactory(new FireTypeAdapterFactory(config)); } for(Map.Entry enumDefault: enumDefaultValues.entrySet()) { builder.registerTypeAdapter(enumDefault.getKey(), new SoftParseEnumTypeAdapter(enumDefault.getKey(), enumDefault.getValue())); } if(dateSerializationPolicy != null){ builder.registerTypeAdapter(Date.class, dateSerializationPolicy.createTypeAdapter(serializeTimeZone)); } builder.registerTypeAdapterFactory(new SimpleIterableTypeAdapterFactory()); builder.registerTypeAdapterFactory(new WrapTypeAdapterFactory(wrappedClasses)); return builder; } /** * Returns a new {@link Gson} instance * @return */ public Gson createGson(){ return createGsonBuilder().create(); } }