Allow for class annotations as a default for when an annotation is not present on a method

This commit is contained in:
jmp 2020-10-21 23:51:56 -07:00 committed by Alexander Söderberg
parent d37f2236e7
commit c9d4f39612
7 changed files with 40 additions and 19 deletions

View file

@ -106,6 +106,25 @@ public final class AnnotationParser<C> {
));
}
protected static <A extends Annotation> @Nullable A getMethodOrClassAnnotation(
final @NonNull Method method,
final @NonNull Class<A> clazz
) {
if (method.isAnnotationPresent(clazz)) {
return method.getAnnotation(clazz);
} else if (method.getDeclaringClass().isAnnotationPresent(clazz)) {
return method.getDeclaringClass().getAnnotation(clazz);
}
return null;
}
protected static <A extends Annotation> boolean methodOrClassHasAnnotation(
final @NonNull Method method,
final @NonNull Class<A> clazz
) {
return getMethodOrClassAnnotation(method, clazz) != null;
}
/**
* Register an annotation mapper
*
@ -186,8 +205,8 @@ public final class AnnotationParser<C> {
final String commandToken = commandMethod.value().split(" ")[0].split("\\|")[0];
@SuppressWarnings("ALL") final CommandManager manager = this.manager;
final SimpleCommandMeta.Builder metaBuilder = SimpleCommandMeta.builder()
.with(this.metaFactory.apply(method.getAnnotations()));
if (method.isAnnotationPresent(Confirmation.class)) {
.with(this.metaFactory.apply(method));
if (methodOrClassHasAnnotation(method, Confirmation.class)) {
metaBuilder.with(CommandConfirmationManager.CONFIRMATION_REQUIRED_META, "true");
}
@ -245,8 +264,9 @@ public final class AnnotationParser<C> {
}
}
if (method.isAnnotationPresent(CommandPermission.class)) {
builder = builder.permission(method.getAnnotation(CommandPermission.class).value());
final CommandPermission commandPermission = getMethodOrClassAnnotation(method, CommandPermission.class);
if (commandPermission != null) {
builder = builder.permission(commandPermission.value());
}
if (commandMethod.requiredSender() != Object.class) {
@ -263,7 +283,7 @@ public final class AnnotationParser<C> {
throw new RuntimeException("Failed to construct command execution handler", e);
}
/* Check if the command should be hidden */
if (method.isAnnotationPresent(Hidden.class)) {
if (methodOrClassHasAnnotation(method, Hidden.class)) {
builder = builder.hidden();
}
/* Apply flags */

View file

@ -34,7 +34,7 @@ import java.lang.annotation.Target;
* Maps to {@link StandardParameters#DESCRIPTION}
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface CommandDescription {
/**

View file

@ -31,7 +31,7 @@ import java.lang.annotation.Target;
/**
* Equivalent to {@link cloud.commandframework.Command.Builder#permission(String)}
*/
@Target(ElementType.METHOD)
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface CommandPermission {

View file

@ -32,7 +32,7 @@ import java.lang.annotation.Target;
* Require confirmation for the command
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Confirmation {
}

View file

@ -33,7 +33,7 @@ import java.lang.annotation.Target;
/**
* Indicates that the command should be hidden. Similar to {@link Command.Builder#hidden()}
*/
@Target(ElementType.METHOD)
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Hidden {

View file

@ -28,9 +28,10 @@ import cloud.commandframework.meta.CommandMeta;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.function.Function;
class MetaFactory implements Function<@NonNull Annotation @NonNull [], @NonNull CommandMeta> {
class MetaFactory implements Function<@NonNull Method, @NonNull CommandMeta> {
private final AnnotationParser<?> annotationParser;
private final Function<ParserParameters, CommandMeta> metaMapper;
@ -44,17 +45,16 @@ class MetaFactory implements Function<@NonNull Annotation @NonNull [], @NonNull
}
@Override
public @NonNull CommandMeta apply(final @NonNull Annotation @NonNull [] annotations) {
public @NonNull CommandMeta apply(final @NonNull Method method) {
final ParserParameters parameters = ParserParameters.empty();
for (final Annotation annotation : annotations) {
@SuppressWarnings("ALL") final Function function = this.annotationParser.getAnnotationMappers()
.get(annotation.annotationType());
if (function == null) {
continue;
this.annotationParser.getAnnotationMappers().forEach(((annotationClass, mapper) -> {
final Annotation annotation = AnnotationParser.getMethodOrClassAnnotation(method, annotationClass);
if (annotation != null) {
@SuppressWarnings("ALL") final Function function = (Function) mapper;
//noinspection unchecked
parameters.merge((ParserParameters) function.apply(annotation));
}
//noinspection unchecked
parameters.merge((ParserParameters) function.apply(annotation));
}
}));
return this.metaMapper.apply(parameters);
}