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 }