'Is there a way to force using annotation only on a var property
I'm making an annotation processor for encrypting personal data due to law. So in order to encrypt those field it should be able to set new value so I want my annotation to force using only on a var property.
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
annotation class PersonalData {
}
data class CreateAccountCommand(
  @PersonalData
  var fullname: String // it would throw an error if using val since it's not mutable
)
class TestAnnotation {
  @Test
  fun testFindAnnotation() {
    val message = EasyRandom().nextObject(CreateAccountCommand::class.java)
    val wrappedCommand = GenericCommandMessage.asCommandMessage<CreateAccountCommand>(message)
    if (isPersonalDataPresent(wrappedCommand.payload)) {
      encryptData(wrappedCommand.payload)
      wrappedCommand.payload.fullname shouldContain "-encrypted"
    }
  }
  private fun isPersonalDataPresent(payload: Any): Boolean {
    return payload::class.memberProperties.any {
      it.annotations.any { ann -> ann.annotationClass == PersonalData::class }
    }
  }
  private fun encryptData(payload: Any) {
    payload::class.memberProperties.map {
      if (it is KMutableProperty<*>) {
        it.setter.call(payload, "${it.getter.call(payload)}-encrypted")
      }
    }
  }
}
or any better way?
Solution 1:[1]
If you only include PROPERTY_SETTER in the annotation targets, the annotation can only be applied to property setters, which is effectively what you want - since a property setter implies a mutable property.
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.PROPERTY_SETTER)
annotation class PersonalData
When using this annotation, you'd usually have to specify the use site target:
data class CreateAccountCommand(
    @set:PersonalData
    var fullname: String
)
Changing it to val would give you an error, just like you expect, because a val does not have a setter.
isPersonalDataPresent also needs a little modification, to check whether the setter has the annotation:
return payload::class.memberProperties
    .filterIsInstance<KMutableProperty<*>>()
    .any {
        it.setter.annotations.any { ann ->
            ann.annotationClass == PersonalData::class
        }
    }
    					Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source | 
|---|---|
| Solution 1 | Sweeper | 
