Package org.nutz.json.entity

Source Code of org.nutz.json.entity.JsonEntity

package org.nutz.json.entity;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.nutz.json.JsonException;
import org.nutz.json.JsonField;
import org.nutz.json.JsonFormat;
import org.nutz.json.ToJson;
import org.nutz.lang.Lang;
import org.nutz.lang.Mirror;
import org.nutz.lang.Strings;
import org.nutz.lang.born.Borning;
import org.nutz.lang.born.BorningException;
import org.nutz.lang.util.Callback;
import org.nutz.lang.util.Callback3;

/**
* 记录一个Java如何映射 JSON 字符串的规则
*
* @author zozoh(zozohtnt@gmail.com)
*/
public class JsonEntity {

    private List<JsonEntityField> fields;

    private Map<String, JsonEntityField> fieldMap = new HashMap<String, JsonEntityField>();

    private Borning<?> borning;

    private BorningException err;

    private Map<String, Integer> typeParams; // 如果本类型是范型,存放范型标识的下标
   
    private Method toJsonMethod;

    public JsonEntity(Mirror<?> mirror) {
        // 处理范型
        Type type = mirror.getActuallyType();
        typeParams = new HashMap<String, Integer>();
        if (type instanceof ParameterizedType) {
            ParameterizedType pmType = (ParameterizedType) type;
            int i = 0;
            for (Type pmA : pmType.getActualTypeArguments()) {
                typeParams.put(pmA.toString(), i++);
            }
        }
        // 开始解析
        Field[] flds = mirror.getFields();
        fields = new ArrayList<JsonEntityField>(flds.length);
        for (Field fld : flds) {

            JsonEntityField ef = JsonEntityField.eval(mirror, fld);
            if (null == ef) {
                continue;
            }
            fields.add(ef);
            fieldMap.put(ef.getName(), ef);
        }
        for (Method m : mirror.getMethods()) {
            final JsonField jf = m.getAnnotation(JsonField.class);
            // 忽略方法
            if (null == jf || jf.ignore())
                continue;

            // 如果有,尝试作新的 Entity
            final Method method = m;
            Callback<Method> whenError = new Callback<Method>() {
                // 给定方法即不是 getter 也不是 setter,靠!玩我!
                public void invoke(Method m) {
                    throw Lang.makeThrow(JsonException.class,
                                         "JsonField '%s' should be getter/setter pair!",
                                         m);
                }
            };
            Callback3<String, Method, Method> whenOk = new Callback3<String, Method, Method>() {
                public void invoke(String name, Method getter, Method setter) {
                    // 防止错误
                    if (null == getter || null == setter || Strings.isBlank(name)) {
                        throw Lang.makeThrow(JsonException.class,
                                             "JsonField '%s' should be getter/setter pair!",
                                             method);
                    }
                    // 加入字段表
                    JsonEntityField ef = JsonEntityField.eval(Strings.sBlank(jf.value(), name),
                                                              getter,
                                                              setter);
                    fields.add(ef);
                    fieldMap.put(ef.getName(), ef);
                }
            };
            Mirror.evalGetterSetter(m, whenOk, whenError);
        }

        try {
            borning = mirror.getBorning();
        }
        catch (BorningException e) {
            err = e;
        }
       
        Class<? extends Object> klass = mirror.getType();
        ToJson tj = klass.getAnnotation(ToJson.class);
        String myMethodName = Strings.sNull(null == tj ? null : tj.value(), "toJson");
        try {
            /*
             * toJson()
             */
            try {
                Method myMethod = klass.getMethod(myMethodName);
                if (!myMethod.isAccessible())
                    myMethod.setAccessible(true);
                toJsonMethod = myMethod;
            }
            /*
             * toJson(JsonFormat fmt)
             */
            catch (NoSuchMethodException e1) {
                try {
                    Method myMethod = klass.getMethod(myMethodName, JsonFormat.class);
                    if (!myMethod.isAccessible())
                        myMethod.setAccessible(true);
                    toJsonMethod = myMethod;
                }
                catch (NoSuchMethodException e) {}
            }
        }
        catch (Exception e) {
            throw Lang.wrapThrow(e);
        }
    }

    public List<JsonEntityField> getFields() {
        return fields;
    }

    public Object born() {
        if (null == borning)
            throw err;
        return borning.born(new Object[0]);
    }

    public JsonEntityField getField(String name) {
        return fieldMap.get(name);
    }
   
    public Method getToJsonMethod() {
        return toJsonMethod;
    }

}
TOP

Related Classes of org.nutz.json.entity.JsonEntity

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.