com.devops4j.skeleton4j.validate.CollectionValidator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of skeleton4j-validator Show documentation
Show all versions of skeleton4j-validator Show documentation
skeleton4j validator, use skeleton4j annoation to validate.
package com.devops4j.skeleton4j.validate;
import com.devops4j.interfaces.EnumBase;
import com.devops4j.interfaces.EnumIntegerCode;
import com.devops4j.interfaces.EnumStringCode;
import com.devops4j.logtrace4j.ErrorContextFactory;
import com.devops4j.reflection4j.GlobalSystemMetadata;
import com.devops4j.reflection4j.MetaObject;
import com.devops4j.reflection4j.Reflector;
import javax.web.doc.annotation.ApidocElement;
import javax.web.doc.enums.PatternType;
import javax.web.validate.Skeleton4jValidator;
import javax.web.validate.ValidateCause;
import javax.web.validate.ValidateContext;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
/**
* Created by devops4j on 2018/1/6.
*/
class CollectionValidator {
static boolean validate(Skeleton4jValidator validator, ValidateContext context, MetaObject metaObject, MetaObject getterMetaObject, String getterName) {
String fullName = getterMetaObject.getFullName();
Reflector reflector = GlobalSystemMetadata.reflector(metaObject.getMetaClass().getType());
Field field = reflector.getField(getterName);
ApidocElement apidocElement = field.getAnnotation(ApidocElement.class);
if (apidocElement == null) {
return true;
}
boolean required = apidocElement.required();
int minLen = apidocElement.minLen();
int maxLen = apidocElement.maxLen();
PatternType patternType = apidocElement.patternType();
String[] patterns = apidocElement.pattern();
String[] defaults = apidocElement.defaults();
Class enumClass = apidocElement.enumClass();
if (metaObject.getObject() == null && required) {
context.setCode(ValidateCause.IS_REQUIRED.getCode());
context.setDesc(context.getCauses().get(ValidateCause.IS_REQUIRED));
context.setFailureField(fullName);
if (context.isThrowException()) {
throw ErrorContextFactory.instance().code(Integer.toString(context.getCode()), context.getDesc()).solution("检查{}类的字段{}", context.getValue().getClass(), fullName).runtimeException();
}
return false;
}
//如果列表为null,则进行初始化
if (getterMetaObject.getObject() == null) {
Class type = getterMetaObject.getMetaClass().getType();
if (List.class.isAssignableFrom(type)) {
metaObject.setValue(getterMetaObject.getFullName(), new ArrayList());
} else if (Set.class.isAssignableFrom(type)) {
metaObject.setValue(getterMetaObject.getFullName(), new HashSet());
} else if (Collection.class.isAssignableFrom(type)) {
metaObject.setValue(getterMetaObject.getFullName(), new ArrayList());
}
}
//如果列表没值,且有默认值,则设置默认值
if (((Collection) metaObject.getValue(getterMetaObject.getFullName())).isEmpty()) {
if (defaults.length > 0) {
for (String defVal : defaults) {
if (EnumStringCode.class.isAssignableFrom(enumClass)) {
((Collection) metaObject.getValue(getterMetaObject.getFullName())).add(defVal);
} else if (EnumIntegerCode.class.isAssignableFrom(enumClass)) {
((Collection) metaObject.getValue(getterMetaObject.getFullName())).add(Integer.valueOf(defVal));
}
}
}
}
for (Object val : (Collection) metaObject.getValue(getterMetaObject.getFullName())) {
if (val == null) {
//TODO
if(context.isThrowException()){
throw ErrorContextFactory.instance()
.code(Integer.toString(context.getCode()), context.getDesc())
.solution("修改{}类的字段{}的数据类型", context.getMetaObject().getType(), getterMetaObject.getFullName())
.runtimeException();
}
return false;
}
Class type = val.getClass();
MetaObject metaObject1 = GlobalSystemMetadata.forObject(type, val);
if (type == String.class || type == Integer.TYPE || type == Integer.class) {//对象含有原生数据类型
//校验集合
if (enumClass != Object.class) {
if (!EnumBase.class.isAssignableFrom(enumClass)) {
context.setCode(ValidateCause.NOT_IMPLEMENT_ENUM_INTERFACE.getCode());
context.setDesc(context.getCauses().get(ValidateCause.NOT_IMPLEMENT_ENUM_INTERFACE));
context.setFailureField(fullName);
if (context.isThrowException()) {
throw ErrorContextFactory.instance().code(Integer.toString(context.getCode()), context.getDesc()).solution("检查{}类的字段{},需要实现接口EnumStringCode或者EnumIntegerCode", context.getValue().getClass(), fullName).runtimeException();
}
return false;
}
Method valueOfCodeMethod = null;
if (EnumStringCode.class.isAssignableFrom(enumClass)) {
Object val0 = null;
try {
valueOfCodeMethod = enumClass.getMethod("valueOfCode", new Class[]{String.class});
val0 = val;
EnumStringCode enumStringCode = (EnumStringCode) valueOfCodeMethod.invoke(null, val0);
if (enumStringCode == null) {
context.setCode(ValidateCause.NOT_MATCH_ENUM.getCode());
context.setDesc(context.getCauses().get(ValidateCause.NOT_MATCH_ENUM));
context.setFailureField(fullName);
if (context.isThrowException()) {
throw ErrorContextFactory.instance().code(Integer.toString(context.getCode()), context.getDesc()).solution("检查{}类的字段{}是否存在能够与编码 '{}' 匹配的枚举定义", context.getValue().getClass(), fullName, val0).runtimeException();
}
return false;
}
} catch (NoSuchMethodException e) {
context.setCode(ValidateCause.NOT_DEFINE_ENUM_FACTORY_METHOD.getCode());
context.setDesc(context.getCauses().get(ValidateCause.NOT_DEFINE_ENUM_FACTORY_METHOD));
context.setFailureField(fullName);
if (context.isThrowException()) {
throw ErrorContextFactory.instance().code(Integer.toString(context.getCode()), context.getDesc()).solution("检查{}类的字段{}是否存在枚举工厂方法 'valueOfCode()' ", context.getValue().getClass(), fullName).runtimeException();
}
return false;
} catch (InvocationTargetException e) {
context.setCode(ValidateCause.NOT_MATCH_ENUM.getCode());
context.setDesc(context.getCauses().get(ValidateCause.NOT_MATCH_ENUM));
context.setFailureField(fullName);
if (context.isThrowException()) {
throw ErrorContextFactory.instance().code(Integer.toString(context.getCode()), context.getDesc()).solution("检查{}类的字段{}的枚举工厂方法 'valueOfCode()' 是否存在编码 '{}' 逻辑问题", context.getValue().getClass(), fullName, val0).runtimeException();
}
return false;
} catch (IllegalAccessException e) {
context.setCode(ValidateCause.NOT_DEFINE_ENUM_FACTORY_METHOD.getCode());
context.setDesc(context.getCauses().get(ValidateCause.NOT_DEFINE_ENUM_FACTORY_METHOD));
context.setFailureField(fullName);
if (context.isThrowException()) {
throw ErrorContextFactory.instance().code(Integer.toString(context.getCode()), context.getDesc()).solution("检查{}类的字段{}的枚举工厂方法 'valueOfCode()' 的访问权限是否为public", context.getValue().getClass(), fullName).runtimeException();
}
return false;
}
} else if (EnumIntegerCode.class.isAssignableFrom(enumClass)) {
Object val0 = null;
try {
valueOfCodeMethod = enumClass.getMethod("valueOfCode", new Class[]{Integer.TYPE});
val0 = Integer.valueOf(val.toString()).intValue();
EnumIntegerCode enumIntegerCode = (EnumIntegerCode) valueOfCodeMethod.invoke(null, val0);
if (enumIntegerCode == null) {
context.setCode(ValidateCause.NOT_MATCH_ENUM.getCode());
context.setDesc(context.getCauses().get(ValidateCause.NOT_MATCH_ENUM));
context.setFailureField(fullName);
if (context.isThrowException()) {
throw ErrorContextFactory.instance().code(Integer.toString(context.getCode()), context.getDesc()).solution("检查{}类的字段{}是否存在能够与编码 '{}' 匹配的枚举定义", context.getValue().getClass(), fullName, val0).runtimeException();
}
return false;
}
} catch (NoSuchMethodException e) {
context.setCode(ValidateCause.NOT_DEFINE_ENUM_FACTORY_METHOD.getCode());
context.setDesc(context.getCauses().get(ValidateCause.NOT_DEFINE_ENUM_FACTORY_METHOD));
context.setFailureField(fullName);
if (context.isThrowException()) {
throw ErrorContextFactory.instance().code(Integer.toString(context.getCode()), context.getDesc()).solution("检查{}类的字段{}是否存在枚举工厂方法 'valueOfCode()' ", context.getValue().getClass(), fullName).runtimeException();
}
return false;
} catch (InvocationTargetException e) {
context.setCode(ValidateCause.NOT_MATCH_ENUM.getCode());
context.setDesc(context.getCauses().get(ValidateCause.NOT_MATCH_ENUM));
context.setFailureField(fullName);
if (context.isThrowException()) {
throw ErrorContextFactory.instance().code(Integer.toString(context.getCode()), context.getDesc()).solution("检查{}类的字段{}的枚举工厂方法 'valueOfCode()' 是否存在编码 '{}' 逻辑问题", context.getValue().getClass(), fullName, val0).runtimeException();
}
return false;
} catch (IllegalAccessException e) {
context.setCode(ValidateCause.NOT_DEFINE_ENUM_FACTORY_METHOD.getCode());
context.setDesc(context.getCauses().get(ValidateCause.NOT_DEFINE_ENUM_FACTORY_METHOD));
context.setFailureField(fullName);
if (context.isThrowException()) {
throw ErrorContextFactory.instance().code(Integer.toString(context.getCode()), context.getDesc()).solution("检查{}类的字段{}的枚举工厂方法 'valueOfCode()' 的访问权限是否为public", context.getValue().getClass(), fullName).runtimeException();
}
return false;
}
} else {//校验类集框架中的Bean
//TODO
if(context.isThrowException()){
throw ErrorContextFactory.instance()
.code(Integer.toString(context.getCode()), context.getDesc())
.solution("修改{}类的字段{}的数据类型", context.getMetaObject().getType(), getterMetaObject.getFullName())
.runtimeException();
}
return false;
}
}
} else {
if (Collection.class.isAssignableFrom(metaObject1.getType())) {
//TODO
if(context.isThrowException()){
throw ErrorContextFactory.instance()
.code(Integer.toString(context.getCode()), context.getDesc())
.solution("修改{}类的字段{}的数据类型", context.getMetaObject().getType(), getterMetaObject.getFullName())
.runtimeException();
}
return false;
} else if (Serializable.class.isAssignableFrom(metaObject1.getType())) {//如果字段为Bean对象,则进行递归校验
ValidateContext context1 = new ValidateContext(context, metaObject1);
if (!validator.validate(context1)) {//如果校验值为假,则阻断
context.setFailureField(context1.getFailureField());
context.setCode(context1.getCode());
context.setDesc(context1.getDesc());
context.setMetaObject(context1.getMetaObject());
context.setThrowException(context1.isThrowException());
context.setValue(context1.getValue());
return false;
}
} else {
context.setCode(ValidateCause.NOT_SUPPORT_JAVA_TYPE.getCode());
context.setDesc(context.getCauses().get(ValidateCause.NOT_SUPPORT_JAVA_TYPE));
context.setFailureField(getterMetaObject.getFullName());
if (context.isThrowException()) {
throw ErrorContextFactory.instance().code(Integer.toString(context.getCode()), context.getDesc()).solution("修改{}类的字段{}的数据类型,或者检查是否未实现 'java.io.Serializable' 接口", context.getMetaObject().getType(), getterMetaObject.getFullName()).runtimeException();
}
return false;
}
}
}
return true;
}
}