Skip to content

Annotation replacers

Revxrsal edited this page Mar 16, 2022 · 2 revisions

Due to the nature of annotations, it is impossible for them to contain anything that isn't known at compile-time. Such use cases could be configurable values, runtime-only information, etc.

Annotation replacers provide a solution to this problem. Using annotation replacers, it is possible to create "placeholder annotations", which are only markers for telling Lamp to further replace these annotations with other ones.

Example use cases of annotation replacers:

  • Use configuration values inside annotations
  • Create annotations that do not return the same value every time
  • Shortcut annotations: An annotation that can represent more than one annotation.
  • Localization: Process strings inside annotations to translate them

Example replacer

We may want to create a single annotation that automatically packages the @Command, @Description, @Usage and @CommandPermission annotations into a single one.

public @interface PluginCommand {

    String command();

    String description();

    String usage();

    String permission();

}

To create a replacer, implement an AnnotationReplacer.

public class PluginCommandAnnotationReplacer implements AnnotationReplacer<PluginCommand> {

    @Override public @Nullable Collection<Annotation> replaceAnnotations(@NotNull AnnotatedElement element, @NotNull PluginCommand annotation) {
        Command command = Annotations.create(Command.class, "value", annotation.command());
        Usage usage = Annotations.create(Usage.class, "value", annotation.usage());
        Description description = Annotations.create(Description.class, "value", annotation.description());
        CommandPermission permission = Annotations.create(CommandPermission.class, "value", annotation.permission());
        return Arrays.asList(
                command,
                usage,
                description,
                permission
        );
    }
}

Lastly, we register it:

commandHandler.registerAnnotationReplacer(PluginCommand.class, new PluginCommandAnnotationReplacer());

That's it! We can now use it on any of our commands as a shorter way rather than having to write 4 different annotations each time.

Clone this wiki locally