Skip to content
Permalink
Browse files

Initial commit

  • Loading branch information...
julman99 committed Jun 9, 2013
0 parents commit bbf6d9a43a471bfd4ed6b7041656b14dd3c53044
@@ -0,0 +1,4 @@
.idea
*.iml
target
settings.xml
101 README.md
@@ -0,0 +1,101 @@
# Gson on Fire

This project implements some useful features missing from the extremely useful [Gson project](https://code.google.com/p/google-gson/)

There is no attempt to modify any existing behavior or existing class of Gson. In fact, this project depends on Gson.
The main objective is to extend Gson using TypeAdapter and TypeAdapterFactory instances to support more features.

## Features

All of the features can be accessed by the ```GsonFireBuilder```. This class will build internally a ```GsonBuilder```
with all the desired features from wich a ```Gson``` instance can be obtained.

### Post Processors

Ability to alter a JsonElement after it has been generated from an object.

```java
GsonFireBuilder builder = new GsonFireBuilder()
.registerPostProcessor(SomeClass.class, new PostProcessor<A>() {
@Override
public void postDeserialize(SomeClass result, JsonElement src) {
//Here you can add logic to change the SomeClass instance
}
@Override
public void postSerialize(JsonElement result, SomeClass src) {
//Here you can inject new fields into the result JsonElement
}
});
Gson gson = builder.createGson();
```

### Type Selectors

Useful when you have a base class and some sub-classes and you need to de-serialize some json into one of the sub-classes.
The sub-class type will be determined by a field on the json.

```java
GsonFireBuilder builder = new GsonFireBuilder()
.registerTypeSelector(Base.class, new TypeSelector<Base>() {
@Override
public Class<? extends Base> getClassForElement(JsonElement readElement) {
String kind = readElement.getAsJsonObject().get("kind").getAsString();
if(kind.equals("a")){
return A.class; //This will cause Gson to deserialize the json mapping to A
} else if(kind.equals("b")) {
return B.class; //This will cause Gson to deserialize the json mapping to B
} else {
return null; //returning null will trigger Gson's default behavior
}
}
});
Gson gson = builder.createGson();
```

### Date format

Dates can be serialized either to a unix epoch with or without milliseconds.

```java
GsonFireBuilder builder = new GsonFireBuilder();
//then
builder.dateSerializationPolicy(DateSerializationPolicy.unixTimeMillis);
//or
builder.dateSerializationPolicy(DateSerializationPolicy.unixTimeSeconds);
```

If no policy is specified, the default Gson behavior will be used

## Using the Gson's GsonBuilder

You will be able to access the old good GsonBuilder:

```java
GsonFireBuilder fireBuilder = new GsonFireBuilder();
GsonBuilder gsonBuilder = fireBuilder.getGsonBuilder();
```

## Limitations

Since the Post Processors and Type Selectors are just Gson TypeAdapter, there is no way right now to register a
Type Selector and a Post Processor to the same class.

## Usage
```xml
<repositories>
<repository>
<id>julman99-github</id>
<url>https://raw.github.com/julman99/mvn-repo/master</url>
</repository>
<repositories>
<dependencies>
<dependency>
<groupId>com.github.julman99.gson-fire</groupId>
<artifactId>gson-fire</artifactId>
<version>0.1</version>
</dependency>
</dependencies>
```
73 pom.xml
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.github.julman99.gson-fire</groupId>
<artifactId>gson-fire</artifactId>
<version>0.1</version>

<build>
<plugins>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.7</version>
<configuration>
<altDeploymentRepository>internal.repo::default::file://${project.build.directory}/mvn-repo</altDeploymentRepository>
</configuration>
</plugin>
<plugin>
<groupId>com.github.github</groupId>
<artifactId>site-maven-plugin</artifactId>
<version>0.8</version>
<configuration>
<message>Maven artifacts for ${project.artifactId} ${project.version}</message> <!-- git commit message -->
<noJekyll>true</noJekyll> <!-- disable webpage processing -->
<outputDirectory>${project.build.directory}/mvn-repo</outputDirectory> <!-- matches distribution management repository url above -->
<branch>refs/heads/master</branch> <!-- remote branch name -->
<includes><include>**/*</include></includes>
<repositoryName>mvn-repo</repositoryName> <!-- github repo name -->
<repositoryOwner>julman99</repositoryOwner> <!-- github username -->
<merge>true</merge>
</configuration>
<executions>
<!-- run site-maven-plugin's 'site' target as part of the build's normal 'deploy' phase -->
<execution>
<goals>
<goal>site</goal>
</goals>
<phase>deploy</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>

<properties>
<!-- github server corresponds to entry in ~/.m2/settings.xml -->
<github.global.server>github</github.global.server>
</properties>

<distributionManagement>
<repository>
<id>github</id>
<name>GitHub ${project.artifactId} Repository</name>
<url>https://raw.github.com/julman99/mvn-repo/master</url>
</repository>
</distributionManagement>
</project>
@@ -0,0 +1,28 @@
package com.github.julman99.gsonfire;

import com.github.julman99.gsonfire.gson.DateIntegerTypeAdapter;
import com.github.julman99.gsonfire.gson.DateLongTypeAdapter;
import com.google.gson.TypeAdapter;

import java.util.Date;

/**
* @autor: julio
*/
public enum DateSerializationPolicy {
unixTimeMillis {
@Override
public TypeAdapter<Date> createTypeAdapter() {
return new DateLongTypeAdapter();
}
},

unixTimeSeconds {
@Override
public TypeAdapter<Date> createTypeAdapter() {
return new DateIntegerTypeAdapter();
}
};

public abstract TypeAdapter<Date> createTypeAdapter();
}
@@ -0,0 +1,39 @@
package com.github.julman99.gsonfire;

import com.github.julman99.gsonfire.gson.PostProcessorTypeAdapterFactory;
import com.github.julman99.gsonfire.gson.TypeSelectorTypeAdapterFactory;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.util.Date;

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

private GsonBuilder builder = new GsonBuilder();

public <T> GsonFireBuilder registerTypeSelector(Class<T> t, TypeSelector<T> factory){
builder.registerTypeAdapterFactory(new TypeSelectorTypeAdapterFactory(t, factory));
return this;
}

public <T> GsonFireBuilder registerPostProcessor(Class<T> clazz, PostProcessor<? super T> postProcessor){
builder.registerTypeAdapterFactory(new PostProcessorTypeAdapterFactory(clazz, postProcessor));
return this;
}

public <T> GsonFireBuilder dateSerializationPolicy(DateSerializationPolicy policy){
builder.registerTypeAdapter(Date.class, policy.createTypeAdapter());
return this;
}

public GsonBuilder createGsonBuilder(){
return builder;
}

public Gson createGson(){
return builder.create();
}
}
@@ -0,0 +1,13 @@
package com.github.julman99.gsonfire;

