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

Initial commit for json serialization #24

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
9 changes: 8 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<groupId>org.lwes</groupId>
<artifactId>lwes-java</artifactId>
<packaging>jar</packaging>
<version>1.4.3-SNAPSHOT</version>
<version>1.4.4-SNAPSHOT</version>
<name>lwes-java</name>
<description>Lightweight event system, java implementation</description>
<url>http://lwes.org</url>
Expand Down Expand Up @@ -48,6 +48,13 @@
</developers>

<dependencies>

<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.4</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/org/lwes/ArrayEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.EnumMap;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedSet;
Expand All @@ -26,6 +27,7 @@
import org.apache.commons.lang3.mutable.MutableInt;
import org.lwes.serializer.Deserializer;
import org.lwes.serializer.DeserializerState;
import org.lwes.serializer.JsonSerializer;
import org.lwes.serializer.Serializer;
import org.lwes.util.EncodedString;

Expand All @@ -38,6 +40,7 @@ public final class ArrayEvent extends DefaultEvent {
private short encoding = DEFAULT_ENCODING;
private static Map<ArrayEventStats, MutableInt> STATS =
new EnumMap<ArrayEventStats, MutableInt>(ArrayEventStats.class);
private Map<String, BaseType> attributes;

static {
byte[] temp = new byte[256];
Expand All @@ -51,6 +54,7 @@ public final class ArrayEvent extends DefaultEvent {
// * UINT64|INT64|BOOLEAN|STRING)

public ArrayEvent() {
attributes = new LinkedHashMap<String, BaseType>();
length = getValueListIndex();
setEncoding(DEFAULT_ENCODING);
final MutableInt creations = STATS.get(ArrayEventStats.CREATIONS);
Expand Down Expand Up @@ -168,6 +172,7 @@ public void set(String key, FieldType type, Object value) {
if (oldType == type && type.isConstantSize()) {
// Modify the value in place, requiring no shifts.
Serializer.serializeValue(type, value, encoding, bytes, tokenIndex + 1);
attributes.put(key, new BaseType(type, value));
return;
}
clear(key);
Expand All @@ -192,6 +197,7 @@ private void appendField(String key, FieldType type, Object value) {
length += Serializer.serializeATTRIBUTEWORD(key, bytes, length);
length += Serializer.serializeBYTE(type.token, bytes, length);
length += Serializer.serializeValue(type, value, encoding, bytes, length);
attributes.put(key, new BaseType(type, value));
setNumEventAttributes(getNumEventAttributes() + 1);
}
catch (ArrayIndexOutOfBoundsException e) {
Expand Down Expand Up @@ -679,4 +685,9 @@ public Object getValue() {
return value;
}
}

public String toJson() {
return JsonSerializer.getInstance().toJson(getEventName(), attributes);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the changes here are correct. I think that instead of keeping around another structure, you should instead just convert in this function. It may require deserializing and then converting to json. @pfarner may have a similar opinion, but hopefully he'll see this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the extra structure i was using to hold attributes.


}
2 changes: 2 additions & 0 deletions src/main/java/org/lwes/Event.java
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ public interface Event extends Iterable<FieldAccessor> {
void deserialize(DataInput stream, int length) throws IOException;

int getBytesSize();

String toJson();

// MISCELLANEOUS

Expand Down
18 changes: 18 additions & 0 deletions src/main/java/org/lwes/EventFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
package org.lwes;

import org.lwes.db.EventTemplateDB;
import org.lwes.serializer.JsonDeserializer;

import java.io.File;
import java.io.InputStream;
Expand Down Expand Up @@ -189,5 +190,22 @@ public Event createEvent(byte[] bytes, boolean validate) throws EventSystemExcep
}
return new MapEvent(bytes, validate, eventTemplateDB);
}

/**
* Create an event from its json representation
* @param json
* @param type
* @return
*/
public Event createEventFromJson(String json, EventImplementation type){
JsonDeserializer deSerializer = JsonDeserializer.getInstance();
switch (type) {
case MAP_EVENT:
return deSerializer.fromJson(json, new MapEvent());
case ARRAY_EVENT:
return deSerializer.fromJson(json, new ArrayEvent());
}
return null;
}

}
5 changes: 5 additions & 0 deletions src/main/java/org/lwes/EventImplementation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.lwes;

public enum EventImplementation {
MAP_EVENT, ARRAY_EVENT;
}
6 changes: 6 additions & 0 deletions src/main/java/org/lwes/MapEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.lwes.db.EventTemplateDB;
import org.lwes.serializer.Deserializer;
import org.lwes.serializer.DeserializerState;
import org.lwes.serializer.JsonSerializer;
import org.lwes.serializer.Serializer;

public class MapEvent extends DefaultEvent {
Expand Down Expand Up @@ -606,4 +607,9 @@ public FieldType getType(String field) {
public int getBytesSize() {
return bytesStoreSize;
}

public String toJson() {
return JsonSerializer.getInstance().toJson(name, attributes);
}

}
19 changes: 19 additions & 0 deletions src/main/java/org/lwes/TypeValue.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.lwes;

public class TypeValue {

private String type;
private String value;
public String getType() {
return type;
}
public String getValue() {
return value;
}
public TypeValue(String type, String value) {
super();
this.type = type;
this.value = value;
}

}
173 changes: 173 additions & 0 deletions src/main/java/org/lwes/serializer/JsonDeserializer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
package org.lwes.serializer;

import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.lwes.Event;
import org.lwes.FieldType;
import org.lwes.TypeValue;
import org.lwes.util.IPAddress;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class JsonDeserializer {

private static JsonDeserializer instance;

private Gson gson;
private JsonParser parser;

public static JsonDeserializer getInstance(){
if(instance == null){
synchronized (JsonSerializer.class) {
//Double-checked locking
if(instance == null)
instance = new JsonDeserializer();
}
}
return instance;
}

private JsonDeserializer(){
parser = new JsonParser();
GsonBuilder bldr = new GsonBuilder();
gson = bldr.create();
}

public Event fromJson(String json, Event e){
try{
JsonObject root = parser.parse(json).getAsJsonObject();
String name = root.getAsJsonPrimitive("name").getAsString();
if(StringUtils.isEmpty(name))
return null;
JsonObject typedContainer = root.getAsJsonObject("typed");
if(typedContainer == null)
return null;
Map<String, TypeValue> typedElems = parseTyped(typedContainer);

e.setEventName(name);
for(Entry<String, TypeValue> element : typedElems.entrySet()){
FieldType ft = FieldType.byName(element.getValue().getType());
e.set(element.getKey(),
FieldType.byName(element.getValue().getType()),
getObjectForType(ft, element.getValue().getValue()));
}

}catch(Exception ex){
ex.printStackTrace();
return null;
}
return e;
}

Map<String, TypeValue> parseTyped(JsonObject typedContainer){
Set<Entry<String, JsonElement>> types = typedContainer.entrySet();
Map<String, TypeValue> typedElements = new HashMap<String, TypeValue>();
for(Entry<String, JsonElement> type : types){
TypeValue tv = getTypeValue(type.getValue().getAsJsonObject());
if(tv != null)
typedElements.put(type.getKey(), tv);
}
return typedElements;
}

TypeValue getTypeValue(JsonObject typedElement){
String type = typedElement.getAsJsonPrimitive("type").getAsString();
String value = typedElement.getAsJsonPrimitive("value").getAsString();
FieldType fType = FieldType.byName(type);
if(fType == null)
return null;
return new TypeValue(fType.name, value);
}

Object getObjectForType(FieldType ft, String str) {
//Giant switch statement dervied from Serializer.serializeValue's
//type system definition
switch (ft) {
case BOOLEAN:
return getObjectForType(str, Boolean.class);
case BYTE:
return getObjectForType(str, Byte.class);
case DOUBLE:
return getObjectForType(str, Double.class);
case FLOAT:
return getObjectForType(str, Float.class);
case INT16:
return getObjectForType(str, Short.class);
case INT32:
return getObjectForType(str, Integer.class);
case INT64:
return getObjectForType(str, Long.class);
case IPADDR:
return getObjectForType(str, IPAddress.class);
case STRING:
return getObjectForType(str, String.class);
case UINT16:
return getObjectForType(str, Integer.class);
case UINT32:
return getObjectForType(str, Long.class);
case UINT64:
return getObjectForType(str, BigInteger.class);
case BOOLEAN_ARRAY:
return getObjectForType(str, boolean[].class);
case BYTE_ARRAY:
return getObjectForType(str, byte[].class);
case DOUBLE_ARRAY:
return getObjectForType(str, double[].class);
case FLOAT_ARRAY:
return getObjectForType(str, float[].class);
case INT16_ARRAY:
return getObjectForType(str, short[].class);
case INT32_ARRAY:
return getObjectForType(str, int[].class);
case INT64_ARRAY:
return getObjectForType(str, long[].class);
case IP_ADDR_ARRAY:
return getObjectForType(str, IPAddress[].class);
case STRING_ARRAY:
return getObjectForType(str, String[].class);
case UINT16_ARRAY:
return getObjectForType(str, int[].class);
case UINT32_ARRAY:
return getObjectForType(str, long[].class);
case UINT64_ARRAY:
return getObjectForType(str, BigInteger[].class);
case NBOOLEAN_ARRAY:
return getObjectForType(str, Boolean[].class);
case NBYTE_ARRAY:
return getObjectForType(str, Byte[].class);
case NDOUBLE_ARRAY:
return getObjectForType(str, Double[].class);
case NFLOAT_ARRAY:
return getObjectForType(str, Float[].class);
case NINT16_ARRAY:
return getObjectForType(str, Short[].class);
case NINT32_ARRAY:
return getObjectForType(str, Integer[].class);
case NINT64_ARRAY:
return getObjectForType(str, Long[].class);
case NSTRING_ARRAY:
return getObjectForType(str, String[].class);
case NUINT16_ARRAY:
return getObjectForType(str, Integer[].class);
case NUINT32_ARRAY:
return getObjectForType(str, Long[].class);
case NUINT64_ARRAY:
return getObjectForType(str, BigInteger[].class);
default:
return str;
}
}

Object getObjectForType(String str, Class clz){
return gson.fromJson(str, clz);
}
}
Loading