mirror of
https://github.com/GeyserMC/Floodgate.git
synced 2025-12-19 06:49:24 +00:00
Added auto-binding
This commit is contained in:
0
ap/build.gradle.kts
Normal file
0
ap/build.gradle.kts
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Floodgate
|
||||
*/
|
||||
|
||||
package org.geysermc.floodgate.ap;
|
||||
|
||||
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
import javax.annotation.processing.SupportedSourceVersion;
|
||||
import javax.lang.model.SourceVersion;
|
||||
|
||||
@SupportedAnnotationTypes("*")
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||
public class AutoBindProcessor extends ClassProcessor {
|
||||
public AutoBindProcessor() {
|
||||
super("org.geysermc.floodgate.util.AutoBind");
|
||||
}
|
||||
}
|
||||
221
ap/src/main/java/org/geysermc/floodgate/ap/ClassProcessor.java
Normal file
221
ap/src/main/java/org/geysermc/floodgate/ap/ClassProcessor.java
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Floodgate
|
||||
*/
|
||||
|
||||
package org.geysermc.floodgate.ap;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.tools.Diagnostic.Kind;
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
/*
|
||||
* Copied from Geyser
|
||||
*/
|
||||
public class ClassProcessor extends AbstractProcessor {
|
||||
private final String annotationClassName;
|
||||
|
||||
private Path outputPath;
|
||||
|
||||
private final Set<String> locations = new HashSet<>();
|
||||
|
||||
public ClassProcessor(String annotationClassName) {
|
||||
this.annotationClassName = annotationClassName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void init(ProcessingEnvironment processingEnv) {
|
||||
super.init(processingEnv);
|
||||
|
||||
processingEnv.getMessager().printMessage(
|
||||
Kind.NOTE, "Initializing processor " + annotationClassName
|
||||
);
|
||||
|
||||
String outputFile = processingEnv.getOptions().get("metadataOutputFile");
|
||||
if (outputFile != null && !outputFile.isEmpty()) {
|
||||
outputPath = Paths.get(outputFile);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
if (roundEnv.processingOver()) {
|
||||
if (!roundEnv.errorRaised()) {
|
||||
complete();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!contains(annotations, annotationClassName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Element element : roundEnv.getRootElements()) {
|
||||
if (element.getKind() != ElementKind.CLASS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!contains(element.getAnnotationMirrors(), annotationClassName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TypeElement typeElement = (TypeElement) element;
|
||||
locations.add(typeElement.getQualifiedName().toString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean contains(Collection<? extends TypeElement> elements, String className) {
|
||||
if (elements.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (TypeElement element : elements) {
|
||||
if (element.getQualifiedName().contentEquals(className)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean contains(List<? extends AnnotationMirror> elements, String className) {
|
||||
if (elements.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (AnnotationMirror element : elements) {
|
||||
if (element.getAnnotationType().toString().equals(className)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void complete() {
|
||||
// Read existing annotation list and verify each class still has this annotation
|
||||
try (BufferedReader reader = createReader()) {
|
||||
if (reader != null) {
|
||||
reader.lines().forEach(canonicalName -> {
|
||||
if (!locations.contains(canonicalName)) {
|
||||
|
||||
TypeElement element =
|
||||
processingEnv.getElementUtils().getTypeElement(canonicalName);
|
||||
|
||||
if (element != null && element.getKind() == ElementKind.CLASS &&
|
||||
contains(element.getAnnotationMirrors(), annotationClassName)) {
|
||||
locations.add(canonicalName);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (!locations.isEmpty()) {
|
||||
try (BufferedWriter writer = createWriter()) {
|
||||
for (String location : locations) {
|
||||
writer.write(location);
|
||||
writer.newLine();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
processingEnv.getMessager().printMessage(Kind.NOTE,
|
||||
"Did not find any classes annotated with " + annotationClassName
|
||||
);
|
||||
}
|
||||
|
||||
processingEnv.getMessager().printMessage(
|
||||
Kind.NOTE, "Completed processing for " + annotationClassName
|
||||
);
|
||||
}
|
||||
|
||||
private BufferedReader createReader() throws IOException {
|
||||
if (outputPath != null) {
|
||||
processingEnv.getMessager().printMessage(Kind.NOTE,
|
||||
"Reading existing " + annotationClassName + " list from " + outputPath
|
||||
);
|
||||
|
||||
return Files.newBufferedReader(outputPath);
|
||||
}
|
||||
|
||||
FileObject obj = processingEnv.getFiler().getResource(
|
||||
StandardLocation.CLASS_OUTPUT, "", annotationClassName
|
||||
);
|
||||
|
||||
if (obj != null) {
|
||||
processingEnv.getMessager().printMessage(
|
||||
Kind.NOTE,
|
||||
"Reading existing " + annotationClassName + " list from " + obj.toUri()
|
||||
);
|
||||
|
||||
try {
|
||||
return new BufferedReader(obj.openReader(false));
|
||||
} catch (NoSuchFileException ignored) {}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private BufferedWriter createWriter() throws IOException {
|
||||
if (outputPath != null) {
|
||||
processingEnv.getMessager().printMessage(
|
||||
Kind.NOTE, "Writing " + annotationClassName + " to " + outputPath
|
||||
);
|
||||
|
||||
return Files.newBufferedWriter(outputPath);
|
||||
}
|
||||
|
||||
FileObject obj = processingEnv.getFiler().createResource(
|
||||
StandardLocation.CLASS_OUTPUT, "", annotationClassName
|
||||
);
|
||||
|
||||
processingEnv.getMessager().printMessage(
|
||||
Kind.NOTE, "Writing " + annotationClassName + " to " + obj.toUri()
|
||||
);
|
||||
|
||||
return new BufferedWriter(obj.openWriter());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
org.geysermc.floodgate.ap.AutoBindProcessor
|
||||
@@ -8,6 +8,9 @@ dependencies {
|
||||
api(projects.api)
|
||||
api("org.geysermc.configutils", "configutils", Versions.configUtilsVersion)
|
||||
|
||||
compileOnly(projects.ap)
|
||||
annotationProcessor(projects.ap)
|
||||
|
||||
api("com.google.inject", "guice", Versions.guiceVersion)
|
||||
api("com.nukkitx.fastutil", "fastutil-short-object-maps", Versions.fastutilVersion)
|
||||
api("com.nukkitx.fastutil", "fastutil-int-object-maps", Versions.fastutilVersion)
|
||||
|
||||
@@ -39,27 +39,22 @@ import org.geysermc.floodgate.api.packet.PacketHandlers;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
import org.geysermc.floodgate.event.PostEnableEvent;
|
||||
import org.geysermc.floodgate.event.ShutdownEvent;
|
||||
import org.geysermc.floodgate.link.PlayerLinkLoader;
|
||||
import org.geysermc.floodgate.module.PostInitializeModule;
|
||||
import org.geysermc.floodgate.news.NewsChecker;
|
||||
import org.geysermc.floodgate.util.Metrics;
|
||||
import org.geysermc.floodgate.util.PostEnableMessages;
|
||||
|
||||
public class FloodgatePlatform {
|
||||
private static final UUID KEY = UUID.randomUUID();
|
||||
@Inject private FloodgateApi api;
|
||||
@Inject private PlatformInjector injector;
|
||||
|
||||
@Inject private FloodgateConfig config;
|
||||
@Inject private Injector guice;
|
||||
|
||||
@Inject
|
||||
public void init(PacketHandlers packetHandlers, HandshakeHandlers handshakeHandlers) {
|
||||
PlayerLink link = guice.getInstance(PlayerLinkLoader.class).load();
|
||||
|
||||
public void init(
|
||||
FloodgateApi api,
|
||||
PlayerLink link,
|
||||
PacketHandlers packetHandlers,
|
||||
HandshakeHandlers handshakeHandlers) {
|
||||
InstanceHolder.set(api, link, this.injector, packetHandlers, handshakeHandlers, KEY);
|
||||
|
||||
guice.getInstance(NewsChecker.class).start();
|
||||
}
|
||||
|
||||
public void enable(Module... postInitializeModules) throws RuntimeException {
|
||||
@@ -75,10 +70,6 @@ public class FloodgatePlatform {
|
||||
|
||||
this.guice = guice.createChildInjector(new PostInitializeModule(postInitializeModules));
|
||||
|
||||
//todo add some kind of auto-load, as this looks kinda weird
|
||||
guice.getInstance(PostEnableMessages.class);
|
||||
guice.getInstance(Metrics.class);
|
||||
|
||||
guice.getInstance(PubSubSupport.class).publish(new PostEnableEvent());
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Floodgate
|
||||
*/
|
||||
|
||||
package org.geysermc.floodgate.module;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import org.geysermc.floodgate.util.AutoBind;
|
||||
import org.geysermc.floodgate.util.Utils;
|
||||
|
||||
public class AutoBindModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
for (Class<?> clazz : Utils.getGeneratedClassesForAnnotation(AutoBind.class)) {
|
||||
bind(clazz).asEagerSingleton();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,7 @@ import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.geysermc.floodgate.api.SimpleFloodgateApi;
|
||||
import org.geysermc.floodgate.api.handshake.HandshakeHandlers;
|
||||
import org.geysermc.floodgate.api.inject.PlatformInjector;
|
||||
import org.geysermc.floodgate.api.link.PlayerLink;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.api.packet.PacketHandlers;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
@@ -56,7 +57,7 @@ import org.geysermc.floodgate.crypto.FloodgateCipher;
|
||||
import org.geysermc.floodgate.crypto.KeyProducer;
|
||||
import org.geysermc.floodgate.event.util.ListenerAnnotationMatcher;
|
||||
import org.geysermc.floodgate.inject.CommonPlatformInjector;
|
||||
import org.geysermc.floodgate.news.NewsChecker;
|
||||
import org.geysermc.floodgate.link.PlayerLinkLoader;
|
||||
import org.geysermc.floodgate.packet.PacketHandlersImpl;
|
||||
import org.geysermc.floodgate.player.FloodgateHandshakeHandler;
|
||||
import org.geysermc.floodgate.pluginmessage.PluginMessageManager;
|
||||
@@ -92,7 +93,7 @@ public class CommonModule extends AbstractModule {
|
||||
bind(PacketHandlers.class).to(PacketHandlersImpl.class);
|
||||
bind(PacketHandlersImpl.class).asEagerSingleton();
|
||||
|
||||
bind(NewsChecker.class).in(Singleton.class);
|
||||
install(new AutoBindModule());
|
||||
}
|
||||
|
||||
@Provides
|
||||
@@ -101,6 +102,12 @@ public class CommonModule extends AbstractModule {
|
||||
return configLoader.load();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public PlayerLink playerLink(PlayerLinkLoader linkLoader) {
|
||||
return linkLoader.load();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public KeyProducer keyProducer() {
|
||||
|
||||
@@ -46,10 +46,12 @@ import org.geysermc.floodgate.news.data.AnnouncementData;
|
||||
import org.geysermc.floodgate.news.data.BuildSpecificData;
|
||||
import org.geysermc.floodgate.news.data.CheckAfterData;
|
||||
import org.geysermc.floodgate.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.util.AutoBind;
|
||||
import org.geysermc.floodgate.util.Constants;
|
||||
import org.geysermc.floodgate.util.HttpClient;
|
||||
import org.geysermc.floodgate.util.HttpClient.HttpResponse;
|
||||
|
||||
@AutoBind
|
||||
@Listener
|
||||
public class NewsChecker {
|
||||
private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
|
||||
@@ -71,6 +73,7 @@ public class NewsChecker {
|
||||
|
||||
private boolean firstCheck;
|
||||
|
||||
@Inject
|
||||
public void start() {
|
||||
executorService.scheduleWithFixedDelay(this::checkNews, 0, 30, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
38
core/src/main/java/org/geysermc/floodgate/util/AutoBind.java
Normal file
38
core/src/main/java/org/geysermc/floodgate/util/AutoBind.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Floodgate
|
||||
*/
|
||||
|
||||
package org.geysermc.floodgate.util;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Automatically binds an instance of itself as an eager singleton during the post-initialise stage
|
||||
* of the FloodgatePlatform. Add the annotation to a class, and it should automatically create an
|
||||
* instance and inject it for you.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface AutoBind {
|
||||
}
|
||||
@@ -44,6 +44,7 @@ import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig.MetricsConfig;
|
||||
import org.geysermc.floodgate.platform.util.PlatformUtils;
|
||||
|
||||
@AutoBind
|
||||
public final class Metrics {
|
||||
private final MetricsBase metricsBase;
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
import org.geysermc.floodgate.event.PostEnableEvent;
|
||||
|
||||
@AutoBind
|
||||
@Listener
|
||||
public final class PostEnableMessages {
|
||||
private final List<String> messages = new ArrayList<>();
|
||||
|
||||
@@ -28,15 +28,20 @@ package org.geysermc.floodgate.util;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Utils {
|
||||
private static final Pattern NON_UNIQUE_PREFIX = Pattern.compile("^\\w{0,16}$");
|
||||
@@ -131,4 +136,42 @@ public class Utils {
|
||||
future.completeExceptionally(ex);
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a set of all the classes that are annotated by a given annotation.
|
||||
* Keep in mind that these are from a set of generated annotations generated
|
||||
* at compile time by the annotation processor, meaning that arbitrary annotations
|
||||
* cannot be passed into this method and expected to get a set of classes back.
|
||||
*
|
||||
* @param annotationClass the annotation class
|
||||
* @return a set of all the classes annotated by the given annotation
|
||||
*/
|
||||
public static Set<Class<?>> getGeneratedClassesForAnnotation(Class<? extends Annotation> annotationClass) {
|
||||
return getGeneratedClassesForAnnotation(annotationClass.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a set of all the classes that are annotated by a given annotation.
|
||||
* Keep in mind that these are from a set of generated annotations generated
|
||||
* at compile time by the annotation processor, meaning that arbitrary annotations
|
||||
* cannot be passed into this method and expected to have a set of classes
|
||||
* returned back.
|
||||
*
|
||||
* @param input the fully qualified name of the annotation
|
||||
* @return a set of all the classes annotated by the given annotation
|
||||
*/
|
||||
public static Set<Class<?>> getGeneratedClassesForAnnotation(String input) {
|
||||
try (InputStream annotatedClass = Utils.class.getClassLoader().getResourceAsStream(input);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(annotatedClass))) {
|
||||
return reader.lines().map(className -> {
|
||||
try {
|
||||
return Class.forName(className);
|
||||
} catch (ClassNotFoundException ex) {
|
||||
throw new RuntimeException("Failed to find class for annotation " + input, ex);
|
||||
}
|
||||
}).collect(Collectors.toSet());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ pluginManagement {
|
||||
rootProject.name = "floodgate-parent"
|
||||
|
||||
include(":api")
|
||||
include(":ap")
|
||||
include(":core")
|
||||
include(":bungee")
|
||||
include(":spigot")
|
||||
|
||||
Reference in New Issue
Block a user