org.zodiac.sdk.json.from.ObjectFromHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of zodiac-sdk-json Show documentation
Show all versions of zodiac-sdk-json Show documentation
Zodiac SDK JSON(JavaScript Object Notation)
package org.zodiac.sdk.json.from;
import java.io.File;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.sql.Clob;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import org.zodiac.sdk.json.JSONNode;
import org.zodiac.sdk.json.core.*;
import org.zodiac.sdk.json.ext.ClassWrapper;
import org.zodiac.sdk.json.ext.FieldWrapper;
import org.zodiac.sdk.json.util.SQLUtil;
/**
* 对象转换器(将 java Object 转为 JSONNode)
*/
public class ObjectFromHandler implements FromHandler {
@Override
public void handle(JSONContext ctx) {
ctx.target = analyse(ctx.options, ctx.source); //如果是null,会返回 JSONNode.Null
}
private JSONNode analyse(JSONOptions opt, Object source) {
JSONNode rst = new JSONNode(opt);
if (source == null) {
return rst;
}
Class> clz = source.getClass();
//尝试自定义编码
for(JSONNodeEncoderObject encoder: opt.encoders()) {
if (encoder.isEncodable(clz)) {
encoder.encode(source, rst);
return rst;
}
}
if (source instanceof JSONNode) {
rst.val(source);
} else if (source instanceof String) {
rst.val().setString((String) source);
} else if (source instanceof Date) {
rst.val().setDate((Date) source);
} else if(source instanceof LocalDateTime){
Instant instant = ((LocalDateTime)source).atZone(JSONDefaultConstants.DEF_TIME_ZONE.toZoneId()).toInstant();
rst.val().setDate(new Date((instant.getEpochSecond() * 1000) + (instant.getNano() / 1000_000)));
} else if(source instanceof LocalDate){
Instant instant = ((LocalDate)source).atTime(LocalTime.MIN).atZone(JSONDefaultConstants.DEF_TIME_ZONE.toZoneId()).toInstant();
rst.val().setDate(new Date(instant.getEpochSecond() * 1000));
} else if(source instanceof LocalTime){
Instant instant = ((LocalTime)source).atDate(LocalDate.of(1970,1,1)).atZone(JSONDefaultConstants.DEF_TIME_ZONE.toZoneId()).toInstant();
rst.val().setDate(new Date(instant.getEpochSecond() * 1000));
} else if (source instanceof Boolean) {
rst.val().setBool((boolean) source);
} else if (source instanceof Number) {
rst.val().setNumber((Number) source);
} else if (source instanceof Throwable) { //新补充的类型
analyseBean(opt, rst, clz, source);
} else if (analyseArray(opt, rst, clz, source)) { //新补充的类型::可适用任何数组
} else if (clz.isEnum()) { //新补充的类型
Enum em = (Enum) source;
if (opt.hasFeature(Feature.EnumUsingName)) {
rst.val().setString(em.name());
} else {
rst.val().setNumber(em.ordinal());
}
} else if (source instanceof Map) {
//为序列化添加特性支持
if (opt.hasFeature(Feature.WriteClassName)) {
typeSet(opt, rst, clz);
}
rst.asObject();
Map map = ((Map) source);
for (Object k : map.keySet()) {
if (k != null) {
rst.setNode(k.toString(), analyse(opt, map.get(k)));
}
}
} else if (source instanceof Iterable) {
rst.asArray();
JSONNode ary =rst;
//为序列化添加特性支持
if (opt.hasFeature(Feature.WriteArrayClassName)) {
rst.add(typeSet(opt,new JSONNode(opt), clz));
ary = rst.addNew().asArray();
}
for (Object o : ((Iterable) source)) {
ary.addNode(analyse(opt, o));
}
} else if (source instanceof Enumeration) { //新补充的类型
rst.asArray();
Enumeration o = (Enumeration) source;
while (o.hasMoreElements()) {
rst.addNode(analyse(opt, o.nextElement()));
}
} else {
String clzName = clz.getName();
if(clzName.endsWith(".Undefined")){
rst.val().setNull();
}else {
if (analyseOther(opt, rst, clz, source) == false) {
if (clzName.startsWith("jdk.") == false) {
analyseBean(opt, rst, clz, source);
}
}
}
}
return rst;
}
private JSONNode typeSet(JSONOptions cfg, JSONNode o, Class> clz) {
return o.set(cfg.getTypePropertyName(), clz.getName());
}
private boolean analyseArray(JSONOptions cfg, JSONNode rst, Class> clz, Object obj) {
if (obj instanceof Object[]) {
rst.asArray();
for (Object o : ((Object[]) obj)) {
rst.addNode(analyse(cfg, o));
}
} else if (obj instanceof byte[]) {
rst.asArray();
for (byte o : ((byte[]) obj)) {
rst.addNode(analyse(cfg, o));
}
} else if (obj instanceof short[]) {
rst.asArray();
for (short o : ((short[]) obj)) {
rst.addNode(analyse(cfg, o));
}
} else if (obj instanceof int[]) {
rst.asArray();
for (int o : ((int[]) obj)) {
rst.addNode(analyse(cfg, o));
}
} else if (obj instanceof long[]) {
rst.asArray();
for (long o : ((long[]) obj)) {
rst.addNode(analyse(cfg, o));
}
} else if (obj instanceof float[]) {
rst.asArray();
for (float o : ((float[]) obj)) {
rst.addNode(analyse(cfg, o));
}
} else if (obj instanceof double[]) {
rst.asArray();
for (double o : ((double[]) obj)) {
rst.addNode(analyse(cfg, o));
}
} else if (obj instanceof boolean[]) {
rst.asArray();
for (boolean o : ((boolean[]) obj)) {
rst.addNode(analyse(cfg, o));
}
} else if (obj instanceof char[]) {
rst.asArray();
for (char o : ((char[]) obj)) {
rst.addNode(analyse(cfg, o));
}
} else {
return false;
}
return true;
}
private boolean analyseBean(JSONOptions cfg, JSONNode rst, Class> clz, Object obj) {
rst.asObject();
/*为序列化添加特性支持*/
if (cfg.hasFeature(Feature.WriteClassName)) {
rst.set(cfg.getTypePropertyName(), clz.getName());
}
/*遍历每个字段*/
Collection list = ClassWrapper.get(clz).fieldAllWraps();
for (FieldWrapper f : list) {
if (f.isSerialize() == false) {
/*不做序列化*/
continue;
}
Object val = f.getValue(obj);
/*如果是null*/
if (val == null) {
/*null string 是否以 空字符处理*/
if (cfg.hasFeature(Feature.StringFieldInitEmpty) && f.genericType == String.class) {
rst.setNode(f.getName(), analyse(cfg, ""));
continue;
}
/*null是否输出*/
if (cfg.hasFeature(Feature.SerializeNulls)) {
rst.setNode(f.getName(), analyse(cfg, null));
}
continue;
}
/*如果是自引用*/
if (val.equals(obj)) {
continue;
}
if (f.getFormat() != null || f.getFormat().length() > 0) {
if (val instanceof Date) {
DateFormat format = new SimpleDateFormat(f.getFormat());
String val2 = format.format((Date) val);
rst.set(f.getName(), val2);
continue;
}
if (val instanceof Number) {
NumberFormat format = new DecimalFormat(f.getFormat());
String val2 = format.format(val);
rst.set(f.getName(), val2);
continue;
}
}
rst.setNode(f.getName(), analyse(cfg, val));
}
return true;
}
private boolean analyseOther(JSONOptions cfg, JSONNode rst, Class> clz, Object obj) {
if (obj instanceof SimpleDateFormat) {
rst.set(cfg.getTypePropertyName(), clz.getName());
rst.set("val", ((SimpleDateFormat) obj).toPattern());
} else if (clz == Class.class) {
rst.val().setString(clz.getName());
} else if (obj instanceof InetSocketAddress) {
InetSocketAddress address = (InetSocketAddress) obj;
InetAddress inetAddress = address.getAddress();
rst.set("address", inetAddress.getHostAddress());
rst.set("port", address.getPort());
} else if (obj instanceof File) {
rst.val().setString(((File) obj).getPath());
} else if (obj instanceof InetAddress) {
rst.val().setString(((InetAddress) obj).getHostAddress());
} else if (obj instanceof TimeZone) {
rst.val().setString(((TimeZone) obj).getID());
} else if (obj instanceof Currency) {
rst.val().setString(((Currency) obj).getCurrencyCode());
} else if (obj instanceof Iterator) {
rst.asArray();
((Iterator) obj).forEachRemaining(v -> {
rst.add(analyse(cfg, v));
});
} else if (obj instanceof Map.Entry) {
Map.Entry kv = (Map.Entry) obj;
Object k = kv.getKey();
Object v = kv.getValue();
rst.asObject();
if (k != null) {
rst.set(k.toString(), analyse(cfg, v));
}
} else if (obj instanceof Calendar) {
rst.val().setDate(((Calendar) obj).getTime());
} else if (obj instanceof Clob) {
rst.val().setString(SQLUtil.clobToString((Clob) obj));
} else if (obj instanceof Appendable) {
rst.val().setString(obj.toString());
} else {
return false;
}
return true;
}
}