✨ Allow for class annotations as a default for when an annotation is not present on a method
This commit is contained in:
parent
d37f2236e7
commit
c9d4f39612
7 changed files with 40 additions and 19 deletions
|
|
@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Allow for combined presence flags, such that `-a -b -c` is equivalent to `-abc`
|
- Allow for combined presence flags, such that `-a -b -c` is equivalent to `-abc`
|
||||||
|
- Allow for class annotations as a default for when an annotation is not present on a method.
|
||||||
|
|
||||||
## [1.0.2] - 2020-10-18
|
## [1.0.2] - 2020-10-18
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
* Register an annotation mapper
|
||||||
*
|
*
|
||||||
|
|
@ -186,8 +205,8 @@ public final class AnnotationParser<C> {
|
||||||
final String commandToken = commandMethod.value().split(" ")[0].split("\\|")[0];
|
final String commandToken = commandMethod.value().split(" ")[0].split("\\|")[0];
|
||||||
@SuppressWarnings("ALL") final CommandManager manager = this.manager;
|
@SuppressWarnings("ALL") final CommandManager manager = this.manager;
|
||||||
final SimpleCommandMeta.Builder metaBuilder = SimpleCommandMeta.builder()
|
final SimpleCommandMeta.Builder metaBuilder = SimpleCommandMeta.builder()
|
||||||
.with(this.metaFactory.apply(method.getAnnotations()));
|
.with(this.metaFactory.apply(method));
|
||||||
if (method.isAnnotationPresent(Confirmation.class)) {
|
if (methodOrClassHasAnnotation(method, Confirmation.class)) {
|
||||||
metaBuilder.with(CommandConfirmationManager.CONFIRMATION_REQUIRED_META, "true");
|
metaBuilder.with(CommandConfirmationManager.CONFIRMATION_REQUIRED_META, "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -245,8 +264,9 @@ public final class AnnotationParser<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method.isAnnotationPresent(CommandPermission.class)) {
|
final CommandPermission commandPermission = getMethodOrClassAnnotation(method, CommandPermission.class);
|
||||||
builder = builder.permission(method.getAnnotation(CommandPermission.class).value());
|
if (commandPermission != null) {
|
||||||
|
builder = builder.permission(commandPermission.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commandMethod.requiredSender() != Object.class) {
|
if (commandMethod.requiredSender() != Object.class) {
|
||||||
|
|
@ -263,7 +283,7 @@ public final class AnnotationParser<C> {
|
||||||
throw new RuntimeException("Failed to construct command execution handler", e);
|
throw new RuntimeException("Failed to construct command execution handler", e);
|
||||||
}
|
}
|
||||||
/* Check if the command should be hidden */
|
/* Check if the command should be hidden */
|
||||||
if (method.isAnnotationPresent(Hidden.class)) {
|
if (methodOrClassHasAnnotation(method, Hidden.class)) {
|
||||||
builder = builder.hidden();
|
builder = builder.hidden();
|
||||||
}
|
}
|
||||||
/* Apply flags */
|
/* Apply flags */
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ import java.lang.annotation.Target;
|
||||||
* Maps to {@link StandardParameters#DESCRIPTION}
|
* Maps to {@link StandardParameters#DESCRIPTION}
|
||||||
*/
|
*/
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.METHOD)
|
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||||
public @interface CommandDescription {
|
public @interface CommandDescription {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ import java.lang.annotation.Target;
|
||||||
/**
|
/**
|
||||||
* Equivalent to {@link cloud.commandframework.Command.Builder#permission(String)}
|
* Equivalent to {@link cloud.commandframework.Command.Builder#permission(String)}
|
||||||
*/
|
*/
|
||||||
@Target(ElementType.METHOD)
|
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface CommandPermission {
|
public @interface CommandPermission {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ import java.lang.annotation.Target;
|
||||||
* Require confirmation for the command
|
* Require confirmation for the command
|
||||||
*/
|
*/
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.METHOD)
|
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||||
public @interface Confirmation {
|
public @interface Confirmation {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ import java.lang.annotation.Target;
|
||||||
/**
|
/**
|
||||||
* Indicates that the command should be hidden. Similar to {@link Command.Builder#hidden()}
|
* Indicates that the command should be hidden. Similar to {@link Command.Builder#hidden()}
|
||||||
*/
|
*/
|
||||||
@Target(ElementType.METHOD)
|
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface Hidden {
|
public @interface Hidden {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,10 @@ import cloud.commandframework.meta.CommandMeta;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.function.Function;
|
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 AnnotationParser<?> annotationParser;
|
||||||
private final Function<ParserParameters, CommandMeta> metaMapper;
|
private final Function<ParserParameters, CommandMeta> metaMapper;
|
||||||
|
|
@ -44,17 +45,16 @@ class MetaFactory implements Function<@NonNull Annotation @NonNull [], @NonNull
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull CommandMeta apply(final @NonNull Annotation @NonNull [] annotations) {
|
public @NonNull CommandMeta apply(final @NonNull Method method) {
|
||||||
final ParserParameters parameters = ParserParameters.empty();
|
final ParserParameters parameters = ParserParameters.empty();
|
||||||
for (final Annotation annotation : annotations) {
|
this.annotationParser.getAnnotationMappers().forEach(((annotationClass, mapper) -> {
|
||||||
@SuppressWarnings("ALL") final Function function = this.annotationParser.getAnnotationMappers()
|
final Annotation annotation = AnnotationParser.getMethodOrClassAnnotation(method, annotationClass);
|
||||||
.get(annotation.annotationType());
|
if (annotation != null) {
|
||||||
if (function == null) {
|
@SuppressWarnings("ALL") final Function function = (Function) mapper;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
parameters.merge((ParserParameters) function.apply(annotation));
|
parameters.merge((ParserParameters) function.apply(annotation));
|
||||||
}
|
}
|
||||||
|
}));
|
||||||
return this.metaMapper.apply(parameters);
|
return this.metaMapper.apply(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue