lukasinios
lukasinios

Reputation: 11

Unable to get an annotation from data class field

I want to create custom request parser, i want to do this by annotating fields and getting value by reflection but I can get annotation only from the class field, the code below doesn't work for data class or constructor in a class, any idea what is wrong?

open class RequestParser {


fun getRequestWithTag(): String {
    var requestString = "<RequestData>"

    val declaredMemberProperties = this::class.declaredMemberProperties

    declaredMemberProperties.filter {
        it.findAnnotation<RequestField>() != null
    }.forEach { filteredMemberProperties ->
        requestString += "<${filteredMemberProperties.name.firstLetterToUpperCase()}>${filteredMemberProperties.getter.call(this)}</${filteredMemberProperties.name.firstLetterToUpperCase()}>"
    }

    requestString += "</RequestData>"
    return requestString
}
}



@Retention(AnnotationRetention.RUNTIME)
@Target(
    FIELD,
    PROPERTY,
    PROPERTY_GETTER,
    VALUE_PARAMETER,
    PROPERTY_SETTER,
    CONSTRUCTOR,
    FUNCTION)
public annotation class  RequestField




//model example
data class RequestTest(
  @RequestField val name: String
) : RequestParser()


//using example
RequestTest("name").getRequestWithTag()

Upvotes: 1

Views: 1184

Answers (1)

Mathias Dpunkt
Mathias Dpunkt

Reputation: 12184

An attribute in a data class constructor is many things, a constructor parameter, a getter, a setter and a field. So you need to set use-site targets to express what you actually mean.

class Example(@field:Ann val foo,    // annotate Java field
              @get:Ann val bar,      // annotate Java getter
              @param:Ann val quux)   // annotate Java constructor parameter

See also https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets

So in your case I would try the following:

data class RequestTest(
  @property:RequestField val name: String
) : RequestParser()

With property I am able to get the annotation from this::class.declaredMemberProperties

If you put field you would be able to get it via this::class.java.declaredFields

Upvotes: 2

Related Questions