com.plusub.lib.annotate.JsonParserUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.plusub.lib.annotate.JsonParserUtils.java

Source

/*
 * FileName: JsonParserUtils.java
 * Copyright (C) 2014 Plusub Tech. Co. Ltd. All Rights Reserved <admin@plusub.com>
 * 
 * Licensed under the Plusub License, Version 1.0 (the "License");
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * author  : service@plusub.com
 * date     : 2015-4-19 ?10:51:14
 * last modify author :
 * version : 1.0
 */
package com.plusub.lib.annotate;

import com.plusub.lib.util.JSONUtils;
import com.plusub.lib.util.logger.Logger;

import org.json.JSONArray;
import org.json.JSONObject;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * JSON?
 * @ClassName: JsonParserUtils
 * @Description: TODO
 * @author qh@plusub.com
 * @date 
 *     <b></b>2015-4-19 ?10:51:14<br>
 *     <b>?</b>2015-4-19 ?10:51:14
 * @version v1.0
 */
public class JsonParserUtils {

    private static final String TAG = "JsonParserUtils";
    private static boolean showLog = false;

    /**
     * ??
     * <p>Title: setPrintSwitch
     * <p>Description: 
     * @param isOpen true
     */
    public static void setLogSwitch(boolean isOpen) {
        showLog = isOpen;
    }

    /**
     * ?JSONobjEntity
     * <p>Title: initEntityParser
     * <p>Description: 
      * @param className ?
     * @param jsonString JSON
     * @return
     * @throws Exception
     */
    public static Object initEntityParser(Class className, String jsonString) throws Exception {
        Object obj = getInstance(className.getName());
        JsonParserClass jsonClass = obj.getClass().getAnnotation(JsonParserClass.class);
        boolean isClassList = false;
        if (jsonClass != null) {
            isClassList = jsonClass.isList();
        }
        return initEntityParser(className, jsonString, isClassList);
    }

    /**
     * ?JSONobjEntity
     * <p>Title: initEntityParser
     * <p>Description: 
     * @param className ?
     * @param jsonString JSON
     * @param isParserList ?className?@JsonParserClass
     * @throws Exception
     */
    public static Object initEntityParser(Class className, String jsonString, boolean isParserList)
            throws Exception {
        JSONObject jo = new JSONObject(jsonString);
        Object obj = getInstance(className.getName());

        JsonParserClass jsonClass = obj.getClass().getAnnotation(JsonParserClass.class);
        String rootKey = "";
        boolean isHasPage = false;
        String pageKey = "";
        if (jsonClass != null) {
            rootKey = jsonClass.parserRoot();
            isHasPage = jsonClass.isHasPage();
            pageKey = jsonClass.pageFieldStr();
        }
        Object result = null;

        if (!isParserList) {
            if (isEmpty(rootKey)) {
                result = parserField(obj, jo);
            } else {
                JSONObject json = JSONUtils.getJSONObject(jo, rootKey, null);
                if (json != null) {
                    result = parserField(obj, json);
                }
            }
        } else {
            Object pageObj = null;
            //?page
            if (isHasPage) {
                Field field;
                try {
                    field = obj.getClass().getDeclaredField(pageKey);
                    JsonParserField jsonField = field.getAnnotation(JsonParserField.class);
                    String key = jsonField.praserKey();
                    if (isEmpty(key)) {
                        key = field.getName();
                    }
                    JSONObject pageJO = JSONUtils.getJSONObject(jo, key, null);
                    if (pageJO != null) {
                        pageObj = getPageInfo(pageJO, field);
                        setFieldValue(obj, field, pageObj);
                    }
                } catch (NoSuchFieldException e) {
                    // TODO Auto-generated catch block
                    if (showLog) {
                        Logger.e("JsonParserUtils", "Field" + pageKey);
                        e.printStackTrace();
                    }
                }
            }

            //?
            JSONArray ja = JSONUtils.getJSONArray(jo, rootKey, null);
            if (ja != null && ja.length() > 0) {
                int size = ja.length();
                Object[] data = new Object[size];
                //?
                for (int index = 0; index < size; index++) {
                    Object oj = parserField(getInstance(className.getName()), ja.getJSONObject(index));

                    //page?
                    if (isHasPage && pageObj != null) {
                        try {
                            setFieldValue(oj, oj.getClass().getDeclaredField(pageKey), pageObj);
                        } catch (NoSuchFieldException e) {
                            // TODO Auto-generated catch block
                            if (showLog) {
                                e.printStackTrace();
                            }
                        }
                    }

                    data[index] = oj;
                }
                result = Arrays.asList(data);
            } else {
                if (showLog) {
                    Logger.i(TAG, "JSONArray is Empty " + rootKey);
                }
            }
        }

        return result;
    }

