Update linkage api
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Dieser Commit ist enthalten in:
yoyosource 2022-09-22 11:52:09 +02:00
Ursprung f152d790ce
Commit 1c7e9ad039
14 geänderte Dateien mit 435 neuen und 56 gelöschten Zeilen

Datei anzeigen

@ -83,6 +83,16 @@ dependencies {
testImplementation 'org.hamcrest:hamcrest:2.2' testImplementation 'org.hamcrest:hamcrest:2.2'
} }
task buildResources {
doLast {
File to = new File("${buildDir}/classes/java/main/META-INF/services/javax.annotation.processing.Processor")
to.parentFile.mkdirs()
to.createNewFile()
to.append("de.steamwar.linkage.LinkageProcessor\n")
}
}
classes.finalizedBy(buildResources)
task buildProject { task buildProject {
description 'Build this project' description 'Build this project'
group "Steamwar" group "Steamwar"

Datei anzeigen

@ -19,21 +19,36 @@
package de.steamwar.linkage; package de.steamwar.linkage;
import de.steamwar.linkage.plan.BuildPlan;
import de.steamwar.linkage.plan.FieldBuilder;
import de.steamwar.linkage.plan.MethodBuilder;
import de.steamwar.linkage.plan.ParameterBuilder;
import de.steamwar.linkage.types.ListenerLink;
import lombok.Getter;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import javax.annotation.processing.*; import javax.annotation.processing.*;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.*;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic; import javax.tools.Diagnostic;
import javax.tools.StandardLocation; import java.io.BufferedWriter;
import java.io.BufferedReader; import java.io.File;
import java.io.InputStreamReader;
import java.io.Writer; import java.io.Writer;
import java.util.Set; import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@SupportedAnnotationTypes("de.steamwar.linkage.Linked") @SupportedAnnotationTypes({"de.steamwar.linkage.Linked", "de.steamwar.linkage.Linked$Linkages"})
public class LinkageProcessor extends AbstractProcessor { public class LinkageProcessor extends AbstractProcessor {
@Getter
private static LinkageType.Context context;
private String packageName;
private String className;
private Messager messager; private Messager messager;
private Writer writer; private Writer writer;
private boolean processed = false; private boolean processed = false;
@ -48,24 +63,168 @@ public class LinkageProcessor extends AbstractProcessor {
public synchronized void init(ProcessingEnvironment processingEnv) { public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv); super.init(processingEnv);
String name = new BufferedReader(new InputStreamReader(processingEnv.getFiler().getResource(StandardLocation.CLASS_OUTPUT, "", "plugin.yml").openInputStream())) String name = new File(System.getProperty("user.dir")).getName();
.lines() if (name.contains(".")) name = name.substring(0, name.indexOf('.'));
.filter(s -> s.startsWith("name: ")) name = name.toLowerCase();
.map(s -> s.substring(6)) context = name.contains("bungee") ? LinkageType.Context.BUNGEE : LinkageType.Context.SPIGOT;
.map(String::toLowerCase)
.findFirst()
.orElse(null);
if (name == null) {
messager.printMessage(Diagnostic.Kind.ERROR, "Could not find plugin name in plugin.yml");
return;
}
writer = processingEnv.getFiler().createSourceFile("de.steamwar." + name + ".linkage.LinkageUtils").openWriter(); writer = processingEnv.getFiler().createSourceFile("de.steamwar." + name + ".linkage.LinkageUtils").openWriter();
messager = processingEnv.getMessager(); messager = processingEnv.getMessager();
packageName = "de.steamwar." + name + ".linkage";
className = "LinkageUtils";
} }
@SneakyThrows
@Override @Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
return false; messager.printMessage(Diagnostic.Kind.NOTE, "Processing linkage types");
if (processed) return false;
processed = true;
BuildPlan buildPlan = new BuildPlan(packageName, className);
buildPlan.addImport("java.util.Set");
buildPlan.addImport("java.lang.Class");
buildPlan.addImport("de.steamwar.linkage.LinkageType");
buildPlan.addImport("java.util.HashSet");
buildPlan.addField(new FieldBuilder("Set<Class<? extends LinkageType>>", "enabled", "new HashSet<>()"));
MethodBuilder runMethod = new MethodBuilder("run", "void");
buildPlan.addMethod(runMethod);
runMethod.addParameter(new ParameterBuilder("Class<? extends LinkageType>", "type"));
runMethod.addLine("if (!enabled.add(type)) return;");
Set<Class<? extends LinkageType>> alreadyGenerated = new HashSet<>();
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(Linked.class);
elements.addAll((Set) roundEnv.getElementsAnnotatedWith(Linked.Linkages.class));
Map<String, TypeElement> neededFields = new HashMap<>();
for (Element element : elements) {
if (element.getKind() != ElementKind.CLASS) {
continue;
}
TypeElement typeElement = (TypeElement) element;
Linked[] linkeds = element.getAnnotationsByType(Linked.class);
if (linkeds.length == 0) {
continue;
}
if (linkeds.length > 1) {
neededFields.put(typeElement.getQualifiedName().toString(), typeElement);
}
List<VariableElement> variableElements = typeElement.getEnclosedElements().stream().filter(e -> e.getKind() == ElementKind.FIELD).map(VariableElement.class::cast).filter(e -> {
return e.getAnnotation(LinkedInstance.class) != null;
}).collect(Collectors.toList());
if (variableElements.isEmpty()) {
continue;
}
for (VariableElement variableElement : variableElements) {
if (!variableElement.getModifiers().contains(Modifier.PUBLIC)) {
messager.printMessage(Diagnostic.Kind.ERROR, "Field " + variableElement.getSimpleName() + " must be public", variableElement);
continue;
}
if (variableElement.getModifiers().contains(Modifier.STATIC)) {
messager.printMessage(Diagnostic.Kind.ERROR, "Field " + variableElement.getSimpleName() + " must be non static", variableElement);
continue;
}
if (variableElement.getModifiers().contains(Modifier.FINAL)) {
messager.printMessage(Diagnostic.Kind.ERROR, "Field " + variableElement.getSimpleName() + " must be non final", variableElement);
continue;
}
neededFields.put(typeElement.getQualifiedName().toString(), typeElement);
TypeElement fieldType = (TypeElement) ((DeclaredType) variableElement.asType()).asElement();
neededFields.put(fieldType.getQualifiedName().toString(), fieldType);
buildPlan.addStaticLine(getElement(typeElement, neededFields) + "." + variableElement.getSimpleName().toString() + " = " + getElement((TypeElement) ((DeclaredType) variableElement.asType()).asElement(), neededFields) + ";");
}
}
neededFields.forEach((s, typeElement) -> {
buildPlan.addImport(typeElement.getQualifiedName().toString());
buildPlan.addField(new FieldBuilder(typeElement.getSimpleName().toString(), typeElement.getSimpleName().toString()));
MethodBuilder initializer = new MethodBuilder(typeElement.getSimpleName().toString(), typeElement.getSimpleName().toString());
initializer.addLine("if (" + typeElement.getSimpleName().toString() + " == null) {");
initializer.addLine(" " + typeElement.getSimpleName().toString() + " = new " + typeElement.getSimpleName().toString() + "();");
initializer.addLine("}");
initializer.addLine("return " + typeElement.getSimpleName().toString() + ";");
buildPlan.addMethod(initializer);
});
Map<Class<?>, MethodBuilder> methods = new HashMap<>();
for (Element element : elements) {
if (element.getKind() != ElementKind.CLASS) {
continue;
}
TypeElement typeElement = (TypeElement) element;
MinVersion minVersion = element.getAnnotation(MinVersion.class);
System.out.println("Found element: " + typeElement.getQualifiedName().toString());
element.getAnnotationMirrors().forEach(annotationMirror -> {
if (!annotationMirror.getAnnotationType().asElement().getSimpleName().toString().equals("Linked")) return;
Class<?> clazz = annotationMirror.getElementValues().entrySet().stream()
.filter(entry -> entry.getKey().getSimpleName().toString().equals("value"))
.map(Map.Entry::getValue)
.map(AnnotationValue::getValue)
.map(Object::toString)
.map(s -> {
try {
return Class.forName(s);
} catch (ClassNotFoundException e) {
return null;
}
})
.findFirst()
.orElse(null);
if (clazz == null) {
messager.printMessage(Diagnostic.Kind.ERROR, "No class specified", element);
return;
}
LinkageType type = null;
try {
type = (LinkageType) clazz.getDeclaredConstructor().newInstance();
} catch (Exception e) {
messager.printMessage(Diagnostic.Kind.ERROR, "Could not instantiate class", element);
return;
}
if (!type.requirements(typeElement.getSuperclass().toString(), typeElement.getInterfaces().stream().map(TypeMirror::toString).collect(Collectors.toSet()))) {
return;
}
if (alreadyGenerated.add((Class<? extends LinkageType>) clazz)) {
runMethod.addLine("if (type == " + clazz.getTypeName() + ".class) {");
runMethod.addLine(" run" + clazz.getSimpleName() + "();");
runMethod.addLine("}");
}
MethodBuilder method = methods.computeIfAbsent(clazz, t -> {
MethodBuilder methodBuilder = new MethodBuilder("run" + t.getSimpleName(), "void");
methodBuilder.setPrivate(true);
buildPlan.addMethod(methodBuilder);
return methodBuilder;
});
if (context == LinkageType.Context.SPIGOT && minVersion != null) {
method.addLine("if (de.steamwar.core.Core.getVersion() >= " + minVersion.value() + ") {");
}
type.generateCode(buildPlan, method, getElement(typeElement, neededFields), typeElement);
if (context == LinkageType.Context.SPIGOT && minVersion != null) {
method.addLine("}");
}
});
}
BufferedWriter writer = new BufferedWriter(this.writer);
buildPlan.write(writer);
writer.close();
return true;
}
private String getElement(TypeElement typeElement, Map<String, TypeElement> neededFields) {
if (neededFields.containsKey(typeElement.getQualifiedName().toString())) {
return typeElement.getSimpleName().toString() + "()";
}
return "new " + typeElement.getQualifiedName().toString() + "()";
} }
} }

