Skip to content

Commit

Permalink
Merge pull request #8 from floralvikings/release/0.2.0-alpha
Browse files Browse the repository at this point in the history
Release 0.2.0-alpha
  • Loading branch information
floralvikings committed Dec 3, 2015
2 parents a4bc34c + 4afc5dd commit 663a7ee
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 11 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ plugins {

description = 'Jenjin Core IO API'
group = 'com.jenjinstudios'
version = '0.1.0-alpha'
version = '0.2.0-alpha'

// Core plugins
apply plugin: 'java'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,12 @@
*
* @return The name of the class from which the Message should be serialized.
*/
String adaptFrom();
String adaptFrom() default "";

/**
* Specify the class to which the Message should be serialized.
*
* @return The name of the class to which the Message should be serialized.
*/
String adaptTo() default "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
public class GsonMessageDeserializer implements JsonDeserializer<Message>
{
private static final Logger LOGGER = LoggerFactory.getLogger(GsonMessageDeserializer.class);
private static final Map<String, Class> ADAPTED_CLASSES = new HashMap<>(10);
private static final Map<String, Class> ADAPT_FROM = new HashMap<>(10);

static {
LOGGER.debug("Scanning for message classes");
Expand All @@ -31,12 +31,15 @@ public class GsonMessageDeserializer implements JsonDeserializer<Message>
LOGGER.debug("Registering message class: " + messageClass.getName());
Annotation annotation = messageClass.getAnnotation(MessageAdapter.class);
if (annotation != null) {
String adaptFromClass = ((MessageAdapter) annotation).adaptFrom();
LOGGER.debug("Registering adapter class: " + adaptFromClass);
ADAPTED_CLASSES.put(adaptFromClass, messageClass);
final MessageAdapter messageAdapter = (MessageAdapter) annotation;
String adaptFromClass = messageAdapter.adaptFrom();
if (!adaptFromClass.isEmpty()) {
LOGGER.debug("Registering adapter class: " + adaptFromClass);
ADAPT_FROM.put(adaptFromClass, messageClass);
}
}
}
LOGGER.debug("Registered Message Classes: {}", ADAPTED_CLASSES);
LOGGER.debug("Registered \"adaptFrom\" Message Classes: {}", ADAPT_FROM);
}

@Override
Expand All @@ -50,8 +53,8 @@ public Message deserialize(JsonElement json, Type typeOfT, JsonDeserializationCo
}
String className = classElement.getAsString();
Class<Message> lookupClass;
if (ADAPTED_CLASSES.containsKey(className)) {
lookupClass = ADAPTED_CLASSES.get(className);
if (ADAPT_FROM.containsKey(className)) {
lookupClass = ADAPT_FROM.get(className);
} else {
try {
lookupClass = (Class<Message>) Class.forName(className);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,16 @@
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.jenjinstudios.io.Message;
import com.jenjinstudios.io.annotations.MessageAdapter;
import org.reflections.Reflections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
* Used to serialize Messages with Gson.
Expand All @@ -15,11 +23,42 @@
*/
public class GsonMessageSerializer implements JsonSerializer<Message>
{
private static final Logger LOGGER = LoggerFactory.getLogger(GsonMessageSerializer.class);
private static final Map<Class, String> ADAPT_TO = new HashMap<>(10);

static {
LOGGER.debug("Scanning for message classes");
Reflections reflections = new Reflections("");
final Set<Class<? extends Message>> messageClasses = reflections.getSubTypesOf(Message.class);
for (Class messageClass : messageClasses) {
LOGGER.debug("Registering message class: " + messageClass.getName());
Annotation annotation = messageClass.getAnnotation(MessageAdapter.class);
if (annotation != null) {
final MessageAdapter messageAdapter = (MessageAdapter) annotation;
String adaptTo = messageAdapter.adaptTo();
if (!adaptTo.isEmpty()) {
LOGGER.debug("Registering adapter class: " + adaptTo);
try {
Class.forName(adaptTo);
ADAPT_TO.put(messageClass, adaptTo);
} catch (ClassNotFoundException e) {
LOGGER.warn("Encountered ClassNotFoundException when registering message adapter", e);
}
}
}
}
LOGGER.debug("Registered \"adaptTo\" Message Classes: {}", ADAPT_TO);
}

@Override
public JsonElement serialize(Message src, Type typeOfSrc, JsonSerializationContext context) {
JsonElement fields = context.serialize(src, src.getClass());
final Class<? extends Message> srcClass = src.getClass();
JsonElement fields = context.serialize(src, srcClass);
JsonObject message = new JsonObject();
message.addProperty("class", src.getClass().getName());

String className = ADAPT_TO.containsKey(srcClass) ? ADAPT_TO.get(srcClass) : srcClass.getName();

message.addProperty("class", className);
message.add("fields", fields);
return message;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.jenjinstudios.io.serialization

import com.jenjinstudios.io.ExecutionContext
import com.jenjinstudios.io.Message
import com.jenjinstudios.io.annotations.MessageAdapter

/**
* Used to test adapting messages.
*
* @author Caleb Brinkman
*/
@MessageAdapter(adaptTo = "com.jenjinstudios.io.serialization.TestMessage")
class AdaptToMessage implements Message{
String name;

@Override
public Message execute(ExecutionContext context) {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,22 @@ public class GsonSerializerSpec extends Specification {
then:
json == expectedJson
}

def "GsonMessageSerializer should properly adapt message objects when serializing"() {
given: "An AdaptToMessage and a GsonBuilder"
def expectedJson = '{"class":"com.jenjinstudios.io.serialization.TestMessage","fields":{"name":"bar"}}';
def message = new AdaptToMessage()
message.name = "bar"
def builder = new GsonBuilder()

when: "The GsonMessageSerializer is registered"
builder.registerTypeAdapter(Message.class, new GsonMessageSerializer())
def gson = builder.create();

and: "The message is serialized"
def json = gson.toJson(message, Message)

then: "The message should be adapted from AdaptToMessage into TestMessage"
json == expectedJson
}
}

0 comments on commit 663a7ee

Please sign in to comment.