    /**
     * ????JSON?
     * <p>Title: getPageInfo
     * <p>Description: 
     * @param jo
     * @param field
     * @return
     */
    private static Object getPageInfo(JSONObject jo, Field field) {
        Object pageObj = null;
        try {
            pageObj = parserField(getInstance(field.getType().getName()), jo);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            if (showLog) {
                e.printStackTrace();
            }
            return pageObj;
        }
        return pageObj;
    }

    /**
     * ??
     * <p>Title: parserField
     * <p>Description: 
     * @param obj
     * @param jsonObj
     * @return
     * @throws Exception
     */
    private static Object parserField(Object obj, JSONObject jsonObj) throws Exception {
        Field[] fields = obj.getClass().getDeclaredFields();
        if (fields != null && fields.length > 0) {
            for (Field field : fields) {
                JsonParserField jsonField = field.getAnnotation(JsonParserField.class);

                //JsonParserField
                if (jsonField != null) {
                    String keyName = jsonField.praserKey(); //json
                    String defaultValue = jsonField.defaultValue(); //
                    boolean isList = jsonField.isList();

                    //???
                    String name = "";
                    if (isEmpty(keyName)) {
                        name = field.getName();
                    } else {
                        name = keyName;
                    }

                    try {
                        field.setAccessible(true);
                        //?
                        if (jsonObj.has(name)) {
                            if (!isList) { //?
                                setSingleValue(obj, field, jsonObj, name);
                            } else { //
                                Class listCls = jsonField.classType();
                                if (listCls.equals(Object.class)) {
                                    if (showLog)
                                        Logger.e(TAG, "" + field.getName()
                                                + "classType?" + keyName);
                                }
                                JSONArray ja = null;
                                if (isEmpty(keyName)) {
                                    ja = JSONUtils.getJSONArray(jsonObj, field.getName(), null);
                                } else {
                                    ja = JSONUtils.getJSONArray(jsonObj, keyName, null);
                                }
                                if (ja != null) {
                                    //
                                    int size = ja.length();
                                    Object[] data = new Object[size];

                                    //?
                                    for (int index = 0; index < size; index++) {
                                        Object oj = parserField(getInstance(listCls.getName()),
                                                ja.getJSONObject(index));
                                        data[index] = oj;
                                    }

                                    //?
                                    Object listObj = field.getType();
                                    if (listObj.equals(List.class)) {
                                        setFieldValue(obj, field, Arrays.asList(data));
                                    } else {
                                        setFieldValue(obj, field, data);
                                    }
                                }
                            }
                        } else {
                            setFieldValue(obj, field, defaultValue);
                        }
                    } catch (Exception e) {
                        throw new RuntimeException(
                                "parser " + obj.getClass().getName() + " error! \n" + e.getMessage());
                    }
                } else { //JsonParserField
                    setSingleValue(obj, field, jsonObj, field.getName());
                }
            }
        }
        return obj;
    }

    /**
     * ??
     * <p>Title: setSingleValue
     * <p>Description: 
     * @param object 
     * @param field 
     * @param jsonObj JSON
     * @param name ?JSON
     * @throws Exception
     */
    private static void setSingleValue(Object object, Field field, JSONObject jsonObj, String name)
            throws Exception {
        //?
        if (!isBaseDataType(field.getType())) {
            JSONObject jo = JSONUtils.getJSONObject(jsonObj, name, null);
            if (jo != null) {
                Object result = parserField(getInstance(field.getType().getName()), jo);
                if (result != null) {
                    setFieldValue(object, field, result);
                }
            }
        } else {
            setFieldValue(object, field, JSONUtils.get(jsonObj, name, null));
        }
    }

    /**
     * ??
     * <p>Title: getInstance
     * <p>Description: 
     * @param className
     * @return
     * @throws Exception
     */
    private static Object getInstance(String className) throws Exception {
        Object obj = null;
        try {
            obj = Class.forName(className).newInstance();
        } catch (Exception e) {
            // TODO: handle exception
            throw new RuntimeException("getInstance init class " + className + " error! \n" + e.getMessage());
        }
        return obj;
    }

    /**
     * ?
     * <p>Title: isEmpty
     * <p>Description: 
     * @param value
     * @return
     */
    private static boolean isEmpty(String value) {
        if (value == null || value.equals("")) {
            return true;
        }
        return false;
    }

