Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.noear.solon.validation.ValidatorManager Maven / Gradle / Ivy
/*
* Copyright 2017-2024 noear.org and 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
*
* https://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 org.noear.solon.validation;
import org.noear.solon.Utils;
import org.noear.solon.core.aspect.Invocation;
import org.noear.solon.core.handle.Action;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Result;
import org.noear.solon.core.wrap.ClassWrap;
import org.noear.solon.core.wrap.FieldWrap;
import org.noear.solon.core.wrap.ParamWrap;
import org.noear.solon.core.util.DataThrowable;
import org.noear.solon.validation.annotation.*;
import org.noear.solon.validation.annotation.Date;
import org.noear.solon.validation.util.FormatUtils;
import java.lang.annotation.Annotation;
import java.util.*;
/**
* 验证管理器
*
* 只支持 Controller 和 Action
*
* @author noear
* @since 1.0
* */
public class ValidatorManager {
/**
* 是否开启所有验证(默认:开启)
*
* 开启后,将对所有的验证注解进行逐一验证
* 关闭后,只要有一个校验不通过,就会停止后续校验,直接返回错误
*/
public static boolean VALIDATE_ALL = false;
/**
* 设定非重复提交检测器
*/
public static void setNoRepeatSubmitChecker(NoRepeatSubmitChecker checker) {
NoRepeatSubmitValidator.instance.setChecker(checker);
}
/**
* 设定已登录状态检测器
*/
public static void setLoginedChecker(LoginedChecker checker) {
LoginedValidator.instance.setChecker(checker);
}
/**
* 设定白名单检测器
*/
public static void setWhitelistChecker(WhitelistChecker checker) {
WhitelistValidator.instance.setChecker(checker);
}
/**
* 设定非黑名单检测器
*/
public static void setNotBlacklistChecker(NotBlacklistChecker checker) {
NotBlacklistValidator.instance.setChecker(checker);
}
/**
* 设定错误处理
*/
public static void setFailureHandler(ValidatorFailureHandler handler) {
if (handler != null) {
failureHandler = handler;
}
}
private static final Map, Validator> validMap = new HashMap<>();
private static ValidatorFailureHandler failureHandler = new ValidatorFailureHandlerDefault();
static {
initialize();
}
/**
* 初始化(验证器注册)
*/
private static void initialize() {
register(Date.class, DateValidator.instance);
register(DecimalMax.class, DecimalMaxValidator.instance);
register(DecimalMin.class, DecimalMinValidator.instance);
register(Email.class, EmailValidator.instance);
register(Max.class, MaxValidator.instance);
register(Min.class, MinValidator.instance);
register(NoRepeatSubmit.class, NoRepeatSubmitValidator.instance);
register(NotBlank.class, NotBlankValidator.instance);
register(NotEmpty.class, NotEmptyValidator.instance);
register(NotNull.class, NotNullValidator.instance);
register(NotZero.class, NotZeroValidator.instance);
register(Null.class, NullValidator.instance);
register(Numeric.class, NumericValidator.instance);
register(Pattern.class, PatternValidator.instance);
register(Length.class, LengthValidator.instance);
register(Size.class, SizeValidator.instance);
register(Range.class, RangeValidator.instance);
register(Whitelist.class, WhitelistValidator.instance);
register(Logined.class, LoginedValidator.instance);
register(NotBlacklist.class, NotBlacklistValidator.instance);
register(Validated.class, ValidatedValidator.instance);
}
/**
* 清除所有验证器
*/
public static void clear() {
validMap.clear();
}
/**
* 移除某个类型的验证器
*/
public static void remove(Class type) {
validMap.remove(type);
}
/**
* 注册验证器
*/
public static void register(Class type, Validator validator) {
validMap.put(type, validator);
}
/**
* 移除某个类型的验证器
* */
public static Validator get(Class type) {
return validMap.get(type);
}
/**
* 执行上下文的验证处理
*/
public static void validateOfContext(Context ctx, Action action) throws Throwable {
StringBuilder tmp = new StringBuilder();
for (Annotation anno : action.controller().annotations()) {
if (validateOfContext0(ctx, anno, null, tmp)) {
return;
}
}
for (Annotation anno : action.method().getAnnotations()) {
if (validateOfContext0(ctx, anno, null, tmp)) {
return;
}
}
}
private static boolean validateOfContext0(Context ctx, Annotation anno, String name, StringBuilder tmp) {
if (ctx.getHandled()) {
return true;
}
Validator valid = validMap.get(anno.annotationType());
if (valid != null) {
tmp.setLength(0);
Result rst = valid.validateOfContext(ctx, anno, name, tmp);
if (rst.getCode() != Result.SUCCEED_CODE) {
if (failureDo(ctx, anno, rst, valid.message(anno))) {
return true;
}
}
}
return false;
}
/**
* 执行参数的验证处理
* */
public static void validateOfInvocation(Invocation inv) throws Throwable {
StringBuilder tmp = new StringBuilder();
Result> result = Result.succeed();
result.setData(new ArrayList<>());
for (int i = 0, len = inv.args().length; i < len; i++) {
ParamWrap pw = inv.method().getParamWraps()[i];
for (Annotation anno : pw.getParameter().getAnnotations()) {
validateOfValue0(pw.getName(), anno, inv.args()[i], result, tmp);
}
}
if (result.getCode() != Result.SUCCEED_CODE) {
tmp.setLength(0);
for (BeanValidateInfo datum : result.getData()) {
tmp.append(datum.message).append(";");
}
if (tmp.length() > 0) {
tmp.setLength(tmp.length() - 1);
}
result.setDescription(tmp.toString());
throw new ValidatorException(result.getCode(), result.getDescription(), null, result);
}
}
private static void validateOfValue0(String label, Annotation anno, Object val, Result> result, StringBuilder tmp) {
Validator valid = validMap.get(anno.annotationType());
if (valid != null) {
tmp.setLength(0);
Result rst = valid.validateOfValue(anno, val, tmp);
if (rst.getCode() == Result.FAILURE_CODE) {
String message = null;
if (Utils.isEmpty(rst.getDescription())) {
rst.setDescription(label);
}
if (rst.getData() instanceof BeanValidateInfo) {
BeanValidateInfo info = (BeanValidateInfo) rst.getData();
anno = info.anno;
message = info.message;
result.getData().add(info);
} else if (rst.getData() instanceof Collection) {
List list = (List) rst.getData();
result.getData().addAll(list);
} else {
BeanValidateInfo beanValidateInfo = new BeanValidateInfo(label, anno, valid.message(anno));
message = beanValidateInfo.message;
rst.setData(beanValidateInfo);
result.getData().add(beanValidateInfo);
}
if (VALIDATE_ALL) {
result.setCode(rst.getCode());
} else {
if (ValidatorManager.failureDo(Context.current(), anno, rst, message)) {
throw new DataThrowable();
} else {
//throw new IllegalArgumentException(rst.getDescription());
String msg = FormatUtils.format(anno, rst, message);
throw new ValidatorException(rst.getCode(), msg, null, rst);
}
}
}
}
}
/**
* 执行实体的验证处理
*/
public static Result validateOfEntity(Object obj, Class>[] groups) {
try {
if (obj instanceof Collection) {
return validateOfEntityAry(obj, groups);
} else if (obj instanceof Map) {
return validateOfEntityMap(obj, groups);
} else {
return validateOfEntityOne(obj, groups);
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
private static Result validateOfEntityAry(Object obj, Class>[] groups) {
Iterator iterator = ((Collection) obj).iterator();
while (iterator.hasNext()) {
Object val2 = iterator.next();
if (val2 != null) {
Result rst = validateOfEntity(val2, groups);
if (rst.getCode() != Result.SUCCEED_CODE) {
return rst;
}
}
}
return Result.succeed();
}
private static Result validateOfEntityMap(Object obj, Class>[] groups) {
Iterator iterator = ((Map) obj).values().iterator();
while (iterator.hasNext()) {
Object val2 = iterator.next();
if (val2 != null) {
Result rst = validateOfEntity(val2, groups);
if (rst.getCode() != Result.SUCCEED_CODE) {
return rst;
}
}
}
return Result.succeed();
}
private static Result validateOfEntityOne(Object obj, Class>[] groups) throws IllegalAccessException {
if (obj == null) {
//null,由 @NotNull 来验证
return Result.succeed();
}
ClassWrap cw = ClassWrap.get(obj.getClass());
StringBuilder tmp = new StringBuilder();
Result result = Result.succeed();
List list = new ArrayList<>();
for (Map.Entry kv : cw.getFieldWraps().entrySet()) {
FieldWrap fieldWrap = kv.getValue();
for (Annotation anno : kv.getValue().annoS) {
Validator valid = ValidatorManager.get(anno.annotationType());
if (valid != null) {
if (inGroup(valid.groups(anno), groups) == false) {
continue;
}
tmp.setLength(0);
Result rst = valid.validateOfValue(anno, fieldWrap.get(obj), tmp);
if (rst.getCode() != Result.SUCCEED_CODE) {
if (Utils.isEmpty(rst.getDescription())) {
rst.setDescription(cw.clz().getSimpleName() + "." + fieldWrap.getName());
}
if (VALIDATE_ALL){
result.setCode(rst.getCode());
if (rst.getData() instanceof BeanValidateInfo ) {
list.add((BeanValidateInfo) rst.getData());
}else if (rst.getData() instanceof Collection){
List list2 = (List) rst.getData();
list.addAll(list2);
}else {
rst.setData(new BeanValidateInfo(fieldWrap.getName(), anno, valid.message(anno)));
list.add((BeanValidateInfo) rst.getData());
}
}else {
if (rst.getData() instanceof BeanValidateInfo == false) {
rst.setData(new BeanValidateInfo(fieldWrap.getName(), anno, valid.message(anno)));
}
return rst;
}
}
}
}
}
result.setData(list);
return result;
}
/**
* 执行错误处理
*
* @return 当为 true,则以 DataThrowable 抛出;否则用 AuthorizationException 抛出。
*/
public static boolean failureDo(Context ctx, Annotation ano, Result result, String message) {
if (ctx == null) {
return false;
}
try {
return failureHandler.onFailure(ctx, ano, result, message);
} catch (Throwable ex) {
ex = Utils.throwableUnwrap(ex);
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
} else {
throw new RuntimeException(ex);
}
}
}
private static boolean inGroup(Class>[] annoGroups, Class>[] groups) {
if (annoGroups == null || annoGroups.length == 0) {
return true;
} else {
if (groups == null || groups.length == 0) {
return false;
} else {
for (Class> g1 : groups) {
for (Class> g2 : annoGroups) {
if (g1 == g2) {
return true;
}
}
}
return false;
}
}
}
}