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

com.loocme.sys.datastruct.Var Maven / Gradle / Ivy

There is a newer version: 7.1.11
Show newest version
package com.loocme.sys.datastruct;

import java.math.BigDecimal;
import java.util.*;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.loocme.sys.constance.RegConst;
import com.loocme.sys.exception.WeektypeCastException;
import com.loocme.sys.util.ListUtil;
import com.loocme.sys.util.PatternUtil;
import com.loocme.sys.util.StringUtil;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;

/**
 * @author liuchi
 */
@Slf4j
public class Var implements java.io.Serializable
{

    private static final String ROUTER_PATH_EXP = "(?<=(^|\\.|\\[))([^\\.\\[\\]]+)(?=(\\.|\\]|\\[|$))";
    private static final String KEY_ARRAY_START = "[";
    private static final String KEY_ARRAY_END = "]";
    private static final String KEY_ARRAY_SIZE = "size";
    private static final String REG_STRING_ISOBJECT = "^\\s*\\{.*\\}\\s*$";
    private static final String REG_STRING_ISARRAY = "^\\s*\\[.*\\]\\s*$";

    public static Var fromObject(Object value)
    {
        if (null == value)
        {
            return new WeekUndefined();
        }

        if (value instanceof Var)
        {
            return (Var) value;
        }

        if (value instanceof Map)
        {
            return new WeekObject(value);
        }

        if (value instanceof List)
        {
            return new WeekArray(value);
        }

        if (value instanceof Object[])
        {
            return new WeekArray(value);
        }

        if (value instanceof Integer || value instanceof Byte
                || value instanceof Long || value instanceof Float
                || value instanceof Double || value instanceof Character
                || value instanceof Date || value instanceof Boolean
                || value instanceof BigDecimal || value instanceof Class)
        {
            return new WeekSimple(value);
        }

        if (value instanceof String)
        {
            return new WeekSimple(value);
            /**
             * String valueStr = (String) value; if
             * (PatternUtil.isMatch(valueStr, "^\\s*\\{.*\\}\\s*$")) { valueStr
             * = valueStr.replaceAll(":null", ":\"\""); JSONObject jobj =
             * JSONObject.fromObject(valueStr); return fromJson(jobj); } else if
             * (PatternUtil.isMatch(valueStr, "^\\s*\\[.*\\]\\s*$")) { valueStr
             * = valueStr.replaceAll(":null", ":\"\""); JSONArray jarr =
             * JSONArray.fromObject(valueStr); return fromJson(jarr); } else if
             * (PatternUtil.isMatch(valueStr,
             * "^\\s*<\\?xml version=\"1\\.0\" encoding.+\\?>\\s*.+$")) { return
             * fromXml(valueStr); } else { return new WeekSimple(value); }
             */
        }

        return new WeekSimple(value);
        // return new WeekObject(ReflectUtil.objToMap(value));
    }

    public static Var fromXml(String xml)
    {
        try
        {
            // 解析xml
            Document doc = DocumentHelper.parseText(xml);
            // 获取根节点
            Element rootEle = doc.getRootElement();
            return fromXml(rootEle);
        }
        catch (DocumentException e)
        {
            log.error("xml解析失败. ", e);
            e.printStackTrace();
        }
        return Var.newUndefined();
    }

    private static Var fromXml(Element ele)
    {
        WeekObject obj = new WeekObject();
        // 获取文本节点
        String text = ele.getTextTrim();
        if (StringUtil.isNotNull(text))
        {
            obj.setValue("text", text);
        }
        // 获取所有属性
        List attrList = ele.attributes();
        if (ListUtil.isNotNull(attrList))
        {
            Attribute attr = null;
            for (int i = 0; i < attrList.size(); i++)
            {
                attr = attrList.get(i);
                obj.setValue("@" + attr.getName(), attr.getValue());
            }
        }
        // 获取子节点
        List subEleList = ele.elements();
        if (ListUtil.isNotNull(subEleList))
        {
            Element tempEle = null;
            for (int i = 0; i < subEleList.size(); i++)
            {
                tempEle = subEleList.get(i);
                obj.setValue(tempEle.getName(), fromXml(tempEle));
            }
        }
        return obj;
    }

    public static Var fromTextXml(String xml)
    {
        try
        {
            // 解析xml
            Document doc = DocumentHelper.parseText(xml);
            // 获取根节点
            Element rootEle = doc.getRootElement();
            return fromTextXml(rootEle);
        }
        catch (DocumentException e)
        {
            log.error("xml解析失败. ", e);
            e.printStackTrace();
        }
        return Var.newUndefined();
    }

    private static Var fromTextXml(Element ele)
    {
        // 获取子节点
        List subEleList = ele.elements();
        if (ListUtil.isNotNull(subEleList))
        {
            WeekObject obj = new WeekObject();
            Element tempEle = null;
            for (int i = 0; i < subEleList.size(); i++)
            {
                tempEle = subEleList.get(i);
                obj.set(ele.getName() + KEY_ARRAY_START + i + "]." + tempEle.getName(), fromTextXml(tempEle));
            }
            return obj;
        }
        else
        {
            // 当做文本节点
            return new WeekSimple(ele.getTextTrim());
        }
    }

    public static Var fromJson(String json)
    {
        if (PatternUtil.isMatch(json, REG_STRING_ISOBJECT))
        {
            JSONObject jobj = JSONObject.parseObject(json);
            return fromJson(jobj);
        }
        else if (PatternUtil.isMatch(json, REG_STRING_ISARRAY))
        {
            JSONArray jarr = JSONArray.parseArray(json);
            return fromJson(jarr);
        }
        return Var.newUndefined();
    }

    private static Var fromJson(JSONObject jobj)
    {
        if (null == jobj)
        {
            return Var.newUndefined();
        }

        WeekObject ret = new WeekObject();
        Iterator it = jobj.keySet().iterator();
        while (it.hasNext())
        {
            String key = it.next();
            Object value = jobj.get(key);
            if (null == value)
            {
                ret.setValue(key, new WeekUndefined());
            }
            else if (value instanceof JSONObject)
            {
                ret.setValue(
                        key,
                        (((JSONObject) value).isEmpty()) ? Var
                                .newUndefined() : fromJson((JSONObject) value));
            }
            else if (value instanceof JSONArray)
            {
                ret.setValue(key, fromJson((JSONArray) value));
            }
            else
            {
                ret.setValue(key, value);
            }
        }
        return ret;
    }

    private static Var fromJson(JSONArray jarr)
    {
        if (null == jarr)
        {
            return Var.newUndefined();
        }

        WeekArray ret = new WeekArray();
        for (int i = 0; i < jarr.size(); i++)
        {
            Object value = jarr.get(i);
            if (null == value)
            {
                ret.setValue(i, new WeekUndefined());
            }
            else if (value instanceof JSONObject)
            {
                ret.setValue(
                        i,
                        (((JSONObject) value).isEmpty()) ? Var
                                .newUndefined() : fromJson((JSONObject) value));
            }
            else if (value instanceof JSONArray)
            {
                ret.setValue(i, fromJson((JSONArray) value));
            }
            else
            {
                ret.setValue(i, value);
            }
        }
        return ret;
    }

    public static Var fromYamlFetchOne(String content)
    {
        List ret = fromYamlFetchAll(content);
        if (ListUtil.isNull(ret))
        {
            return Var.newUndefined();
        }
        return ret.get(0);
    }

    public static List fromYamlFetchAll(String content)
    {
        List ret = new ArrayList<>();
        Yaml yaml = new Yaml();
        Iterable iterable = yaml.loadAll(content);
        for (Object o: iterable)
        {
            Var var = Var.fromObject(o);
            ret.add(var);
        }
        return ret;
    }

    public static Var newObject()
    {
        return new WeekObject();
    }

    public static Var newArray()
    {
        return new WeekArray();
    }

    public static Var newSimple()
    {
        return new WeekSimple();
    }

    public static Var newSimple(Object value)
    {
        return new WeekSimple(value);
    }

    public static Var newUndefined()
    {
        return new WeekUndefined();
    }

    public boolean isObject()
    {
        return false;
    }

    public boolean isArray()
    {
        return false;
    }

    public boolean isBasicType()
    {
        return false;
    }

    public boolean isUndefined()
    {
        return false;
    }

    public boolean isNull()
    {
        return true;
    }
    
    public void foreach(IVarForeachHandler handler)
    {

    }

    public void clear()
    {

    }

    public Object getObject()
    {
        return null;
    }
    
    public void addAll(Var var)
    {

    }
    
    public String toXml(boolean simple)
    {
        return null;
    }

    public String toYaml()
    {
        DumperOptions options = new DumperOptions();
        options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
        Yaml yaml = new Yaml(options);
        return yaml.dumpAsMap(this.getObjectMap(false));
    }

    public static String toYaml(List vars)
    {
        if (ListUtil.isNull(vars))
        {
            return null;
        }
        return toYaml(vars.toArray(new Var[vars.size()]));
    }