    /**
     * 
     * <p>Title: setFieldValue
     * <p>Description: 
     * @param object 
     * @param field 
     * @param value 
     */
    private static void setFieldValue(Object object, Field field, Object value) {
        Object ov = null;
        try {
            ov = getType(field, value, field.getName());
            field.set(object, ov);
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            if (showLog) {
                e.printStackTrace();
            }

            //fieldset
            try {
                Method m = object.getClass().getMethod(getSetMethodName(field), field.getType());
                if (m != null) {
                    m.invoke(object, ov);
                }
            } catch (Exception e1) {
                // TODO Auto-generated catch block
                if (showLog) {
                    Logger.e(TAG,
                            "set field value fail field:" + field.getName() + " method:" + getSetMethodName(field));
                    e1.printStackTrace();
                }
            }
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            if (showLog) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            if (showLog) {
                e.printStackTrace();
            }
        }
    }

    /**
     * ?
     * <p>Title: isWrapClass
     * <p>Description: 
     * @param clazz
     * @return
     */
    private static boolean isBaseDataType(Class clazz) {
        return (clazz.isPrimitive() || clazz.equals(String.class) || clazz.equals(Integer.class)
                || clazz.equals(Boolean.class) || clazz.equals(Long.class) || clazz.equals(Double.class)
                || clazz.equals(Float.class) || clazz.equals(Short.class) || clazz.equals(Character.class)
                || clazz.equals(Date.class)) || clazz.equals(Byte.class) || clazz.equals(Void.class)
                || clazz.equals(BigDecimal.class) || clazz.equals(BigInteger.class);
    }

    /**
     * ?
     * <p>Title: getType
     * <p>Description: 
     * @param field ?
     * @param defaultValue (Json?String)
     * @return defaultValue?obj
     */
    private static Object getType(Field field, Object defaultValue, String fieldName) {
        Object value = defaultValue;
        if (showLog) {
            Logger.i(TAG,
                    "getType:" + field.getName() + " " + field.getType().getName() + " " + " " + defaultValue);
        }
        if (defaultValue == null) {
            return value;
        }

        String type = field.getType().getName();
        Class clazz = field.getType();
        try {
            if (isBaseDataType(field.getType())) {
                String str = defaultValue + "";
                if (clazz.equals(String.class)) {
                    value = defaultValue;
                } else if (clazz.equals(Integer.class) || type.equals("int")) {
                    value = Integer.parseInt(str);
                } else if (clazz.equals(Boolean.class) || type.equals("boolean")) {
                    String defaultStr = str;
                    String result = defaultStr.toLowerCase();
                    if (result.equals("true")) {
                        value = true;
                    } else if (result.equals("false")) {
                        value = false;
                    } else {
                        value = Integer.parseInt(result) > 0 ? true : false;
                    }
                } else if (clazz.equals(Double.class) || type.equals("double")) {
                    value = Double.parseDouble(str);
                } else if (clazz.equals(Float.class) || type.equals("float")) {
                    value = Float.parseFloat(str);
                } else if (clazz.equals(Short.class) || type.equals("short")) {
                    value = Short.parseShort(str);
                } else if (clazz.equals(Long.class) || type.equals("long")) {
                    value = Long.parseLong(str);
                } else if (clazz.equals(Byte.class) || type.equals("byte")) {
                    value = Byte.parseByte(str);
                }
            } else { //?
                if (showLog) {
                    Logger.i(TAG, "?, " + defaultValue);
                }
            }
        } catch (Exception e) {
            // TODO: handle exception
            if (showLog) {
                Logger.e(TAG, "?" + fieldName + "String-->" + field.getType().getName()
                        + ", " + value);
                e.printStackTrace();
            }
            return value;
        }
        return value;
    }

    /**
     * ?set??
     * <p>Title: getSetMethodName
     * <p>Description: 
     * @param field
     * @return
     */
    private static String getSetMethodName(Field field) {
        Class clazz = field.getType();
        String name = field.getName();
        StringBuilder sb = new StringBuilder();
        //boolean ?set? 
        //private boolean ishead; setIshead
        //private boolean isHead; setHead
        //private boolean head; setHead
        if (clazz.equals(Boolean.class) || clazz.getName().equals("boolean")) {
            sb.append("set");
            if (name.startsWith("is")) {
                if (name.length() > 2) {
                    //private boolean isHead; setHead
                    if (Character.isUpperCase(name.charAt(2))) {
                        sb.append(name.substring(2));
                    } else {//private boolean ishead; setIshead
                        sb.append(name.toUpperCase().charAt(0));
                        sb.append(name.substring(1));
                    }
                } else {
                    sb.append(name.toUpperCase().charAt(0));
                    sb.append(name.substring(1));
                }
            } else {//private boolean head; setHead
                sb.append(name.toUpperCase().charAt(0));
                sb.append(name.substring(1));
            }
        } else {
            sb.append("set");
            sb.append(name.toUpperCase().charAt(0));
            sb.append(name.substring(1));
        }
        return sb.toString();
    }
}