Search in sources :

Example 1 with LoadKey

use of top.tangyh.basic.echo.manager.LoadKey in project lamp-util by zuihou.

the class EchoService method iterationWrite.

private void iterationWrite(Object obj, Map<LoadKey, Map<Serializable, Object>> typeMap, int depth, String... ignoreFields) {
    // 解析方法上的注解,计算出obj对象中所有需要查询的数据
    List<Field> fields = ClassManager.getFields(obj.getClass());
    for (Field field : fields) {
        FieldParam fieldParam = getFieldParam(obj, field, typeMap, innerTypeMap -> write(ReflectUtil.getFieldValue(obj, field), innerTypeMap, depth + 1, ignoreFields), ignoreFields);
        if (fieldParam == null) {
            continue;
        }
        Echo inField = fieldParam.getEcho();
        Object actualValue = fieldParam.getActualValue();
        Object originalValue = fieldParam.getOriginalValue();
        String fieldName = fieldParam.getFieldName();
        String ref = inField.ref();
        LoadKey loadKey = fieldParam.getLoadKey();
        Object echoValue = getEchoValue(inField, actualValue, originalValue, loadKey, typeMap);
        if (echoValue == null) {
            continue;
        }
        if (echoValue instanceof Map && ((Map<?, ?>) echoValue).isEmpty()) {
            continue;
        }
        // feign 接口序列化 丢失类型
        if (echoValue instanceof Map && !Object.class.equals(inField.beanClass())) {
            echoValue = JsonUtil.parse(JsonUtil.toJson(echoValue), inField.beanClass());
        }
        if (StrUtil.isNotEmpty(ref)) {
            ReflectUtil.setFieldValue(obj, ref, echoValue);
        }
        // 将新的值 反射 到指定字段
        if (obj instanceof EchoVO) {
            EchoVO vo = (EchoVO) obj;
            vo.getEchoMap().put(fieldName, echoValue);
        } else if (originalValue instanceof RemoteData) {
            RemoteData remoteData = (RemoteData) originalValue;
            remoteData.setData(echoValue);
        } else {
            ReflectUtil.setFieldValue(obj, field, echoValue);
        }
    }
}
Also used : LoadKey(top.tangyh.basic.echo.manager.LoadKey) Field(java.lang.reflect.Field) FieldParam(top.tangyh.basic.echo.manager.FieldParam) Echo(top.tangyh.basic.annotation.echo.Echo) RemoteData(top.tangyh.basic.model.RemoteData) EchoVO(top.tangyh.basic.model.EchoVO) HashMap(java.util.HashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 2 with LoadKey

use of top.tangyh.basic.echo.manager.LoadKey in project lamp-util by zuihou.

the class EchoService method load.

/**
 * 加载数据
 * <p>
 * 注意: 需要自行实现LoadService的2个方法
 *
 * @param typeMap
 */
@SneakyThrows
private void load(Map<LoadKey, Map<Serializable, Object>> typeMap, boolean isUseCache) {
    for (Map.Entry<LoadKey, Map<Serializable, Object>> entries : typeMap.entrySet()) {
        LoadKey type = entries.getKey();
        Map<Serializable, Object> valueMap = entries.getValue();
        Set<Serializable> keys = valueMap.keySet();
        LoadService loadService = strategyMap.get(type.getApi());
        if (loadService == null) {
            log.warn("处理字段的回显数据时,没有找到 @Echo 中的api:[{}]实例。" + "请确保你自定义的接口实现了 LoadService 中的 findByIds 方法。" + "若api指定的是ServiceImpl,请确保在同一个服务内。", type.getApi());
            continue;
        }
        CacheLoadKeys lk = new CacheLoadKeys(type, loadService, keys);
        Map<Serializable, Object> value = ips.getGuavaCache().getEnabled() && isUseCache ? caches.get(lk) : lk.loadMap();
        typeMap.put(type, value);
    }
}
Also used : LoadKey(top.tangyh.basic.echo.manager.LoadKey) Serializable(java.io.Serializable) LoadService(top.tangyh.basic.model.LoadService) CacheLoadKeys(top.tangyh.basic.echo.manager.CacheLoadKeys) HashMap(java.util.HashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) SneakyThrows(lombok.SneakyThrows)

Example 3 with LoadKey

use of top.tangyh.basic.echo.manager.LoadKey in project lamp-util by zuihou.

the class EchoService method parse.

/**
 * 1,遍历字段,解析出那些字段上标记了@Echo注解
 *
 * @param obj          对象
 * @param typeMap      数据
 * @param depth        当前递归深度
 * @param ignoreFields 忽略回显的字段
 */
private void parse(Object obj, Map<LoadKey, Map<Serializable, Object>> typeMap, int depth, String... ignoreFields) {
    if (obj == null) {
        return;
    }
    if (depth > ips.getMaxDepth()) {
        log.info("出现循环依赖,最多执行 {} 次, 已执行 {} 次,已为您跳出循环", ips.getMaxDepth(), depth);
        return;
    }
    if (obj instanceof IPage) {
        List<?> records = ((IPage<?>) obj).getRecords();
        parseList(records, typeMap, depth, ignoreFields);
        return;
    }
    if (obj instanceof Collection) {
        parseList((Collection<?>) obj, typeMap, depth, ignoreFields);
        return;
    }
    // 解析方法上的注解,计算出obj对象中所有需要查询的数据
    List<Field> fields = ClassManager.getFields(obj.getClass());
    for (Field field : fields) {
        FieldParam fieldParam = getFieldParam(obj, field, typeMap, innerTypeMap -> parse(ReflectUtil.getFieldValue(obj, field), innerTypeMap, depth + 1, ignoreFields), ignoreFields);
        if (fieldParam == null) {
            continue;
        }
        LoadKey type = fieldParam.getLoadKey();
        Map<Serializable, Object> valueMap = typeMap.getOrDefault(type, new ConcurrentHashMap<>(DEF_MAP_SIZE));
        valueMap.put(fieldParam.getActualValue(), Collections.emptyMap());
        typeMap.put(type, valueMap);
    }
}
Also used : LoadKey(top.tangyh.basic.echo.manager.LoadKey) Field(java.lang.reflect.Field) IPage(com.baomidou.mybatisplus.core.metadata.IPage) Serializable(java.io.Serializable) FieldParam(top.tangyh.basic.echo.manager.FieldParam) Collection(java.util.Collection)

Example 4 with LoadKey

use of top.tangyh.basic.echo.manager.LoadKey in project lamp-util by zuihou.

the class EchoService method getFieldParam.

/**
 * 提取参数
 *
 * @param obj          当前对象
 * @param field        当前字段
 * @param typeMap      待查询的集合
 * @param consumer     字段为复杂类型时的回调处理
 * @param ignoreFields 忽略回显的字段
 * @return 字段参数
 */
private FieldParam getFieldParam(Object obj, Field field, Map<LoadKey, Map<Serializable, Object>> typeMap, Consumer<Map<LoadKey, Map<Serializable, Object>>> consumer, String... ignoreFields) {
    String key = obj.getClass().getName() + "###" + field.getName();
    FieldParam fieldParam;
    // 是否排除
    if (ArrayUtil.contains(ignoreFields, field.getName())) {
        log.debug("已经忽略{}字段的解析", field.getName());
        return null;
    }
    // 类型
    if (isNotBaseType(field)) {
        consumer.accept(typeMap);
        return null;
    }
    if (CACHE.containsKey(key)) {
        fieldParam = CACHE.get(key);
    } else {
        // 是否标记@Echo注解
        Echo echo = field.getDeclaredAnnotation(Echo.class);
        LoadKey loadKey = new LoadKey(echo);
        fieldParam = FieldParam.builder().echo(echo).loadKey(loadKey).fieldName(field.getName()).build();
        CACHE.put(key, fieldParam);
    }
    field.setAccessible(true);
    Object originalValue = ReflectUtil.getFieldValue(obj, field);
    if (originalValue == null) {
        log.debug("字段[{}]为空,跳过", field.getName());
        return null;
    }
    Serializable actualValue = getActualValue(fieldParam.getEcho(), originalValue);
    if (ObjectUtil.isEmpty(actualValue)) {
        return null;
    }
    fieldParam.setOriginalValue(originalValue);
    fieldParam.setActualValue(actualValue);
    return fieldParam;
}
Also used : LoadKey(top.tangyh.basic.echo.manager.LoadKey) Serializable(java.io.Serializable) FieldParam(top.tangyh.basic.echo.manager.FieldParam) Echo(top.tangyh.basic.annotation.echo.Echo)

Example 5 with LoadKey

use of top.tangyh.basic.echo.manager.LoadKey in project lamp-util by zuihou.

the class EchoServiceImpl method parse.

/**
 * 1,遍历字段,解析出那些字段上标记了@Echo注解
 *
 * @param obj          对象
 * @param typeMap      数据
 * @param depth        当前递归深度
 * @param ignoreFields 忽略回显的字段
 */
private void parse(Object obj, Map<LoadKey, Map<Serializable, Object>> typeMap, int depth, String... ignoreFields) {
    if (obj == null) {
        return;
    }
    if (depth > ips.getMaxDepth()) {
        log.info("递归回显层级过深 或 出现循环递归,最多执行 {} 次, 已执行 {} 次,已为您跳出循环", ips.getMaxDepth(), depth);
        return;
    }
    if (obj instanceof IPage) {
        List<?> records = ((IPage<?>) obj).getRecords();
        parseList(records, typeMap, depth, ignoreFields);
        return;
    }
    if (obj instanceof Collection) {
        parseList((Collection<?>) obj, typeMap, depth, ignoreFields);
        return;
    }
    // 解析方法上的注解,计算出obj对象中所有需要查询的数据
    List<Field> fields = ClassManager.getFields(obj.getClass());
    for (Field field : fields) {
        FieldParam fieldParam = getFieldParam(obj, field, typeMap, innerTypeMap -> parse(ReflectUtil.getFieldValue(obj, field), innerTypeMap, depth + 1, ignoreFields), ignoreFields);
        if (fieldParam == null) {
            continue;
        }
        LoadKey type = fieldParam.getLoadKey();
        Map<Serializable, Object> valueMap = typeMap.getOrDefault(type, new ConcurrentHashMap<>(DEF_MAP_SIZE));
        valueMap.put(fieldParam.getActualValue(), Collections.emptyMap());
        typeMap.put(type, valueMap);
    }
}
Also used : LoadKey(top.tangyh.basic.echo.manager.LoadKey) Field(java.lang.reflect.Field) IPage(com.baomidou.mybatisplus.core.metadata.IPage) Serializable(java.io.Serializable) FieldParam(top.tangyh.basic.echo.manager.FieldParam) Collection(java.util.Collection)

Aggregations

LoadKey (top.tangyh.basic.echo.manager.LoadKey)8 Serializable (java.io.Serializable)6 FieldParam (top.tangyh.basic.echo.manager.FieldParam)6 Field (java.lang.reflect.Field)4 HashMap (java.util.HashMap)4 Map (java.util.Map)4 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)4 Echo (top.tangyh.basic.annotation.echo.Echo)4 IPage (com.baomidou.mybatisplus.core.metadata.IPage)2 Collection (java.util.Collection)2 SneakyThrows (lombok.SneakyThrows)2 CacheLoadKeys (top.tangyh.basic.echo.manager.CacheLoadKeys)2 BaseEnum (top.tangyh.basic.interfaces.BaseEnum)1 EchoVO (top.tangyh.basic.interfaces.echo.EchoVO)1 LoadService (top.tangyh.basic.interfaces.echo.LoadService)1 EchoVO (top.tangyh.basic.model.EchoVO)1 LoadService (top.tangyh.basic.model.LoadService)1 RemoteData (top.tangyh.basic.model.RemoteData)1