    public static String toYaml(Var... vars)
    {
        DumperOptions options = new DumperOptions();
        options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
        Yaml yaml = new Yaml(options);
        List> list = new ArrayList<>();
        for (Var var : vars)
        {
            if (null == var || var.isNull())
            {
                continue;
            }
            list.add(var.getObjectMap(false));
        }
        return yaml.dumpAll(list.iterator());
    }

    public Var myClone()
    {
        return Var.fromObject(this.getObject());
    }

    public void setObject(Object value)
    {
        if (null == value)
        {
            this.clear();
        }
        else if (value instanceof Map)
        {
            WeekObject obj = (WeekObject) this;
            obj.setValue(value);
        }
        else if (value instanceof List)
        {
            WeekArray arr = (WeekArray) this;
            arr.setValue(value);
        }
        else
        {
            WeekSimple simple = (WeekSimple) this;
            simple.setValue(value);
        }
    }

    public void setByIndex(int index, Object value)
    {
        this.setByKey(index + "", value);
    }

    public void setByKey(String key, Object value)
    {
        if (this.isArray())
        {
            if (!PatternUtil.isMatch(key, RegConst.INT))
            {
                try
                {
                    throw new WeektypeCastException("C0");
                }
                catch (WeektypeCastException e)
                {
                    log.error("类型转换失败. ", e);
                    e.printStackTrace();
                }
                return;
            }
            WeekArray arr = (WeekArray) this;
            arr.setValue(StringUtil.getInteger(key), Var.fromObject(value));
        }
        else if (this.isObject())
        {
            WeekObject obj = (WeekObject) this;
            obj.setValue(key, Var.fromObject(value));
        }
        else
        {
            try
            {
                throw new WeektypeCastException("C0");
            }
            catch (WeektypeCastException e)
            {
                log.error("类型转换失败. ", e);
                e.printStackTrace();
            }
        }
    }

    public void set(String path, Object value)
    {
        Var lastWt = this.mkdirPath(path);

        List groupList = PatternUtil
                .getMatches(path, ROUTER_PATH_EXP);
        String[] tempGroup = groupList.get(groupList.size() - 1);
        lastWt.setByKey(tempGroup[2], Var.fromObject(value));
    }

    public void add(Object value)
    {
        if (value instanceof List)
        {
            try
            {
                throw new WeektypeCastException("C0");
            }
            catch (WeektypeCastException e)
            {
                log.error("类型转换失败. ", e);
                e.printStackTrace();
            }
            return;
        }

        WeekArray arr = (WeekArray) this;
        arr.addValue(value);
    }

    public Var getByIndex(int index)
    {
        return this.getByKey(index + "");
    }

    public Var getByKey(String key)
    {
        if (this.isArray())
        {
            WeekArray arr = (WeekArray) this;
            if (KEY_ARRAY_SIZE.equals(key))
            {
                return Var.newSimple(arr.getSize());
            }
            if (!PatternUtil.isMatch(key, RegConst.INT))
            {
                try
                {
                    throw new WeektypeCastException("C0");
                }
                catch (WeektypeCastException e)
                {
                    log.error("类型转换失败. ", e);
                    e.printStackTrace();
                }
                return Var.newUndefined();
            }

            return arr.getValue(StringUtil.getInteger(key));
        }
        else if (this.isObject())
        {
            WeekObject obj = (WeekObject) this;
            return obj.getValue(key);
        }
        else
        {
            try
            {
                throw new WeektypeCastException("C0");
            }
            catch (WeektypeCastException e)
            {
                log.error("类型转换失败. ", e);
                e.printStackTrace();
            }
            return Var.newUndefined();
        }
    }

    public Var get(String path)
    {
        if (StringUtil.isNull(path))
        {
            try
            {
                throw new WeektypeCastException("C1");
            }
            catch (WeektypeCastException e)
            {
                log.error("类型转换失败. ", e);
                e.printStackTrace();
            }
            return Var.newUndefined();
        }

        if (this.isNull())
        {
            return Var.newUndefined();
        }

        List groupList = PatternUtil
                .getMatches(path, ROUTER_PATH_EXP);

        Var wt = this;
        String[] tempGroup = null;
        int size = groupList.size();
        for (int i = 0; i < size; i++)
        {
            tempGroup = groupList.get(i);
            if (KEY_ARRAY_START.equals(tempGroup[1]) && KEY_ARRAY_END.equals(tempGroup[3]))
            {
                if (!wt.isArray())
                {
                    return Var.newUndefined();
                }
                wt = wt.getByIndex(StringUtil.getInteger(tempGroup[2]));
            }
            else
            {
                if (!wt.isObject() && !wt.isArray())
                {
                    return Var.newUndefined();
                }
                wt = wt.getByKey(tempGroup[2]);
            }
            if (null == wt || wt.isNull())
            {
                return Var.newUndefined();
            }
        }
        return wt;
    }

    public String getString(String path)
    {
        Var var = this.get(path);
        return var.isNull() ? "" : var.toString();
    }
    
    public int getInt(String path)
    {
        return StringUtil.getInteger(this.getString(path));
    }

    public long getLong(String path)
    {
        return StringUtil.getLong(this.getString(path));
    }
    
    public float getFloat(String path)
    {
        return StringUtil.getFloat(this.getString(path));
    }
    
    public double getDouble(String path)
    {
        return StringUtil.getDouble(this.getString(path));
    }
    
    public WeekArray getArray(String path)
    {
        Var var = this.get(path);
        if (var.isArray())
        {
            return (WeekArray) var;
        }
        return new WeekArray();
    }

    public boolean getBoolean(String path)
    {
        Var var = this.get(path);
        if (var.isBasicType())
        {
            Object obj = var.getObject();
            if (obj instanceof Boolean)
            {
                return (Boolean) var.getObject();
            }
            if (obj instanceof String)
            {
                return StringUtil.getBoolean((String) var.getObject());
            }
            if (obj instanceof Number)
            {
                return StringUtil.getDouble(obj.toString()) != 0;
            }
        }
        return false;
    }

    private Var removeByKey(String key)
    {
        if (this.isNull())
        {
            return this;
        }

        if (this.isArray())
        {
            if (!PatternUtil.isMatch(key, RegConst.INT))
            {
                try
                {
                    throw new WeektypeCastException("C0");
                }
                catch (WeektypeCastException e)
                {
                    log.error("类型转换失败. ", e);
                    e.printStackTrace();
                }
                return Var.newUndefined();
            }
            WeekArray arr = (WeekArray) this;
            return arr.removeValue(StringUtil.getInteger(key));
        }
        else if (this.isObject())
        {
            WeekObject obj = (WeekObject) this;
            return obj.removeValue(key);
        }
        else
        {
            try
            {
                throw new WeektypeCastException("C0");
            }
            catch (WeektypeCastException e)
            {
                log.error("类型转换失败. ", e);
                e.printStackTrace();
            }
            return Var.newUndefined();
        }
    }

    private Var removeByIndex(int index)
    {
        return this.removeByKey(index + "");
    }

    public Var remove(String path)
    {
        if (StringUtil.isNull(path))
        {
            try
            {
                throw new WeektypeCastException("C1");
            }
            catch (WeektypeCastException e)
            {
                log.error("类型转换失败. ", e);
                e.printStackTrace();
            }
            return Var.newUndefined();
        }

        List groupList = PatternUtil
                .getMatches(path, ROUTER_PATH_EXP);

        Var wt = this;
        int size = groupList.size() - 1;
        if (0 < size)
        {
            StringBuffer parentPath = new StringBuffer();
            for (int i = 0; i < groupList.size() - 1; i++)
            {
                parentPath.append(groupList.get(i)[1]).append(
                        groupList.get(i)[2]);
            }
            wt = this.get(parentPath.toString());
        }
        if (null == wt)
        {
            return null;
        }

        return wt.removeByKey(groupList.get(size)[2]);
    }

    private Var mkdirPath(String path)
    {
        if (StringUtil.isNull(path))
        {
            try
            {
                throw new WeektypeCastException("C1");
            }
            catch (WeektypeCastException e)
            {
                log.error("类型转换失败. ", e);
                e.printStackTrace();
            }
            return Var.newUndefined();
        }

        List groupList = PatternUtil
                .getMatches(path, ROUTER_PATH_EXP);

        Var wt = this;
        String[] tempGroup = null;
        int size = groupList.size() - 1;
        for (int i = 0; i < size; i++)
        {
            tempGroup = groupList.get(i);
            Var tempWt = null;
            if (KEY_ARRAY_START.equals(tempGroup[1]) && KEY_ARRAY_END.equals(tempGroup[3]))
            {
                tempWt = wt.getByIndex(StringUtil.getInteger(tempGroup[2]));
            }
            else
            {
                tempWt = wt.getByKey(tempGroup[2]);
            }
            if (null == tempWt || tempWt.isNull())
            {
                if (KEY_ARRAY_START.equals(groupList.get(i + 1)[1])
                        && KEY_ARRAY_END.equals(groupList.get(i + 1)[3]))
                {
                    tempWt = new WeekArray();
                }
                else
                {
                    tempWt = new WeekObject();
                }
                if (KEY_ARRAY_START.equals(tempGroup[1]) && KEY_ARRAY_END.equals(tempGroup[3]))
                {
                    wt.setByIndex(StringUtil.getInteger(tempGroup[2]), tempWt);
                }
                else
                {
                    wt.setByKey(tempGroup[2], tempWt);
                }
            }
            wt = tempWt;
        }

        if (KEY_ARRAY_START.equals(groupList.get(size)[1])
                && KEY_ARRAY_END.equals(groupList.get(size)[3]))
        {
            wt.setByIndex(StringUtil.getInteger(groupList.get(size)[2]),
                    new WeekUndefined());
        }
        else
        {
            wt.setByKey(groupList.get(size)[2], new WeekUndefined());
        }

        return wt;
    }

