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

com.jn.agileway.http.rest.GlobalRestResponseBodyHandlerConfiguration Maven / Gradle / Ivy

There is a newer version: 5.0.4
Show newest version
package com.jn.agileway.http.rest;

import com.jn.langx.util.Emptys;
import com.jn.langx.util.Strings;
import com.jn.langx.util.collection.Collects;
import com.jn.langx.util.collection.Pipeline;
import com.jn.langx.util.function.Consumer;
import com.jn.langx.util.function.Predicate;
import com.jn.langx.util.reflect.Reflects;
import com.jn.langx.util.struct.Holder;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

/***
 * 对标 ControllerAdvice
 */
public class GlobalRestResponseBodyHandlerConfiguration {
    /**
     * 该配置指定包下的类会被应用统一响应
     */
    private List basePackages = Collects.newArrayList();
    /**
     * 该配置指定包下的类不会被应用统一响应
     */
    private List excludedBasePackages = Collects.newArrayList();
    /**
     * 该配置指定的类不会被应用统一响应
     */
    private List excludedBasePackageClasses = Collects.newArrayList();

    /**
     * 该配置指定的类的类以及子类会被应用统一响应
     */
    private List assignableTypes = Collects.newArrayList();
    /**
     * 该配置指定的类的类以及子类不会会被应用统一响应
     */
    private List excludedAssignableTypes = Collects.newArrayList();
    /**
     * 被该配置指定的注解标注的类会被应用统一响应
     */
    private List annotations = Collects.newArrayList();
    /**
     * 被该配置指定的注解标注的类不会被应用统一响应
     */
    private List excludedAnnotations = Collects.newArrayList();

    private Set excludedMethods = new CopyOnWriteArraySet();

    /**
     * 响应 体要忽略的字段,字段 只对标 @see com.jn.langx.http.rest.RestRespBody
     *
     * @see GlobalRestHandlers#GLOBAL_IGNORED_REST_FIELDS
     */
    private Set ignoredFields = Collects.newHashSet();


    public List getBasePackages() {
        return basePackages;
    }


    private ConcurrentHashMap> judged = new ConcurrentHashMap>();

    public void setBasePackages(List basePackages) {
        if (basePackages != null) {
            this.basePackages.addAll(basePackages);
        }
    }

    public void addBasePackage(String basePackage) {
        this.basePackages.add(basePackage);
    }

    public List getExcludedBasePackages() {
        return excludedBasePackages;
    }

    public void setExcludedBasePackages(List excludedBasePackages) {
        if (excludedBasePackages != null) {
            this.excludedBasePackages.addAll(excludedBasePackages);
        }
    }

    public void addExcludedBasePackage(String excludedBasePackage) {
        this.excludedBasePackages.add(excludedBasePackage);
    }

    public List getExcludedBasePackageClasses() {
        return excludedBasePackageClasses;
    }

    public void setExcludedBasePackageClasses(List excludedBasePackageClasses) {
        this.excludedBasePackageClasses = excludedBasePackageClasses;
    }

    public List getAssignableTypes() {
        return assignableTypes;
    }

    public void setAssignableTypes(List assignableTypes) {
        if (assignableTypes != null) {
            this.assignableTypes.addAll(assignableTypes);
        }
    }

    public void addAssignableType(Class clazz) {
        this.assignableTypes.add(clazz);
    }

    public List getExcludedAssignableTypes() {
        return excludedAssignableTypes;
    }

    public void setExcludedAssignableTypes(List excludedAssignableTypes) {
        if (excludedAssignableTypes != null) {
            this.excludedAssignableTypes.addAll(excludedAssignableTypes);
        }
    }

    public void addExcludedAssignableType(Class clazz) {
        this.excludedAssignableTypes.add(clazz);
    }

    public List getAnnotations() {
        return annotations;
    }

    public void setAnnotations(List annotations) {
        if (annotations != null) {
            this.annotations.addAll(annotations);
        }
    }

    public void addAnnotation(Class annotation) {
        this.annotations.add(annotation);
    }

    public List getExcludedAnnotations() {
        return excludedAnnotations;
    }

    public void setExcludedAnnotations(List excludedAnnotations) {
        if (excludedAnnotations != null) {
            this.excludedAnnotations.addAll(excludedAnnotations);
        }
    }

    public void addExcludedAnnotation(Class annotation) {
        this.excludedAnnotations.add(annotation);
    }

    private boolean isAcceptable(final Class clazz) {
        return isAssignableTypeMatched(clazz) || isPackageMatched(clazz) || isAnnotationMatched(clazz);
    }

