Add MetaData to bundle metadata annotations
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Dieser Commit ist enthalten in:
Ursprung
f2c0a2a16b
Commit
19e4949048
@ -26,7 +26,6 @@ import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntPredicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -139,18 +138,18 @@ public abstract class AbstractSWCommand<T> {
|
||||
.collect(Collectors.toList());
|
||||
for (Method method : methods) {
|
||||
Cached cached = method.getAnnotation(Cached.class);
|
||||
addMapper(Mapper.class, method, (anno, typeMapper) -> {
|
||||
this.<Mapper, AbstractTypeMapper<?, ?>>add(Mapper.class, method, (anno, typeMapper) -> {
|
||||
TabCompletionCache.add(typeMapper, cached);
|
||||
(anno.local() ? ((Map) localTypeMapper) : SWCommandUtils.getMAPPER_FUNCTIONS()).put(anno.value(), typeMapper);
|
||||
});
|
||||
addMapper(ClassMapper.class, method, (anno, typeMapper) -> {
|
||||
this.<ClassMapper, AbstractTypeMapper<?, ?>>add(ClassMapper.class, method, (anno, typeMapper) -> {
|
||||
TabCompletionCache.add(typeMapper, cached);
|
||||
(anno.local() ? ((Map) localTypeMapper) : SWCommandUtils.getMAPPER_FUNCTIONS()).put(anno.value().getName(), typeMapper);
|
||||
});
|
||||
addValidator(Validator.class, method, (anno, validator) -> {
|
||||
this.<Validator, AbstractValidator<?, ?>>add(Validator.class, method, (anno, validator) -> {
|
||||
(anno.local() ? ((Map) localValidators) : SWCommandUtils.getVALIDATOR_FUNCTIONS()).put(anno.value(), validator);
|
||||
});
|
||||
addValidator(ClassValidator.class, method, (anno, validator) -> {
|
||||
this.<ClassValidator, AbstractValidator<?, ?>>add(ClassValidator.class, method, (anno, validator) -> {
|
||||
(anno.local() ? ((Map) localValidators) : SWCommandUtils.getVALIDATOR_FUNCTIONS()).put(anno.value().getName(), validator);
|
||||
});
|
||||
}
|
||||
@ -176,42 +175,28 @@ public abstract class AbstractSWCommand<T> {
|
||||
|
||||
this.commandList.sort((o1, o2) -> {
|
||||
int compare = Integer.compare(-o1.subCommand.length, -o2.subCommand.length);
|
||||
if (compare != 0) {
|
||||
if (compare == 0) return Integer.compare(o1.comparableValue, o2.comparableValue);
|
||||
return compare;
|
||||
} else {
|
||||
return Integer.compare(o1.comparableValue, o2.comparableValue);
|
||||
}
|
||||
});
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
private boolean validateMethod(Method method) {
|
||||
if (!checkType(method.getAnnotations(), method.getReturnType(), annotation -> {
|
||||
MethodMetaData methodMetaData = annotation.annotationType().getAnnotation(MethodMetaData.class);
|
||||
MetaData.Method methodMetaData = annotation.annotationType().getAnnotation(MetaData.Method.class);
|
||||
if (methodMetaData == null) return null;
|
||||
if (method.getParameterCount() > methodMetaData.maxParameterCount()) {
|
||||
return new Class[0];
|
||||
}
|
||||
if (method.getParameterCount() < methodMetaData.minParameterCount()) {
|
||||
return new Class[0];
|
||||
}
|
||||
return methodMetaData.possibleReturnTypes();
|
||||
}, "The method '" + method + "'")) {
|
||||
return false;
|
||||
}
|
||||
if (method.getParameterCount() > methodMetaData.maxParameterCount() || method.getParameterCount() < methodMetaData.minParameterCount()) return new Class[0];
|
||||
return methodMetaData.value();
|
||||
}, "The method '" + method + "'")) return false;
|
||||
boolean valid = true;
|
||||
for (Parameter parameter : method.getParameters()) {
|
||||
Class<?> type = parameter.getType();
|
||||
if (parameter.isVarArgs()) {
|
||||
type = type.getComponentType();
|
||||
}
|
||||
if (parameter.isVarArgs()) type = type.getComponentType();
|
||||
if (!checkType(parameter.getAnnotations(), type, annotation -> {
|
||||
ParameterMetaData parameterMetaData = annotation.annotationType().getAnnotation(ParameterMetaData.class);
|
||||
MetaData.Parameter parameterMetaData = annotation.annotationType().getAnnotation(MetaData.Parameter.class);
|
||||
if (parameterMetaData == null) return null;
|
||||
return parameterMetaData.possibleTypes();
|
||||
}, "The parameter '" + parameter + "'")) {
|
||||
valid = false;
|
||||
}
|
||||
return parameterMetaData.value();
|
||||
}, "The parameter '" + parameter + "'")) valid = false;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
@ -248,22 +233,11 @@ public abstract class AbstractSWCommand<T> {
|
||||
Arrays.stream(anno).forEach(t -> consumer.accept(t, parameters));
|
||||
}
|
||||
|
||||
private <T extends Annotation> void addMapper(Class<T> annotation, Method method, BiConsumer<T, AbstractTypeMapper<?, ?>> consumer) {
|
||||
private <T extends Annotation, K> void add(Class<T> annotation, Method method, BiConsumer<T, K> consumer) {
|
||||
add(annotation, method, false, (anno, parameters) -> {
|
||||
try {
|
||||
method.setAccessible(true);
|
||||
consumer.accept(anno, (AbstractTypeMapper<T, ?>) method.invoke(this));
|
||||
} catch (Exception e) {
|
||||
throw new SecurityException(e.getMessage(), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private <T extends Annotation> void addValidator(Class<T> annotation, Method method, BiConsumer<T, AbstractValidator<T, ?>> consumer) {
|
||||
add(annotation, method, false, (anno, parameters) -> {
|
||||
try {
|
||||
method.setAccessible(true);
|
||||
consumer.accept(anno, (AbstractValidator<T, ?>) method.invoke(this));
|
||||
consumer.accept(anno, (K) method.invoke(this));
|
||||
} catch (Exception e) {
|
||||
throw new SecurityException(e.getMessage(), e);
|
||||
}
|
||||
@ -295,7 +269,7 @@ public abstract class AbstractSWCommand<T> {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
@Repeatable(Register.Registeres.class)
|
||||
@MethodMetaData(possibleReturnTypes = void.class, minParameterCount = 1)
|
||||
@MetaData.Method(value = void.class, minParameterCount = 1)
|
||||
protected @interface Register {
|
||||
|
||||
/**
|
||||
@ -312,7 +286,7 @@ public abstract class AbstractSWCommand<T> {
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
@MethodMetaData(possibleReturnTypes = void.class, minParameterCount = 1)
|
||||
@MetaData.Method(value = void.class, minParameterCount = 1)
|
||||
@interface Registeres {
|
||||
Register[] value();
|
||||
}
|
||||
@ -320,7 +294,7 @@ public abstract class AbstractSWCommand<T> {
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.PARAMETER, ElementType.METHOD})
|
||||
@MethodMetaData(possibleReturnTypes = AbstractTypeMapper.class, minParameterCount = 0, maxParameterCount = 0)
|
||||
@MetaData.Method(value = AbstractTypeMapper.class, maxParameterCount = 0)
|
||||
protected @interface Mapper {
|
||||
String value();
|
||||
|
||||
@ -329,7 +303,7 @@ public abstract class AbstractSWCommand<T> {
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
@MethodMetaData(possibleReturnTypes = AbstractTypeMapper.class, minParameterCount = 0, maxParameterCount = 0)
|
||||
@MetaData.Method(value = AbstractTypeMapper.class, maxParameterCount = 0)
|
||||
protected @interface ClassMapper {
|
||||
Class<?> value();
|
||||
|
||||
@ -338,7 +312,7 @@ public abstract class AbstractSWCommand<T> {
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
@MethodMetaData(possibleReturnTypes = AbstractTypeMapper.class, minParameterCount = 0, maxParameterCount = 0)
|
||||
@MetaData.Method(value = AbstractTypeMapper.class, maxParameterCount = 0)
|
||||
protected @interface Cached {
|
||||
long cacheDuration() default 5;
|
||||
TimeUnit timeUnit() default TimeUnit.SECONDS;
|
||||
@ -347,7 +321,7 @@ public abstract class AbstractSWCommand<T> {
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.PARAMETER, ElementType.METHOD})
|
||||
@MethodMetaData(possibleReturnTypes = AbstractValidator.class, minParameterCount = 0, maxParameterCount = 0)
|
||||
@MetaData.Method(value = AbstractValidator.class, maxParameterCount = 0)
|
||||
protected @interface Validator {
|
||||
String value() default "";
|
||||
|
||||
@ -356,7 +330,7 @@ public abstract class AbstractSWCommand<T> {
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
@MethodMetaData(possibleReturnTypes = AbstractValidator.class, minParameterCount = 0, maxParameterCount = 0)
|
||||
@MetaData.Method(value = AbstractValidator.class, maxParameterCount = 0)
|
||||
protected @interface ClassValidator {
|
||||
Class<?> value();
|
||||
|
||||
@ -367,7 +341,7 @@ public abstract class AbstractSWCommand<T> {
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.PARAMETER})
|
||||
@ParameterMetaData(possibleTypes = {String.class, int.class, Integer.class, long.class, Long.class, boolean.class, Boolean.class})
|
||||
@MetaData.Parameter({String.class, int.class, Integer.class, long.class, Long.class, boolean.class, Boolean.class})
|
||||
protected @interface StaticValue {
|
||||
String[] value();
|
||||
|
||||
@ -424,13 +398,13 @@ public abstract class AbstractSWCommand<T> {
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.PARAMETER})
|
||||
@ParameterMetaData(possibleTypes = {String.class})
|
||||
@MetaData.Parameter({String.class})
|
||||
protected @interface Quotable {
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.PARAMETER})
|
||||
@ParameterMetaData(possibleTypes = {int.class, Integer.class, long.class, Long.class, float.class, Float.class, double.class, Double.class})
|
||||
@MetaData.Parameter({int.class, Integer.class, long.class, Long.class, float.class, Float.class, double.class, Double.class})
|
||||
protected @interface Min {
|
||||
int intValue() default Integer.MIN_VALUE;
|
||||
long longValue() default Long.MIN_VALUE;
|
||||
@ -442,7 +416,7 @@ public abstract class AbstractSWCommand<T> {
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.PARAMETER})
|
||||
@ParameterMetaData(possibleTypes = {int.class, Integer.class, long.class, Long.class, float.class, Float.class, double.class, Double.class})
|
||||
@MetaData.Parameter({int.class, Integer.class, long.class, Long.class, float.class, Float.class, double.class, Double.class})
|
||||
protected @interface Max {
|
||||
int intValue() default Integer.MAX_VALUE;
|
||||
long longValue() default Long.MAX_VALUE;
|
||||
|
@ -24,10 +24,19 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.ANNOTATION_TYPE)
|
||||
@interface MethodMetaData {
|
||||
Class<?>[] possibleReturnTypes();
|
||||
@interface MetaData {
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.ANNOTATION_TYPE)
|
||||
@interface Method {
|
||||
Class<?>[] value();
|
||||
int minParameterCount() default 0;
|
||||
int maxParameterCount() default Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.ANNOTATION_TYPE)
|
||||
@interface Parameter {
|
||||
Class<?>[] value();
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2022 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.command;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.ANNOTATION_TYPE)
|
||||
@interface ParameterMetaData {
|
||||
Class<?>[] possibleTypes();
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren