Package org.nutz.json

Source Code of org.nutz.json.JsonParsing

package org.nutz.json;

import java.io.Reader;
import java.lang.reflect.Array;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.nutz.castor.Castors;
import org.nutz.json.entity.JsonEntity;
import org.nutz.json.entity.JsonEntityField;
import org.nutz.lang.Lang;
import org.nutz.lang.Mirror;

public class JsonParsing {

  Object parse(Type type, Reader reader) {
    Object obj = new JsonCompile().parse(reader);
    return convert(type, obj);
  }

  @SuppressWarnings("unchecked")
  Object convert(Type type, Object obj) {
    if (obj == null)
      return null;
    if (type == null)
      return obj;
    if (obj instanceof Map) {
      return map2Object(type, (Map<String, Object>) obj);
    } else if (obj instanceof List) {
      return list2Object(type, (List<Object>) obj);
    } else {// obj是基本数据类型或String
      return Castors.me().castTo(obj, (Class<?>) type);
    }
  }

  @SuppressWarnings({"rawtypes", "unchecked"})
  Object map2Object(Type type, Map<String, Object> map) {
    Class<?> clazz = Lang.getTypeClass(type);
    Mirror<?> me = Mirror.me(clazz);
    if (Map.class.isAssignableFrom(clazz)) {
      Map re = null;
      if (clazz.isInterface())
        re = new HashMap();
      else
        re = (Map) me.born();
      if (type instanceof ParameterizedType) {
        // 看来有泛型信息哦
        ParameterizedType pt = (ParameterizedType) type;
        Type[] ts = pt.getActualTypeArguments();
        Type tt = null;
        if (ts != null && ts.length > 1)
          tt = Lang.getTypeClass(ts[1]);// TODO 只能做到一层的泛型
        for (Entry<String, Object> entry : map.entrySet()) {
          re.put(entry.getKey(), convert(tt, entry.getValue()));
        }
      } else
        re.putAll(map);
      return re;
    } else { // 看来是Pojo
      JsonEntity jen = Json.getEntity(me.getType());
      Object re = jen.born();
      // 遍历目标对象的全部字段
      for (JsonEntityField jef : jen.getFields()) {
        Object value = map.get(jef.getName());
        if (value == null)
          continue;
        jef.setValue(re, convert(jef.getGenericType(), value));
      }
      return re;
    }
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  Object list2Object(Type type, List<Object> list) {
    Class<?> clazz = Lang.getTypeClass(type);
    Type tt = null;
    if (type instanceof ParameterizedType) {
      ParameterizedType pt = (ParameterizedType) type;
      Type[] ts = pt.getActualTypeArguments();
      if (ts != null && ts.length > 0)
        tt = Lang.getTypeClass(ts[0]);// TODO 只能做到一层的泛型
    }
    if (clazz.isArray()) {// 看来是数组
      List re = new ArrayList(list.size());
      for (Object object : list) {
        re.add(convert(clazz.getComponentType(), object));
      }
      Object ary = Array.newInstance(clazz.getComponentType(), list.size());
      int i = 0;

      for (Iterator it = re.iterator(); it.hasNext();) {
        if (tt != null)
          Array.set(ary, i++, convert(tt, it.next()));
        else
          Array.set(ary, i++, Castors.me().castTo(it.next(), clazz.getComponentType()));
      }
      return ary;
    }
    if (List.class.isAssignableFrom(clazz)) {
      if (tt == null) // 没有泛型信息? 那只好直接返回了
        return list;
      Mirror me = Mirror.me(clazz);
      List re = null;
      if (clazz.isInterface())
        re = new LinkedList();
      else
        re = (List) me.born();
      for (Object object : list) {
        re.add(convert(tt, object));
      }
      return re;
    }
    throw unexpectedType(List.class, clazz);
  }

  private static final RuntimeException unexpectedType(Type expect, Type act) {
    return Lang.makeThrow("expect %s but %s", expect, act);
  }
}
TOP

Related Classes of org.nutz.json.JsonParsing

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.