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

com.iqiny.silly.common.util.SillyMapUtils Maven / Gradle / Ivy

The newest version!
/*
 *  Copyright  iqiny.com
 *
 *  https://gitee.com/iqiny/silly
 *
 *  project name:silly-common
 *  project description:top silly project pom.xml file
 */
package com.iqiny.silly.common.util;

import com.iqiny.silly.common.SillyConstant;
import com.iqiny.silly.common.exception.SillyException;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * MapUtils
 */
public abstract class SillyMapUtils {

    /**
     * 属性名称拼接串
     */
    public static final String FIELD_NAME_APPEND = ".";
    /**
     * 属性名称裁剪串
     */
    public static final String FIELD_NAME_SPLIT = "\\.";
    
    /**
     * 设置Map 键-值
     *
     * @param map
     * @param key   支持深层命名如:entity.user.loginName / entity[1][office].code
     * @param value
     * @return 原先数据值 或 null
     */
    public static  T put(final Map map, String key, Object value) {
        List names = resolvingFieldName(key);
        return put(map, names, value);
    }

    public static  T putLayerKey(final Map map, Object value, Serializable... layerKeys) {
        return put(map, new ArrayList<>(Arrays.asList(layerKeys)), value);
    }

    @SuppressWarnings("all")
    public static  T put(final Map map, List names, Object value) {
        if (map == null) {
            return null;
        }

        if (names.isEmpty()) {
            return null;
        }

        synchronized (map) {
            Serializable preName = names.get(0);
            Object preObj = map;
            for (int i = 0; i < names.size(); i++) {
                Object currentObj = null;
                boolean lastNameFlag = (names.size() == (i + 1));
                Serializable name = names.get(i);
                if (!lastNameFlag) {
                    // 获取值并设置空值过程
                    if (name instanceof Integer) {
                        if (preObj instanceof List) {
                            // 若为List 则设置值
                            Integer index = (Integer) name;
                            List list = (List) preObj;
                            if (index >= list.size()) {
                                currentObj = null;
                            } else {
                                currentObj = list.get(index);
                            }
                        } else {
                            // 若不为List 则抛出异常
                            throw new SillyException("数据设置值数据类型错误应为 List ==> " + currentObj.getClass());
                        }
                    } else if (preObj instanceof Map) {
                        Map objMap = (Map) preObj;
                        currentObj = objMap.get(name);
                    } else if (name instanceof String) {
                        String fieldName = (String) name;
                        try {
                            // 其他类型,通过反射设置值
                            Class aClass = preObj.getClass();
                            Field declaredField = aClass.getDeclaredField(fieldName);
                            declaredField.setAccessible(true);
                            currentObj = declaredField.get(preObj);
                        } catch (NoSuchFieldException | IllegalAccessException e) {
                            throw new SillyException(e.getMessage(), e);
                        }
                    } else {
                        throw new SillyException("Map值设置数据类型不支持 key:" + name);
                    }

                    // 设置空值情况
                    if (currentObj == null) {
                        // 根据下一属性,确定数据类型
                        Serializable nextName = names.get(i + 1);
                        if (nextName instanceof Integer) {
                            currentObj = new ArrayList<>();
                        } else {
                            currentObj = new LinkedHashMap<>();
                        }

                        if (name instanceof Integer) {
                            List list = (List) preObj;
                            Integer index = (Integer) name;
                            int e = index - list.size();
                            if (e > 0) {
                                for (int j = 0; j <= e; j++) {
                                    list.add(null);
                                }
                            }
                            list.set(index, currentObj);
                        } else {
                            Map objMap = (Map) preObj;
                            objMap.put(name, currentObj);
                        }
                    }
                } else {
                    // 最终值设置
                    if (name instanceof Integer && preObj instanceof List) {
                        List list = (List) preObj;
                        Integer index = (Integer) name;
                        int e = index - list.size();
                        if (e > 0) {
                            for (int j = 0; j <= e; j++) {
                                list.add(null);
                            }
                        }
                        return (T) list.set(index, value);
                    } else if (preObj instanceof Map) {
                        Map objMap = (Map) preObj;
                        return (T) objMap.put(name, value);
                    } else if (name instanceof String) {
                        String fieldName = (String) name;
                        try {
                            // 其他类型,通过反射设置值
                            Class aClass = preObj.getClass();
                            Field declaredField = aClass.getDeclaredField(fieldName);
                            declaredField.setAccessible(true);
                            Object o = declaredField.get(preObj);
                            declaredField.set(preObj, value);
                            return (T) o;
                        } catch (NoSuchFieldException | IllegalAccessException e) {
                            throw new SillyException("数据类型不支持" + preObj.getClass() + " 错误:" + e.getMessage(), e);
                        }
                    } else {
                        throw new SillyException("Map值设置数据类型不支持 lastKey:" + name);
                    }
                }

                preObj = currentObj;
                preName = name;
            }
        }
        return null;
    }

    /**
     * 删除Map 键-值
     *
     * @param key 支持深层命名如:entity.user.loginName / entity[1][office].code
     * @return 原先数据值 或 null
     */

    public static  T remove(final Map map, String key) {
        List names = resolvingFieldName(key);
        return remove(map, names);
    }

    public static  T removeLayerKey(final Map map, Serializable... layerKey) {
        return remove(map, new ArrayList<>(Arrays.asList(layerKey)));
    }

    @SuppressWarnings("all")
    public static  T remove(final Map map, List names) {
        if (map == null) {
            return null;
        }

        if (names.isEmpty()) {
            return null;
        }

        synchronized (map) {
            Serializable preName = names.get(0);
            Object preObj = map;
            for (int i = 0; i < names.size(); i++) {
                Object currentObj = null;
                boolean lastNameFlag = (names.size() == (i + 1));
                Serializable name = names.get(i);
                if (!lastNameFlag) {
                    // 获取值
                    if (name instanceof Integer) {
                        if (preObj instanceof List) {
                            // 若为List 则设置值
                            Integer index = (Integer) name;
                            List list = (List) preObj;
                            if (index >= list.size()) {
                                return null;
                            } else {
                                currentObj = list.get(index);
                            }
                        } else {
                            // 若不为List 则抛出异常
                            throw new SillyException("数据设置值数据类型错误应为 List ==> " + currentObj.getClass());
                        }
                    } else if (preObj instanceof Map) {
                        Map objMap = (Map) preObj;
                        currentObj = objMap.get(name);
                    } else if (name instanceof String) {
                        String fieldName = (String) name;
                        try {
                            // 其他类型,通过反射设置值
                            Class aClass = preObj.getClass();
                            Field declaredField = aClass.getDeclaredField(fieldName);
                            declaredField.setAccessible(true);
                            currentObj = declaredField.get(preObj);
                        } catch (NoSuchFieldException | IllegalAccessException e) {
                            throw new SillyException(e.getMessage(), e);
                        }
                    } else {
                        throw new SillyException("Map值设置数据类型不支持 key:" + name);
                    }

                    // 设置空值情况
                    if (currentObj == null) {
                        return null;
                    }
                } else {
                    // 最终值设置
                    if (name instanceof Integer && preObj instanceof List) {
                        List list = (List) preObj;
                        Integer index = (Integer) name;
                        Object o = list.get(index);
                        list.remove(index);
                        return (T) o;
                    } else if (preObj instanceof Map) {
                        Map objMap = (Map) preObj;
                        return (T) objMap.remove(name);
                    } else if (name instanceof String) {
                        String fieldName = (String) name;
                        try {
                            // 其他类型,通过反射设置值
                            Class aClass = preObj.getClass();
                            Field declaredField = aClass.getDeclaredField(fieldName);
                            declaredField.setAccessible(true);
                            Object o = declaredField.get(preObj);
                            declaredField.set(preObj, null);
                            return (T) o;
                        } catch (NoSuchFieldException | IllegalAccessException e) {
                            throw new SillyException("数据类型不支持" + preObj.getClass() + " 错误:" + e.getMessage(), e);
                        }
                    } else {
                        throw new SillyException("Map值设置数据类型不支持 lastKey:" + name);
                    }
                }

                preObj = currentObj;
                preName = name;
            }
        }
        return null;
    }

    /**
     * 判断Map中是否存在此KEY
     *
     * @param key 支持深层命名如:entity.user.loginName / entity[1][office].code
     * @return 是否存在KEY
     */
    public static boolean containsKey(final Map map, String key) {
        List names = resolvingFieldName(key);
        return containsKey(map, names);
    }

    public static boolean containsLayerKey(final Map map, Serializable... layerKeys) {
        return containsKey(map, new ArrayList<>(Arrays.asList(layerKeys)));
    }

    public static boolean containsKey(final Map map, List names) {
        if (map == null) {
            return false;
        }

        if (names.isEmpty()) {
            return false;
        }

        if (names.size() == 1) {
            return map.containsKey(names.get(0));
        }

        Object currentKey = names.remove(names.size() - 1);
        Object currentObj = getObj(map, names, null);

        if (currentKey instanceof Integer) {
            if (currentObj instanceof List) {
                List list = (List) currentObj;
                Integer i = (Integer) currentKey;
                return list.size() > i;
            } else {
                return false;
            }
        } else if (currentObj instanceof Map) {
            Map objMap = (Map) currentObj;
            return objMap.containsKey(currentKey);
        } else if (currentKey instanceof String) {
            String fieldName = (String) currentKey;
            // 其他类型,通过反射设置值
            Class aClass = currentObj.getClass();
            Field[] declaredFields = aClass.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                if (Objects.equals(declaredField.getName(), fieldName)) {
                    return true;
                }
            }
            return false;
        } else {
            throw new SillyException("Map值设置数据类型不支持 lastKey:" + currentKey);
        }
    }

    public static Map beanToMap(Object beanObj, String... ignore) {
        if (beanObj instanceof Map) {
            return new TreeMap<>((Map) beanObj);
        }
        return beanToMap(beanObj, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), ignore);
    }

    /**
     * 使用Introspector,对象转换为map集合
     */
    public static Map beanToMap(Object beanObj, DateFormat df, String... ignore) {
        if (null == beanObj) {
            return null;
        }
        List ignorList = new ArrayList<>();
        if (ignore != null) {
            ignorList = Arrays.asList(ignore);
        }
        TreeMap map = new TreeMap<>();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(beanObj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                if (ignorList.contains(key) || key.compareToIgnoreCase("class") == 0) {
                    continue;
                }

                Method getter = property.getReadMethod();
                Object value = getter != null ? getter.invoke(beanObj) : null;
                if (value instanceof Date && df != null) {
                    value = df.format(value);
                }
                map.put(key, value);
            }
            return map;
        } catch (Exception ex) {
            throw new SillyException(ex.getMessage());
        }
    }

    /**
     * 使用 JSON 将Map 转为 bean
     */
    public static  T mapToBean(Map map, Class tClass) {
        return mapToBean(map, tClass, (String[]) null);
    }

    /**
     * 使用 JSON 将Map 转为 bean
     */
    public static  T mapToBean(Map map, Class tClass, String... ignore) {
        if (map == null) {
            return null;
        }

        if (ignore != null) {
            List ignoreList = Arrays.asList(ignore);
            ignoreList.forEach(map::remove);
        }
        String jsonString = SillyObjectUtil.objectToJsonString(map);
        return SillyObjectUtil.jsonToObject(jsonString, tClass);
    }

    public static String getString(Map map, String key) {
        return getString(map, key, null);
    }

    public static String getString(Map map, String key, String defaultValue) {
        Object currentObj = getObj(map, key, null);
        return currentObj == null ? defaultValue : currentObj.toString();
    }

    public static boolean getBooleanValue(Map map, String key) {
        return getBooleanValue(map, key, false);
    }

    public static boolean getBooleanValue(Map map, String key, boolean defaultValue) {
        if (map == null) {
            return defaultValue;
        }

        Object o = getObj(map, key, null);
        if (o instanceof Boolean) {
            return (boolean) o;
        }
        if (o instanceof String) {
            String s = (String) o;
            boolean aTrue = "true".equals(s.toLowerCase(Locale.ROOT));
            if (aTrue) {
                return true;
            }
            return s.equals(SillyConstant.YesOrNo.YES);
        }
        return defaultValue;
    }

    public static  T getObj(Map map, String key) {
        return getObj(map, key, null);
    }

    public static  T getObj(Map map, String key, T defaultValue) {
        List names = resolvingFieldName(key);
        return getObj(map, names, defaultValue);
    }

    @SuppressWarnings("all")
    public static  T getObj(Map map, List names, T defaultValue) {
        if (map == null) {
            return defaultValue;
        }

        if (names.isEmpty()) {
            return defaultValue;
        }

        Object currentObj = map;
        for (Serializable name : names) {
            if (currentObj == null) {
                return defaultValue;
            }

            if (name instanceof Integer) {
                if (currentObj instanceof List) {
                    List list = (List) currentObj;
                    Integer i = (Integer) name;
                    if (list.size() <= i) {
                        return defaultValue;
                    }
                    currentObj = list.get(i);
                } else {
                    return defaultValue;
                }
            } else if (currentObj instanceof Map) {
                Map objMap = (Map) currentObj;
                boolean b = objMap.containsKey(name);
                if (b) {
                    currentObj = objMap.get(name);
                } else {
                    return defaultValue;
                }
            } else if (name instanceof String) {
                String fieldName = (String) name;
                try {
                    // 其他类型,通过反射设置值
                    Class aClass = currentObj.getClass();
                    Field declaredField = aClass.getDeclaredField(fieldName);
                    declaredField.setAccessible(true);
                    currentObj = declaredField.get(currentObj);
                } catch (NoSuchFieldException | IllegalAccessException e) {
                    throw new SillyException("数据类型不支持" + currentObj.getClass() + " 错误:" + e.getMessage(), e);
                }
            } else {
                throw new SillyException("Map值设置数据类型不支持 lastKey:" + name);
            }
        }
        return currentObj == null ? defaultValue : (T) currentObj;
    }

    /**
     * 支持深层命名如: entity.user.loginName / entity[1][office].code
     * 解析获取真实属性 (不支持 KEY => null, KEY => "")
     * entity.user.loginName => ["entity","user","loginName"]
     * entity[1][office].code => ["entity", 1, "office", "code"]
     */
    public static List resolvingFieldName(String fieldName) {
        List names = new ArrayList<>();
        if (fieldName == null) {
            return names;
        }
        String[] fieldNameArr = fieldName.split(FIELD_NAME_SPLIT);
        for (String name : fieldNameArr) {
            resolvingFieldArrayName(names, name);
        }
        return names;
    }

    protected static List resolvingFieldArrayName(List names, String fieldName) {
        if (StringUtils.isEmpty(fieldName)) {
            return names;
        }

        if (!fieldName.startsWith("[")) {
            int i = fieldName.indexOf("[");
            if (i > 0) {
                names.add(fieldName.substring(0, i));
            } else {
                names.add(fieldName);
            }
        }
        if (fieldName.endsWith("]") && fieldName.contains("[")) {
            int i = fieldName.indexOf("]");
            String substring = fieldName.substring(fieldName.indexOf("[") + 1, i);
            if (StringUtils.isNumeric(substring)) {
                names.add(Integer.valueOf(substring));
            } else {
                names.add(substring);
            }
            return resolvingFieldArrayName(names, fieldName.substring(i + 1));
        }
        return names;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy