package org.nutz.mapl.impl.compile;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.nutz.json.Json;
import org.nutz.json.entity.JsonEntity;
import org.nutz.json.entity.JsonEntityField;
import org.nutz.lang.FailToGetValueException;
import org.nutz.lang.Mirror;
import org.nutz.mapl.MaplCompile;
/**
* 将对象理解成Map+List
*
* @author juqkai(juqkai@gmail.com)
*/
public class ObjCompileImpl implements MaplCompile<Object> {
private Map<Object, Object> memo = new HashMap<Object, Object>();
@SuppressWarnings("rawtypes")
public Object parse(Object obj) {
if (null == obj) {
return null;
} else if (obj instanceof ObjCompileImpl) {
return ((ObjCompileImpl) obj).parse(null);
} else if (obj instanceof Class) {
return obj;
} else if (obj instanceof Mirror) {
return ((Mirror<?>) obj).getType().getName();
} else {
Mirror mr = Mirror.me(obj.getClass());
// 枚举
if (mr.isEnum()) {
return obj;
}
// 数字,布尔等
else if (mr.isNumber() || mr.isBoolean()) {
return obj;
}
// 字符串
else if (mr.isStringLike() || mr.isChar()) {
return obj;
}
// 日期时间
else if (mr.isDateTimeLike()) {
return obj;
}
// 其他
else {
// 既然到了这里, 那么断定它只有List, Array, Map, Object这4种类型
// 是否已经存在(循环引用)
if (memo.containsKey(obj)) {
return memo.get(obj);
} else {
// 这里使用了一个小小的占坑技巧,
if (obj instanceof Collection || obj.getClass().isArray()) {
List<Object> list = new ArrayList<Object>();
memo.put(obj, list);
// 集合
if (obj instanceof Collection) {
return coll2Json((Collection) obj, list);
}
// 数组
return array2Json(obj, list);
} else {
Map<String, Object> map = new HashMap<String, Object>();
memo.put(obj, map);
// Map
if (obj instanceof Map) {
return map2Json((Map) obj, map);
}
// 普通 Java 对象
return pojo2Json(obj, map);
}
}
}
}
}
static class Pair {
public Pair(String name, Object value) {
this.name = name;
this.value = value;
}
String name;
Object value;
}
@SuppressWarnings({"unchecked", "rawtypes"})
private Map<String, Object> map2Json(Map map, Map<String, Object> valMap) {
if (null == map)
return null;
ArrayList<Pair> list = new ArrayList<Pair>(map.size());
Set<Entry<?, ?>> entrySet = map.entrySet();
for (Entry entry : entrySet) {
String name = null == entry.getKey() ? "null" : entry.getKey().toString();
Object value = entry.getValue();
list.add(new Pair(name, value));
}
return writeItem(list, valMap);
}
private Map<String, Object> pojo2Json(Object obj, Map<String, Object> map) {
if (null == obj)
return null;
Class<? extends Object> type = obj.getClass();
JsonEntity jen = Json.getEntity(Mirror.me(type));
List<JsonEntityField> fields = jen.getFields();
ArrayList<Pair> list = new ArrayList<Pair>(fields.size());
for (JsonEntityField jef : fields) {
String name = jef.getName();
try {
Object value = jef.getValue(obj);
if (null != value) {
// 递归
Mirror<?> mirror = Mirror.me(value);
if (mirror.isPojo()) {
value = parse(value);
}
}
// 加入输出列表 ...
list.add(new Pair(name, value));
}
catch (FailToGetValueException e) {}
}
return writeItem(list, map);
}
private Map<String, Object> writeItem(List<Pair> list, Map<String, Object> map) {
for (Pair p : list) {
map.put(p.name, p.value);
}
return map;
}
private List<Object> array2Json(Object obj, List<Object> list) {
int len = Array.getLength(obj);
for (int i = 0; i < len; i++) {
list.add(parse(Array.get(obj, i)));
}
return list;
}
@SuppressWarnings("rawtypes")
private List<Object> coll2Json(Collection iterable, List<Object> list) {
for (Iterator<?> it = iterable.iterator(); it.hasNext();) {
list.add(parse(it.next()));
}
return list;
}
}