    public boolean isAcceptable(final Method method) {
        Holder acceptHolder = judged.get(method);
        if (acceptHolder == null) {
            boolean accept = judgeMethodAcceptable(method);
            acceptHolder = new Holder(accept);
            judged.put(method, acceptHolder);
        }
        return acceptHolder.get();
    }

    private boolean judgeMethodAcceptable(final Method method) {
        // 有@RestAction注解时,根据该注解来判断
        String className = Reflects.getFQNClassName(method.getDeclaringClass());
        String methodFQN = className + "." + method.getName();
        if (Reflects.hasAnnotation(method, RestAction.class)) {
            RestAction restAction = Reflects.getAnnotation(method, RestAction.class);
            return restAction.value();
        }

        // 没有注解时,根据配置来判断
        if (isAcceptable(method.getDeclaringClass())) {
            if (isExcludedMethod(methodFQN)) {
                return false;
            }
            // 存在 excludedAnnotations 中的任何一个
            if (Collects.anyMatch(this.excludedAnnotations, new Predicate() {
                @Override
                public boolean test(Class excludedAnnotationClass) {
                    return Reflects.hasAnnotation(method, excludedAnnotationClass);
                }
            })) {
                return false;
            }
            return true;
        } else {
            // 存在 excludedAnnotations 中的任何一个
            if (Collects.anyMatch(this.annotations, new Predicate() {
                @Override
                public boolean test(Class annotationClass) {
                    return Reflects.hasAnnotation(method, annotationClass);
                }
            })) {
                return true;
            }
            return false;
        }
    }

    private boolean isAnnotationMatched(final Class clazz) {
        if (Collects.anyMatch(annotations, new Predicate() {
            @Override
            public boolean test(Class annotationClass) {
                return Reflects.isAnnotationPresent(clazz, annotationClass);
            }
        })) {
            return Collects.noneMatch(excludedAnnotations, new Predicate() {
                @Override
                public boolean test(Class annotationClass) {
                    return Reflects.isAnnotationPresent(clazz, annotationClass);
                }
            });
        }
        return false;
    }

    private boolean isAssignableTypeMatched(final Class clazz) {
        if (Collects.anyMatch(assignableTypes, new Predicate() {
            @Override
            public boolean test(Class assignableType) {
                return Reflects.isSubClassOrEquals(assignableType, clazz);
            }
        })) {
            return Collects.noneMatch(excludedAssignableTypes, new Predicate() {
                @Override
                public boolean test(Class assignableType) {
                    return Reflects.isSubClassOrEquals(assignableType, clazz);
                }
            });
        }
        return false;
    }

    private boolean isPackageMatched(final Class clazz) {

        final String packageName = clazz.getPackage().getName();
        // 不在指定的包下
        if (Collects.noneMatch(basePackages, new Predicate() {
            @Override
            public boolean test(String basePackage) {
                return packageName.startsWith(basePackage);
            }
        })) {
            return false;
        }

        // 在任何一个指定的排除包下,就是要排除的
        if (Collects.anyMatch(excludedBasePackages, new Predicate() {
            @Override
            public boolean test(String excludeBasePackage) {
                return packageName.startsWith(excludeBasePackage);
            }
        })) {
            return false;
        }

        // 是任何一个要排除的类时
        if (Collects.anyMatch(excludedBasePackageClasses, new Predicate() {
            @Override
            public boolean test(Class value) {
                return Reflects.isSubClassOrEquals(clazz, value);
            }
        })) {
            return false;
        }
        return true;
    }

    public void addExcludedMethod(String methodFQN) {
        if (Emptys.isNotEmpty(methodFQN)) {
            this.excludedMethods.add(methodFQN);
        }
    }

    public void addExcludedMethod(Method method) {
        String className = Reflects.getFQNClassName(method.getDeclaringClass());
        addExcludedMethod(className + "." + method.getName());
    }

    public void addExcludedMethods(List methodFQNs) {
        Collects.forEach(methodFQNs, new Consumer() {
            @Override
            public void accept(String methodFQN) {
                addExcludedMethod(methodFQN);
            }
        });
    }

    /**
     * 是否为在要排除的方法
     *
     * @param method
     */
    public boolean isExcludedMethod(String method) {
        return this.excludedMethods.contains(method);
    }

    public Set getIgnoredFields() {
        return ignoredFields;
    }

    public void setIgnoredFields(Collection ignoredFields) {
        if (ignoredFields != null) {
            this.ignoredFields = Pipeline.of(ignoredFields).distinct().asSet(true);
        }
    }

    public boolean isIgnoredField(String fieldName) {
        if (Strings.isBlank(fieldName)) {
            return true;
        }
        return ignoredFields.contains(fieldName);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy