package org.molgenis.util;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapterFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static com.google.common.collect.Maps.newHashMap;
/**
* A {@link FactoryBean} for creating a Google Gson 2.x {@link Gson} instance.
*/
public class GsonFactoryBean implements FactoryBean<Gson>, InitializingBean
{
private boolean serializeNulls = false;
private boolean prettyPrinting = false;
private boolean disableHtmlEscaping = false;
private String dateFormatPattern = MolgenisDateFormat.getDateTimeFormat().toPattern();
private List<TypeAdapterFactory> typeAdapterFactoryList;
private Map<Class<?>, Object> typeAdapterHierarchyFactoryMap;
private Gson gson;
/**
* Whether to use the {@link GsonBuilder#serializeNulls()} option when writing JSON. This is a shortcut for setting
* up a {@code Gson} as follows:
* <p>
* <pre class="code">
* new GsonBuilder().serializeNulls().create();
* </pre>
*/
public void setSerializeNulls(boolean serializeNulls)
{
this.serializeNulls = serializeNulls;
}
/**
* Whether to use the {@link GsonBuilder#setPrettyPrinting()} when writing JSON. This is a shortcut for setting up a
* {@code Gson} as follows:
* <p>
* <pre class="code">
* new GsonBuilder().setPrettyPrinting().create();
* </pre>
*/
public void setPrettyPrinting(boolean prettyPrinting)
{
this.prettyPrinting = prettyPrinting;
}
/**
* Whether to use the {@link GsonBuilder#disableHtmlEscaping()} when writing JSON. Set to {@code true} to disable
* HTML escaping in JSON. This is a shortcut for setting up a {@code Gson} as follows:
* <p>
* <pre class="code">
* new GsonBuilder().disableHtmlEscaping().create();
* </pre>
*/
public void setDisableHtmlEscaping(boolean disableHtmlEscaping)
{
this.disableHtmlEscaping = disableHtmlEscaping;
}
/**
* Define the date/time format with a {@link SimpleDateFormat}-style pattern. This is a shortcut for setting up a
* {@code Gson} as follows:
* <p>
* <pre class="code">
* new GsonBuilder().setDateFormat(dateFormatPattern).create();
* </pre>
*/
public void setDateFormatPattern(String dateFormatPattern)
{
this.dateFormatPattern = dateFormatPattern;
}
public void registerTypeAdapterFactory(TypeAdapterFactory typeAdapterFactory)
{
if (typeAdapterFactoryList == null) typeAdapterFactoryList = new ArrayList<TypeAdapterFactory>();
typeAdapterFactoryList.add(typeAdapterFactory);
}
public void registerTypeHierarchyAdapter(Class<?> clazz, Object typeAdapter)
{
if (typeAdapterHierarchyFactoryMap == null) typeAdapterHierarchyFactoryMap = newHashMap();
typeAdapterHierarchyFactoryMap.put(clazz, typeAdapter);
}
@Override
public void afterPropertiesSet()
{
GsonBuilder builder = new GsonBuilder();
if (this.serializeNulls)
{
builder.serializeNulls();
}
if (this.prettyPrinting)
{
builder.setPrettyPrinting();
}
if (this.disableHtmlEscaping)
{
builder.disableHtmlEscaping();
}
if (this.dateFormatPattern != null)
{
builder.setDateFormat(this.dateFormatPattern);
}
if (this.typeAdapterFactoryList != null)
{
typeAdapterFactoryList.forEach(builder::registerTypeAdapterFactory);
}
if (this.typeAdapterHierarchyFactoryMap != null)
{
typeAdapterHierarchyFactoryMap.forEach(builder::registerTypeHierarchyAdapter);
}
this.gson = builder.create();
}
/**
* Return the created Gson instance.
*/
@Override
public Gson getObject()
{
return this.gson;
}
@Override
public Class<?> getObjectType()
{
return Gson.class;
}
@Override
public boolean isSingleton()
{
return true;
}
}