org.zodiac.sdk.json.to.ObjectToHandler Maven / Gradle / Ivy
Show all versions of zodiac-sdk-json Show documentation
package org.zodiac.sdk.json.to;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetSocketAddress;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import org.zodiac.sdk.json.*;
import org.zodiac.sdk.json.core.JSONContext;
import org.zodiac.sdk.json.core.JSONDefaultConstants;
import org.zodiac.sdk.json.core.JSONNodeDecoderObject;
import org.zodiac.sdk.json.exception.JSONException;
import org.zodiac.sdk.json.ext.ClassWrapper;
import org.zodiac.sdk.json.ext.EnumWrapper;
import org.zodiac.sdk.json.ext.FieldWrapper;
import org.zodiac.sdk.json.util.ClassUtil;
import org.zodiac.sdk.json.util.CollectionUtil;
import org.zodiac.sdk.json.util.NumberUtil;
import org.zodiac.sdk.json.util.StringUtil;
import org.zodiac.sdk.json.util.TypeUtil;
/**
* 对象转换器。
*
* 将 JSONNode 转为 java Object。
*/
public class ObjectToHandler implements ToHandler {
public ObjectToHandler() {
super();
}
@Override
public void handle(JSONContext ctx) throws Exception {
JSONNode o = (JSONNode) ctx.source;
if (null != o) {
ctx.target = analyse(ctx, o, ctx.target_clz, ctx.target_type);
}
}
private Object analyse(JSONContext ctx, JSONNode o, Class> clz, Type type) throws Exception {
if (o == null) {
return null;
}
if (clz != null) {
if (JSONNode.class.isAssignableFrom(clz)) {
return o;
}
}
//提前找到@type类型,便于自定义解码器定位
if(o.isObject() || o.isArray()) {
clz = getTypeByNode(ctx, o, clz);
}
if (clz != null) {
//自定义解析
for(JSONNodeDecoderObject decoder: ctx.options.decoders()) {
if (decoder.isDecodable(clz)) {
return decoder.decode(o, clz);
}
}
}
switch (o.nodeType()) {
case Value:
return analyseVal(ctx, o.nodeData(), clz);
case Object:
//clz = getTypeByNode(ctx, o, clz);
o.remove(ctx.options.getTypePropertyName());//尝试移除类型内容
if (Map.class.isAssignableFrom(clz)) {
return analyseMap(ctx, o, clz, type);
} else if (StackTraceElement.class.isAssignableFrom(clz)) {
String declaringClass = o.get("declaringClass").getString();
if(declaringClass == null){
//todo: 兼容fastjson的序列化
declaringClass = o.get("className").getString();
}
return new StackTraceElement(
declaringClass,
o.get("methodName").getString(),
o.get("fileName").getString(),
o.get("lineNumber").getInt());
} else {
return analyseBean(ctx, o, clz);
}
case Array:
//clz = getTypeByNode(ctx, o, clz);
if (clz.isArray()) {
return analyseArray(ctx, o.nodeData(), clz);
} else {
return analyseCollection(ctx, o, clz, type);
}
default:
return null;
}
}
private boolean is(Class> s, Class> t) {
return s.isAssignableFrom(t);
}
public Object analyseVal(JSONContext ctx, JSONNodeData d, Class> clz) throws Exception {
JSONValue v = d.value;
if (v.type() == JSONValueType.Null) {
return null;
}
if (clz == null) {
return v.getRaw();
}
if (is(Byte.class, clz) || clz == Byte.TYPE) {
return (byte) v.getLong();
} else if (is(Short.class, clz) || clz == Short.TYPE) {
return v.getShort();
} else if (is(Integer.class, clz) || clz == Integer.TYPE) {
return v.getInt();
} else if (is(Long.class, clz) || clz == Long.TYPE) {
return v.getLong();
} else if (is(Float.class, clz) || clz == Float.TYPE) {
return v.getFloat();
} else if (is(Double.class, clz) || clz == Double.TYPE) {
return v.getDouble();
} else if (is(Boolean.class, clz) || clz == Boolean.TYPE) {
return v.getBoolean();
} else if (is(Character.class, clz) || clz == Character.TYPE) {
return v.getChar();
} else if (is(String.class, clz)) {
return v.getString();
} else if (is(java.sql.Timestamp.class, clz)) {
return new java.sql.Timestamp(v.getLong());
} else if (is(java.sql.Date.class, clz)) {
return new java.sql.Date(v.getLong());
} else if (is(java.sql.Time.class, clz)) {
return new java.sql.Time(v.getLong());
} else if (is(Date.class, clz)) {
return v.getDate();
} else if (is(LocalDateTime.class, clz)) {
return v.getDate().toInstant().atZone(JSONDefaultConstants.DEF_TIME_ZONE.toZoneId()).toLocalDateTime();
} else if (is(LocalDate.class, clz)) {
return v.getDate().toInstant().atZone(JSONDefaultConstants.DEF_TIME_ZONE.toZoneId()).toLocalDate();
} else if (is(LocalTime.class, clz)) {
return v.getDate().toInstant().atZone(JSONDefaultConstants.DEF_TIME_ZONE.toZoneId()).toLocalTime();
} else if (is(BigDecimal.class, clz)) {
if (v.type() == JSONValueType.Number) {
if (v.getRawNumber() instanceof BigDecimal) {
return v.getRawNumber();
}
}
return new BigDecimal(v.getString());
} else if (is(BigInteger.class, clz)) {
if (v.type() == JSONValueType.Number) {
if (v.getRawNumber() instanceof BigInteger) {
return v.getRawNumber();
}
}
return new BigInteger(v.getString());
} else if (clz.isEnum()) {
return analyseEnum(ctx, d, clz);
} else if (is(Class.class, clz)) {
return this.getClass().getClassLoader().loadClass(v.getString());
} else if (is(Object.class, clz)) {
return v.getRaw();
} else {
throw new JSONException("Unsupported type " + clz.getName());
}
}
public Object analyseEnum(JSONContext ctx, JSONNodeData d, Class> target) {
EnumWrapper ew = TypeUtil.createEnum(target);
if (d.value.type() == JSONValueType.String) {
return ew.get(d.value.getString());
} else {
return ew.get(d.value.getInt());
}
}
public Object analyseArray(JSONContext ctx, JSONNodeData d, Class> target) throws Exception {
int len = d.array.size();
if (is(byte[].class, target)) {
byte[] val = new byte[len];
for (int i = 0; i < len; i++) {
val[i] = (byte) d.array.get(i).getLong();
}
return val;
} else if (is(short[].class, target)) {
short[] val = new short[len];
for (int i = 0; i < len; i++) {
val[i] = d.array.get(i).getShort();
}
return val;
} else if (is(int[].class, target)) {
int[] val = new int[len];
for (int i = 0; i < len; i++) {
val[i] = d.array.get(i).getInt();
}
return val;
} else if (is(long[].class, target)) {
long[] val = new long[len];
for (int i = 0; i < len; i++) {
val[i] = d.array.get(i).getLong();
}
return val;
} else if (is(float[].class, target)) {
float[] val = new float[len];
for (int i = 0; i < len; i++) {
val[i] = d.array.get(i).getFloat();
}
return val;
} else if (is(double[].class, target)) {
double[] val = new double[len];
for (int i = 0; i < len; i++) {
val[i] = d.array.get(i).getDouble();
}
return val;
} else if (is(boolean[].class, target)) {
boolean[] val = new boolean[len];
for (int i = 0; i < len; i++) {
val[i] = d.array.get(i).getBoolean();
}
return val;
} else if (is(char[].class, target)) {
char[] val = new char[len];
for (int i = 0; i < len; i++) {
val[i] = d.array.get(i).getChar();
}
return val;
} else if (is(String[].class, target)) {
String[] val = new String[len];
for (int i = 0; i < len; i++) {
val[i] = d.array.get(i).getString();
}
return val;
} else if (is(Object[].class, target)) {
Class> c = target.getComponentType();
Object[] val = (Object[]) Array.newInstance(c, len);
for (int i = 0; i < len; i++) {
val[i] = analyse(ctx, d.array.get(i), c, c);
}
return val;
} else {
throw new JSONException("Unsupported type " + target.getName());
}
}
public Object analyseCollection(JSONContext ctx, JSONNode o, Class> clz, Type type) throws Exception {
Collection list = CollectionUtil.createCollection(clz, false);
if (list == null) {
return null;
}
if (o.count() == 2) {
JSONNode o1 = o.get(0);
if (o1.count() == 1 && o1.contains(ctx.options.getTypePropertyName())) { //说明,是有类型的集合
o = o.get(1); //取第二个节点,做为数据节点(第1个为类型节点);
}
}
Type itemType = null;
if (ctx.target_type != null) {
itemType = ClassUtil.getCollectionItemType(type);
}
//解决无法识别的范型
if (itemType != null && "T".equals(itemType.getTypeName())) {
itemType = null;
}
for (JSONNode o1 : o.nodeData().array) {
list.add(analyse(ctx, o1, (Class>) itemType, itemType));
}
return list;
}
public Object analyseMap(JSONContext ctx, JSONNode o, Class> clz, Type type) throws Exception {
Map