package com.luticate.utils.dbo; import com.luticate.utils.dbo.JSONContainer.LuAbstractJsonContainer; import com.luticate.utils.dbo.JSONContainer.LuJSONArrayContainer; import com.luticate.utils.dbo.JSONContainer.LuJSONObjectContainer; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import org.joda.time.format.DateTimeFormat; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.util.AbstractMap; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Vector; /** * Created by robin on 11/27/15. */ public abstract class LuDbo { public static String DEFAULT_DATE_FORMAT = "yy-MM-dd"; public static String DEFAULT_TIME_FORMAT = "HH:mm:ss"; public static String DEFAULT_DATE_TIME_FORMAT = DEFAULT_DATE_FORMAT + " " + DEFAULT_TIME_FORMAT; public String getFieldFromJson(String jsonName) { if (!jsonName.startsWith("_")) { return String.format("_%s", jsonName); } return jsonName; } public String getJsonFromField(String fieldName) { if (fieldName.startsWith("_")) { return fieldName.substring(1); } return fieldName; } public Object getObjectFromJson(Class clazz, LuAbstractJsonContainer json, Object key) throws Exception { if (json.isNull(key)) { return null; } if (clazz == Byte.class || clazz == byte.class) { return (byte) json.getInt(key); } if (clazz == Character.class || clazz == char.class) { return json.getString(key).charAt(0); } if (clazz == Short.class || clazz == short.class) { return (short) json.getInt(key); } if (clazz == Integer.class || clazz == int.class) { return json.getInt(key); } if (clazz == Long.class || clazz == long.class) { return json.getLong(key); } if (clazz == Float.class || clazz == float.class) { return (float) json.getDouble(key); } if (clazz == Double.class || clazz == double.class) { return json.getDouble(key); } if (clazz == Boolean.class || clazz == boolean.class) { return json.getBoolean(key); } if (clazz == String.class) { return json.getString(key); } if (clazz == LocalDateTime.class) { return LocalDateTime.parse(json.getString(key), DateTimeFormat.forPattern(DEFAULT_DATE_TIME_FORMAT)); } if (clazz == DateTime.class) { return DateTime.parse(json.getString(key), DateTimeFormat.forPattern(DEFAULT_DATE_TIME_FORMAT)); } if (LuDbo.class.isAssignableFrom(clazz)) { LuDbo dbo = (LuDbo) getInstance(clazz); dbo.fromJson(json.getJSONObject(key)); return dbo; } return null; } public Object getJsonFromObject(Class clazz, Object obj) { if (obj == null) { return null; } if (clazz == char.class || clazz == Character.class) { return obj.toString(); } if (clazz.isPrimitive() || clazz == Byte.class || clazz == Character.class || clazz == Short.class || clazz == Integer.class || clazz == Long.class || clazz == Float.class || clazz == Double.class || clazz == Boolean.class || clazz == String.class) { return obj; } if (clazz == LocalDateTime.class) { return ((LocalDateTime)obj).toString(DateTimeFormat.forPattern(DEFAULT_DATE_TIME_FORMAT)); } if (clazz == DateTime.class) { return ((DateTime)obj).toString(DateTimeFormat.forPattern(DEFAULT_DATE_TIME_FORMAT)); } if (LuDbo.class.isAssignableFrom(clazz)) { return ((LuDbo)obj).toJson(); } if (List.class.isAssignableFrom(clazz)) { List objList = (List) obj; JSONArray list = new JSONArray(); for (Object item : objList) { list.put(getJsonFromObject(getClazz(item), item)); } return list; } if (AbstractMap.class.isAssignableFrom(clazz)) { HashMap objMap = (HashMap) obj; JSONObject map = new JSONObject(); for (Object k : objMap.keySet()) { if (k.getClass() == String.class) { Object item = objMap.get(k); try { map.put((String) k, getJsonFromObject(getClazz(item), item)); } catch (JSONException ignored) { } } } return map; } if (clazz.isArray()) { JSONArray list = new JSONArray(); for (int i = 0; i < Array.getLength(obj); ++i) { Object item = Array.get(obj, i); list.put(getJsonFromObject(item == null ? null : item.getClass(), item)); } return list; } return null; } public Object getInstance(Class clazz) throws Exception { if (clazz == List.class) { return new Vector<>(); } if (clazz == AbstractMap.class) { return new HashMap<>(); } return clazz.newInstance(); } public Class getClazz(Object obj) { return obj == null ? null : obj.getClass(); } public void fromJson(String data) throws Exception { JSONObject json = new JSONObject(data); fromJson(json); } public void fromJson(JSONObject json) throws Exception { for (Field field : getClass().getDeclaredFields()) { if (Modifier.isTransient(field.getModifiers())) { continue; } String key = getJsonFromField(field.getName()); Class clazz = field.getType(); if (json.has(key)) { Object value = null; if (List.class.isAssignableFrom(clazz)) { ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType(); Class type = (Class) parameterizedType.getActualTypeArguments()[0]; List list = (List) getInstance(clazz); JSONArray jsonArray = json.getJSONArray(key); for (int i = 0; i < jsonArray.length(); ++i) { list.add(getObjectFromJson(type, new LuJSONArrayContainer(jsonArray), i)); } value = list; } else if (clazz.isArray()) { Class type = clazz.getComponentType(); JSONArray jsonArray = json.getJSONArray(key); Object array = Array.newInstance(type, jsonArray.length()); for (int i = 0; i < jsonArray.length(); ++i) { Array.set(array, i, getObjectFromJson(type, new LuJSONArrayContainer(jsonArray), i)); } value = array; } else if (AbstractMap.class.isAssignableFrom(clazz)) { ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType(); Class type = (Class) parameterizedType.getActualTypeArguments()[0]; if (type == String.class) { type = (Class) parameterizedType.getActualTypeArguments()[1]; AbstractMap map = (AbstractMap) getInstance(clazz); JSONObject obj = json.getJSONObject(key); Iterator it = obj.keys(); while (it.hasNext()) { String k = it.next(); map.put(k, getObjectFromJson(type, new LuJSONObjectContainer(obj), k)); } value = map; } } else { value = getObjectFromJson(clazz, new LuJSONObjectContainer(json), key); } field.setAccessible(true); field.set(this, value); field.setAccessible(false); } } } public HashMap toArray() { HashMap map = new HashMap<>(); for (Field field : getClass().getDeclaredFields()) { if (Modifier.isTransient(field.getModifiers())) { continue; } String key = getJsonFromField(field.getName()); Class clazz = field.getType(); field.setAccessible(true); Object obj = null; try { obj = field.get(this); } catch (IllegalAccessException ignored) { } field.setAccessible(false); map.put(key, getJsonFromObject(clazz, obj)); } return map; } public JSONObject toJson() { HashMap array = toArray(); JSONObject json = new JSONObject(array); return json; } @Override public String toString() { return toJson().toString(); } }