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; } }