import com.google.gson.JsonElement;

/**
* @autor: julio
*/
public interface PostProcessor<T> {

public void postDeserialize(T result, JsonElement src);

public void postSerialize(JsonElement result, T src);
}
@@ -0,0 +1,12 @@
package com.github.julman99.gsonfire;

import com.google.gson.JsonElement;

/**
* @autor: julio
*/
public interface TypeSelector<T> {

public Class<? extends T> getClassForElement(JsonElement readElement);

}
@@ -0,0 +1,33 @@
package com.github.julman99.gsonfire.gson;

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.util.Date;

/**
* @autor: julio
*/
public class DateIntegerTypeAdapter extends TypeAdapter<Date> {
@Override
public void write(JsonWriter out, Date value) throws IOException {
if(value != null){
out.value(value.getTime() / 1000L);
} else {
out.nullValue();
}
}

@Override
public Date read(JsonReader in) throws IOException {
if(in.peek() != JsonToken.NULL){
int time = in.nextInt();
return new Date(time * 1000L);
} else {
return null;
}
}
}
@@ -0,0 +1,33 @@
package com.github.julman99.gsonfire.gson;

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.util.Date;

/**
* @autor: julio
*/
public class DateLongTypeAdapter extends TypeAdapter<Date> {
@Override
public void write(JsonWriter out, Date value) throws IOException {
if(value != null){
out.value(value.getTime());
} else {
out.nullValue();
}
}

@Override
public Date read(JsonReader in) throws IOException {
if(in.peek() != JsonToken.NULL){
long time = in.nextLong();
return new Date(time);
} else {
return null;
}
}
}
Oops, something went wrong.

0 comments on commit bbf6d9a

Please sign in to comment.
You can’t perform that action at this time.