I'm building a framework which hides annotations used by internal libraries and I'm using byte-buddy to do this.
The goal I'd like to achieve is that developers can define classes like this:
@ClassAnnotation(name = "Hello World", description = "A simple Hello World example")
public class HelloWorld {
@FieldAnnotation(a = "foo", b = "bar")
private String something;
}
The annotations I'm hiding are the following:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface InjectedClassAnnotation {
String name() default "";
String[] description() default "";
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface InjectedFieldAnnotation {
String a() default "";
String b() default "";
String c() default "baz";
}
I'm able to replace the class level annotation in the following way:
final Class<HelloWorld> clazz = HelloWorld.class;
final ClassAnnotation classAnnotation = clazz.getAnnotation(ClassAnnotation.class);
final AnnotationDescription annotationDescription = AnnotationDescription.Builder.ofType(InjectedClassAnnotation.class)
.define("name", classAnnotation.name())
.defineArray("description", classAnnotation.description())
.build();
new ByteBuddy()
.redefine(clazz)
.annotateType(annotationDescription)
// todo: Get all fields annotated with @FieldAnnotation and add the @InjectedFieldAnnotation with mapped values.
.make()
.load(clazz.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
But I would also like to scan for occurrences of @FieldAnnotation
on fields and if they exist, I would like to add an @InjectedFieldAnnotation
to that field and map the values from @FieldAnnotation
to those of @InjectedFieldAnnotation
.
The expected end-result after byte-buddy has done it's magic would be:
@ClassAnnotation(name = "Hello World", description = "A simple Hello World example")
@InjectedClassAnnotation(name = "Hello World", description = "A simple Hello World example")
public class HelloWorld {
@FieldAnnotation(a = "foo", b = "bar")
@InjectedFieldAnnotation(a = "foo", b = "bar", c = "baz")
private String something;
}
I've found some things like AsmVisitorWrapper
and Class-/Method-/Field-/Annotation- Visitors etc. But I'm not sure what would be the best way to achieve this. Help & thoughts are greatly appreciated!
PS: For clarity, the class annotation injection is working. I'm stuck on the field annotation.
Aucun commentaire:
Enregistrer un commentaire