commit a947f14f35bbec74b1581377c6a6981f891d95b7 Author: Sander Hautvast Date: Tue Jan 5 20:16:06 2016 +0100 initial commit diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..e9f40da --- /dev/null +++ b/.classpath @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/.gradle/2.3/taskArtifacts/cache.properties b/.gradle/2.3/taskArtifacts/cache.properties new file mode 100644 index 0000000..45fe99b --- /dev/null +++ b/.gradle/2.3/taskArtifacts/cache.properties @@ -0,0 +1 @@ +#Wed Aug 12 16:00:24 CEST 2015 diff --git a/.gradle/2.3/taskArtifacts/cache.properties.lock b/.gradle/2.3/taskArtifacts/cache.properties.lock new file mode 100644 index 0000000..d47aea3 Binary files /dev/null and b/.gradle/2.3/taskArtifacts/cache.properties.lock differ diff --git a/.gradle/2.3/taskArtifacts/fileHashes.bin b/.gradle/2.3/taskArtifacts/fileHashes.bin new file mode 100644 index 0000000..97cbc2e Binary files /dev/null and b/.gradle/2.3/taskArtifacts/fileHashes.bin differ diff --git a/.gradle/2.3/taskArtifacts/fileSnapshots.bin b/.gradle/2.3/taskArtifacts/fileSnapshots.bin new file mode 100644 index 0000000..7f56db4 Binary files /dev/null and b/.gradle/2.3/taskArtifacts/fileSnapshots.bin differ diff --git a/.gradle/2.3/taskArtifacts/outputFileStates.bin b/.gradle/2.3/taskArtifacts/outputFileStates.bin new file mode 100644 index 0000000..bde8340 Binary files /dev/null and b/.gradle/2.3/taskArtifacts/outputFileStates.bin differ diff --git a/.gradle/2.3/taskArtifacts/taskArtifacts.bin b/.gradle/2.3/taskArtifacts/taskArtifacts.bin new file mode 100644 index 0000000..2be79df Binary files /dev/null and b/.gradle/2.3/taskArtifacts/taskArtifacts.bin differ diff --git a/.project b/.project new file mode 100644 index 0000000..6dc5fad --- /dev/null +++ b/.project @@ -0,0 +1,16 @@ + + + SyntheticSerializer + + + + org.eclipse.jdt.core.javanature + + + + org.eclipse.jdt.core.javabuilder + + + + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..ad76736 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,13 @@ +# +#Tue Aug 18 20:35:37 CEST 2015 +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..8002c1e --- /dev/null +++ b/build.gradle @@ -0,0 +1,22 @@ + +apply plugin: 'java' +apply plugin: 'eclipse' + +repositories{ + mavenLocal() + mavenCentral() +} + +dependencies{ + compile 'commons-io:commons-io:1.4' + compile 'org.javassist:javassist:3.20.0-GA' + + compile 'ch.qos.logback:logback-core:0.9.29' + compile 'org.slf4j:slf4j-api:1.6.1' + compile 'ch.qos.logback:logback-classic:0.9.29' + + testCompile 'junit:junit:4.8.2' + testCompile 'org.mockito:mockito-core:1.9.5' + testCompile 'com.fasterxml.jackson.core:jackson-databind:2.6.1' + +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..085a1cd Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..bca1314 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Aug 12 16:00:24 CEST 2015 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.3-bin.zip diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..91a7e26 --- /dev/null +++ b/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/main/java/nl/jssl/sd/Deserializer.java b/src/main/java/nl/jssl/sd/Deserializer.java new file mode 100644 index 0000000..85c0d62 --- /dev/null +++ b/src/main/java/nl/jssl/sd/Deserializer.java @@ -0,0 +1,12 @@ +package nl.jssl.sd; + +public class Deserializer { + + public static Object deserialize(String json) { + if (json.equals("{}")) { + return null; + } else + return 1; + } + +} diff --git a/src/main/java/nl/jssl/ss/JSONSerializer.java b/src/main/java/nl/jssl/ss/JSONSerializer.java new file mode 100644 index 0000000..b168f3a --- /dev/null +++ b/src/main/java/nl/jssl/ss/JSONSerializer.java @@ -0,0 +1,21 @@ +package nl.jssl.ss; + +import java.util.Formatter; + +public abstract class JSONSerializer { + 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.toString(); + } else if (object instanceof CharSequence || object instanceof Character) { + return "\"" + object.toString() + "\""; + } else { + return handle(object); + } + } +} diff --git a/src/main/java/nl/jssl/ss/Serializer.java b/src/main/java/nl/jssl/ss/Serializer.java new file mode 100644 index 0000000..b983e76 --- /dev/null +++ b/src/main/java/nl/jssl/ss/Serializer.java @@ -0,0 +1,45 @@ +package nl.jssl.ss; + +public class Serializer { + private static SerializerFactory 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 "\"" + Character.toString(c) + "\""; + } + + @SuppressWarnings("unchecked") + public static String toJSONString(T o) { + if (o == null) { + return "null"; + } + return instance.createSerializer((Class) o.getClass()).toJSONString(o); + } + + public static void setInstance(SerializerFactory instance) { + Serializer.instance = instance; + } +} diff --git a/src/main/java/nl/jssl/ss/SerializerCreationException.java b/src/main/java/nl/jssl/ss/SerializerCreationException.java new file mode 100644 index 0000000..955adaf --- /dev/null +++ b/src/main/java/nl/jssl/ss/SerializerCreationException.java @@ -0,0 +1,10 @@ +package nl.jssl.ss; + +@SuppressWarnings("serial") +public class SerializerCreationException extends RuntimeException { + + public SerializerCreationException(Throwable t) { + super(t); + } + +} diff --git a/src/main/java/nl/jssl/ss/SerializerFactory.java b/src/main/java/nl/jssl/ss/SerializerFactory.java new file mode 100644 index 0000000..49af73c --- /dev/null +++ b/src/main/java/nl/jssl/ss/SerializerFactory.java @@ -0,0 +1,5 @@ +package nl.jssl.ss; + +public interface SerializerFactory { + public JSONSerializer createSerializer(Class beanjavaClass); +} diff --git a/src/main/java/nl/jssl/ss/SynthSerializerFactory.java b/src/main/java/nl/jssl/ss/SynthSerializerFactory.java new file mode 100644 index 0000000..daba6ba --- /dev/null +++ b/src/main/java/nl/jssl/ss/SynthSerializerFactory.java @@ -0,0 +1,377 @@ +package nl.jssl.ss; + +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; + +public class SynthSerializerFactory implements SerializerFactory { + 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 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> serializers = new HashMap<>(); + private static final String ROOT_PACKAGE = "serializer."; + + private final ClassPool pool = ClassPool.getDefault(); + private CtClass serializerBase; + private final Map primitiveWrappers = new HashMap(); + + public SynthSerializerFactory() { + init(); + } + + void init() { + try { + serializerBase = pool.get(JSONSerializer.class.getName()); + + primitiveWrappers.put("int", pool.get(INTEGER)); + primitiveWrappers.put("short", pool.get(SHORT)); + primitiveWrappers.put("byte", pool.get(BYTE)); + primitiveWrappers.put("long", pool.get(LONG)); + primitiveWrappers.put("float", pool.get(FLOAT)); + primitiveWrappers.put("double", pool.get(DOUBLE)); + primitiveWrappers.put("boolean", pool.get(BOOLEAN)); + primitiveWrappers.put("char", pool.get(CHARACTER)); + } catch (NotFoundException e) { + throw new SerializerCreationException(e); + } + } + + public JSONSerializer createSerializer(Class beanjavaClass) { + try { + CtClass beanClass = pool.get(beanjavaClass.getName()); + + JSONSerializer jsonSerializer = createSerializer(beanClass); + + return jsonSerializer; + } catch (NotFoundException e) { + throw new SerializerCreationException(e); + } + } + + @SuppressWarnings("unchecked") + private JSONSerializer createSerializer(CtClass beanClass) { + if (serializers.containsKey(createSerializerName(beanClass))) { + return (JSONSerializer) serializers.get(createSerializerName(beanClass)); + } + try { + return tryCreateSerializer(beanClass); + } catch (NotFoundException | CannotCompileException | InstantiationException | IllegalAccessException e) { + throw new SerializerCreationException(e); + } + } + + private JSONSerializer tryCreateSerializer(CtClass beanClass) throws NotFoundException, CannotCompileException, InstantiationException, + IllegalAccessException { + CtClass serializerClass = pool.makeClass(createSerializerName(beanClass), serializerBase); + + addToJsonStringMethod(beanClass, serializerClass); + + JSONSerializer jsonSerializer = createSerializerInstance(serializerClass); + + serializers.put(createSerializerName(beanClass), 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(beanClass); + } else if (isCollection(beanClass)) { + source += "\tObject[] array=((java.util.Collection)object).toArray();\n"; + source += handleArray(beanClass); + } else if (isMap(beanClass)) { + source += handleMap(beanClass); + } else if (!isPrimitiveOrWrapperOrString(beanClass)) { + List getters = getGetters(beanClass); + if (shouldAddGetterCallers(getters)) { + source = addGetterCallers(beanClass, source, getters); + } + } else { + source += "\treturn \"\";}"; + } + System.out.println(source); + 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(CtClass beanClass) { + String source = "\tStringBuilder result=new StringBuilder(\"[\");\n"; + source += "\tfor (int i=0; i getters) throws NotFoundException { + 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 JSONSerializer createSerializerInstance(CtClass serializerClass) throws InstantiationException, IllegalAccessException, + CannotCompileException { + return (JSONSerializer) serializerClass.toClass().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 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 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) throws NotFoundException { + 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) throws NotFoundException { + String source = ""; + CtClass returnType = getter.getReturnType(); + + /* primitives are wrapped so the produced methods adhere to the JSONSerializer interface */ + source = createSubSerializerForReturnTypeAndAddInvocationToSource(classToSerialize, getter, source, returnType); + + return source; + } + + private String createSubSerializerForReturnTypeAndAddInvocationToSource(CtClass classToSerialize, CtMethod getter, String source, CtClass returnType) { + /* NB there does not seem to be auto(un))boxing nor generic types (or other jdk1.5 stuff) in javassist compileable code */ + + 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 getGetters(CtClass beanClass) { + List methods = new ArrayList(); + List 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 getAllFields(CtClass beanClass) { + try { + List allfields = new ArrayList<>(); + for (CtField field : beanClass.getDeclaredFields()) { + allfields.add(field); + } + if (beanClass.getSuperclass() != null) { + return getAllFields(beanClass.getSuperclass(), allfields); + } + return allfields; + } catch (NotFoundException e) { + throw new SerializerCreationException(e); + } + + } + + private List getAllFields(CtClass beanClass, List allfields) { + for (CtField field : beanClass.getDeclaredFields()) { + allfields.add(field); + } + + return allfields; + } + + /* + * is getter list is not empty then callers should be added + */ + boolean shouldAddGetterCallers(List 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()); + } +} diff --git a/src/test/java/nl/jssl/sd/EmptyTest.java b/src/test/java/nl/jssl/sd/EmptyTest.java new file mode 100644 index 0000000..2da0762 --- /dev/null +++ b/src/test/java/nl/jssl/sd/EmptyTest.java @@ -0,0 +1,12 @@ +package nl.jssl.sd; + +import static junit.framework.Assert.assertEquals; + +import org.junit.Test; + +public class EmptyTest { + @Test + public void null_shouldReturnEmpty() { + assertEquals(null, Deserializer.deserialize("{}")); + } +} diff --git a/src/test/java/nl/jssl/sd/IntegerTest.java b/src/test/java/nl/jssl/sd/IntegerTest.java new file mode 100644 index 0000000..42fe1f7 --- /dev/null +++ b/src/test/java/nl/jssl/sd/IntegerTest.java @@ -0,0 +1,13 @@ +package nl.jssl.sd; + +import static junit.framework.Assert.assertEquals; + +import org.junit.Test; + +public class IntegerTest { + + @Test + public void testPrimitive() { + assertEquals(1, Deserializer.deserialize("1")); + } +} diff --git a/src/test/java/nl/jssl/sd/StringTest.java b/src/test/java/nl/jssl/sd/StringTest.java new file mode 100644 index 0000000..3646aa6 --- /dev/null +++ b/src/test/java/nl/jssl/sd/StringTest.java @@ -0,0 +1,12 @@ +package nl.jssl.sd; + +import static junit.framework.Assert.assertEquals; + +import org.junit.Test; + +public class StringTest { + @Test + public void shouldReturnStringvalue() { + assertEquals("test", Deserializer.deserialize("\"test\"")); + } +} diff --git a/src/test/java/nl/jssl/ss/StringPropertyTest.java b/src/test/java/nl/jssl/ss/StringPropertyTest.java new file mode 100644 index 0000000..d484ee2 --- /dev/null +++ b/src/test/java/nl/jssl/ss/StringPropertyTest.java @@ -0,0 +1,51 @@ +package nl.jssl.ss; + +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; + } + + } +} diff --git a/src/test/java/nl/jssl/ss/collections/ArrayTest.java b/src/test/java/nl/jssl/ss/collections/ArrayTest.java new file mode 100644 index 0000000..3b311ed --- /dev/null +++ b/src/test/java/nl/jssl/ss/collections/ArrayTest.java @@ -0,0 +1,34 @@ +package nl.jssl.ss.collections; + +import static junit.framework.Assert.assertEquals; +import nl.jssl.ss.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; + } + + } + +} diff --git a/src/test/java/nl/jssl/ss/collections/ListTest.java b/src/test/java/nl/jssl/ss/collections/ListTest.java new file mode 100644 index 0000000..7e03552 --- /dev/null +++ b/src/test/java/nl/jssl/ss/collections/ListTest.java @@ -0,0 +1,41 @@ +package nl.jssl.ss.collections; + +import static junit.framework.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; + +import nl.jssl.ss.Serializer; + +import org.junit.Test; + +public class ListTest { + @Test + public void testValue() { + List 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; + } + + } + +} diff --git a/src/test/java/nl/jssl/ss/collections/MapTest.java b/src/test/java/nl/jssl/ss/collections/MapTest.java new file mode 100644 index 0000000..be4529b --- /dev/null +++ b/src/test/java/nl/jssl/ss/collections/MapTest.java @@ -0,0 +1,59 @@ +package nl.jssl.ss.collections; + +import static junit.framework.Assert.assertTrue; + +import java.util.HashMap; +import java.util.Map; + +import nl.jssl.ss.SerializerCreationException; +import nl.jssl.ss.Serializer; +import nl.jssl.ss.SynthSerializerFactory; + +import org.junit.Test; + +public class MapTest { + @Test + public void testValue() { + Map 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 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)); + } + + @Test + public void pumpUpTheVolume() { + Serializer.setInstance(new SynthSerializerFactory()); + try { + throw new SerializerCreationException(new Exception()); + } catch (Exception e) { + } + } + + public class Bean { + + private Map map; + + public Map getMap() { + return map; + } + + public void setMap(Map map) { + this.map = map; + } + + } + +} diff --git a/src/test/java/nl/jssl/ss/collections/SetTest.java b/src/test/java/nl/jssl/ss/collections/SetTest.java new file mode 100644 index 0000000..b077c97 --- /dev/null +++ b/src/test/java/nl/jssl/ss/collections/SetTest.java @@ -0,0 +1,43 @@ +package nl.jssl.ss.collections; + +import static junit.framework.Assert.assertTrue; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import nl.jssl.ss.Serializer; + +import org.junit.Test; + +public class SetTest { + @Test + public void testValue() { + Set list = new HashSet(); + 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(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 set; + + public Set getSet() { + return set; + } + + public void setSet(Set set) { + this.set = set; + } + } + +} diff --git a/src/test/java/nl/jssl/ss/nested/Bean1.java b/src/test/java/nl/jssl/ss/nested/Bean1.java new file mode 100644 index 0000000..68bdd81 --- /dev/null +++ b/src/test/java/nl/jssl/ss/nested/Bean1.java @@ -0,0 +1,48 @@ +package nl.jssl.ss.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; + } + +} diff --git a/src/test/java/nl/jssl/ss/nested/Bean2.java b/src/test/java/nl/jssl/ss/nested/Bean2.java new file mode 100644 index 0000000..53594d6 --- /dev/null +++ b/src/test/java/nl/jssl/ss/nested/Bean2.java @@ -0,0 +1,13 @@ +package nl.jssl.ss.nested; + +public class Bean2 { + private String data2; + + public String getData2() { + return data2; + } + + public void setData2(String data2) { + this.data2 = data2; + } +} diff --git a/src/test/java/nl/jssl/ss/nested/Bean2Child.java b/src/test/java/nl/jssl/ss/nested/Bean2Child.java new file mode 100644 index 0000000..8071d75 --- /dev/null +++ b/src/test/java/nl/jssl/ss/nested/Bean2Child.java @@ -0,0 +1,14 @@ +package nl.jssl.ss.nested; + +public class Bean2Child extends Bean2 { + private String data3; + + public String getData3() { + return data3; + } + + public void setData3(String data3) { + this.data3 = data3; + } + +} diff --git a/src/test/java/nl/jssl/ss/nested/NestedBeanTest.java b/src/test/java/nl/jssl/ss/nested/NestedBeanTest.java new file mode 100644 index 0000000..780ab39 --- /dev/null +++ b/src/test/java/nl/jssl/ss/nested/NestedBeanTest.java @@ -0,0 +1,37 @@ +package nl.jssl.ss.nested; + +import static junit.framework.Assert.assertEquals; +import nl.jssl.ss.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)); + } +} diff --git a/src/test/java/nl/jssl/ss/performance/Jackson.java b/src/test/java/nl/jssl/ss/performance/Jackson.java new file mode 100644 index 0000000..85f3cde --- /dev/null +++ b/src/test/java/nl/jssl/ss/performance/Jackson.java @@ -0,0 +1,63 @@ +package nl.jssl.ss.performance; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import nl.jssl.ss.Serializer; +import nl.jssl.ss.nested.Bean1; +import nl.jssl.ss.nested.Bean2; + +import org.junit.Test; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class Jackson { + List trashbin = new ArrayList(); + + @Test + public void jackson() throws JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper(); + Bean1 bean1 = new Bean1(); + Bean2 bean2 = new Bean2(); + bean1.setData1(UUID.randomUUID().toString()); + bean1.setBean2(bean2); + bean2.setData2(UUID.randomUUID().toString()); + String valueAsString = objectMapper.writeValueAsString(bean1); + String jsonString = Serializer.toJSONString(bean1); + + for (int c = 0; c < 20; c++) { + trashbin.clear(); + System.gc(); + long t0 = System.currentTimeMillis(); + for (int i = 0; i < 100000; i++) { + bean1 = new Bean1(); + bean2 = new Bean2(); + bean1.setData1(UUID.randomUUID().toString()); + bean1.setBean2(bean2); + bean2.setData2(UUID.randomUUID().toString()); + valueAsString = objectMapper.writeValueAsString(bean1); + // System.out.println(valueAsString); + trashbin.add(valueAsString); + } + System.out.print(System.currentTimeMillis() - t0); + System.out.print(","); + trashbin.clear(); + System.gc(); + long tt0 = System.currentTimeMillis(); + for (int i = 0; i < 100000; i++) { + bean1 = new Bean1(); + bean2 = new Bean2(); + bean1.setData1(UUID.randomUUID().toString()); + bean1.setBean2(bean2); + bean2.setData2(UUID.randomUUID().toString()); + jsonString = Serializer.toJSONString(bean1); + // System.out.println(jsonString); + trashbin.add(jsonString); + } + System.out.println(System.currentTimeMillis() - tt0); + } + + } +} diff --git a/src/test/java/nl/jssl/ss/performance/SmartJson.java b/src/test/java/nl/jssl/ss/performance/SmartJson.java new file mode 100644 index 0000000..9550890 --- /dev/null +++ b/src/test/java/nl/jssl/ss/performance/SmartJson.java @@ -0,0 +1,54 @@ +package nl.jssl.ss.performance; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import net.minidev.json.JSONValue; +import nl.jssl.ss.Serializer; +import nl.jssl.ss.nested.Bean1; +import nl.jssl.ss.nested.Bean2; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class SmartJson { + public void jackson() throws JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper(); + Bean1 bean1 = new Bean1(); + Bean2 bean2 = new Bean2(); + bean1.setData1(UUID.randomUUID().toString()); + bean1.setBean2(bean2); + bean2.setData2(UUID.randomUUID().toString()); + + Serializer.toJSONString(bean1); + JSONValue.toJSONString(bean1); + for (int c = 0; c < 200; c++) { + System.gc(); + long t0 = System.currentTimeMillis(); + List trashbin = new ArrayList(); + for (int i = 0; i < 10000; i++) { + bean1.setData1(UUID.randomUUID().toString()); + bean1.setBean2(bean2); + bean2.setData2(UUID.randomUUID().toString()); + String valueAsString = JSONValue.toJSONString(bean1); + trashbin.add(valueAsString); + } + System.out.print(System.currentTimeMillis() - t0); + System.out.print(","); + trashbin.clear(); + System.gc(); + long tt0 = System.currentTimeMillis(); + for (int i = 0; i < 10000; i++) { + bean1.setData1(UUID.randomUUID().toString()); + bean1.setBean2(bean2); + bean2.setData2(UUID.randomUUID().toString()); + String jsonString = Serializer.toJSONString(bean1); + // System.out.println(jsonString); + trashbin.add(jsonString); + } + System.out.println(System.currentTimeMillis() - tt0); + } + + } +} diff --git a/src/test/java/nl/jssl/ss/primitives/BooleanPropertyTest.java b/src/test/java/nl/jssl/ss/primitives/BooleanPropertyTest.java new file mode 100644 index 0000000..03921b7 --- /dev/null +++ b/src/test/java/nl/jssl/ss/primitives/BooleanPropertyTest.java @@ -0,0 +1,39 @@ +package nl.jssl.ss.primitives; + +import static junit.framework.Assert.assertEquals; +import nl.jssl.ss.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; + } + + } +} diff --git a/src/test/java/nl/jssl/ss/primitives/BytePropertyTest.java b/src/test/java/nl/jssl/ss/primitives/BytePropertyTest.java new file mode 100644 index 0000000..adcf854 --- /dev/null +++ b/src/test/java/nl/jssl/ss/primitives/BytePropertyTest.java @@ -0,0 +1,38 @@ +package nl.jssl.ss.primitives; + +import static junit.framework.Assert.assertEquals; +import nl.jssl.ss.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; + } + + } +} diff --git a/src/test/java/nl/jssl/ss/primitives/CharPropertyTest.java b/src/test/java/nl/jssl/ss/primitives/CharPropertyTest.java new file mode 100644 index 0000000..6598f82 --- /dev/null +++ b/src/test/java/nl/jssl/ss/primitives/CharPropertyTest.java @@ -0,0 +1,38 @@ +package nl.jssl.ss.primitives; + +import static junit.framework.Assert.assertEquals; +import nl.jssl.ss.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; + } + + } +} diff --git a/src/test/java/nl/jssl/ss/primitives/DoublePropertyTest.java b/src/test/java/nl/jssl/ss/primitives/DoublePropertyTest.java new file mode 100644 index 0000000..629eb6d --- /dev/null +++ b/src/test/java/nl/jssl/ss/primitives/DoublePropertyTest.java @@ -0,0 +1,38 @@ +package nl.jssl.ss.primitives; + +import static junit.framework.Assert.assertEquals; +import nl.jssl.ss.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; + } + + } +} diff --git a/src/test/java/nl/jssl/ss/primitives/FloatPropertyTest.java b/src/test/java/nl/jssl/ss/primitives/FloatPropertyTest.java new file mode 100644 index 0000000..e870589 --- /dev/null +++ b/src/test/java/nl/jssl/ss/primitives/FloatPropertyTest.java @@ -0,0 +1,38 @@ +package nl.jssl.ss.primitives; + +import static junit.framework.Assert.assertEquals; +import nl.jssl.ss.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; + } + + } +} diff --git a/src/test/java/nl/jssl/ss/primitives/IntPropertyTest.java b/src/test/java/nl/jssl/ss/primitives/IntPropertyTest.java new file mode 100644 index 0000000..c0485c0 --- /dev/null +++ b/src/test/java/nl/jssl/ss/primitives/IntPropertyTest.java @@ -0,0 +1,39 @@ +package nl.jssl.ss.primitives; + +import static junit.framework.Assert.assertEquals; +import nl.jssl.ss.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; + } + + } +} diff --git a/src/test/java/nl/jssl/ss/primitives/LongPropertyTest.java b/src/test/java/nl/jssl/ss/primitives/LongPropertyTest.java new file mode 100644 index 0000000..3f1ddc1 --- /dev/null +++ b/src/test/java/nl/jssl/ss/primitives/LongPropertyTest.java @@ -0,0 +1,38 @@ +package nl.jssl.ss.primitives; + +import static junit.framework.Assert.assertEquals; +import nl.jssl.ss.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; + } + + } +} diff --git a/src/test/java/nl/jssl/ss/primitives/NullPropertyTest.java b/src/test/java/nl/jssl/ss/primitives/NullPropertyTest.java new file mode 100644 index 0000000..f5a04ad --- /dev/null +++ b/src/test/java/nl/jssl/ss/primitives/NullPropertyTest.java @@ -0,0 +1,33 @@ +package nl.jssl.ss.primitives; + +import static junit.framework.Assert.assertEquals; +import nl.jssl.ss.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; + } + + } +} diff --git a/src/test/java/nl/jssl/ss/primitives/ShortPropertyTest.java b/src/test/java/nl/jssl/ss/primitives/ShortPropertyTest.java new file mode 100644 index 0000000..f87d022 --- /dev/null +++ b/src/test/java/nl/jssl/ss/primitives/ShortPropertyTest.java @@ -0,0 +1,38 @@ +package nl.jssl.ss.primitives; + +import static junit.framework.Assert.assertEquals; +import nl.jssl.ss.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; + } + + } +}