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

com.neko233.toolchain.validator.Validator233 Maven / Gradle / Ivy

package com.neko233.toolchain.validator;


import com.neko233.toolchain.common.reflect.ReflectUtils233;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 注解校验器
 *
 * @author SolarisNeko on 2022-12-30
 */
public class Validator233 {

    private static boolean isInit = false;
    public static final Map, Map>> classValidateCache = new ConcurrentHashMap<>();

    public static ValidateContext validate(Object object) {
        if (!isInit) {
            initByLock();
        }
        if (object == null) {
            return ValidateContext.builder()
                    .isOk(false)
                    .reason("object is null")
                    .build();
        }

        Map> fieldValidateApiMap = classValidateCache.get(object.getClass());
        if (fieldValidateApiMap == null) {
            createValidateApi(object);
            fieldValidateApiMap = classValidateCache.get(object.getClass());
        }

        boolean isOk = true;
        String reason = null;
        for (Map.Entry> fieldValidateApiEntry : fieldValidateApiMap.entrySet()) {
            Field field = fieldValidateApiEntry.getKey();
            Object value = null;
            try {
                value = field.get(object);
            } catch (IllegalAccessException e) {
                return ValidateContext.builder()
                        .isOk(false)
                        .reason("reflect get field value error")
                        .throwable(e)
                        .build();
            }
            for (ValidateApi validateApi : fieldValidateApiEntry.getValue()) {
                Class annotationType = validateApi.getAnnotationType();
                if (annotationType == null) {
                    continue;
                }
                try {
                    Annotation anno = field.getAnnotation(annotationType);
                    isOk = validateApi.validateOk(anno, value);
                    if (!isOk) {
                        reason = validateApi.getReason(anno, field.getName(), value);
                    }
                } catch (Throwable t) {
                    return ValidateContext.builder()
                            .isOk(false)
                            .reason(String.format("happen error. fieldName = `%s`", field.getName()))
                            .throwable(t)
                            .build();
                }
            }

        }
        return ValidateContext.builder()
                .isOk(isOk)
                .reason(reason)
                .build();
    }

    /**
     * 初始化原生校验器
     */
    private static void initByLock() {
        synchronized (Validator233.class) {
            if (isInit) {
                return;
            }
            isInit = true;
            registerByScan(Validator233.class.getPackage().getName());
        }
    }

    public static void registerByScan(String packagePath) {
        ValidateApiFactory.registerByScanPackage(packagePath);
    }

    private static synchronized void createValidateApi(Object build) {
        Map> fieldValidateApiMap = classValidateCache.get(build.getClass());
        if (fieldValidateApiMap != null) {
            return;
        }
        List allFields = ReflectUtils233.getAllFieldsRecursive(build);

        Map> fieldValidateMap = new HashMap<>();
        for (Field field : allFields) {
            field.setAccessible(true);
            for (Annotation annotation : field.getAnnotations()) {
                ValidateApi api = ValidateApiFactory.choose(annotation);
                if (api == null) {
                    continue;
                }

                fieldValidateMap.merge(field, Collections.singletonList(api), (v1, v2) -> {
                    v1.addAll(v2);
                    return v1;
                });
            }
        }
        classValidateCache.put(build.getClass(), fieldValidateMap);
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy