Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gson extension #586

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions modules/org.restlet.ext.gson/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Restlet Extension - Gson
Bundle-SymbolicName: org.restlet.ext.gson
Bundle-Version: 2.2
Bundle-Vendor: Restlet S.A.S.
Export-Package: org.restlet.ext.gson
Import-Package:
org.restlet,
org.restlet.data,
org.restlet.engine,
org.restlet.engine.converter,
org.restlet.engine.resource,
org.restlet.representation,
org.restlet.resource,
org.restlet.service,
org.restlet.util
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
4 changes: 4 additions & 0 deletions modules/org.restlet.ext.gson/build.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.
15 changes: 15 additions & 0 deletions modules/org.restlet.ext.gson/module.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<module id="gson" excludes="gwt" type="integration" package="org.restlet.ext.gson">
<name>Restlet Extension - Gson</name>
<description>Integration with Gson.</description>
<distributions>
<distribution id="classic" />
<distribution id="maven" />
<distribution id="p2" />
</distributions>

<dependencies>
<dependency type="library" id="gson" primary="true" />
<dependency type="module" id="core" />
</dependencies>
<wikiUri>299-restlet</wikiUri>
</module>
34 changes: 34 additions & 0 deletions modules/org.restlet.ext.gson/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.restlet.dev</groupId>
<artifactId>org.restlet.parent</artifactId>
<version>2.2-SNAPSHOT</version>
</parent>

<artifactId>org.restlet.ext.gson</artifactId>
<name>Restlet Extension - Gson</name>
<description>Integration with Gson.</description>

<dependencies>
<dependency>
<groupId>org.restlet.dev</groupId>
<artifactId>org.restlet</artifactId>
<!-- <version>2.2-SNAPSHOT</version> -->
<version>${version}</version>

</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.restlet.ext.gson.GsonConverter
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package org.restlet.ext.gson;

import java.io.IOException;
import java.util.List;

import org.restlet.data.MediaType;
import org.restlet.data.Preference;
import org.restlet.engine.converter.ConverterHelper;
import org.restlet.engine.resource.VariantInfo;
import org.restlet.representation.Representation;
import org.restlet.representation.Variant;
import org.restlet.resource.Resource;

/**
* Inspired from Jackson extension of Restlet
*
* @author nealmi
*
* Copyright 2012 Neal Mi
*
* 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.
*/
public class GsonConverter extends ConverterHelper {
private static final VariantInfo VARIANT_JSON = new VariantInfo(MediaType.APPLICATION_JSON);

protected <T> GsonRepresentation<T> create(Representation source, Class<T> objectClass) {
return new GsonRepresentation<T>(source, objectClass);
}

protected <T> GsonRepresentation<T> create(MediaType mediaType, T source) {
return new GsonRepresentation<T>(mediaType, source);
}

@Override
public List<Class<?>> getObjectClasses(Variant source) {
List<Class<?>> result = null;

if (VARIANT_JSON.isCompatible(source)) {
result = addObjectClass(result, Object.class);
result = addObjectClass(result, GsonRepresentation.class);
}

return result;
}

@Override
public List<VariantInfo> getVariants(Class<?> source) {
List<VariantInfo> result = null;

if (source != null) {
result = addVariant(result, VARIANT_JSON);
}

return result;
}

@Override
public float score(Object source, Variant target, Resource resource) {
float result = -1.0F;

if (source instanceof GsonRepresentation<?>) {
result = 1.0F;
} else {
if (target == null) {
result = 0.5F;
} else if (VARIANT_JSON.isCompatible(target)) {
result = 0.8F;
} else {
result = 0.5F;
}
}

return result;
}

@Override
public <T> float score(Representation source, Class<T> target, Resource resource) {
float result = -1.0F;

if (source instanceof GsonRepresentation<?>) {
result = 1.0F;
} else if ((target != null) && GsonRepresentation.class.isAssignableFrom(target)) {
result = 1.0F;
} else if (VARIANT_JSON.isCompatible(source)) {
result = 0.8F;
}

return result;
}

@SuppressWarnings("unchecked")
@Override
public <T> T toObject(Representation source, Class<T> target, Resource resource) throws IOException {
Object result = null;

// The source for the gson conversion
GsonRepresentation<?> gsonSource = null;

if (source instanceof GsonRepresentation) {
gsonSource = (GsonRepresentation<?>) source;
} else if (VARIANT_JSON.isCompatible(source)) {
gsonSource = create(source, target);
}

if (gsonSource != null) {
// Handle the conversion
if ((target != null) && GsonRepresentation.class.isAssignableFrom(target)) {
result = gsonSource;
} else {
result = gsonSource.getObject();
}
}

return (T) result;
}

@Override
public Representation toRepresentation(Object source, Variant target, Resource resource) throws IOException {
Representation result = null;

if (source instanceof GsonRepresentation) {
result = (GsonRepresentation<?>) source;
} else {
if (target.getMediaType() == null) {
target.setMediaType(MediaType.APPLICATION_JSON);
}

if (VARIANT_JSON.isCompatible(target)) {
GsonRepresentation<Object> gsonRepresentation = create(target.getMediaType(), source);
result = gsonRepresentation;
}
}

return result;
}

@Override
public <T> void updatePreferences(List<Preference<MediaType>> preferences, Class<T> entity) {
updatePreferences(preferences, MediaType.APPLICATION_JSON, 1.0F);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package org.restlet.ext.gson;

import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.Type;
import java.text.DateFormat;
import java.util.Date;

import org.joda.time.DateTime;
import org.restlet.data.MediaType;
import org.restlet.representation.Representation;
import org.restlet.representation.WriterRepresentation;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

/**
* Inspired from Jackson extension of Restlet
*
* @author nealmi
*
* @param <T>
*
* Copyright 2012 Neal Mi
*
* 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.
*/
public class GsonRepresentation<T> extends WriterRepresentation {
/** The (parsed) object to format. */
private T object;

/** The object class to instantiate. */
private Class<T> objectClass;

/** The JSON representation to parse. */
private Representation jsonRepresentation;

/** The modifiable Gson builder. */
private GsonBuilder builder;

public GsonRepresentation(MediaType mediaType) {
super(mediaType);
}

@SuppressWarnings("unchecked")
public GsonRepresentation(T object) {
super(MediaType.APPLICATION_JSON);
this.object = object;
this.objectClass = ((Class<T>) ((object == null) ? null : object.getClass()));
this.jsonRepresentation = null;
this.builder = null;
}

public GsonRepresentation(Representation representation, Class<T> objectClass) {
super(representation.getMediaType());
this.object = null;
this.objectClass = objectClass;
this.jsonRepresentation = representation;
this.builder = null;
}

@SuppressWarnings("unchecked")
public GsonRepresentation(MediaType mediaType, T object) {
super(mediaType);
this.object = object;
this.objectClass = ((Class<T>) ((object == null) ? null : object.getClass()));
this.jsonRepresentation = null;
this.builder = null;
}

@Override
public void write(Writer writer) throws IOException {
if (jsonRepresentation != null) {
jsonRepresentation.write(writer);
} else {
Gson gson = getBuilder().create();
gson.toJson(object, objectClass, new JsonWriter(writer));
}
}

public T getObject() throws IOException {
T result = null;

if (this.object != null) {
result = this.object;
} else if (this.jsonRepresentation != null) {
Gson gson = getBuilder().create();
result = gson.fromJson(new JsonReader(jsonRepresentation.getReader()), this.objectClass);
}

return result;
}

public void setObject(T object) {
this.object = object;
}

public Class<T> getObjectClass() {
return objectClass;
}

public void setObjectClass(Class<T> objectClass) {
this.objectClass = objectClass;
}

public Representation getJsonRepresentation() {
return jsonRepresentation;
}

public void setJsonRepresentation(Representation jsonRepresentation) {
this.jsonRepresentation = jsonRepresentation;
}

private class ISODateSerializer implements JsonSerializer<Date> {
public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
DateTime dt = new DateTime(src);
// DateTime dtz = dt.withZone(DateTimeZone.forOffsetHours(-8));
return new JsonPrimitive(dt.toString());
}
}

private class ISODateDeserializer implements JsonDeserializer<Date> {
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return new DateTime(json.getAsJsonPrimitive().getAsString()).toDate();
}
}

public GsonBuilder getBuilder() {
if (builder == null) {
builder = createBuilder().registerTypeAdapter(Date.class, new ISODateSerializer()).registerTypeAdapter(
Date.class, new ISODateDeserializer());
}
return builder;
}

private GsonBuilder createBuilder() {
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setDateFormat(DateFormat.FULL);
return gsonBuilder;
}

public void setBuilder(GsonBuilder builder) {
this.builder = builder;
}

}
Loading