校验字符(注解)

前言

使用注解需要用到上篇文章:https://mp.youkuaiyun.com/postedit/81352719  校验字符封装类

先贴使用代码:

data class AddUserInfo(
        @VCLevel(2)
        @VCRequired(stringName = "pleaseTypeInYourName")
        var name:String,

        @VCLevel(1)
        @VCRemoveSpace
        @VCRequired(stringName = "pleaseTypeInYourMsg")
        @VCMinLength(min = 6,stringName = "msgMinimumLength")
        @VCBetweenLength(min = 6,max = 18,stringName = "string_xml_name")
        @VCEqual(fieldName = "name",stringName = "string_xml_name")
        @VCMaxLength(max = 18,stringName = "string_xml_name")
        @VCMatches(regularExpression = "^[a-zA-Z]\\w{5,17}\$",stringName = "string_xml_name")
        var msg:String?
)

stringName  是string.xml中的name

@VCLevel 级别, 最小值先判断

@VCRequired 必填

@VCRemoveSpace 移除空格

@VCMinLength 最小长度

@VCBetweenLength 之间

@VCEqual  判断值是否相等, fieldName 当前类的属性名称

@VCMaxLength 最大长度

@VCMatches 正则 , java1.8 环境下可对同个属性注解多次

 

有了这些, 基本上已经满足了项目中的需求。下面我贴上代码, 需要跟 上篇文章一起使用。

import android.content.Context
import com.ml.lib_common.util.resValues.getStringId
import java.lang.reflect.Field
import java.lang.reflect.Type
import java.util.*
import kotlin.collections.ArrayList


/**
 * 校验字符 注解
 */


/**
 *是否移除空格
 * level 校验的级别必须为0
 */
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
annotation class VCRemoveSpace(val value:Boolean = true,val level: Int = 0)

/**
 *必填
 *stringName=string.xml中的字符name(提示错误信息)
 *level 校验的级别大于0
 */
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
annotation class VCRequired(val stringName:String,val level: Int = 1)

/**
 *最小长度
 *stringName=string.xml 中的字符name(提示错误信息)
 *level 校验的级别大于0
 */
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
annotation class VCMinLength(val min:Int,val stringName:String,val level: Int = 2)

/**
 *最大长度
 *stringName=string.xml 中的字符name(提示错误信息)
 *level 校验的级别大于0
 */
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
annotation class VCMaxLength(val max:Int,val stringName:String,val level: Int = 2)

/**
 *在 ... 之中
 *stringName=string.xml 中的字符name(提示错误信息)
 *level 校验的级别大于0
 */
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
annotation class VCBetweenLength(val min:Int,val max:Int,val stringName:String,val level: Int = 2)

/**
 *比较值是否相等
 * fieldName = 本类要比较值的属性名称
 * stringName=string.xml 中的字符name(提示错误信息)
 * level 校验的级别大于0
 */
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
annotation class VCEqual(val fieldName:String,val stringName:String,val level: Int = 2)

/**
 *正则校验
 * regularExpression = 正则表达式
 * stringName=string.xml 中的字符name(提示错误信息)
 * level 校验的级别大于0
 */
@Repeatable
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
annotation class VCMatches(val regularExpression:String,val stringName:String,val level: Int = 2)


/**
 *校验级别,0最先校验
 */
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
annotation class VCLevel(val value:Int)




private data class AnnotationLeveles(val level:Int,val annotations:Array<Annotation>,val fieldValue:Any?)
private data class AnnotationLevel(val level:Int,val annotation:Annotation)


/**
 * 执行校验注解
 * context:上下文
 * any:有注解的类
 */
fun vcExecute(context: Context,any:Any):Boolean{
   return  vcExecute(context,any,false)
}


/**
 * 执行校验注解
 * context:上下文
 * any:有注解的类
 * isRemoveSpace:是否去掉空格,当属性有 VCRemoveSpace注解时,会使用VCRemoveSpace的值
 */
fun vcExecute(context: Context,any:Any,isRemoveSpace: Boolean):Boolean{

    val verifyChar = VerifyChar()

    val jClass=any.javaClass
    //存放属性有VCLevel注解
    val levelAnnotations = ArrayList<AnnotationLeveles>()

    //获取所有属性
    jClass.declaredFields.forEach { field ->
        run {
            //获取属性上的注解
            field.annotations.forEach { annotation ->
                run {
                    if (annotation is VCLevel) {//找到级别注解
                        val annotationLeveles =  AnnotationLeveles(annotation.value,field.annotations,
                                getValueByFieldName(field,jClass,any))

                        levelAnnotations.add(annotationLeveles)
                        return@forEach
                    }
                }
            }
        }
    }

    //根据VCLevel注解,对所有属性上的注解排序
    Collections.sort(levelAnnotations) { p0, p1 ->
        if(p0.level>p1.level){
            return@sort 1
        }else if(p0.level==p1.level){
            return@sort 0
        }else {
            return@sort -1
        }
    }


    levelAnnotations.forEach { levelAnnotation ->
        run {
            //处理字符校验
            if(levelAnnotation.fieldValue is String){
                val levelAnnotations2 = ArrayList<AnnotationLevel>()
                levelAnnotation.annotations.forEach {
                    //拿到每个属性的所有字符校验注解
                    when(it){
                        is VCRemoveSpace  ->{
                            levelAnnotations2.add(AnnotationLevel(it.level,it))
                        }
                        is VCRequired  ->{
                            levelAnnotations2.add(AnnotationLevel(it.level,it))
                        }
                        is VCMinLength ->{
                            levelAnnotations2.add(AnnotationLevel(it.level,it))
                        }
                        is VCMaxLength ->{
                            levelAnnotations2.add(AnnotationLevel(it.level,it))
                        }
                        is VCBetweenLength ->{
                            levelAnnotations2.add(AnnotationLevel(it.level,it))
                        }
                        is VCEqual ->{
                            levelAnnotations2.add(AnnotationLevel(it.level,it))
                        }
                        is VCMatches ->{
                            levelAnnotations2.add(AnnotationLevel(it.level,it))
                        }
                    }
                }
                //根据注解的level值排序
                Collections.sort(levelAnnotations2) { p0, p1 ->
                    if(p0.level>p1.level){
                        return@sort 1
                    }else if(p0.level==p1.level){
                        return@sort 0
                    }else {
                        return@sort -1
                    }
                }

                var fIsRemoveSpace:Boolean? = null
                //对排序后注解,进行处理
                levelAnnotations2.forEach {
                    when(it.annotation){
                        is VCRemoveSpace  ->{
                            fIsRemoveSpace = it.annotation.value
                        }
                        is VCRequired  ->{
                            verifyChar
                                    .with(levelAnnotation.fieldValue,fIsRemoveSpace?:isRemoveSpace)
                                    .required(getStringId(it.annotation.stringName))
                        }
                        is VCMinLength ->{
                            verifyChar
                                    .with(levelAnnotation.fieldValue,fIsRemoveSpace?:isRemoveSpace)
                                    .minLength(it.annotation.min,getStringId(it.annotation.stringName))
                        }
                        is VCMaxLength ->{
                            verifyChar
                                    .with(levelAnnotation.fieldValue,fIsRemoveSpace?:isRemoveSpace)
                                    .maxLength(it.annotation.max,getStringId(it.annotation.stringName))
                        }
                        is VCBetweenLength ->{
                            verifyChar
                                    .with(levelAnnotation.fieldValue,fIsRemoveSpace?:isRemoveSpace)
                                                .betweenLength(it.annotation.min,it.annotation.max,getStringId(it.annotation.stringName))
                        }
                        is VCEqual ->{
                            val v = getValueByFieldName(it.annotation.fieldName,jClass,any)
                            if(v is String){
                                verifyChar
                                        .with(levelAnnotation.fieldValue,fIsRemoveSpace?:isRemoveSpace)
                                        .equal(v,getStringId(it.annotation.stringName))
                            }else{
                                verifyChar
                                        .with(levelAnnotation.fieldValue,fIsRemoveSpace?:isRemoveSpace)
                                        .equal(null,getStringId(it.annotation.stringName))
                            }
                        }
                        is VCMatches ->{
                            verifyChar
                                    .with(levelAnnotation.fieldValue,fIsRemoveSpace?:isRemoveSpace)
                                    .matches(it.annotation.regularExpression,getStringId(it.annotation.stringName))
                        }
                    }
                    if(!verifyChar.isValid){//有一次校验不通过了
                        return verifyChar.isValid(context)//结束此次校验
                    }
                }
            }else{//是否内部类中包含字符校验注解
                levelAnnotation.fieldValue?.let {
                    //内部类中, 有数据校验不通过,结束此次校验
                    if(!vcExecute(context,levelAnnotation.fieldValue,isRemoveSpace)){
                        return false
                    }
                }
            }
        }
    }

    return true
}

/**
 * 得到属性的值
 */
private fun getValueByFieldName(fieldName: String,jClass:Class<*>,ob:Any): Any? {

    try {
        return jClass.getField(fieldName).get(ob)
    }catch (e:IllegalAccessException){
//      e.printStackTrace()
        //私用属性, 通过get方法获取值
        val nameIndex0 = fieldName.subSequence(0,1).toString().toUpperCase()
        var nameIndexEnd = ""
        if(fieldName.length>1){
            nameIndexEnd = fieldName.subSequence(1,fieldName.length).toString()
        }
        val methodGetName = "get$nameIndex0$nameIndexEnd"

        try {
            return jClass.getMethod(methodGetName).invoke(ob)
        }catch (e:UninitializedPropertyAccessException){
//            e.printStackTrace()
        }
    }
    return null
}

/**
 * 得到属性的值,String为null时转换为""
 */
private fun getValueByFieldName(field: Field,jClass:Class<*>,ob:Any): Any? {
    val name = field.name

    try {
        return toNullString(field.genericType,field.get(ob))
    }catch (e:IllegalAccessException){
//        e.printStackTrace()
        //私用属性, 通过get方法获取值
        val nameIndex0 = name.subSequence(0,1).toString().toUpperCase()
        var nameIndexEnd = ""
        if(name.length>1){
            nameIndexEnd = name.subSequence(1,name.length).toString()
        }
        val methodGetName = "get$nameIndex0$nameIndexEnd"

        try {
            return toNullString(field.genericType,jClass.getMethod(methodGetName).invoke(ob))
        }catch (e:UninitializedPropertyAccessException){
//            e.printStackTrace()
        }
    }
    return toNullString(field.genericType,null)
}

/**
 * 把string null 转为 ""
 */
private fun toNullString(genericType: Type,any :Any?):Any?{
    if(any==null){
        return if ("class java.lang.String"==genericType.toString()){
            ""
        }else{
            null
        }
    }
    return any

}

 

祝大家, 生活愉快~。~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值