001 package net.sourceforge.javajson.converter; 002 003 import java.lang.reflect.InvocationTargetException; 004 import java.lang.reflect.Method; 005 import java.lang.reflect.Type; 006 import java.text.DateFormat; 007 import java.text.ParseException; 008 import java.text.SimpleDateFormat; 009 import java.util.ArrayList; 010 import java.util.Collection; 011 import java.util.Date; 012 import java.util.HashSet; 013 import java.util.Iterator; 014 import java.util.List; 015 import java.util.regex.Matcher; 016 import java.util.regex.Pattern; 017 018 import net.sourceforge.javajson.JsonArray; 019 import net.sourceforge.javajson.JsonObject; 020 import net.sourceforge.javajson.JsonValue; 021 022 public class Utils { 023 024 public static DateFormat dateFormat = new SimpleDateFormat( 025 "yyyy/MM/dd HH:mm:ss"); 026 027 public static void fromJson(Object obj, JsonObject json) 028 throws IllegalArgumentException, IllegalAccessException, 029 InvocationTargetException, InstantiationException, 030 ClassNotFoundException { 031 if (obj != null && json != null) { 032 List<Method> methods = Reflection.getSetterFieldMethods(obj 033 .getClass()); 034 for (Method method : methods) { 035 apply(obj, json, method); 036 } 037 } 038 } 039 040 /** 041 * Applies a method on an object 042 * 043 * @param obj 044 * @param json 045 * @param method 046 * @return false if the method couldn't be applied 047 * @throws InvocationTargetException 048 * @throws IllegalAccessException 049 * @throws IllegalArgumentException 050 * @throws InstantiationException 051 * @throws ClassNotFoundException 052 */ 053 private static boolean apply(Object obj, JsonObject json, Method method) 054 throws IllegalArgumentException, IllegalAccessException, 055 InvocationTargetException, InstantiationException, 056 ClassNotFoundException { 057 String fieldName = Reflection.getFieldName(method.getName()); 058 if (json.hasKey(fieldName) && !json.isNull(fieldName)) { 059 Object[] args = prepareParameter(json, method, fieldName); 060 if (args[0] != null) 061 method.invoke(obj, args); 062 } else if (json.hasKey(fieldName)) { 063 System.out.println("null field:" + fieldName + ", " 064 + json.getString(fieldName)); 065 } 066 067 return true; 068 } 069 070 @SuppressWarnings("unchecked") 071 private static Object[] prepareParameter(JsonObject json, Method method, 072 String fieldName) throws IllegalArgumentException, 073 IllegalAccessException, InvocationTargetException, 074 InstantiationException, ClassNotFoundException { 075 Object[] ret = new Object[1]; 076 Class[] params = method.getParameterTypes(); 077 Class param = params[0]; 078 079 if (param == String.class) { 080 ret[0] = json.getString(fieldName); 081 } else if (param == Integer.class || param == int.class) { 082 ret[0] = new Integer(json.getInt(fieldName)); 083 } else if (param == Long.class || param == long.class) { 084 ret[0] = new Long(json.getLong(fieldName)); 085 } else if (param == Float.class || param == float.class) { 086 ret[0] = new Float(json.getFloat(fieldName)); 087 } else if (param == Double.class || param == double.class) { 088 ret[0] = new Double(json.getDouble(fieldName)); 089 } else if (param == Date.class) { 090 try { 091 // System.out.println("todate: " + json.getString(fieldName) + " 092 // " + json.isNull(fieldName)); 093 ret[0] = dateFormat.parse(json.getString(fieldName)); 094 } catch (ParseException e) { 095 // TODO Auto-generated catch block 096 e.printStackTrace(); 097 } 098 // System.out.println("date, fieldname:" + fieldName + ", " + 099 // ret[0]); 100 } else if (Collection.class.isAssignableFrom(param)) { 101 Type genericType = method.getGenericParameterTypes()[0]; 102 Matcher m = Pattern.compile(".*<(.+)>.*").matcher(genericType.toString()); 103 String typeName = null; 104 if (m.matches()) 105 typeName = m.group(1); 106 Collection c; 107 if (List.class.isAssignableFrom(param)) { 108 c = new ArrayList(); 109 } else { 110 c = new HashSet(); 111 } 112 ret[0] = c; 113 if (json.isJsonArray(fieldName)) { 114 for (JsonValue value : json.getJsonArray(fieldName)) { 115 116 System.out.println("gt/int:" + genericType.toString() + " " + Integer.class.getName() + "\n"); 117 118 if (value.isJsonObject()) { 119 Object o = Converter.getInstance().fromJson( 120 value.getJsonObject()); 121 c.add(o); 122 } else if (value.isJsonArray()) { 123 //TODO: do something about nested arrays 124 } else if (value.isBoolean() && (typeName == null || Boolean.class.getName().equals(typeName))) { 125 c.add(value.getBoolean()); 126 } else if (value.isFloat() && (typeName == null || Float.class.getName().equals(typeName))) { 127 c.add(value.getFloat()); 128 } else if (value.isDouble() && (typeName == null || Double.class.getName().equals(typeName))) { 129 c.add(value.getDouble()); 130 } else if (value.isInt() && (typeName == null || Integer.class.getName().equals(typeName))) { 131 c.add(value.getInt()); 132 } else if (value.isLong() && (typeName == null || Long.class.getName().equals(typeName))) { 133 c.add(value.getLong()); 134 } else if (value.isString()) { 135 c.add(value.getString()); 136 } 137 } 138 } else { 139 // throw some kind of exception or something 140 } 141 // System.out.println("do something with a list"); 142 } else { 143 System.out.println("** object:" + fieldName + ", " 144 + param.getName()); 145 Object o = param.newInstance(); 146 Utils.fromJson(o, json.getJsonObject(fieldName)); 147 ret[0] = o; 148 } 149 150 return ret; 151 } 152 153 /** 154 * Convers an object to a simple (flat) json object. For depth, use the 155 * Converter with proper mappers 156 * 157 * @param cls 158 * @param obj 159 * @return 160 * @throws IllegalArgumentException 161 * @throws IllegalAccessException 162 * @throws InvocationTargetException 163 */ 164 @SuppressWarnings("unchecked") 165 public static JsonObject toJson(Object obj, Class cls) 166 throws IllegalArgumentException, IllegalAccessException, 167 InvocationTargetException { 168 JsonObject ret = null; 169 if (obj != null && cls.isAssignableFrom(obj.getClass())) { 170 ret = new JsonObject(); 171 List<Method> methods = Reflection.getGetterFieldMethods(cls); 172 Object[] ARGS = new Object[0]; 173 174 for (Iterator<Method> it = methods.iterator(); it.hasNext();) { 175 Method m = it.next(); 176 String fld = Reflection.getFieldName(m.getName()); 177 Object o = m.invoke(obj, ARGS); 178 objectIntoJsonObject(ret, fld, o); 179 } 180 } else if (!cls.isAssignableFrom(obj.getClass())) { 181 182 System.out.println("\n\noops!\n\n"); 183 184 System.out.println(cls.getName()); 185 System.out.println(obj.getClass().getName()); 186 187 } 188 189 return ret; 190 } 191 192 /** 193 * Adds known simple types to the json object 194 * 195 * @param obj 196 * @param key 197 * @param o 198 * @return True if the object as of a simple type 199 */ 200 public static boolean objectIntoJsonObject(JsonObject obj, String key, 201 Object o) { 202 if (o instanceof Long) { 203 obj.put(key, ((Long) o).longValue()); 204 } else if (o instanceof Integer) { 205 obj.put(key, ((Integer) o).intValue()); 206 } else if (o instanceof Double) { 207 obj.put(key, ((Double) o).doubleValue()); 208 } else if (o instanceof Float) { 209 obj.put(key, ((Float) o).doubleValue()); 210 } else if (o instanceof Boolean) { 211 obj.put(key, ((Boolean) o).booleanValue()); 212 } else if (o instanceof Date) { 213 obj.put(key, dateFormat.format((Date) o)); 214 } else if (o instanceof String) { 215 obj.put(key, (String) o); 216 } else if (o instanceof Class) { 217 obj.put(key, ((Class) o).getName()); 218 } else if (o == null) { 219 obj.put(key, (String) null); 220 } else { 221 return false; 222 } 223 224 return true; 225 } 226 227 /** 228 * Adds known simple types to the json array 229 * 230 * @param obj 231 * @param key 232 * @param o 233 * @return True if the object as of a simple type 234 */ 235 public static boolean objectIntoJsonArray(JsonArray arr, Object o) { 236 if (o instanceof Long) { 237 arr.add(((Long) o).longValue()); 238 } else if (o instanceof Integer) { 239 arr.add(((Integer) o).intValue()); 240 } else if (o instanceof Double) { 241 arr.add(((Double) o).doubleValue()); 242 } else if (o instanceof Float) { 243 arr.add(((Float) o).doubleValue()); 244 } else if (o instanceof Boolean) { 245 arr.add(((Boolean) o).booleanValue()); 246 } else if (o instanceof Date) { 247 arr.add(dateFormat.format((Date) o)); 248 } else if (o instanceof String) { 249 arr.add((String) o); 250 } else if (o instanceof Class) { 251 arr.add(((Class) o).getName()); 252 } else if (o == null) { 253 arr.add((String) null); 254 } else { 255 return false; 256 } 257 258 return true; 259 } 260 }