2

I'm trying to create a custom annotation and validator to use in conjunction with the javax validation Api and I'm having trouble access the values of an enum.

The objective of the annotation and the validator is validate if an input data is present within the enum values.

This is the annotation class

import javax.validation.Constraint
import javax.validation.Payload
import kotlin.reflect.KClass

@kotlin.annotation.Target(
    AnnotationTarget.FIELD,
)
@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
@Constraint(validatedBy = [ValueOfEnumValidator::class])
annotation class ValueOfEnum(
    val enumClass: KClass<Enum<*>>,
    val message: String ="",
    val groups: Array<KClass<*>> = [],
    val payload: Array<KClass<out Payload>> = []
)

This is the validator implementation

import javax.validation.ConstraintValidator
import javax.validation.ConstraintValidatorContext

class ValueOfEnumValidator: ConstraintValidator<ValueOfEnum, CharSequence> {
    private val acceptedValues: MutableList<String> = mutableListOf()

    override fun initialize(constraintAnnotation: ValueOfEnum) {
        super.initialize(constraintAnnotation)

        acceptedValues.addAll(constraintAnnotation.enumClass.java
            .enumConstants
            .map {it.name}
        )
    }

    override fun isValid(value: CharSequence?, context: ConstraintValidatorContext): Boolean {
        return if (value == null) {
            true
        } else acceptedValues.contains(value.toString())

    }
}

I'm aiming to use annotation like this:

@field:ValueOfEnum(enumClass = SortDirectionEnum::class, message = "{variants.sorted.sort.direction.not.valid}")
    var sortDirection:String?=

But my IDE is reporting me the following error in the enumClass parameter

Type mismatch.
Required:KClass<Enum<*>>
Found:KClass<SortDirectionEnum>

How can I make the annotation generic enough to support different enums, and fix this issue ?

1 Answer 1

2

You are restricting enumClass to instances of Enum<*>, allowing Enum instances (Enum is an abstract class though, so nothing can be used) with all types of data, you however want to also allow child classes of Enum, which can be achieved with the out keyword there.

val enumClass: KClass<out Enum<*>>,

https://kotlinlang.org/docs/generics.html

Sign up to request clarification or add additional context in comments.

1 Comment

True, I almost got it, i completely forgot the out

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.