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    }