diff --git a/src/main/java/com/fathzer/util/TinyJackson.java b/src/main/java/com/fathzer/util/TinyJackson.java
new file mode 100644
index 0000000..dd615f7
--- /dev/null
+++ b/src/main/java/com/fathzer/util/TinyJackson.java
@@ -0,0 +1,165 @@
+package com.fathzer.util;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/** A simplified version of Jackson Databind that only works on beans (default constructor + set and get accessors).
+ *
Jackson is cool, very easy to use, but fat, very fat (more than 4MB).
+ *
Json from json.org is light, but has nothing to convert json to an object (except JSONObject).
+ *
This class, adds bean parsing to the org.json library. Additionally, it provides you with method to convert beans and arrays
+ * to JSONObject and JSONArray (json.org ones have strange naming convention: for instance an object's attribute named 'aChar' is transformed
+ * in a JSON attribute named 'AChar'.
+ *
Current limitations:
+ *
All attributes of bean should be present in JSON
+ * The following types are not supported as bean's attributes: byte, short
+ *
+ */
+public class TinyJackson {
+
+ private TinyJackson() {
+ super();
+ }
+
+ public static T toObject(JSONObject json, Class tClass) {
+ try {
+ final T result = tClass.getConstructor().newInstance();
+ final Field[] fields = tClass.getDeclaredFields();
+ for (Field field : fields) {
+ final Class> attrClass = field.getType();
+ final String name = field.getName();
+ final Method method = tClass.getMethod(getSetMethodName(name), attrClass);
+ final Object value = getValue(json, attrClass, name);
+ method.invoke(result, value);
+ }
+ return result;
+ } catch (ReflectiveOperationException | IllegalArgumentException e) {
+ throw new JSONException(e);
+ }
+ }
+
+ private static Object getValue(JSONObject json, Class> attrClass, String name) {
+ if (attrClass.isArray()) {
+ return toArray(json.getJSONArray(name), attrClass.getComponentType());
+ } else if (attrClass.equals(String.class)) {
+ return json.getString(name);
+ } else if (attrClass.equals(int.class)) {
+ return json.getInt(name);
+ } else if (attrClass.equals(long.class)) {
+ return json.getLong(name);
+ } else if (attrClass.equals(float.class)) {
+ return json.getFloat(name);
+ } else if (attrClass.equals(double.class)) {
+ return json.getDouble(name);
+ } else if (attrClass.equals(boolean.class)) {
+ return json.getBoolean(name);
+ } else if (attrClass.equals(char.class)) {
+ final Object obj = json.get(name);
+ if (obj instanceof Character c) {
+ return c.charValue();
+ } else if (obj instanceof String string) {
+ if (string.length()!=1) {
+ throw new IllegalArgumentException(name+ "attribute length != 1");
+ }
+ return string.charAt(0);
+ } else {
+ throw new IllegalArgumentException("Unexpected type "+obj.getClass()+" for char attribute "+name);
+ }
+ } else {
+ // java object
+ return toObject(json.getJSONObject(name), attrClass);
+ }
+ }
+
+ private static Object getValue(JSONArray json, Class> attrClass, int index) {
+ if (attrClass.isArray()) {
+ //TODO To be tested
+ return toArray(json.getJSONArray(index), attrClass.getComponentType());
+ } else if (attrClass.equals(String.class)) {
+ return json.getString(index);
+ } else if (attrClass.equals(int.class)) {
+ return json.getInt(index);
+ } else if (attrClass.equals(long.class)) {
+ return json.getLong(index);
+ } else if (attrClass.equals(float.class)) {
+ return json.getFloat(index);
+ } else if (attrClass.equals(double.class)) {
+ return json.getDouble(index);
+ } else if (attrClass.equals(boolean.class)) {
+ return json.getBoolean(index);
+ } else if (attrClass.equals(char.class)) {
+ final String string = json.getString(index);
+ if (string.length()!=1) {
+ throw new IllegalArgumentException(index+ "attribute length != 1");
+ }
+ return string.charAt(0);
+ } else {
+ // java object
+ return toObject(json.getJSONObject(index), attrClass);
+ }
+ }
+
+ private static String getSetMethodName(String attrName) {
+ return "set"+attrName.substring(0,1).toUpperCase()+attrName.substring(1);
+ }
+
+ private static String getGetMethodName(Field field) {
+ final String attrName = field.getName();
+ final String prefix = field.getType().equals(boolean.class) ? "is" : "get";
+ return prefix+attrName.substring(0,1).toUpperCase()+attrName.substring(1);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static T[] toArray(JSONArray json, Class toClass) {
+ T[] result = (T[]) Array.newInstance(toClass, json.length());
+ for (int i=0;i tClass = obj.getClass();
+ final Field[] fields = tClass.getDeclaredFields();
+ for (Field field : fields) {
+ final Class> attrClass = field.getType();
+ final String name = field.getName();
+ final Method method = tClass.getMethod(getGetMethodName(field));
+ final Object attr = method.invoke(obj);
+ if (attrClass.equals(String.class) || attrClass.equals(boolean.class) || attrClass.equals(int.class) || attrClass.equals(long.class)
+ || attrClass.equals(float.class) || attrClass.equals(double.class) || attrClass.equals(char.class)) {
+ result.put(name, attr);
+ } else if (attrClass.isArray()) {
+ result.put(name, toJSONArray((Object[])attr));
+ } else {
+ result.put(name, toJSONObject(attr));
+ }
+ }
+ } catch (ReflectiveOperationException | IllegalArgumentException e) {
+ throw new JSONException(e);
+ }
+ return result;
+ }
+
+ public static JSONArray toJSONArray(T[] array) {
+ final JSONArray result = new JSONArray();
+ final Class> elClass = array.getClass().componentType();
+ for (T element : array) {
+ if (elClass.equals(String.class) || elClass.equals(boolean.class) || elClass.equals(int.class) || elClass.equals(long.class)
+ || elClass.equals(float.class) || elClass.equals(double.class) || elClass.equals(char.class)) {
+ result.put(element);
+ } else if (elClass.isArray()) {
+ result.put(toJSONArray((Object[])element));
+ } else {
+ result.put(toJSONObject(element));
+ }
+ }
+ return result;
+ }
+}
diff --git a/src/test/java/com/fathzer/util/TinyJacksonTest.java b/src/test/java/com/fathzer/util/TinyJacksonTest.java
new file mode 100644
index 0000000..a64bd52
--- /dev/null
+++ b/src/test/java/com/fathzer/util/TinyJacksonTest.java
@@ -0,0 +1,50 @@
+package com.fathzer.util;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.json.JSONObject;
+import org.junit.jupiter.api.Test;
+
+import lombok.AllArgsConstructor;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+class TinyJacksonTest {
+ @NoArgsConstructor
+ @Getter
+ @Setter
+ @ToString
+ @AllArgsConstructor
+ @EqualsAndHashCode
+ public static class TestClass {
+ private String str;
+ private int anInt;
+ private long aLong;
+ private char aChar;
+ private String[] strs;
+ private OtherClass other;
+ }
+
+ @AllArgsConstructor
+ @NoArgsConstructor
+ @Setter
+ @Getter
+ @ToString
+ @EqualsAndHashCode
+ public static class OtherClass {
+ private String str;
+ private double value;
+ }
+
+ @Test
+ void test() {
+ final TestClass obj = new TestClass("x",1,2,'a',new String[] {"a","b"}, new OtherClass("c",2.0));
+ final JSONObject json = TinyJackson.toJSONObject(obj);
+ final String jsonString = json.toString();
+ assertEquals(obj, TinyJackson.toObject(json, TestClass.class));
+ assertEquals(obj, TinyJackson.toObject(new JSONObject(jsonString), TestClass.class));
+ }
+}