changed everything
This commit is contained in:
parent
9df9fba621
commit
f4d9d0c8c5
49 changed files with 1078 additions and 1123 deletions
12
README.md
12
README.md
|
|
@ -1,9 +1,11 @@
|
||||||
# JsonToy
|
# Json
|
||||||
a JSON serializer based on bytecode manipulation
|
a JSON serializer based on bytecode manipulation
|
||||||
|
|
||||||
* creates a Json serializer for a java type using javassist
|
* uses ASM for creating object mappers
|
||||||
* deserializing not yet implemented
|
* deserializing not (yet?) implemented
|
||||||
* see the unit tests to see how it works
|
* write to String: Mapper.json(...)
|
||||||
|
|
||||||
|
|
||||||
* as of java9 it needs `--add-opens java.base/java.lang=ALL-UNNAMED` as java commandline option.
|
* ~~as of java9 it needs `--add-opens java.base/java.lang=ALL-UNNAMED` as java commandline option.~~
|
||||||
|
|
||||||
|
* prerequisite: at least jdk9
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
package nl.jssl.jsontoy.deserialize;
|
|
||||||
|
|
||||||
public class Deserializer {
|
|
||||||
|
|
||||||
private int position;
|
|
||||||
private final String jsonString;
|
|
||||||
|
|
||||||
private Deserializer( String jsonString,int position) {
|
|
||||||
this.position = position;
|
|
||||||
this.jsonString = jsonString;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize;
|
|
||||||
|
|
||||||
import java.util.Formatter;
|
|
||||||
|
|
||||||
public abstract class JSONSerializer<T> {
|
|
||||||
protected abstract String handle(T object);
|
|
||||||
|
|
||||||
protected Formatter formatter = new Formatter();
|
|
||||||
|
|
||||||
public String toJSONString(T object) {
|
|
||||||
if (object == null) {
|
|
||||||
return "";
|
|
||||||
} else if (object instanceof Number || object instanceof Boolean) {
|
|
||||||
return "" + object;
|
|
||||||
} else if (object instanceof CharSequence || object instanceof Character) {
|
|
||||||
return "\"" + object + "\"";
|
|
||||||
} else {
|
|
||||||
return handle(object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize;
|
|
||||||
|
|
||||||
public class Serializer {
|
|
||||||
private static SynthSerializerFactory instance = new SynthSerializerFactory();
|
|
||||||
|
|
||||||
public static String toJSONString(boolean b) {
|
|
||||||
return Boolean.toString(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toJSONString(short s) {
|
|
||||||
return Short.toString(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toJSONString(int i) {
|
|
||||||
return Integer.toString(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toJSONString(float f) {
|
|
||||||
return Float.toString(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toJSONString(double d) {
|
|
||||||
return Double.toString(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toJSONString(long l) {
|
|
||||||
return Long.toString(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toJSONString(char c) {
|
|
||||||
return "\"" + c + "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static <T> String toJSONString(T o) {
|
|
||||||
if (o == null) {
|
|
||||||
return "null";
|
|
||||||
}
|
|
||||||
return instance.createSerializer((Class<T>) o.getClass()).toJSONString(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize;
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
public class SerializerCreationException extends RuntimeException {
|
|
||||||
|
|
||||||
public SerializerCreationException(Throwable t) {
|
|
||||||
super(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,348 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javassist.CannotCompileException;
|
|
||||||
import javassist.ClassPool;
|
|
||||||
import javassist.CtClass;
|
|
||||||
import javassist.CtField;
|
|
||||||
import javassist.CtMethod;
|
|
||||||
import javassist.CtNewMethod;
|
|
||||||
import javassist.Modifier;
|
|
||||||
import javassist.NotFoundException;
|
|
||||||
|
|
||||||
class SynthSerializerFactory {
|
|
||||||
private static final String STRING = "java.lang.String";
|
|
||||||
private static final String BOOLEAN = "java.lang.Boolean";
|
|
||||||
private static final String CHARACTER = "java.lang.Character";
|
|
||||||
private static final String BYTE = "java.lang.Byte";
|
|
||||||
private static final String DOUBLE = "java.lang.Double";
|
|
||||||
private static final String FLOAT = "java.lang.Float";
|
|
||||||
private static final String LONG = "java.lang.Long";
|
|
||||||
private static final String SHORT = "java.lang.Short";
|
|
||||||
private static final String INTEGER = "java.lang.Integer";
|
|
||||||
|
|
||||||
private final static Set<String> wrappersAndString = new HashSet<>(Arrays.asList(BOOLEAN, CHARACTER, BYTE, DOUBLE, FLOAT, LONG, SHORT, INTEGER,
|
|
||||||
STRING));
|
|
||||||
|
|
||||||
private static final String COLLECTION = "java.util.Collection";
|
|
||||||
private static final String LIST = "java.util.List";
|
|
||||||
private static final String SET = "java.util.Set";
|
|
||||||
private static final String MAP = "java.util.Map";
|
|
||||||
|
|
||||||
private static final Map<Class<?>, JSONSerializer<?>> serializers = new HashMap<>();
|
|
||||||
private static final String ROOT_PACKAGE = "serializer.";
|
|
||||||
|
|
||||||
private final ClassPool pool = ClassPool.getDefault();
|
|
||||||
private CtClass serializerBase;
|
|
||||||
|
|
||||||
|
|
||||||
public SynthSerializerFactory() {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void init() {
|
|
||||||
try {
|
|
||||||
serializerBase = pool.get(JSONSerializer.class.getName());
|
|
||||||
} catch (NotFoundException e) {
|
|
||||||
throw new SerializerCreationException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
<T> JSONSerializer<T> createSerializer(Class<T> beanjavaClass) {
|
|
||||||
JSONSerializer<T> serializer = (JSONSerializer<T>) serializers.get(beanjavaClass);
|
|
||||||
if (serializer != null) {
|
|
||||||
return serializer;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return tryCreateSerializer(beanjavaClass);
|
|
||||||
} catch (NotFoundException | CannotCompileException | InstantiationException | IllegalAccessException |
|
|
||||||
InvocationTargetException | NoSuchMethodException e) {
|
|
||||||
throw new SerializerCreationException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> JSONSerializer<T> tryCreateSerializer(Class<?> javaClass) throws NotFoundException, CannotCompileException, InstantiationException,
|
|
||||||
IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
||||||
CtClass beanClass = pool.get(javaClass.getName());
|
|
||||||
CtClass serializerClass = pool.makeClass(createSerializerName(beanClass), serializerBase);
|
|
||||||
|
|
||||||
addToJsonStringMethod(beanClass, serializerClass);
|
|
||||||
|
|
||||||
JSONSerializer<T> jsonSerializer = createSerializerInstance(serializerClass);
|
|
||||||
|
|
||||||
serializers.put(javaClass, jsonSerializer);
|
|
||||||
return jsonSerializer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* create method source, compile it and add it to the class under construction
|
|
||||||
*/
|
|
||||||
private void addToJsonStringMethod(CtClass beanClass, CtClass serializerClass) throws NotFoundException, CannotCompileException {
|
|
||||||
serializerClass.addMethod(CtNewMethod.make(createToJSONStringMethodSource(beanClass), serializerClass));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Creates the source, handling the for JSON different types of classes
|
|
||||||
*/
|
|
||||||
private String createToJSONStringMethodSource(CtClass beanClass) throws NotFoundException {
|
|
||||||
String source = "public String handle(Object object){\n";
|
|
||||||
if (beanClass.isArray()) {
|
|
||||||
source += "\tObject[] array=(Object[])object;\n";
|
|
||||||
source += handleArray();
|
|
||||||
} else if (isCollection(beanClass)) {
|
|
||||||
source += "\tObject[] array=((java.util.Collection)object).toArray();\n";
|
|
||||||
source += handleArray();
|
|
||||||
} else if (isMap(beanClass)) {
|
|
||||||
source += handleMap();
|
|
||||||
} else if (!isPrimitiveOrWrapperOrString(beanClass)) {
|
|
||||||
List<CtMethod> getters = getGetters(beanClass);
|
|
||||||
if (shouldAddGetterCallers(getters)) {
|
|
||||||
source = addGetterCallers(beanClass, source, getters);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
source += "\treturn \"\";}";
|
|
||||||
}
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Any Collection is converted to an array, after which code is generated to handle the single elements.
|
|
||||||
*
|
|
||||||
* A subserializer is created for every single element, but most of the time it will be the same cached instance.
|
|
||||||
*
|
|
||||||
* The generated code fills a StringBuilder. The values are generated by the subserializers
|
|
||||||
*/
|
|
||||||
private String handleArray() {
|
|
||||||
String source = "\tStringBuilder result=new StringBuilder(\"[\");\n";
|
|
||||||
source += "\tfor (int i=0; i<array.length; i++){\n";
|
|
||||||
source += "\t\tresult.append(" + Serializer.class.getName() + ".toJSONString(array[i]));\n";
|
|
||||||
source += "\t\tresult.append(\", \");\n";
|
|
||||||
source += "\t};\n";
|
|
||||||
source += "\tresult.setLength(result.length()-2);\n";
|
|
||||||
source += "\tresult.append(\"]\");\n";
|
|
||||||
source += "\treturn result.toString();\n";
|
|
||||||
source += "}";
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String handleMap() {
|
|
||||||
String source = "StringBuilder result=new StringBuilder(\"{\");\n";
|
|
||||||
source += "\tfor (java.util.Iterator entries=((java.util.Map)object).entrySet().iterator();entries.hasNext();){\n";
|
|
||||||
source += "\t\tjava.util.Map.Entry entry=(java.util.Map.Entry)entries.next();\n";
|
|
||||||
source += "\t\tresult.append(\"\\\"\"+entry.getKey().toString()+\"\\\"\");\n";
|
|
||||||
source += "\t\tresult.append(\": \");\n";
|
|
||||||
source += "\t\tresult.append(" + Serializer.class.getName() + ".toJSONString(entry.getValue()));\n";
|
|
||||||
source += "\t\tresult.append(\", \");\n";
|
|
||||||
source += "\t};\n";
|
|
||||||
source += "\tresult.setLength(result.length()-2);\n";
|
|
||||||
source += "\tresult.append(\"}\");\n";
|
|
||||||
source += "\treturn result.toString();\n";
|
|
||||||
source += "}";
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the class contains fields for which public getters are available, then these will be called in the generated code.
|
|
||||||
*/
|
|
||||||
private String addGetterCallers(CtClass beanClass, String source, List<CtMethod> getters) {
|
|
||||||
int index = 0;
|
|
||||||
source += "\treturn ";
|
|
||||||
source += "\"{";
|
|
||||||
for (CtMethod getter : getters) {
|
|
||||||
source = addPair(beanClass, source, getter);
|
|
||||||
if (index++ < getters.size() - 1) {
|
|
||||||
source += ",";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
source += "}\";\n}";
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private <T> JSONSerializer<T> createSerializerInstance(CtClass serializerClass) throws InstantiationException, IllegalAccessException,
|
|
||||||
CannotCompileException, NoSuchMethodException, InvocationTargetException {
|
|
||||||
return (JSONSerializer<T>) serializerClass.toClass().getConstructor().newInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* custom root package is prepended to avoid the java.lang class in which it's illegal to create new classes
|
|
||||||
*
|
|
||||||
* Array marks ( '[]' ) are replaced by the 'Array', Otherwise the SerializerClassName would be syntactically incorrect
|
|
||||||
*/
|
|
||||||
public String createSerializerName(CtClass beanClass) {
|
|
||||||
return createSerializerName(beanClass.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String createSerializerName(String name) {
|
|
||||||
return ROOT_PACKAGE + name.replaceAll("\\[]", "Array") + "Serializer";
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isCollection(CtClass beanClass) throws NotFoundException {
|
|
||||||
List<CtClass> interfaces = new ArrayList<>(Arrays.asList(beanClass.getInterfaces()));
|
|
||||||
interfaces.add(beanClass);
|
|
||||||
for (CtClass interfaze : interfaces) {
|
|
||||||
if (interfaze.getName().equals(COLLECTION) || interfaze.getName().equals(LIST) || interfaze.getName().equals(SET)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isMap(CtClass beanClass) throws NotFoundException {
|
|
||||||
List<CtClass> interfaces = new ArrayList<>(Arrays.asList(beanClass.getInterfaces()));
|
|
||||||
interfaces.add(beanClass);
|
|
||||||
for (CtClass interfaze : interfaces) {
|
|
||||||
if (interfaze.getName().equals(MAP)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The JSON vernacular for key:value is pair...
|
|
||||||
*/
|
|
||||||
private String addPair(CtClass classToSerialize, String source, CtMethod getter) {
|
|
||||||
source += jsonKey(getter);
|
|
||||||
source += ": "; // what is the rule when it comes to spaces in json?
|
|
||||||
source += jsonValue(classToSerialize, getter);
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* derive property key from getter
|
|
||||||
*/
|
|
||||||
private String jsonKey(CtMethod getter) {
|
|
||||||
return "\\\"" + toFieldName(getter.getName()) + "\\\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
private String jsonValue(CtClass classToSerialize, CtMethod getter) {
|
|
||||||
/* primitives are wrapped so the produced methods adhere to the JSONSerializer interface */
|
|
||||||
return createSubSerializerForReturnTypeAndAddInvocationToSource(classToSerialize, getter);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String createSubSerializerForReturnTypeAndAddInvocationToSource(CtClass classToSerialize, CtMethod getter) {
|
|
||||||
/* NB there does not seem to be auto(un))boxing nor generic types (or other jdk1.5 stuff) in javassist compileable code */
|
|
||||||
String source = "\"+" + Serializer.class.getName() + ".toJSONString(";
|
|
||||||
|
|
||||||
// cast because of lack of generics
|
|
||||||
source += "(" + cast(regularClassname(classToSerialize.getName())) + "object)." + getter.getName() + "()";
|
|
||||||
|
|
||||||
source += ")+\"";
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* turns for example 'getValue' into 'value'
|
|
||||||
*/
|
|
||||||
private String toFieldName(String name) {
|
|
||||||
return name.substring(3, 4).toLowerCase() + (name.length() > 4 ? name.substring(4) : "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String regularClassname(String name) {
|
|
||||||
return name.replaceAll("\\$", ".");
|
|
||||||
}
|
|
||||||
|
|
||||||
private String cast(String classToSerialize) {
|
|
||||||
return "(" + classToSerialize + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Retrieves getter methods from a class
|
|
||||||
*/
|
|
||||||
private List<CtMethod> getGetters(CtClass beanClass) {
|
|
||||||
List<CtMethod> methods = new ArrayList<>();
|
|
||||||
List<CtField> fields = getAllFields(beanClass);
|
|
||||||
for (CtField field : fields) {
|
|
||||||
try {
|
|
||||||
CtMethod method = beanClass.getMethod(getGetterMethod(field), getDescription(field));
|
|
||||||
if (Modifier.isPublic(method.getModifiers())) {
|
|
||||||
methods.add(method);
|
|
||||||
}
|
|
||||||
} catch (NotFoundException n) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return methods;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getGetterMethod(CtField field) {
|
|
||||||
return "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<CtField> getAllFields(CtClass beanClass) {
|
|
||||||
try {
|
|
||||||
List<CtField> allfields = new ArrayList<>(Arrays.asList(beanClass.getDeclaredFields()));
|
|
||||||
if (beanClass.getSuperclass() != null) {
|
|
||||||
return getAllFields(beanClass.getSuperclass(), allfields);
|
|
||||||
}
|
|
||||||
return allfields;
|
|
||||||
} catch (NotFoundException e) {
|
|
||||||
throw new SerializerCreationException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<CtField> getAllFields(CtClass beanClass, List<CtField> allfields) {
|
|
||||||
allfields.addAll(Arrays.asList(beanClass.getDeclaredFields()));
|
|
||||||
|
|
||||||
return allfields;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* is getter list is not empty then callers should be added
|
|
||||||
*/
|
|
||||||
boolean shouldAddGetterCallers(List<CtMethod> getters) {
|
|
||||||
return !getters.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
String getDescription(CtField field) throws NotFoundException {
|
|
||||||
if (field.getType().isArray()) {
|
|
||||||
return "()[" + innerClassName(field.getType().getName()) + ";";
|
|
||||||
} else if (!field.getType().isPrimitive()) {
|
|
||||||
return "()" + innerClassName(field.getType().getName()) + ";";
|
|
||||||
} else {
|
|
||||||
|
|
||||||
return "()" + asPrimitive(field.getType().getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String asPrimitive(String name) {
|
|
||||||
switch (name) {
|
|
||||||
case "int":
|
|
||||||
return "I";
|
|
||||||
case "byte":
|
|
||||||
return "B";
|
|
||||||
case "float":
|
|
||||||
return "F";
|
|
||||||
case "long":
|
|
||||||
return "J";
|
|
||||||
case "boolean":
|
|
||||||
return "Z";
|
|
||||||
case "char":
|
|
||||||
return "C";
|
|
||||||
case "double":
|
|
||||||
return "D";
|
|
||||||
case "short":
|
|
||||||
return "S";
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
String innerClassName(String name) {
|
|
||||||
return "L" + name.replaceAll("\\.", "/").replaceAll("\\[]", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean isPrimitiveOrWrapperOrString(CtClass beanClass) {
|
|
||||||
return beanClass.isPrimitive() || wrappersAndString.contains(beanClass.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
7
src/main/java/nl/sanderhautvast/json/ser/BaseMapper.java
Normal file
7
src/main/java/nl/sanderhautvast/json/ser/BaseMapper.java
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
package nl.sanderhautvast.json.ser;
|
||||||
|
|
||||||
|
public abstract class BaseMapper<T> {
|
||||||
|
|
||||||
|
protected abstract String json(T value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package nl.sanderhautvast.json.ser;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
public class ByteClassLoader extends ClassLoader {
|
||||||
|
|
||||||
|
private final ConcurrentMap<String, Class<?>> classes = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
||||||
|
Class<?> instance = classes.get(name);
|
||||||
|
if (instance == null) {
|
||||||
|
throw new ClassNotFoundException(name);
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addClass(String name, byte[] bytecode) {
|
||||||
|
Class<?> classDef = defineClass(name, bytecode, 0, bytecode.length);
|
||||||
|
classes.put(name, classDef);
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/main/java/nl/sanderhautvast/json/ser/JsonError.java
Normal file
7
src/main/java/nl/sanderhautvast/json/ser/JsonError.java
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
package nl.sanderhautvast.json.ser;
|
||||||
|
|
||||||
|
public class JsonError extends RuntimeException{
|
||||||
|
public JsonError(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
302
src/main/java/nl/sanderhautvast/json/ser/Mapper.java
Normal file
302
src/main/java/nl/sanderhautvast/json/ser/Mapper.java
Normal file
|
|
@ -0,0 +1,302 @@
|
||||||
|
package nl.sanderhautvast.json.ser;
|
||||||
|
|
||||||
|
import org.objectweb.asm.ClassReader;
|
||||||
|
import org.objectweb.asm.ClassWriter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
|
||||||
|
public class Mapper {
|
||||||
|
private static final Map<Class<?>, BaseMapper<?>> mappers = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private static final ByteClassLoader generatedClassesLoader = new ByteClassLoader();
|
||||||
|
|
||||||
|
static {
|
||||||
|
addMapper(String.class, new StringMapper());
|
||||||
|
addMapper(Boolean.class, new BooleanMapper());
|
||||||
|
addMapper(Integer.class, new IntegerMapper());
|
||||||
|
addMapper(Long.class, new LongMapper());
|
||||||
|
addMapper(Short.class, new ShortMapper());
|
||||||
|
addMapper(Byte.class, new ByteMapper());
|
||||||
|
addMapper(Character.class, new CharMapper());
|
||||||
|
addMapper(Float.class, new FloatMapper());
|
||||||
|
addMapper(Double.class, new DoubleMapper());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new (custom) mapper implementation for the specified type
|
||||||
|
*
|
||||||
|
* @param type The class to serialize to json
|
||||||
|
* @param mapper the Mapper implementation
|
||||||
|
*/
|
||||||
|
public static <T> void addMapper(Class<T> type, BaseMapper<T> mapper) {
|
||||||
|
mappers.put(type, mapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the json representation of the value as a String
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
public static <J> String json(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
|
Class<J> type = (Class<J>) value.getClass();
|
||||||
|
if (type.isArray()) {
|
||||||
|
return array((Object[]) value);
|
||||||
|
}
|
||||||
|
if (value instanceof Collection) {
|
||||||
|
return list((Collection) value);
|
||||||
|
}
|
||||||
|
if (value instanceof Map) {
|
||||||
|
return object((Map) value);
|
||||||
|
}
|
||||||
|
BaseMapper mapper = mappers.computeIfAbsent(type, key -> createObjectMapper(type));
|
||||||
|
return mapper.json(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
|
private static String array(Object[] array) {
|
||||||
|
if (array.length == 0) {
|
||||||
|
return "[]";
|
||||||
|
}
|
||||||
|
Object first = array[0];
|
||||||
|
Class<?> elementType = first.getClass();
|
||||||
|
BaseMapper mapper = mappers.computeIfAbsent(elementType, key -> createObjectMapper(elementType));
|
||||||
|
StringBuilder builder = new StringBuilder("[");
|
||||||
|
builder.append(mapper.json(first));
|
||||||
|
Arrays.stream(array).skip(1)
|
||||||
|
.forEach(element -> {
|
||||||
|
builder.append(",");
|
||||||
|
builder.append(mapper.json(element));
|
||||||
|
});
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
|
private static String list(Collection list) {
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
return "[]";
|
||||||
|
}
|
||||||
|
Object first = list.iterator().next();
|
||||||
|
Class<?> elementType = first.getClass();
|
||||||
|
BaseMapper mapper = mappers.computeIfAbsent(elementType, key -> createObjectMapper(elementType));
|
||||||
|
StringBuilder builder = new StringBuilder("[");
|
||||||
|
builder.append(mapper.json(first));
|
||||||
|
list.stream().skip(1)
|
||||||
|
.forEach(element -> {
|
||||||
|
builder.append(",");
|
||||||
|
builder.append(mapper.json(element));
|
||||||
|
});
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
|
private static String object(Map map) {
|
||||||
|
if (map.isEmpty()) {
|
||||||
|
return "{}";
|
||||||
|
}
|
||||||
|
Set<Map.Entry> entries = map.entrySet();
|
||||||
|
Map.Entry first = entries.iterator().next();
|
||||||
|
Class<?> valueType = first.getValue().getClass();
|
||||||
|
|
||||||
|
BaseMapper mapper = mappers.computeIfAbsent(valueType, key -> createObjectMapper(valueType));
|
||||||
|
StringBuilder builder = new StringBuilder("{");
|
||||||
|
builder.append("\"").append(first.getKey()).append("\":").append(mapper.json(first.getValue()));
|
||||||
|
entries.stream().skip(1)
|
||||||
|
.forEach(entry -> {
|
||||||
|
builder.append(",\"");
|
||||||
|
builder.append(entry.getKey()).append("\":");
|
||||||
|
builder.append(mapper.json(entry.getValue()));
|
||||||
|
});
|
||||||
|
builder.append("}");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String json(byte value) {
|
||||||
|
return Byte.toString(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String json(boolean value) {
|
||||||
|
return Boolean.toString(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String json(short value) {
|
||||||
|
return Short.toString(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String json(int value) {
|
||||||
|
return Integer.toString(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String json(long value) {
|
||||||
|
return Long.toString(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String json(char value) {
|
||||||
|
return "\"" + escape(value) + "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String json(float value) {
|
||||||
|
return Float.toString(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String json(double value) {
|
||||||
|
return Double.toString(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static <T> BaseMapper<T> createObjectMapper(Class<T> forType) {
|
||||||
|
try {
|
||||||
|
ClassReader cr = new ClassReader(forType.getName());
|
||||||
|
MapperFactory mapperFactory = new MapperFactory();
|
||||||
|
cr.accept(mapperFactory, 0);
|
||||||
|
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||||
|
|
||||||
|
mapperFactory.classNode.accept(classWriter);
|
||||||
|
byte[] byteArray = classWriter.toByteArray();
|
||||||
|
generatedClassesLoader.addClass(mapperFactory.classNode.name, byteArray);
|
||||||
|
return (BaseMapper<T>) generatedClassesLoader.loadClass(mapperFactory.classNode.name).getConstructor().newInstance();
|
||||||
|
} catch (IOException | ClassNotFoundException | NoSuchMethodException | InstantiationException |
|
||||||
|
IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new JsonError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String escape(char c) {
|
||||||
|
return escape(String.valueOf(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
static String escape(String value) {
|
||||||
|
StringBuilder b = new StringBuilder(value);
|
||||||
|
int i = 0;
|
||||||
|
while (i < b.length()) {
|
||||||
|
char c = b.charAt(i);
|
||||||
|
switch (c) {
|
||||||
|
case '\t':
|
||||||
|
b.replace(i,i+1, "\\");
|
||||||
|
b.insert(i+1, "t");
|
||||||
|
break;
|
||||||
|
case '\"':
|
||||||
|
b.replace(i,i+1, "\\");
|
||||||
|
b.insert(++i, "\"");
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
b.replace(i,i+1, "\\");
|
||||||
|
b.insert(++i, "/");
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
b.replace(i,i+1, "\\");
|
||||||
|
b.insert(++i, "r");
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
b.replace(i,i+1, "\\");
|
||||||
|
b.insert(++i, "n");
|
||||||
|
break;
|
||||||
|
case '\b':
|
||||||
|
b.replace(i,i+1, "\\");
|
||||||
|
b.insert(++i, "b");
|
||||||
|
break;
|
||||||
|
case '\f':
|
||||||
|
b.replace(i,i+1, "\\");
|
||||||
|
b.insert(++i, "f");
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
b.replace(i,i+1, "\\");
|
||||||
|
b.insert(++i, "\\");
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if ((c <= '\u001F') || (c >= '\u007F' && c <= '\u009F') || (c >= '\u2000' && c <= '\u20FF')) {
|
||||||
|
String ss = Integer.toHexString(c);
|
||||||
|
b.replace(i,i+1,"\\");
|
||||||
|
b.insert(++i, "u");
|
||||||
|
for (int k = 0; k < 4 - ss.length(); k++) {
|
||||||
|
b.insert(++i,'0');
|
||||||
|
}
|
||||||
|
b.insert(++i,ss.toUpperCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return b.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BooleanMapper extends BaseMapper<Boolean> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String json(Boolean b) {
|
||||||
|
return Boolean.toString(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ShortMapper extends BaseMapper<Short> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String json(Short value) {
|
||||||
|
return Short.toString(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class StringMapper extends BaseMapper<String> {
|
||||||
|
@Override
|
||||||
|
public String json(String value) {
|
||||||
|
return "\"" + Mapper.escape(value) + "\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IntegerMapper extends BaseMapper<Integer> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String json(Integer value) {
|
||||||
|
return Integer.toString(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LongMapper extends BaseMapper<Long> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String json(Long value) {
|
||||||
|
return Long.toString(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ByteMapper extends BaseMapper<Byte> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String json(Byte value) {
|
||||||
|
return Byte.toString(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CharMapper extends BaseMapper<Character> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String json(Character value) {
|
||||||
|
return "\"" + value + "\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FloatMapper extends BaseMapper<Float> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String json(Float value) {
|
||||||
|
return Float.toString(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DoubleMapper extends BaseMapper<Double> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String json(Double value) {
|
||||||
|
return Double.toString(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
148
src/main/java/nl/sanderhautvast/json/ser/MapperFactory.java
Normal file
148
src/main/java/nl/sanderhautvast/json/ser/MapperFactory.java
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
package nl.sanderhautvast.json.ser;
|
||||||
|
|
||||||
|
import org.objectweb.asm.ClassVisitor;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.objectweb.asm.tree.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
|
public class MapperFactory extends ClassVisitor {
|
||||||
|
|
||||||
|
public static final String MAPPERBASECLASS = javaName(BaseMapper.class.getName());
|
||||||
|
|
||||||
|
public static final String INIT = "<init>";
|
||||||
|
public static final String ZERO_ARGS_VOID = "()V";
|
||||||
|
public static final String APPEND = "append";
|
||||||
|
public static final String STRINGBUILDER = "java/lang/StringBuilder";
|
||||||
|
public static final String MAPPER = "nl/sanderhautvast/json/ser/Mapper";
|
||||||
|
public static final String APPEND_SIGNATURE = "(Ljava/lang/String;)Ljava/lang/StringBuilder;";
|
||||||
|
public static final String OBJECT = "Ljava/lang/Object;";
|
||||||
|
|
||||||
|
public MapperFactory() {
|
||||||
|
super(ASM7);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
final ClassNode classNode = new ClassNode();
|
||||||
|
|
||||||
|
private String classToMap;
|
||||||
|
|
||||||
|
private MethodNode jsonMethod;
|
||||||
|
|
||||||
|
private boolean firstGetter = true;
|
||||||
|
|
||||||
|
private final LinkedList<AbstractInsnNode> getterInsnList = new LinkedList<>();
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
classNode.version = V1_5;
|
||||||
|
classNode.access = ACC_PUBLIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
|
||||||
|
this.classToMap = name;
|
||||||
|
classNode.name = "Mapper"+ UUID.randomUUID();
|
||||||
|
classNode.superName = MAPPERBASECLASS;
|
||||||
|
MethodNode constructor = new MethodNode(ACC_PUBLIC, INIT, ZERO_ARGS_VOID, null, null);
|
||||||
|
constructor.instructions.add(new VarInsnNode(ALOAD, 0));
|
||||||
|
constructor.instructions.add(new MethodInsnNode(INVOKESPECIAL, MAPPERBASECLASS, INIT, ZERO_ARGS_VOID));
|
||||||
|
constructor.instructions.add(new InsnNode(RETURN));
|
||||||
|
classNode.methods.add(constructor);
|
||||||
|
|
||||||
|
jsonMethod = new MethodNode(ACC_PUBLIC,
|
||||||
|
"json", "(Ljava/lang/Object;)Ljava/lang/String;", null, null);
|
||||||
|
classNode.methods.add(jsonMethod);
|
||||||
|
add(new VarInsnNode(ALOAD, 1));
|
||||||
|
add(new TypeInsnNode(CHECKCAST, name));
|
||||||
|
add(new VarInsnNode(ASTORE, 1));
|
||||||
|
add(new TypeInsnNode(NEW, STRINGBUILDER));
|
||||||
|
add(new InsnNode(DUP));
|
||||||
|
add(new MethodInsnNode(INVOKESPECIAL, STRINGBUILDER, "<init>", "()V"));
|
||||||
|
add(new VarInsnNode(ASTORE, 2));
|
||||||
|
add(new VarInsnNode(ALOAD, 2));
|
||||||
|
add(new LdcInsnNode("{"));
|
||||||
|
add(new MethodInsnNode(INVOKEVIRTUAL, STRINGBUILDER, APPEND, APPEND_SIGNATURE));
|
||||||
|
add(new InsnNode(POP));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MethodVisitor visitMethod(int access, String methodname,
|
||||||
|
String desc, String signature, String[] exceptions) {
|
||||||
|
if (!hasArgs(desc) && access == Modifier.PUBLIC &&
|
||||||
|
(methodname.startsWith("get") || (methodname.startsWith("is")) && desc.equals("()Z"))) {
|
||||||
|
visitGetter(methodname, getReturnType(desc));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void visitGetter(String getterMethodName, String returnType) {
|
||||||
|
int startIndex;
|
||||||
|
if (getterMethodName.startsWith("is")) {
|
||||||
|
startIndex = 2;
|
||||||
|
} else {
|
||||||
|
startIndex = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!firstGetter){
|
||||||
|
getterInsnList.add(new VarInsnNode(ALOAD, 2));
|
||||||
|
getterInsnList.add(new LdcInsnNode(","));
|
||||||
|
getterInsnList.add(new MethodInsnNode(INVOKEVIRTUAL, STRINGBUILDER, APPEND, APPEND_SIGNATURE));
|
||||||
|
getterInsnList.add(new InsnNode(POP));
|
||||||
|
} else {
|
||||||
|
firstGetter = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
getterInsnList.add(new VarInsnNode(ALOAD, 2));
|
||||||
|
getterInsnList.add(new LdcInsnNode("\"" + getterMethodName.substring(startIndex).toLowerCase() + "\":"));
|
||||||
|
getterInsnList.add(new MethodInsnNode(INVOKEVIRTUAL, STRINGBUILDER, APPEND, APPEND_SIGNATURE));
|
||||||
|
getterInsnList.add(new InsnNode(POP));
|
||||||
|
getterInsnList.add(new VarInsnNode(ALOAD, 2));
|
||||||
|
getterInsnList.add(new VarInsnNode(ALOAD, 1));
|
||||||
|
getterInsnList.add(new MethodInsnNode(INVOKEVIRTUAL, classToMap, getterMethodName, "()" + returnType));
|
||||||
|
getterInsnList.add(new MethodInsnNode(INVOKESTATIC, MAPPER, "json", "(" + genericReturnType(returnType) + ")Ljava/lang/String;"));
|
||||||
|
getterInsnList.add(new MethodInsnNode(INVOKEVIRTUAL, STRINGBUILDER, APPEND, APPEND_SIGNATURE));
|
||||||
|
getterInsnList.add(new InsnNode(POP));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String genericReturnType(String returnType) {
|
||||||
|
char firstChar = returnType.charAt(0);
|
||||||
|
if (firstChar == 'L' || firstChar == '[') {
|
||||||
|
return OBJECT;
|
||||||
|
} else {
|
||||||
|
return returnType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitEnd() {
|
||||||
|
for (AbstractInsnNode insn : getterInsnList) {
|
||||||
|
add(insn);
|
||||||
|
}
|
||||||
|
add(new VarInsnNode(ALOAD, 2));
|
||||||
|
add(new LdcInsnNode("}"));
|
||||||
|
add(new MethodInsnNode(INVOKEVIRTUAL, STRINGBUILDER, APPEND, APPEND_SIGNATURE));
|
||||||
|
add(new VarInsnNode(ALOAD, 2));
|
||||||
|
add(new MethodInsnNode(INVOKEVIRTUAL, STRINGBUILDER, "toString", "()Ljava/lang/String;"));
|
||||||
|
add(new InsnNode(ARETURN));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void add(AbstractInsnNode ins) {
|
||||||
|
jsonMethod.instructions.add(ins);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getReturnType(String desc) {
|
||||||
|
return desc.substring(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasArgs(String desc) {
|
||||||
|
return desc.charAt(1) != ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String javaName(String className) {
|
||||||
|
return className.replaceAll("\\.", "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class StringPropertyTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void stringValue() {
|
|
||||||
assertEquals("\"value\"", Serializer.toJSONString("value"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void stringProperty() {
|
|
||||||
Bean object = new Bean();
|
|
||||||
object.setData1("value1");
|
|
||||||
object.setData2("value2");
|
|
||||||
assertEquals("{\"data1\": \"value1\",\"data2\": \"value2\"}", Serializer.toJSONString(object));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void stringPropertyNull() {
|
|
||||||
Bean object = new Bean();
|
|
||||||
object.setData1("value1");
|
|
||||||
object.setData2("null");
|
|
||||||
assertEquals("{\"data1\": \"value1\",\"data2\": \"null\"}", Serializer.toJSONString(object));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Bean {
|
|
||||||
private String data1;
|
|
||||||
private String data2;
|
|
||||||
|
|
||||||
public String getData1() {
|
|
||||||
return data1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData1(String data1) {
|
|
||||||
this.data1 = data1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getData2() {
|
|
||||||
return data2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData2(String data2) {
|
|
||||||
this.data2 = data2;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize.collections;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import nl.jssl.jsontoy.serialize.Serializer;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class ArrayTest {
|
|
||||||
@Test
|
|
||||||
public void testValue() {
|
|
||||||
assertEquals("[\"value1\", \"value2\"]", Serializer.toJSONString(new String[] { "value1", "value2" }));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPropertyValue() {
|
|
||||||
Bean object = new Bean();
|
|
||||||
object.setArray(new String[] { "value1", "value2" });
|
|
||||||
assertEquals("{\"array\": [\"value1\", \"value2\"]}", Serializer.toJSONString(object));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Bean {
|
|
||||||
private String[] array;
|
|
||||||
|
|
||||||
public String[] getArray() {
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setArray(String[] array) {
|
|
||||||
this.array = array;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize.collections;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import nl.jssl.jsontoy.serialize.Serializer;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class ListTest {
|
|
||||||
@Test
|
|
||||||
public void testValue() {
|
|
||||||
List<String> list = new ArrayList();
|
|
||||||
list.add("value1");
|
|
||||||
list.add("value2");
|
|
||||||
assertEquals("[\"value1\", \"value2\"]", Serializer.toJSONString(list));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPropertyValue() {
|
|
||||||
Bean object = new Bean();
|
|
||||||
object.setArray(new String[] { "value1", "value2" });
|
|
||||||
assertEquals("{\"array\": [\"value1\", \"value2\"]}", Serializer.toJSONString(object));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Bean {
|
|
||||||
private String[] array;
|
|
||||||
|
|
||||||
public String[] getArray() {
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setArray(String[] array) {
|
|
||||||
this.array = array;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize.collections;
|
|
||||||
|
|
||||||
import nl.jssl.jsontoy.serialize.Serializer;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
public class MapTest {
|
|
||||||
@Test
|
|
||||||
public void testValue() {
|
|
||||||
Map<String, String> map = new HashMap<>();
|
|
||||||
map.put("key1", "value1");
|
|
||||||
map.put("key2", "value2");
|
|
||||||
String jsonString = Serializer.toJSONString(map);
|
|
||||||
assertTrue("{\"key1\": \"value1\", \"key2\": \"value2\"}".equals(jsonString) || "{\"key2\": \"value2\", \"key1\": \"value1\"}".equals(jsonString));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPropertyValue() {
|
|
||||||
Bean object = new Bean();
|
|
||||||
Map<String, String> map = new HashMap<>();
|
|
||||||
map.put("key1", "value1");
|
|
||||||
map.put("key2", "value2");
|
|
||||||
object.setMap(map);
|
|
||||||
String jsonString = Serializer.toJSONString(object);
|
|
||||||
assertTrue("{\"map\": {\"key1\": \"value1\", \"key2\": \"value2\"}}".equals(jsonString)
|
|
||||||
|| "{\"map\": {\"key2\": \"value2\", \"key1\": \"value1\"}}".equals(jsonString));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Bean {
|
|
||||||
|
|
||||||
private Map<String, String> map;
|
|
||||||
|
|
||||||
public Map<String, String> getMap() {
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMap(Map<String, String> map) {
|
|
||||||
this.map = map;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize.collections;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import nl.jssl.jsontoy.serialize.Serializer;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class SetTest {
|
|
||||||
@Test
|
|
||||||
public void testValue() {
|
|
||||||
Set<String> list = new HashSet<String>();
|
|
||||||
list.add("value1");
|
|
||||||
list.add("value2");
|
|
||||||
String jsonString = Serializer.toJSONString(list);
|
|
||||||
assertTrue("[\"value2\", \"value1\"]".equals(jsonString) || "[\"value1\", \"value2\"]".equals(jsonString));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPropertyValue() {
|
|
||||||
Bean object = new Bean();
|
|
||||||
object.setSet(new HashSet<String>(Arrays.asList("value1", "value2")));
|
|
||||||
String jsonString = Serializer.toJSONString(object);
|
|
||||||
assertTrue("{\"set\": [\"value2\", \"value1\"]}".equals(jsonString) || "{\"set\": [\"value1\", \"value2\"]}".equals(jsonString));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Bean {
|
|
||||||
private Set<String> set;
|
|
||||||
|
|
||||||
public Set<String> getSet() {
|
|
||||||
return set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSet(Set<String> set) {
|
|
||||||
this.set = set;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize.nested;
|
|
||||||
|
|
||||||
public class Bean1 {
|
|
||||||
private String data1;
|
|
||||||
private Bean2 bean2;
|
|
||||||
|
|
||||||
public String getData1() {
|
|
||||||
return data1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData1(String data1) {
|
|
||||||
this.data1 = data1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bean2 getBean2() {
|
|
||||||
return bean2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBean2(Bean2 bean2) {
|
|
||||||
this.bean2 = bean2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((data1 == null) ? 0 : data1.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj)
|
|
||||||
return true;
|
|
||||||
if (obj == null)
|
|
||||||
return false;
|
|
||||||
if (getClass() != obj.getClass())
|
|
||||||
return false;
|
|
||||||
Bean1 other = (Bean1) obj;
|
|
||||||
if (data1 == null) {
|
|
||||||
if (other.data1 != null)
|
|
||||||
return false;
|
|
||||||
} else if (!data1.equals(other.data1))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize.nested;
|
|
||||||
|
|
||||||
public class Bean2 {
|
|
||||||
private String data2;
|
|
||||||
|
|
||||||
public String getData2() {
|
|
||||||
return data2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData2(String data2) {
|
|
||||||
this.data2 = data2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize.nested;
|
|
||||||
|
|
||||||
public class Bean2Child extends Bean2 {
|
|
||||||
private String data3;
|
|
||||||
|
|
||||||
public String getData3() {
|
|
||||||
return data3;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData3(String data3) {
|
|
||||||
this.data3 = data3;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize.nested;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import nl.jssl.jsontoy.serialize.Serializer;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class NestedBeanTest {
|
|
||||||
@Test
|
|
||||||
public void testBeans() {
|
|
||||||
Bean1 object1 = new Bean1();
|
|
||||||
object1.setData1("value1");
|
|
||||||
Bean2 object2 = new Bean2();
|
|
||||||
object2.setData2("value2");
|
|
||||||
object1.setBean2(object2);
|
|
||||||
assertEquals("{\"data1\": \"value1\",\"bean2\": {\"data2\": \"value2\"}}", Serializer.toJSONString(object1));
|
|
||||||
assertEquals("{\"data1\": \"value1\",\"bean2\": {\"data2\": \"value2\"}}", Serializer.toJSONString(object1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNullValueForBean() {
|
|
||||||
Bean1 object1 = new Bean1();
|
|
||||||
object1.setData1("value1");
|
|
||||||
assertEquals("{\"data1\": \"value1\",\"bean2\": null}", Serializer.toJSONString(object1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBeanChildren() {
|
|
||||||
Bean1 object1 = new Bean1();
|
|
||||||
object1.setData1("value1");
|
|
||||||
Bean2Child object3 = new Bean2Child();
|
|
||||||
object3.setData2("value2");
|
|
||||||
object3.setData3("value3");
|
|
||||||
object1.setBean2(object3);
|
|
||||||
assertEquals("{\"data1\": \"value1\",\"bean2\": {\"data3\": \"value3\",\"data2\": \"value2\"}}", Serializer.toJSONString(object1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize.primitives;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import nl.jssl.jsontoy.serialize.Serializer;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class BooleanPropertyTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPrimitive() {
|
|
||||||
assertEquals("false", Serializer.toJSONString(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testWrapper() {
|
|
||||||
assertEquals("false", Serializer.toJSONString(Boolean.FALSE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testProperty() {
|
|
||||||
Bean object = new Bean();
|
|
||||||
object.setData(true);
|
|
||||||
assertEquals("{\"data\": true}", Serializer.toJSONString(object));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Bean {
|
|
||||||
private boolean data;
|
|
||||||
|
|
||||||
public boolean getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData(boolean data) {
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize.primitives;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import nl.jssl.jsontoy.serialize.Serializer;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class BytePropertyTest {
|
|
||||||
@Test
|
|
||||||
public void testPrimitive() {
|
|
||||||
assertEquals("-55", Serializer.toJSONString((byte) -55));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testWrapper() {
|
|
||||||
assertEquals("55", Serializer.toJSONString((byte) 55));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testProperty() {
|
|
||||||
Bean object = new Bean();
|
|
||||||
object.setData((byte) 1);
|
|
||||||
assertEquals("{\"data\": 1}", Serializer.toJSONString(object));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Bean {
|
|
||||||
private byte data;
|
|
||||||
|
|
||||||
public byte getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData(byte data) {
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize.primitives;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import nl.jssl.jsontoy.serialize.Serializer;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class CharPropertyTest {
|
|
||||||
@Test
|
|
||||||
public void testPrimitive() {
|
|
||||||
assertEquals("\"d\"", Serializer.toJSONString('d'));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testWrapper() {
|
|
||||||
assertEquals("\"s\"", Serializer.toJSONString('s'));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testProperty() {
|
|
||||||
Bean object = new Bean();
|
|
||||||
object.setData('a');
|
|
||||||
assertEquals("{\"data\": \"a\"}", Serializer.toJSONString(object));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Bean {
|
|
||||||
private char data;
|
|
||||||
|
|
||||||
public char getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData(char data) {
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize.primitives;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import nl.jssl.jsontoy.serialize.Serializer;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class DoublePropertyTest {
|
|
||||||
@Test
|
|
||||||
public void testPrimitive() {
|
|
||||||
assertEquals("-55.6", Serializer.toJSONString(-55.6D));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testWrapper() {
|
|
||||||
assertEquals("55.0", Serializer.toJSONString(Double.valueOf("55.0")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testProperty() {
|
|
||||||
Bean object = new Bean();
|
|
||||||
object.setData(326.2D);
|
|
||||||
assertEquals("{\"data\": 326.2}", Serializer.toJSONString(object));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Bean {
|
|
||||||
private double data;
|
|
||||||
|
|
||||||
public double getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData(double data) {
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize.primitives;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import nl.jssl.jsontoy.serialize.Serializer;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class FloatPropertyTest {
|
|
||||||
@Test
|
|
||||||
public void testPrimitive() {
|
|
||||||
assertEquals("-55.6", Serializer.toJSONString(-55.6F));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testWrapper() {
|
|
||||||
assertEquals("55.0", Serializer.toJSONString(Float.valueOf("55.0")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testProperty() {
|
|
||||||
Bean object = new Bean();
|
|
||||||
object.setData(1F);
|
|
||||||
assertEquals("{\"data\": 1.0}", Serializer.toJSONString(object));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Bean {
|
|
||||||
private float data;
|
|
||||||
|
|
||||||
public float getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData(float data) {
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize.primitives;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import nl.jssl.jsontoy.serialize.Serializer;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class IntPropertyTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPrimitive() {
|
|
||||||
assertEquals("-55", Serializer.toJSONString(-55));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testWrapper() {
|
|
||||||
assertEquals("55", Serializer.toJSONString(Integer.valueOf("55")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPropertyValue() {
|
|
||||||
Bean object = new Bean();
|
|
||||||
object.setData(1);
|
|
||||||
assertEquals("{\"data\": 1}", Serializer.toJSONString(object));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Bean {
|
|
||||||
private int data;
|
|
||||||
|
|
||||||
public int getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData(int data) {
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize.primitives;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import nl.jssl.jsontoy.serialize.Serializer;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class LongPropertyTest {
|
|
||||||
@Test
|
|
||||||
public void testPrimitive() {
|
|
||||||
assertEquals("-55", Serializer.toJSONString(-55L));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testWrapper() {
|
|
||||||
assertEquals("55", Serializer.toJSONString(Long.valueOf("55")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testProperty() {
|
|
||||||
Bean object = new Bean();
|
|
||||||
object.setData(1L);
|
|
||||||
assertEquals("{\"data\": 1}", Serializer.toJSONString(object));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Bean {
|
|
||||||
private long data;
|
|
||||||
|
|
||||||
public long getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData(long data) {
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize.primitives;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import nl.jssl.jsontoy.serialize.Serializer;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class NullPropertyTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPrimitive() {
|
|
||||||
assertEquals("null", Serializer.toJSONString(null));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testProperty() {
|
|
||||||
Bean object = new Bean();
|
|
||||||
assertEquals("{\"data\": null}", Serializer.toJSONString(object));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Bean {
|
|
||||||
private String data;
|
|
||||||
|
|
||||||
public String getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData(String data) {
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
package nl.jssl.jsontoy.serialize.primitives;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import nl.jssl.jsontoy.serialize.Serializer;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class ShortPropertyTest {
|
|
||||||
@Test
|
|
||||||
public void testPrimitive() {
|
|
||||||
assertEquals("-55", Serializer.toJSONString((short) -55));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testWrapper() {
|
|
||||||
assertEquals("5", Serializer.toJSONString(Short.valueOf("5")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testProperty() {
|
|
||||||
Bean object = new Bean();
|
|
||||||
object.setData((short) 3);
|
|
||||||
assertEquals("{\"data\": 3}", Serializer.toJSONString(object));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Bean {
|
|
||||||
private short data;
|
|
||||||
|
|
||||||
public short getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData(short data) {
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package nl.sanderhautvast.json.ser;
|
||||||
|
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
public class ByteClassLoaderTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void foo() {
|
||||||
|
assertThrows(ClassNotFoundException.class, () -> new ByteClassLoader().findClass("WrongName"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package nl.sanderhautvast.json.ser;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
|
public class StringPropertyTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void stringValue() {
|
||||||
|
assertEquals("\"value\"", Mapper.json("value"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void stringProperty() {
|
||||||
|
Bean object = new Bean();
|
||||||
|
object.setData1("value1");
|
||||||
|
object.setData2("value2");
|
||||||
|
assertEquals("{\"data1\":\"value1\",\"data2\":\"value2\"}", Mapper.json(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void stringPropertyNull() {
|
||||||
|
Bean object = new Bean();
|
||||||
|
object.setData1("value1");
|
||||||
|
object.setData2(null);
|
||||||
|
assertEquals("{\"data1\":\"value1\",\"data2\":null}", Mapper.json(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Bean {
|
||||||
|
private String data1;
|
||||||
|
private String data2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package nl.sanderhautvast.json.ser.collections;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import nl.sanderhautvast.json.ser.Mapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class ArrayTest {
|
||||||
|
@Test
|
||||||
|
public void testValue() {
|
||||||
|
assertEquals("[\"value1\",\"value2\"]", Mapper.json(new String[]{"value1", "value2"}));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPropertyValue() {
|
||||||
|
Bean object = new Bean();
|
||||||
|
object.setArray(new String[]{"value1", "value2"});
|
||||||
|
assertEquals("{\"array\":[\"value1\",\"value2\"]}", Mapper.json(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Bean {
|
||||||
|
private String[] array;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package nl.sanderhautvast.json.ser.collections;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import nl.sanderhautvast.json.ser.Mapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class ListTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEmpty() {
|
||||||
|
assertEquals("[]", Mapper.json(List.of()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testValue() {
|
||||||
|
assertEquals("[\"value1\",\"value2\"]", Mapper.json(List.of("value1", "value2")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPropertyValue() {
|
||||||
|
Bean object = new Bean();
|
||||||
|
object.setList(List.of("value1", "value2"));
|
||||||
|
assertEquals("{\"list\":[\"value1\",\"value2\"]}", Mapper.json((object)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Bean {
|
||||||
|
private List<String> list;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
package nl.sanderhautvast.json.ser.collections;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import nl.sanderhautvast.json.ser.Mapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
|
||||||
|
public class MapTest {
|
||||||
|
@Test
|
||||||
|
public void testValue() {
|
||||||
|
String jsonString = Mapper.json(Map.of("key1", "value1", "key2", "value2"));
|
||||||
|
assertTrue("{\"key1\":\"value1\",\"key2\":\"value2\"}".equals(jsonString)
|
||||||
|
|| "{\"key2\":\"value2\",\"key1\":\"value1\"}".equals(jsonString), jsonString); //order doesn't matter
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIntegerKeys() {
|
||||||
|
String jsonString = Mapper.json(Map.of(1, "value1", 2, "value2"));
|
||||||
|
assertTrue("{\"1\":\"value1\",\"2\":\"value2\"}".equals(jsonString)
|
||||||
|
|| "{\"2\":\"value2\",\"1\":\"value1\"}".equals(jsonString), jsonString); //order doesn't matter
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEmpty(){
|
||||||
|
assertEquals("{}", Mapper.json(Map.of()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPropertyValue() {
|
||||||
|
Bean object = new Bean();
|
||||||
|
object.setMap(Map.of("key1", "value1", "key2", "value2"));
|
||||||
|
String jsonString = Mapper.json(object);
|
||||||
|
assertTrue("{\"map\":{\"key1\":\"value1\",\"key2\":\"value2\"}}".equals(jsonString)
|
||||||
|
|| "{\"map\":{\"key2\":\"value2\",\"key1\":\"value1\"}}".equals(jsonString), jsonString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Bean {
|
||||||
|
private Map<String, String> map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
package nl.sanderhautvast.json.ser.collections;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import nl.sanderhautvast.json.ser.Mapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
public class SetTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEmpty(){
|
||||||
|
assertEquals("[]", Mapper.json(Set.of()));
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
public void testValue() {
|
||||||
|
String jsonString = Mapper.json(Set.of("value1", "value2"));
|
||||||
|
assertTrue("[\"value2\",\"value1\"]".equals(jsonString)
|
||||||
|
|| "[\"value1\",\"value2\"]".equals(jsonString), jsonString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPropertyValue() {
|
||||||
|
Bean object = new Bean();
|
||||||
|
object.setSet(Set.of("value1", "value2"));
|
||||||
|
String jsonString = Mapper.json(object);
|
||||||
|
assertTrue("{\"set\":[\"value2\",\"value1\"]}".equals(jsonString)
|
||||||
|
|| "{\"set\":[\"value1\",\"value2\"]}".equals(jsonString));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Bean {
|
||||||
|
private Set<String> set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
package nl.sanderhautvast.json.ser.collections;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import nl.sanderhautvast.json.ser.Mapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
class StringTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCharEscapes() {
|
||||||
|
assertEquals("\"\\t\"", Mapper.json('\t'));
|
||||||
|
assertEquals("\"\\b\"", Mapper.json('\b'));
|
||||||
|
assertEquals("\"\\r\"", Mapper.json('\r'));
|
||||||
|
assertEquals("\"\\n\"", Mapper.json('\n'));
|
||||||
|
assertEquals("\"\\\"\"", Mapper.json('\"'));
|
||||||
|
assertEquals("\"\\\\\"", Mapper.json('\\'));
|
||||||
|
assertEquals("\"\\f\"", Mapper.json('\f'));
|
||||||
|
assertEquals("\"\\/\"", Mapper.json('/'));
|
||||||
|
assertEquals("\"'\"", Mapper.json('\''));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testStringEscapes() {
|
||||||
|
assertEquals("\"bla\\tbla\"", Mapper.json("bla\tbla"));
|
||||||
|
assertEquals("\"\\b\\b\"", Mapper.json("\b\b"));
|
||||||
|
assertEquals("\"\\r\\n\"", Mapper.json("\r\n"));
|
||||||
|
assertEquals("\"\\n\"", Mapper.json("\n"));
|
||||||
|
assertEquals("\"\\\"\"", Mapper.json("\""));
|
||||||
|
assertEquals("\"\\\\\"", Mapper.json("\\"));
|
||||||
|
assertEquals("\"\\f\"", Mapper.json("\f"));
|
||||||
|
assertEquals("\"\\/\"", Mapper.json("/"));
|
||||||
|
assertEquals("\"'\"", Mapper.json("'"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void unicodeTests() {
|
||||||
|
assertEquals("\"angry=😠\"", Mapper.json("angry=😠"));
|
||||||
|
assertEquals("\"\\u20A7dings\"", Mapper.json("₧dings"));
|
||||||
|
assertEquals("\"狗=dog\"", Mapper.json("狗=dog")); // dog
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
10
src/test/java/nl/sanderhautvast/json/ser/nested/Bean1.java
Normal file
10
src/test/java/nl/sanderhautvast/json/ser/nested/Bean1.java
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
package nl.sanderhautvast.json.ser.nested;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Bean1 {
|
||||||
|
private String data1;
|
||||||
|
private Bean2 bean2;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package nl.sanderhautvast.json.ser.nested;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Bean2 {
|
||||||
|
private String data2;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
//package nl.jssl.jsontoy.serialize.nested;
|
||||||
|
//
|
||||||
|
//import static junit.framework.Assert.assertEquals;
|
||||||
|
//import nl.jssl.jsontoy.serialize.Serializer;
|
||||||
|
//
|
||||||
|
//import org.junit.Test;
|
||||||
|
//
|
||||||
|
//public class NestedBeanTest {
|
||||||
|
// @Test
|
||||||
|
// public void testBeans() {
|
||||||
|
// Bean1 object1 = new Bean1();
|
||||||
|
// object1.setData1("value1");
|
||||||
|
// Bean2 object2 = new Bean2();
|
||||||
|
// object2.setData2("value2");
|
||||||
|
// object1.setBean2(object2);
|
||||||
|
// assertEquals("{\"data1\": \"value1\",\"bean2\": {\"data2\": \"value2\"}}", Serializer.toJSONString(object1));
|
||||||
|
// assertEquals("{\"data1\": \"value1\",\"bean2\": {\"data2\": \"value2\"}}", Serializer.toJSONString(object1));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void testNullValueForBean() {
|
||||||
|
// Bean1 object1 = new Bean1();
|
||||||
|
// object1.setData1("value1");
|
||||||
|
// assertEquals("{\"data1\": \"value1\",\"bean2\": null}", Serializer.toJSONString(object1));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void testBeanChildren() {
|
||||||
|
// Bean1 object1 = new Bean1();
|
||||||
|
// object1.setData1("value1");
|
||||||
|
// Bean2Child object3 = new Bean2Child();
|
||||||
|
// object3.setData2("value2");
|
||||||
|
// object3.setData3("value3");
|
||||||
|
// object1.setBean2(object3);
|
||||||
|
// assertEquals("{\"data1\": \"value1\",\"bean2\": {\"data3\": \"value3\",\"data2\": \"value2\"}}", Serializer.toJSONString(object1));
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
@ -1,22 +1,21 @@
|
||||||
package nl.jssl.jsontoy.serialize.performance;
|
package nl.sanderhautvast.json.ser.performance;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import nl.jssl.jsontoy.serialize.Serializer;
|
|
||||||
import nl.jssl.jsontoy.serialize.nested.Bean1;
|
|
||||||
import nl.jssl.jsontoy.serialize.nested.Bean2;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import nl.sanderhautvast.json.ser.Mapper;
|
||||||
|
import nl.sanderhautvast.json.ser.nested.Bean1;
|
||||||
|
import nl.sanderhautvast.json.ser.nested.Bean2;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* => about 10% faster than jackson
|
||||||
|
*/
|
||||||
public class JacksonComparisonTest {
|
public class JacksonComparisonTest {
|
||||||
private static final int ITERATIONS = 20;
|
private static final int ITERATIONS = 20;
|
||||||
private static final int INNERLOOP_COUNT = 100000;
|
private static final int INNERLOOP_COUNT = 100000;
|
||||||
List<String> trashbin = new ArrayList<>();
|
private final List<String> trashbin = new ArrayList<>();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPerformance() throws JsonProcessingException {
|
public void testPerformance() throws JsonProcessingException {
|
||||||
|
|
@ -52,7 +51,7 @@ public class JacksonComparisonTest {
|
||||||
bean1.setData1(UUID.randomUUID().toString());
|
bean1.setData1(UUID.randomUUID().toString());
|
||||||
bean1.setBean2(bean2);
|
bean1.setBean2(bean2);
|
||||||
bean2.setData2(UUID.randomUUID().toString());
|
bean2.setData2(UUID.randomUUID().toString());
|
||||||
jsonString = Serializer.toJSONString(bean1);
|
jsonString = Mapper.json(bean1);
|
||||||
trashbin.add(jsonString);
|
trashbin.add(jsonString);
|
||||||
}
|
}
|
||||||
System.out.printf("% 7d%n",System.currentTimeMillis() - tt0);
|
System.out.printf("% 7d%n",System.currentTimeMillis() - tt0);
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package nl.sanderhautvast.json.ser.primitives;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import nl.sanderhautvast.json.ser.Mapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class BooleanPropertyTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPrimitive() {
|
||||||
|
assertEquals("true", Mapper.json(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWrapper() {
|
||||||
|
assertEquals("true", Mapper.json(Boolean.TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testProperty() {
|
||||||
|
Bean object = new Bean();
|
||||||
|
object.setData(true);
|
||||||
|
assertEquals("{\"data\":true}", Mapper.json(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Bean {
|
||||||
|
boolean data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package nl.sanderhautvast.json.ser.primitives;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import nl.sanderhautvast.json.ser.Mapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class BytePropertyTest {
|
||||||
|
@Test
|
||||||
|
public void testPrimitive() {
|
||||||
|
assertEquals("-55", Mapper.json((byte) -55));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWrapper() {
|
||||||
|
assertEquals("55", Mapper.json(Byte.valueOf((byte) 55)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testProperty() {
|
||||||
|
Bean object = new Bean();
|
||||||
|
object.setData((byte) 1);
|
||||||
|
assertEquals("{\"data\":1}", Mapper.json(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Bean {
|
||||||
|
private byte data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package nl.sanderhautvast.json.ser.primitives;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import nl.sanderhautvast.json.ser.Mapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class CharPropertyTest {
|
||||||
|
@Test
|
||||||
|
public void testPrimitive() {
|
||||||
|
assertEquals("\"d\"", Mapper.json('d'));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWrapper() {
|
||||||
|
assertEquals("\"s\"", Mapper.json(Character.valueOf('s')));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testProperty() {
|
||||||
|
Bean object = new Bean();
|
||||||
|
object.setData('a');
|
||||||
|
assertEquals("{\"data\":\"a\"}", Mapper.json(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Bean {
|
||||||
|
private char data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package nl.sanderhautvast.json.ser.primitives;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import nl.sanderhautvast.json.ser.Mapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class DoublePropertyTest {
|
||||||
|
@Test
|
||||||
|
public void testPrimitive() {
|
||||||
|
assertEquals("-55.6", Mapper.json(-55.6D));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWrapper() {
|
||||||
|
assertEquals("55.0", Mapper.json(Double.valueOf("55.0")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testProperty() {
|
||||||
|
Bean object = new Bean();
|
||||||
|
object.setData(326.2D);
|
||||||
|
assertEquals("{\"data\":326.2}", Mapper.json(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Bean {
|
||||||
|
private double data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package nl.sanderhautvast.json.ser.primitives;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import nl.sanderhautvast.json.ser.Mapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class FloatPropertyTest {
|
||||||
|
@Test
|
||||||
|
public void testPrimitive() {
|
||||||
|
assertEquals("-55.6", Mapper.json(-55.6F));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWrapper() {
|
||||||
|
assertEquals("55.0", Mapper.json(Float.valueOf("55.0")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testProperty() {
|
||||||
|
Bean object = new Bean();
|
||||||
|
object.setData(1F);
|
||||||
|
assertEquals("{\"data\":1.0}", Mapper.json(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Bean {
|
||||||
|
private float data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package nl.sanderhautvast.json.ser.primitives;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import nl.sanderhautvast.json.ser.Mapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class IntPropertyTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPrimitive() {
|
||||||
|
assertEquals("-55", Mapper.json(-55));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWrapper() {
|
||||||
|
assertEquals("55", Mapper.json(Integer.valueOf("55")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPropertyValue() {
|
||||||
|
Bean object = new Bean();
|
||||||
|
object.setData(1);
|
||||||
|
assertEquals("{\"data\":1}", Mapper.json(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Bean {
|
||||||
|
int data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package nl.sanderhautvast.json.ser.primitives;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import nl.sanderhautvast.json.ser.Mapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
|
public class LongPropertyTest {
|
||||||
|
@Test
|
||||||
|
public void testPrimitive() {
|
||||||
|
assertEquals("-55", Mapper.json(-55L));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWrapper() {
|
||||||
|
assertEquals("55", Mapper.json(Long.valueOf("55")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testProperty() {
|
||||||
|
Bean object = new Bean();
|
||||||
|
object.setData(1L);
|
||||||
|
assertEquals("{\"data\":1}", Mapper.json(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Bean {
|
||||||
|
private long data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package nl.sanderhautvast.json.ser.primitives;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import nl.sanderhautvast.json.ser.Mapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class NullPropertyTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testProperty() {
|
||||||
|
Bean object = new Bean();
|
||||||
|
assertEquals("{\"data\":null}", Mapper.json(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Bean {
|
||||||
|
private String data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package nl.sanderhautvast.json.ser.primitives;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import nl.sanderhautvast.json.ser.Mapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class ShortPropertyTest {
|
||||||
|
@Test
|
||||||
|
public void testPrimitive() {
|
||||||
|
assertEquals("-55", Mapper.json((short) -55));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWrapper() {
|
||||||
|
assertEquals("5", Mapper.json(Short.valueOf("5")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testProperty() {
|
||||||
|
Bean object = new Bean();
|
||||||
|
object.setData((short) 3);
|
||||||
|
assertEquals("{\"data\":3}", Mapper.json(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Bean {
|
||||||
|
private short data;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue