org.istsms.util.Javabean2JSON.java Source code

Java tutorial

Introduction

Here is the source code for org.istsms.util.Javabean2JSON.java

Source

/*
Javabean2JSON: a simple approach to Java Beans serialization into JSON 
Author: Giovanni Bartolomeo
Copyright (C) 2007, 2008  University of Rome Tor Vergata - Dipartimento di Ingegneria Elettronica
    
    
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

package org.istsms.util;

//Andrea - cambiato il package. Prima era "org.json.me"
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Calendar;
import java.util.Hashtable;
import java.util.Vector;

import org.jsonref.JSONArray;
import org.jsonref.JSONException;
import org.jsonref.JSONObject;

public class Javabean2JSON {

    private static final Hashtable primitiveType = new Hashtable();
    static {
        primitiveType.put("java.lang.Boolean", "boolean");
        primitiveType.put("java.lang.Byte", "byte");
        primitiveType.put("java.lang.Character", "char");
        primitiveType.put("java.lang.Double", "double");
        primitiveType.put("java.lang.Float", "float");
        primitiveType.put("java.lang.Integer", "int");
        primitiveType.put("java.lang.Long", "long");
        primitiveType.put("java.lang.Short", "short");
        primitiveType.put("java.lang.String", "java.lang.String");
        //      primitiveType.put("java.util.Calendar", "java.lang.String");
        primitiveType.put("boolean", "boolean");
        primitiveType.put("byte", "byte");
        primitiveType.put("char", "char");
        primitiveType.put("double", "double");
        primitiveType.put("float", "float");
        primitiveType.put("int", "int");
        primitiveType.put("long", "long");
        primitiveType.put("short", "short");
    }

    private static boolean equalPrimitive(String canonicalName, String type) {
        String cN = (String) primitiveType.get(canonicalName);
        String t = (String) primitiveType.get(type);
        if ((cN != null) && (t != null))
            return cN.equals(t);
        return canonicalName.equals(type);
    }

    private static boolean isPrimitive(String type) {
        return (primitiveType.get(type) != null);
    }

    private static Object getPrimitive(Object value, String type) {
        Object arg = null;
        if (type.equals("boolean") || type.equals("java.lang.Boolean")) {

            arg = new Boolean(value.toString());

        } else if (type.equals("byte") || type.equals("java.lang.Byte")) {
            arg = new Byte(value.toString());
        } else if (type.equals("char") || type.equals("java.lang.Character")) {
            arg = new Character((char) value.toString().getBytes()[0]);
        } else if (type.equals("double") || type.equals("java.lang.Double")) {
            arg = new Double(value.toString());
        } else if (type.equals("float") || type.equals("java.lang.Float")) {
            arg = new Float(value.toString());
        } else if (type.equals("int") || type.equals("java.lang.Integer")) {
            arg = new Integer(value.toString());
        } else if (type.equals("long") || type.equals("java.lang.Long")) {
            arg = new Long(value.toString());
        } else if (type.equals("short") || type.equals("java.lang.Short")) {
            arg = new Short(value.toString());
        } else if (type.equals("java.lang.String")) {
            arg = value;
        }
        //      else if (type.equals("java.util.Calendar")) {
        //         java.util.Calendar c=java.util.Calendar.getInstance();
        //         c.setTime(new java.util.Date(Long.parseLong(value.toString())));
        //         arg=c;
        //      }       
        return arg;
    }

    public static Object fromJSONObject(JSONObject jObj) {
        return fromJSONObject(jObj, null);
    }

    public static Object fromJSONObject(JSONObject jObj0, Class suggestion) {

        if ((suggestion != null) && (suggestion.equals(JSONObject.class)))
            return jObj0;
        JSONObject jObj = (JSONObject) jObj0;
        Class c;
        String cl = null;
        if (suggestion != null)
            cl = suggestion.getCanonicalName();
        try {
            try {
                cl = jObj.getString("__class");
            } catch (JSONException e) {
            } catch (ClassCastException e) {
            }
            if (cl == null)
                return null;
            if (isPrimitive(cl)) {
                return getPrimitive(jObj0.getString("__value"), jObj0.getString("__class"));
            }
            if (isCalendar(cl)) {
                return toJavaCalendar(jObj0);
            }
            c = Class.forName(cl);
            Object temp = c.newInstance();
            Method[] m = c.getMethods();
            //Note: private and protected methods are not considered!
            Method method;
            String methodName;
            for (int i = 0; i < m.length; i++) {
                method = m[i];
                if (Modifier.isStatic(method.getModifiers()))
                    continue;
                methodName = method.getName();
                if (methodName.startsWith("set")) {
                    Class[] params = method.getParameterTypes();
                    if (params.length == 1) {
                        //String key=methodName.substring(3); //ANDREA - cambiato in:
                        String key = methodName.substring(3, 4).toLowerCase() + methodName.substring(4);
                        String type = params[0].getCanonicalName();
                        if (params[0].isArray()) {
                            //it's an array!
                            //type=type.substring(0, type.length()-2); //skip '[]' now done inside _fromJSONArray()
                            JSONArray jArr = null;
                            try {
                                jArr = jObj.getJSONArray(key);
                            } catch (JSONException e) {
                            }
                            Object objArr = fromJSONArray(jArr, params[0]); //10.7.08 GB to support array of array deserialization
                            if (objArr != null)
                                method.invoke(temp, objArr);
                        } else {
                            Object value = null;
                            try {
                                value = jObj.get(key);
                            } catch (JSONException e) {
                            }
                            //if (value==null) continue; //ANDREA - cambiato in:
                            if (value == null || value.equals(null))
                                continue;
                            Object arg = null;
                            if (isCalendar(type))
                                try {
                                    arg = toJavaCalendar((JSONObject) value);
                                } catch (ClassCastException e) {
                                    e.printStackTrace();
                                }
                            else {
                                if (value instanceof JSONObject) {
                                    arg = fromJSONObject((JSONObject) value, params[0]);
                                } else
                                    arg = getPrimitive(value, type);
                            }
                            method.invoke(temp, new Object[] { arg });
                        }
                    }
                }
            }
            return temp;
        } catch (Exception e) {
            e.printStackTrace();
            log(e.getMessage());
        }
        return null;
    }

    public static Object fromJSONArray(JSONArray jArr, Class arrayType) {
        if (jArr != null && arrayType != null) {
            Class baseType = arrayType.getComponentType();
            if (baseType == null)
                return null; //it was not an array!      
            String baseTypeName = baseType.getCanonicalName();
            int length = jArr.length();
            Object argArray = Array.newInstance(baseType, length);
            try {
                Vector v = new Vector();
                for (int j = 0; j < jArr.length(); j++) {
                    //four cases: the json Array element may be:
                    //a. a JSON Array (in case of array of arrays)
                    //b. a calendar
                    //c. a JSON Object
                    //d. a primitive value (serialized as a String)                           
                    Object jElement = jArr.get(j);
                    if (jElement.equals(null))
                        continue;
                    if (jElement instanceof JSONArray) {
                        Object element = fromJSONArray((JSONArray) jElement, baseType);
                        if (element != null)
                            Array.set(argArray, j, element);
                    } else if (isCalendar(baseTypeName)) {
                        Object element = toJavaCalendar((JSONObject) jElement);
                        if (element != null)
                            Array.set(argArray, j, element);
                    } else if (jElement instanceof JSONObject) {
                        Object element = fromJSONObject((JSONObject) jElement, baseType);
                        if (element != null)
                            Array.set(argArray, j, element);
                    } else {
                        Object primitive = getPrimitive(jArr.getString(j), baseTypeName);
                        if (primitive != null)
                            Array.set(argArray, j, primitive);
                    }
                }

                return argArray;
            } catch (NegativeArraySizeException e) {
            } catch (JSONException e) {
            }
        }
        return null;
    }

    public static JSONObject toJSONObject(Object obj) {
        JSONObject temp = _toJSONObject(obj);
        if (!(obj instanceof java.util.Calendar))
            try {
                temp.put("__class", obj.getClass().getCanonicalName());
            } catch (JSONException e) {
                e.printStackTrace();
                return null;
            }
        return temp;
    }

    private static JSONObject _toJSONObject(Object obj) {
        if (obj instanceof JSONObject)
            return (JSONObject) obj;
        if (obj instanceof java.util.Calendar)
            return fromJavaCalendar((java.util.Calendar) obj);
        JSONObject temp = new JSONObject();
        if (isPrimitive(obj.getClass().getCanonicalName())) {
            try {
                temp.put("__value", obj.toString());
                //                     (obj instanceof java.util.Calendar)
                //                     ?""+((java.util.Calendar)obj).getTime().getTime()   
                //                     :obj.toString());
            } catch (JSONException e) {
                e.printStackTrace();
            }
        } else {
            addInherited(obj, obj.getClass(), temp);
        }
        return temp;
    }

    public static JSONArray toJSONArray(Object value) {
        return _toJSONArray(value, value.getClass());
    }

    private static JSONArray _toJSONArray(Object value, Class c) {
        if (value == null)
            return null;
        if (!c.isArray())
            return null;
        if (value.getClass().isArray()) {
            //it's an array!                  
            Vector v = new Vector();
            int length = Array.getLength(value);
            for (int j = 0; j < length; j++) {
                Object element = Array.get(value, j);
                if (element != null) {
                    if (element.getClass().isArray()) {
                        v.add(_toJSONArray(element, c.getComponentType()));
                    } else {
                        String suggestedComponentType = c.getComponentType().getCanonicalName();
                        if (isCalendar(element.getClass().getCanonicalName())) {
                            v.add(fromJavaCalendar((java.util.Calendar) element));
                        } else if (isPrimitive(element.getClass().getCanonicalName())) {
                            v.add(equalPrimitive(element.getClass().getCanonicalName(), suggestedComponentType)
                                    ? element.toString()
                                    //                            (element instanceof java.util.Calendar)
                                    //                               ?""+((java.util.Calendar)element).getTime().getTime()   
                                    //                            :element.toString()

                                    : toJSONObject(element));
                        } else {
                            v.add(suggestedComponentType.equals(element.getClass().getCanonicalName())
                                    ? _toJSONObject(element)
                                    : toJSONObject(element));
                        }
                    }
                } else {
                    v.add(JSONObject.NULL);
                }
            }
            return new JSONArray(v);
        }
        return null;
    }

    private static void addInherited(Object obj, Class cl, JSONObject jObj) {
        if (cl == Object.class)
            return;
        addAttributes(obj, cl, jObj);
        Class ancestor = cl.getSuperclass();
        addInherited(obj, ancestor, jObj);
    }

    private static void addAttributes(Object obj, Class c, JSONObject jObj) {
        //String objectClass=c.getCanonicalName();
        //      Method[] m=c.getDeclaredMethods();
        Method[] m = c.getMethods();
        //Note: private and protected methods are not considered!
        Method method;
        String methodName;
        for (int i = 0; i < m.length; i++) {
            method = m[i];
            if (Modifier.isStatic(method.getModifiers()))
                continue;
            if (!method.getDeclaringClass().equals(c))
                continue; //it is an inherited method, do not consider
            //TODO:maybe also private and protected methods have to be discarder!
            methodName = method.getName();
            if (methodName.startsWith("get") || methodName.startsWith("is")) {
                Class[] params = method.getParameterTypes();
                if (params.length == 0) {
                    String key;
                    if (methodName.startsWith("get"))
                        key = methodName.substring(3);
                    else
                        key = methodName.substring(2);
                    String type = method.getReturnType().getCanonicalName();
                    log("found method GET " + key + " returned type: " + type);
                    Object value;
                    try {
                        value = method.invoke(obj, (Object[]) null);
                        //now enumerate primitive types, if it is a primitive value, put it in the json object
                        //its value as a string; otherwise call recursively this method
                        if (value == null)
                            continue;
                        if (value.getClass().isArray()) {
                            //it's an array!      
                            JSONArray ja = _toJSONArray(value, method.getReturnType()); //10.07.08 GB to support array of array serialization
                            if (ja != null)
                                jObj.put(key, ja);
                        } else {
                            put(jObj, type, key, value);
                        }

                    } catch (Exception e) {
                        log("Exception: " + e.getMessage());
                    }
                }
            }
        }
    }

    private static void put(JSONObject jObj, String type, String key, Object value) {
        try {
            if (isCalendar(type)) {
                jObj.put(key, fromJavaCalendar((java.util.Calendar) value));
            } else if (isPrimitive(type)) {
                jObj.put(key, value.toString());
            } else {
                if (isPrimitive(value.getClass().getCanonicalName())) {
                    if (!equalPrimitive(value.getClass().getCanonicalName(), type)) {
                        //in case the getXXX method returns a generic interface, then put an explicit information
                        //about the actual object's class
                        JSONObject jo = _toJSONObject(value);
                        jo.put("__class", value.getClass().getCanonicalName());
                        jObj.put(key, jo);
                    } else {
                        jObj.put(key, value.toString());
                    }
                } else {
                    JSONObject jo;
                    if (value.getClass().getCanonicalName().equals(type)) {
                        jo = _toJSONObject(value);
                    } else {
                        jo = toJSONObject(value);
                    }
                    jObj.put(key, jo);
                }
            }
        } catch (JSONException e) {
            log(e.getMessage());
        }
    }

    private static void log(String s) {
        //System.out.println("[Javabean2JSON] "+s);
    }

    //extra methods to manage java.util.Calendar serialization

    private static Object toJavaCalendar(JSONObject jo) {
        if (jo == null)
            return null;
        try {
            if (jo.getString("__class").equals(Calendar.class.getCanonicalName())) {
                java.util.Calendar c = java.util.Calendar.getInstance();
                c.setTime(new java.util.Date(Long.parseLong(jo.getString("__value"))));
                c.setTimeZone(java.util.TimeZone.getTimeZone(jo.getString("__timezn")));
                return c;
            }
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (RuntimeException r) {
            r.printStackTrace();
        }
        return null;
    }

    private static JSONObject fromJavaCalendar(Calendar obj) {
        if (obj == null)
            return null;
        try {
            JSONObject jo = new JSONObject();
            jo.put("__class", Calendar.class.getCanonicalName());
            jo.put("__value", "" + obj.getTime().getTime());
            jo.put("__timezn", obj.getTimeZone().getID());
            return jo;
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }
    }

    private static boolean isCalendar(String cl) {
        return cl.equals(Calendar.class.getCanonicalName());
    }
}