All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.zodiac.sdk.json.from.ObjectFromHandler Maven / Gradle / Ivy

There is a newer version: 1.5.17
Show newest version
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;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy