Java tutorial
/* The MIT License (MIT) Copyright (c) 2015 Riki Network Systems Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package jp.rikinet.util.dto; import org.json.JSONArray; import org.json.JSONObject; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; /** * Root ?? Root ?? DTO ? JSON ?? */ public class DtoFactory { /** * ?????JSON??? * ????????????? */ static final String KEY_CLASS = "_class_"; /** * ????? * ??????????????? * * @see DtoFactory#register(Class) */ private static HashMap<String, Class<? extends Root>> classTable; static { classTable = new HashMap<>(); } private DtoFactory() { // singleton } /** * ??????? DTO ?? * @param cl classTable ???? DTO * @param jo DTO ??????? JSONObject * @param <T> DTO ? * @return ??? DTO */ private static <T extends Root> T newSimpleDto(Class<T> cl, JSONObject jo) { T dto; try { Constructor<T> cons = cl.getConstructor(JSONObject.class); dto = cons.newInstance(jo); } catch (NoSuchMethodException e) { throw new IllegalArgumentException("constructor not found", e); } catch (InvocationTargetException | InstantiationException | IllegalAccessException e) { throw new IllegalArgumentException("constructor call failed", e); } return dto; } /** * ?? DTO ?? * @param dto ??? DTO * @param name ??birthDate ? setter ? setBirthDate() * @param value ? */ private static void setProperty(Root dto, String name, Object value) { Class<?> cl = dto.getClass(); String mName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1); try { Method m = cl.getMethod(mName, value.getClass()); m.invoke(dto, value); } catch (NoSuchMethodException e) { throw new IllegalArgumentException("setter not found", e); } catch (InvocationTargetException | IllegalAccessException e) { throw new IllegalArgumentException("setter call failed", e); } } /** * JSONArray DtoArray ??? * array object ????????????? * @param ja ???? JSONArray * @return ??? DtoArray */ @SuppressWarnings("unchecked") private static <E> DtoArray<E> convert(JSONArray ja) { DtoArray da = new DtoArray<E>(ja.length()); // ????????????? for (int i = 0; i < ja.length(); i++) { Object obj = ja.get(i); if (obj instanceof JSONArray) { DtoArray subArr = convert((JSONArray) obj); da.put(i, subArr); } else if (obj instanceof JSONObject) { Root dto = convert((JSONObject) obj); da.put(i, dto); } else { da.put(i, obj); } } return da; } /** * ?? JSDONObject ? DTO ?? * ?????DTO ??? setter ???? * ???????? * @param jo ????? DTO ?? * @param <T> ?? DTO ? * @return ??? DTO */ private static <T extends Root> T convert(JSONObject jo) { String typeName = jo.getString(KEY_CLASS); if (typeName == null) { // ???? throw new IllegalArgumentException("Type key _class_ undefined."); } Class<?> cl = classTable.get(typeName); if (cl == null) { // ?????? throw new IllegalArgumentException("Type " + classTable.get(typeName) + "not registered."); } T newDto = newSimpleDto((Class<T>) cl, jo); // ?????????? Iterator<String> iter = jo.keys(); while (iter.hasNext()) { String key = iter.next(); Object val = jo.get(key); if (val instanceof JSONArray) { // construct array DtoArray da = convert((JSONArray) val); // set as property value setProperty(newDto, key, da); } else if (val instanceof JSONObject) { // construct sub object Root subObj = convert((JSONObject) val); // set as property value setProperty(newDto, key, subObj); } } return newDto; } /** * JSON ??????? DTO ?? * @param str JSON ??? _class_ ???? * @param <T> ?? DTO ? * @return T ? DTO */ public static <T extends Root> T deserialize(String str) { JSONObject jObj = new JSONObject(str); return convert(jObj); } /** * JSON ????????? * ????? * @param clazz Root ?? */ public static void register(Class<? extends Root> clazz) { if (!clazz.isAnnotationPresent(DtoType.class)) return; DtoType dt = clazz.getAnnotation(DtoType.class); classTable.put(dt.value(), clazz); } }