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

net.ymate.platform.validation.ValidationMeta Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2007-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.ymate.platform.validation;

import net.ymate.platform.commons.util.ClassUtils;
import net.ymate.platform.validation.annotation.VField;
import net.ymate.platform.validation.annotation.VModel;
import net.ymate.platform.validation.annotation.VMsg;
import net.ymate.platform.validation.annotation.Validation;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 目标类型验证配置描述
 *
 * @author 刘镇 ([email protected]) on 15/5/23 上午1:55
 */
public final class ValidationMeta implements Serializable {

    private final IValidation validation;

    private final Validation.MODE mode;

    private String resourcesName;

    private final Class targetClass;

    /**
     * 类成员参数描述
     */
    private final Map fields = new LinkedHashMap<>();

    /**
     * 方法参数描述
     */
    private final Map methods = new LinkedHashMap<>();

    public ValidationMeta(IValidation validation, Class targetClass) {
        this.validation = validation;
        // 处理targetClass声明的@Validation注解,提取默认验证模式
        Validation classAnnotation = targetClass.getAnnotation(Validation.class);
        if (classAnnotation != null) {
            mode = classAnnotation.mode();
            resourcesName = classAnnotation.resourcesName();
        } else {
            mode = Validation.MODE.NORMAL;
        }
        this.targetClass = targetClass;
        // 处理targetClass所有Field成员属性
        fields.putAll(parseClassFields(null, targetClass));
        // 处理targetClass所有Method方法
        for (Method method : targetClass.getDeclaredMethods()) {
            if (!ClassUtils.isNormalMethod(method)) {
                continue;
            }
            MethodInfo methodInfo = new MethodInfo();
            // 处理每个方法上有@Validation的注解
            methodInfo.setValidation(method.getAnnotation(Validation.class));
            // 处理每个方法参数上有关验证的注解
            String[] methodParamNames = ClassUtils.getMethodParamNames(method);
            Parameter[] methodParams = method.getParameters();
            if (ArrayUtils.isNotEmpty(methodParamNames) && ArrayUtils.isNotEmpty(methodParams) && methodParamNames.length == methodParams.length) {
                int idx = 0;
                for (Parameter parameter : methodParams) {
                    ParamInfo paramInfo = new ParamInfo();
                    paramInfo.setName(methodParamNames[idx]);
                    List tmpAnnList = new ArrayList<>();
                    // 尝试获取自定义的参数别名
                    VField vField = parameter.getAnnotation(VField.class);
                    if (vField != null) {
                        paramInfo.setCustomName(StringUtils.trimToNull(vField.name()));
                        paramInfo.setLabel(StringUtils.trimToNull(vField.label()));
                    }
                    if (parameter.isAnnotationPresent(VModel.class)) {
                        // 递归处理@VModel
                        methodInfo.getParams().putAll(parseClassFields(paramInfo.getCustomName(), parameter.getType()));
                    } else {
                        tmpAnnList = Arrays.stream(parameter.getAnnotations()).filter(this::isValid).collect(Collectors.toList());
                    }
                    if (!tmpAnnList.isEmpty()) {
                        paramInfo.setAnnotations(tmpAnnList.toArray(new Annotation[0]));
                        methodInfo.getParams().put(paramInfo.getCustomName(), paramInfo);
                    }
                    idx++;
                }
            }
            if (!methodInfo.getParams().isEmpty()) {
                methods.put(method, methodInfo);
            }
        }
    }

    /**
     * @param parentFieldName 父类属性名称(用于递归)
     * @param targetClass     目标类
     * @return 处理targetClass所有Field成员属性
     */
    public Map parseClassFields(String parentFieldName, Class targetClass) {
        Map returnValues = new LinkedHashMap<>();
        for (Field field : targetClass.getDeclaredFields()) {
            if (Modifier.isStatic(field.getModifiers())) {
                continue;
            }
            ParamInfo paramInfo = new ParamInfo();
            paramInfo.setName(buildFieldName(parentFieldName, field.getName()));
            // 尝试获取自定义的参数别名
            VField vField = field.getAnnotation(VField.class);
            if (vField != null) {
                if (StringUtils.isNotBlank(vField.name())) {
                    paramInfo.setCustomName(vField.name());
                }
                if (StringUtils.isNotBlank(vField.label())) {
                    paramInfo.setLabel(vField.label());
                }
            }
            List annotations = new ArrayList<>();
            if (field.isAnnotationPresent(VModel.class)) {
                // 递归处理@VModel
                returnValues.putAll(parseClassFields(paramInfo.getCustomName(), field.getType()));
            } else {
                // 尝试获取自定义消息内容
                VMsg vMsg = field.getAnnotation(VMsg.class);
                if (vMsg != null && StringUtils.isNotBlank(vMsg.value())) {
                    paramInfo.setMessage(vMsg.value());
                }
                annotations = Arrays.stream(field.getAnnotations()).filter(this::isValid).collect(Collectors.toList());
            }
            if (!annotations.isEmpty()) {
                paramInfo.setAnnotations(annotations.toArray(new Annotation[0]));
                returnValues.put(paramInfo.getCustomName(), paramInfo);
            }
        }
        return returnValues;
    }

    /**
     * @param parentFieldName 父类属性名称
     * @param fieldName       属性名称
     * @return 返回带层级关系的Field名称
     */
    private String buildFieldName(String parentFieldName, String fieldName) {
        if (StringUtils.isNotBlank(parentFieldName)) {
            return parentFieldName.concat(".").concat(fieldName);
        }
        return fieldName;
    }

    private boolean isValid(Annotation annotation) {
        // 判断是否包含验证器中声明的注解
        return validation.containsValidator(annotation.annotationType());
    }

    public Validation.MODE getMode() {
        return mode;
    }

    public String getResourcesName() {
        return resourcesName;
    }

    public Class getTargetClass() {
        return targetClass;
    }

    public Map getFields() {
        return Collections.unmodifiableMap(fields);
    }

    public MethodInfo getMethod(Method method) {
        return methods.get(method);
    }

    public static final class MethodInfo {

        private String name;

        private Map params = new LinkedHashMap<>();

        private Validation validation;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Map getParams() {
            return params;
        }

        public void setParams(Map params) {
            this.params = params;
        }

        public Validation getValidation() {
            return validation;
        }

        public void setValidation(Validation validation) {
            this.validation = validation;
        }
    }

    public static final class ParamInfo {

        private String name;

        /**
         * 业务自定义参数名(来自VField, 若未提供则与name取值相同)
         */
        private String customName;

        /**
         * 业务参数显示名称(来自VField, 用于匹配I18N键名)
         */
        private String label;

        /**
         * 自定义消息(来自VMsg)
         */
        private String message;

        private Class type;

        private Annotation[] annotations;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getCustomName() {
            return StringUtils.defaultIfBlank(customName, name);
        }

        public void setCustomName(String customName) {
            this.customName = customName;
        }

        public String getLabel() {
            return label;
        }

        public void setLabel(String label) {
            this.label = label;
        }

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

        public Class getType() {
            return type;
        }

        public void setType(Class type) {
            this.type = type;
        }

        public Annotation[] getAnnotations() {
            return annotations;
        }

        public void setAnnotations(Annotation[] annotations) {
            this.annotations = annotations;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy