I simply want to have my own annotation to clean up the annotation mass and to be able to change them easily when I want;
import javax.persistence.Column import javax.validation.constraints.Size class Foo(){ @Column(name="bar_", nullable = false, length = 32) @Size(min = 32, max = 32) String bar; @Column(nullable = false, length = 32) @Size(min = 32, max = 32) String bas; @Column(nullable = false, length = 32, unique=true) @Size(min = 32, max = 32) String baq; }
Wish I could
class Foo(){ @MyColumn(name="bar_") String bar; @MyColumn String bas; @MyColumn(unique=true) String baq; }
nullable = false, length = 32
are the default params.
Java or Kotlin solutions are welcome.
Advertisement
Answer
Since you’re using 3-rd party annotations imported from javax
the best option is to introduce a composite annotation. (Kotlin doesn’t support annotation inheritance.
@Column(name = "bar_", nullable = false, length = 32) @Size(min = 32, max = 32) annotation class Anno
Spring boot is doing a pretty good job combining tons of config annotations all together – check it out.
There is a problem with composite annotation Anno
, tho. You have to supply annotation parameters with constant values.
If you’re sure, you need a parametrised annotation like
@Column(...) @Size(min = Anno.max, max = Anno.min) annotation class Anno(val min: Int, val max: Int)
have a look at Kapt or Kotlin Compiler plugins, you will need a piece of code generation.
With Kapt or Kotlin compiler plugin you will need just to override a newField
method of your custom ClassBuilder
:
override fun newField( origin: JvmDeclarationOrigin, access: Int, name: String, desc: String, signature: String?, value: Any? ): FieldVisitor { // if field is annotated with Anno -- add two custom annotation with parameters of your choice // otherwise perform a standard field init }
And then register it with
class AnnoRegister : ComponentRegistrar { override fun registerProjectComponents( project: MockProject, configuration: CompilerConfiguration ) { ... }
It should be relatively easy to integrate this processing into an existing gradle or maven project, or just pass to kotlinc
.