Datei anzeigen

@ -22,14 +22,22 @@ package de.steamwar.linkage;
import de.steamwar.linkage.plan.BuildPlan; import de.steamwar.linkage.plan.BuildPlan;
import de.steamwar.linkage.plan.MethodBuilder; import de.steamwar.linkage.plan.MethodBuilder;
import javax.lang.model.element.TypeElement;
import java.util.OptionalInt;
import java.util.Set;
public interface LinkageType { public interface LinkageType {
default Class<?> clazzType() { Context context = LinkageProcessor.getContext();
return null;
} enum Context {
default Class<?> interfaceType() { BUNGEE,
return null; SPIGOT
} }
void generateCode(BuildPlan buildPlan, MethodBuilder linkageTypeMethod, String instance); default boolean requirements(String superClass, Set<String> interfaces) {
return true;
}
void generateCode(BuildPlan buildPlan, MethodBuilder linkageTypeMethod, String instance, TypeElement typeElement);
} }

Datei anzeigen

@ -25,7 +25,7 @@ import java.lang.annotation.*;
@Target({ElementType.TYPE}) @Target({ElementType.TYPE})
@Repeatable(Linked.Linkages.class) @Repeatable(Linked.Linkages.class)
public @interface Linked { public @interface Linked {
Class<LinkageType> value(); Class<? extends LinkageType> value();
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE}) @Target({ElementType.TYPE})