    public boolean contains(String path)
    {
        if (StringUtil.isNull(path))
        {
            try
            {
                throw new WeektypeCastException("C1");
            }
            catch (WeektypeCastException e)
            {
                log.error("类型转换失败. ", e);
                e.printStackTrace();
            }
            return false;
        }

        if (this.isNull() || this.isBasicType())
        {
            return false;
        }

        List groupList = PatternUtil
                .getMatches(path, ROUTER_PATH_EXP);

        Var wt = this;
        String[] tempGroup = null;
        int size = groupList.size();
        for (int i = 0; i < size; i++)
        {
            tempGroup = groupList.get(i);
            if (KEY_ARRAY_START.equals(tempGroup[1]) && KEY_ARRAY_END.equals(tempGroup[3]))
            {
                if (!wt.isArray())
                {
                    return false;
                }
                wt = wt.getByIndex(StringUtil.getInteger(tempGroup[2]));
            }
            else
            {
                if (!wt.isObject())
                {
                    return false;
                }
                wt = wt.getByKey(tempGroup[2]);
            }
            if (null == wt || wt.isUndefined())
            {
                return false;
            }
        }
        return !wt.isUndefined();
    }

    public Map getObjectMap()
    {
        return this.getObjectMap(false);
    }

    @SuppressWarnings("unchecked")
    public Map getObjectMap(boolean deep)
    {
        if (!this.isObject())
        {
            try
            {
                throw new WeektypeCastException("C0");
            } catch (WeektypeCastException e)
            {
                log.error("类型转换失败. ", e);
                e.printStackTrace();
            }
            return null;
        }

        if (!deep)
        {
            Object obj = this.getObject();
            if (obj instanceof Map)
            {
                return (Map) obj;
            }
            else
            {
                return null;
            }
        }

        Map jmap = new HashMap<>();
        this.foreach(new IVarForeachHandler()
        {
            @Override
            public void execute(String key, Var value)
            {
                if (value.isNull())
                {
                    jmap.put(key, value.toString());
                }
                else if (value.isBasicType())
                {
                    jmap.put(key, ((WeekSimple) value).getValue());
                }
                else if (value.isObject())
                {
                    jmap.put(key, value.getObjectMap(true));
                }
                else if (value.isArray())
                {
                    jmap.put(key, value.getObjectList(true));
                }
            }
        });
        return jmap;
    }

    public List getObjectList()
    {
        return this.getObjectList(false);
    }

    @SuppressWarnings("unchecked")
    public List getObjectList(boolean deep)
    {
        if (!this.isArray())
        {
            try
            {
                throw new WeektypeCastException("C0");
            }
            catch (WeektypeCastException e)
            {
                log.error("类型转换失败. ", e);
                e.printStackTrace();
            }
            return null;
        }

        if (!deep)
        {
            Object obj = this.getObject();
            if (obj instanceof List)
            {
                return (List) this.getObject();
            }
            else
            {
                return null;
            }
        }

        List jlist = new ArrayList<>();
        this.foreach(new IVarForeachHandler()
        {
            @Override
            public void execute(String idx, Var value)
            {
                if (value.isNull())
                {
                    jlist.add(value.toString());
                }
                else if (value.isBasicType())
                {
                    jlist.add(((WeekSimple) value).getValue());
                }
                else if (value.isObject())
                {
                    jlist.add(value.getObjectMap(true));
                }
                else if (value.isArray())
                {
                    jlist.add(value.getObjectList(true));
                }
            }
        });

        return jlist;
    }

    public String getConditionString()
    {
        if (this.isNull() || this.isObject() || this.isArray())
        {
            return "null";
        }

        Object value = this.getObject();
        if (value instanceof Integer || value instanceof Byte
                || value instanceof Long || value instanceof Float
                || value instanceof Double || value instanceof Boolean
                || value instanceof BigDecimal)
        {
            return value.toString();
        }
        return "'" + value.toString() + "'";
    }
}