Reputation: 11
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
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