Datei anzeigen

@ -24,27 +24,32 @@ import lombok.RequiredArgsConstructor;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.*;
import java.util.Map;
@RequiredArgsConstructor @RequiredArgsConstructor
public class BuildPlan implements Writer { public class BuildPlan implements Writer {
private final String packageName; private final String packageName;
private Set<String> imports = new HashSet<>();
private final String className; private final String className;
private Map<Class<?>, FieldBuilder> fieldBuilderMap = new HashMap<>(); private Map<String, FieldBuilder> fieldBuilderMap = new HashMap<>();
private Map<String, MethodBuilder> methodBuilderMap = new HashMap<>(); private Map<String, MethodBuilder> methodBuilderMap = new HashMap<>();
private List<String> staticLines = new ArrayList<>();
public void addImport(String importName) {
imports.add(importName);
}
public void addField(FieldBuilder fieldBuilder) { public void addField(FieldBuilder fieldBuilder) {
fieldBuilderMap.putIfAbsent(fieldBuilder.getType(), fieldBuilder); fieldBuilderMap.putIfAbsent(fieldBuilder.getType(), fieldBuilder);
} }
public boolean hasField(Class<?> type) { public boolean hasField(String type) {
return fieldBuilderMap.containsKey(type); return fieldBuilderMap.containsKey(type);
} }
public String getFieldName(Class<?> type) { public String getFieldName(String type) {
return fieldBuilderMap.get(type).getFieldName(); return fieldBuilderMap.get(type).getFieldName();
} }
@ -56,19 +61,38 @@ public class BuildPlan implements Writer {
return methodBuilderMap.containsKey(methodName); return methodBuilderMap.containsKey(methodName);
} }
public void addStaticLine(String line) {
staticLines.add(line);
}
@Override @Override
public void write(BufferedWriter writer) throws IOException { public void write(BufferedWriter writer) throws IOException {
writer.write("package " + packageName + ";\n"); writer.write("package " + packageName + ";\n");
if (!imports.isEmpty()) {
writer.write("\n");
for (String importName : imports) {
writer.write("import " + importName + ";\n");
}
}
writer.write("\n"); writer.write("\n");
writer.write("public class " + className + " {\n"); writer.write("public class " + className + " {\n");
if (!fieldBuilderMap.isEmpty()) {
for (FieldBuilder fieldBuilder : fieldBuilderMap.values()) { for (FieldBuilder fieldBuilder : fieldBuilderMap.values()) {
fieldBuilder.write(writer); fieldBuilder.write(writer);
} }
if (!fieldBuilderMap.isEmpty() && !methodBuilderMap.isEmpty()) { writer.write("\n");
}
if (!staticLines.isEmpty()) {
writer.write(" static {\n");
for (String line : staticLines) {
writer.write(" " + line + "\n");
}
writer.write(" }\n");
writer.write("\n"); writer.write("\n");
} }
for (MethodBuilder methodBuilder : methodBuilderMap.values()) { for (MethodBuilder methodBuilder : methodBuilderMap.values()) {
methodBuilder.write(writer); methodBuilder.write(writer);
writer.write("\n");
} }
writer.write("}\n"); writer.write("}\n");
} }

Datei anzeigen

@ -22,21 +22,25 @@ package de.steamwar.linkage.plan;
import de.steamwar.linkage.Writer; import de.steamwar.linkage.Writer;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.IOException; import java.io.IOException;
@RequiredArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class FieldBuilder implements Writer { public class FieldBuilder implements Writer {
@Getter @Getter
private Class<?> type; private final String type;
private final String name;
private String initializer;
public String getFieldName() { public String getFieldName() {
return type.getSimpleName(); return name;
} }
@Override @Override
public void write(BufferedWriter writer) throws IOException { public void write(BufferedWriter writer) throws IOException {
writer.write(" private static " + type.getTypeName() + " " + getFieldName() + ";\n"); writer.write(" private static " + type + " " + getFieldName() + (initializer == null ? "" : " = " + initializer) + ";\n");
} }
} }

Datei anzeigen

@ -31,9 +31,10 @@ import java.util.List;
public class MethodBuilder implements Writer { public class MethodBuilder implements Writer {
private final String name; private final String name;
private final Class<?> returnType; private final String returnType;
private List<ParameterBuilder> parameters = new ArrayList<>(); private List<ParameterBuilder> parameters = new ArrayList<>();
private List<String> lines = new ArrayList<>(); private List<String> lines = new ArrayList<>();
private boolean isPrivate = false;
public void addParameter(ParameterBuilder parameterBuilder) { public void addParameter(ParameterBuilder parameterBuilder) {
parameters.add(parameterBuilder); parameters.add(parameterBuilder);
@ -47,9 +48,13 @@ public class MethodBuilder implements Writer {
return name; return name;
} }
public void setPrivate(boolean isPrivate) {
this.isPrivate = isPrivate;
}
@Override @Override
public void write(BufferedWriter writer) throws IOException { public void write(BufferedWriter writer) throws IOException {
writer.write(" public static " + returnType.getTypeName() + " " + getMethodName() + "("); writer.write(" " + (isPrivate ? "private" : "public") + " static " + returnType + " " + getMethodName() + "(");
for (int i = 0; i < parameters.size(); i++) { for (int i = 0; i < parameters.size(); i++) {
parameters.get(i).write(writer); parameters.get(i).write(writer);
if (i < parameters.size() - 1) { if (i < parameters.size() - 1) {
@ -58,8 +63,10 @@ public class MethodBuilder implements Writer {
} }
writer.write(") {"); writer.write(") {");
for (String line : lines) { for (String line : lines) {
writer.write("\n");
writer.write(" " + line); writer.write(" " + line);
} }
writer.write("\n");
writer.write(" }\n"); writer.write(" }\n");
} }
} }

Datei anzeigen

@ -27,11 +27,11 @@ import java.io.IOException;
@AllArgsConstructor @AllArgsConstructor
public class ParameterBuilder implements Writer { public class ParameterBuilder implements Writer {
private Class<?> type; private String type;
private String name; private String name;
@Override @Override
public void write(BufferedWriter writer) throws IOException { public void write(BufferedWriter writer) throws IOException {
writer.write(type.getTypeName() + " " + name); writer.write(type + " " + name);
} }
} }

Datei anzeigen

@ -19,19 +19,15 @@
package de.steamwar.linkage.types; package de.steamwar.linkage.types;
import de.steamwar.command.AbstractSWCommand;
import de.steamwar.linkage.LinkageType; import de.steamwar.linkage.LinkageType;
import de.steamwar.linkage.plan.BuildPlan; import de.steamwar.linkage.plan.BuildPlan;
import de.steamwar.linkage.plan.MethodBuilder; import de.steamwar.linkage.plan.MethodBuilder;
import javax.lang.model.element.TypeElement;
public class Command implements LinkageType { public class Command implements LinkageType {
@Override @Override
public Class<?> clazzType() { public void generateCode(BuildPlan buildPlan, MethodBuilder linkageTypeMethod, String instance, TypeElement typeElement) {
return AbstractSWCommand.class;
}
@Override
public void generateCode(BuildPlan buildPlan, MethodBuilder linkageTypeMethod, String instance) {
} }
} }

Datei anzeigen

@ -20,20 +20,21 @@
package de.steamwar.linkage.types; package de.steamwar.linkage.types;
import de.steamwar.linkage.LinkageType; import de.steamwar.linkage.LinkageType;
import de.steamwar.linkage.api.Disable;
import de.steamwar.linkage.api.Enable;
import de.steamwar.linkage.plan.BuildPlan; import de.steamwar.linkage.plan.BuildPlan;
import de.steamwar.linkage.plan.MethodBuilder; import de.steamwar.linkage.plan.MethodBuilder;
import javax.lang.model.element.TypeElement;
import java.util.Set;
public class DisableLink implements LinkageType { public class DisableLink implements LinkageType {
@Override @Override
public Class<?> interfaceType() { public boolean requirements(String superClass, Set<String> interfaces) {
return Disable.class; return interfaces.contains("de.steamwar.linkage.api.Disable");
} }
@Override @Override
public void generateCode(BuildPlan buildPlan, MethodBuilder linkageTypeMethod, String instance) { public void generateCode(BuildPlan buildPlan, MethodBuilder linkageTypeMethod, String instance, TypeElement typeElement) {
linkageTypeMethod.addLine(instance + ".disable();"); linkageTypeMethod.addLine(instance + ".disable();");
} }
} }

Datei anzeigen

@ -24,15 +24,18 @@ import de.steamwar.linkage.api.Enable;
import de.steamwar.linkage.plan.BuildPlan; import de.steamwar.linkage.plan.BuildPlan;
import de.steamwar.linkage.plan.MethodBuilder; import de.steamwar.linkage.plan.MethodBuilder;
import javax.lang.model.element.TypeElement;
import java.util.Set;
public class EnableLink implements LinkageType { public class EnableLink implements LinkageType {
@Override @Override
public Class<?> interfaceType() { public boolean requirements(String superClass, Set<String> interfaces) {
return Enable.class; return interfaces.contains("de.steamwar.linkage.api.Enable");
} }
@Override @Override
public void generateCode(BuildPlan buildPlan, MethodBuilder linkageTypeMethod, String instance) { public void generateCode(BuildPlan buildPlan, MethodBuilder linkageTypeMethod, String instance, TypeElement typeElement) {
linkageTypeMethod.addLine(instance + ".enable();"); linkageTypeMethod.addLine(instance + ".enable();");
} }
} }

Datei anzeigen

@ -0,0 +1,114 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 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.linkage.types;
import de.steamwar.linkage.LinkageType;
import de.steamwar.linkage.plan.BuildPlan;
import de.steamwar.linkage.plan.FieldBuilder;
import de.steamwar.linkage.plan.MethodBuilder;
import de.steamwar.linkage.plan.ParameterBuilder;
import lombok.SneakyThrows;
import javax.lang.model.element.*;
import javax.lang.model.type.DeclaredType;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class ListenerLink implements LinkageType {
@Override
public boolean requirements(String superClass, Set<String> interfaces) {
if (context == Context.BUNGEE) {
return interfaces.contains("net.md_5.bungee.api.plugin.Listener");
} else {
return interfaces.contains("org.bukkit.event.Listener");
}
}
@Override
public void generateCode(BuildPlan buildPlan, MethodBuilder linkageTypeMethod, String instance, TypeElement typeElement) {
if (context == Context.BUNGEE) {
buildPlan.addImport("net.md_5.bungee.api.ProxyServer");
buildPlan.addImport("de.steamwar.bungeecore.BungeeCore");
linkageTypeMethod.addLine("ProxyServer.getInstance().getPluginManager().registerListener(BungeeCore.get(), " + instance + ");");
} else {
Map<String, TypeElement> eventClasses = new HashMap<>();
Map<TypeElement, ExecutableElement> eventMethods = new HashMap<>();
typeElement.getEnclosedElements().stream().filter(e -> e.getKind() == ElementKind.METHOD).map(ExecutableElement.class::cast).filter(e -> {
return e.getAnnotationMirrors().stream().anyMatch(annotationMirror -> {
return annotationMirror.getAnnotationType().asElement().getSimpleName().toString().equals("EventHandler");
});
}).forEach(e -> {
TypeElement current = ((TypeElement)((DeclaredType) e.getParameters().get(0).asType()).asElement());
eventClasses.put(current.getQualifiedName().toString(), current);
eventMethods.put(current, e);
});
eventClasses.forEach((s, eventType) -> {
if (buildPlan.hasMethod(s)) return;
buildPlan.addImport("org.bukkit.event.HandlerList");
buildPlan.addImport("org.bukkit.event.Listener");
buildPlan.addImport("java.util.function.Consumer");
buildPlan.addImport("org.bukkit.event.EventPriority");
buildPlan.addImport("org.bukkit.plugin.RegisteredListener");
buildPlan.addImport("org.bukkit.plugin.EventExecutor");
buildPlan.addImport("de.steamwar.core.Core");
buildPlan.addImport(s);
buildPlan.addField(new FieldBuilder("HandlerList", "handlerList" + eventType.getSimpleName()));
MethodBuilder methodBuilder = new MethodBuilder(eventType.getSimpleName().toString(), "void");
methodBuilder.addParameter(new ParameterBuilder("Listener", "listener"));
methodBuilder.addParameter(new ParameterBuilder("Consumer<" + eventType.getSimpleName() + ">", "consumer"));
methodBuilder.addParameter(new ParameterBuilder("EventPriority", "eventPriority"));
methodBuilder.addParameter(new ParameterBuilder("boolean", "ignoreCancelled"));
methodBuilder.setPrivate(true);
methodBuilder.addLine("EventExecutor eventExecutor = (l, event) -> {");
methodBuilder.addLine(" if (event instanceof " + eventType.getSimpleName() + ") {");
methodBuilder.addLine(" consumer.accept((" + eventType.getSimpleName() + ") event);");
methodBuilder.addLine(" }");
methodBuilder.addLine("};");
methodBuilder.addLine("handlerList" + eventType.getSimpleName() + ".register(new RegisteredListener(listener, eventExecutor, eventPriority, Core.getInstance(), ignoreCancelled));");
buildPlan.addMethod(methodBuilder);
linkageTypeMethod.addLine("handlerList" + eventType.getSimpleName() + " = " + s + ".getHandlerList();");
});
buildPlan.addImport(typeElement.getQualifiedName().toString());
String localInstance = "local" + typeElement.getSimpleName().toString();
linkageTypeMethod.addLine(typeElement.getSimpleName() + " " + localInstance + " = " + instance + ";");
eventMethods.forEach((type, executableElement) -> {
AnnotationMirror eventHandler = executableElement.getAnnotationMirrors().stream().filter(annotationMirror -> annotationMirror.getAnnotationType().asElement().getSimpleName().toString().equals("EventHandler")).findFirst().orElse(null);
if (eventHandler == null) {
return;
}
String priority = "NORMAL";
String ignoreCancelled = "false";
for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : eventHandler.getElementValues().entrySet()) {
if (entry.getKey().getSimpleName().toString().equals("priority")) {
priority = entry.getValue().getValue().toString();
} else if (entry.getKey().getSimpleName().toString().equals("ignoreCancelled")) {
ignoreCancelled = entry.getValue().getValue().toString();
}
}
linkageTypeMethod.addLine(type.getSimpleName().toString() + "(" + localInstance + ", " + localInstance + "::" + executableElement.getSimpleName().toString() + ", EventPriority." + priority + ", " + ignoreCancelled + ");");
});
}
}
}

Datei anzeigen

@ -23,10 +23,12 @@ import de.steamwar.linkage.LinkageType;
import de.steamwar.linkage.plan.BuildPlan; import de.steamwar.linkage.plan.BuildPlan;
import de.steamwar.linkage.plan.MethodBuilder; import de.steamwar.linkage.plan.MethodBuilder;
import javax.lang.model.element.TypeElement;
public class Plain implements LinkageType { public class Plain implements LinkageType {
@Override @Override
public void generateCode(BuildPlan buildPlan, MethodBuilder linkageTypeMethod, String instance) { public void generateCode(BuildPlan buildPlan, MethodBuilder linkageTypeMethod, String instance, TypeElement typeElement) {
linkageTypeMethod.addLine(instance + ";"); linkageTypeMethod.addLine(instance + ";");
} }
} }

Datei anzeigen

@ -0,0 +1,51 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 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.linkage.types;
import de.steamwar.linkage.LinkageType;
import de.steamwar.linkage.plan.BuildPlan;
import de.steamwar.linkage.plan.MethodBuilder;
import javax.lang.model.element.TypeElement;
import java.util.Set;
public class UnlinkListener implements LinkageType {
@Override
public boolean requirements(String superClass, Set<String> interfaces) {
if (context == Context.BUNGEE) {
return interfaces.contains("net.md_5.bungee.api.plugin.Listener");
} else {
return interfaces.contains("org.bukkit.event.Listener");
}
}
@Override
public void generateCode(BuildPlan buildPlan, MethodBuilder linkageTypeMethod, String instance, TypeElement typeElement) {
if (context == Context.BUNGEE) {
buildPlan.addImport("net.md_5.bungee.api.ProxyServer");
buildPlan.addImport("de.steamwar.bungeecore.BungeeCore");
linkageTypeMethod.addLine("ProxyServer.getInstance().getPluginManager().registerListener(" + instance + ");");
} else {
buildPlan.addImport("org.bukkit.event.HandlerList");
linkageTypeMethod.addLine("HandlerList.unregisterAll(" + instance + ");");
}
}
}