mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2024-11-26 20:26:01 +01:00
Improve dependency graph task
- Simplify logic for converting a dependency description to its display name - Add new common supertypes
This commit is contained in:
parent
dfd81b069a
commit
3e95d30c6b
@ -3,16 +3,22 @@ package tools.dependencygraph;
|
||||
import ch.jalu.injector.handlers.instantiation.DependencyDescription;
|
||||
import ch.jalu.injector.handlers.instantiation.Instantiation;
|
||||
import ch.jalu.injector.handlers.instantiation.StandardInjectionProvider;
|
||||
import ch.jalu.injector.utils.ReflectionUtils;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Multimap;
|
||||
import fr.xephi.authme.ClassCollector;
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.command.executable.authme.debug.DebugCommand;
|
||||
import fr.xephi.authme.data.limbo.persistence.LimboPersistence;
|
||||
import fr.xephi.authme.datasource.converter.Converter;
|
||||
import fr.xephi.authme.initialization.DataFolder;
|
||||
import fr.xephi.authme.initialization.factory.Factory;
|
||||
import fr.xephi.authme.initialization.factory.SingletonStore;
|
||||
import fr.xephi.authme.process.AsynchronousProcess;
|
||||
import fr.xephi.authme.process.SynchronousProcess;
|
||||
import fr.xephi.authme.process.register.executors.RegistrationExecutor;
|
||||
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
||||
import org.bukkit.event.Listener;
|
||||
import tools.utils.ToolTask;
|
||||
@ -20,13 +26,14 @@ import tools.utils.ToolsConstants;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
@ -36,8 +43,7 @@ public class DrawDependency implements ToolTask {
|
||||
|
||||
private static final String DOT_FILE = ToolsConstants.TOOLS_SOURCE_ROOT + "dependencygraph/graph.dot";
|
||||
|
||||
private static final List<Class<?>> SUPER_TYPES = ImmutableList.of(ExecutableCommand.class,
|
||||
SynchronousProcess.class, AsynchronousProcess.class, EncryptionMethod.class, Converter.class, Listener.class);
|
||||
private static final List<Class<?>> SUPER_TYPES = buildSuperTypesList();
|
||||
|
||||
/** Annotation types by which dependencies are identified. */
|
||||
private static final List<Class<? extends Annotation>> ANNOTATION_TYPES = ImmutableList.of(DataFolder.class);
|
||||
@ -113,6 +119,24 @@ public class DrawDependency implements ToolTask {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parameter of generic container classes, otherwise the input class.
|
||||
* This is interesting so that a dependency in a class to {@code Factory<Foo>} is
|
||||
* rendered as a dependency to {@code Foo}, not to {@code Factory}.
|
||||
*
|
||||
* @param clazz class of the dependency
|
||||
* @param genericType generic type of the dependency
|
||||
* @return the class to use to render the dependency
|
||||
*/
|
||||
private Class<?> unwrapGenericClass(Class<?> clazz, Type genericType) {
|
||||
if (clazz == Factory.class || clazz == SingletonStore.class) {
|
||||
Class<?> parameterType = ReflectionUtils.getGenericType(genericType);
|
||||
Objects.requireNonNull(parameterType, "Parameter type for '" + clazz + "' should be a concrete class");
|
||||
return parameterType;
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
|
||||
private List<String> getDependencies(Class<?> clazz) {
|
||||
Instantiation<?> instantiation = new StandardInjectionProvider().safeGet(clazz);
|
||||
return instantiation == null ? null : formatInjectionDependencies(instantiation);
|
||||
@ -127,21 +151,15 @@ public class DrawDependency implements ToolTask {
|
||||
* @return list of dependencies in a friendly format
|
||||
*/
|
||||
private List<String> formatInjectionDependencies(Instantiation<?> injection) {
|
||||
List<? extends DependencyDescription> descriptions = injection.getDependencies();
|
||||
final int totalDependencies = descriptions.size();
|
||||
Class<?>[] dependencies = new Class<?>[totalDependencies];
|
||||
Class<?>[] annotations = new Class<?>[totalDependencies];
|
||||
for (int i = 0; i < descriptions.size(); ++i) {
|
||||
dependencies[i] = descriptions.get(i).getType();
|
||||
annotations[i] = getRelevantAnnotationClass(descriptions.get(i).getAnnotations());
|
||||
}
|
||||
|
||||
List<String> result = new ArrayList<>(dependencies.length);
|
||||
for (int i = 0; i < dependencies.length; ++i) {
|
||||
if (annotations[i] != null) {
|
||||
result.add("@" + annotations[i].getSimpleName());
|
||||
List<DependencyDescription> descriptions = injection.getDependencies();
|
||||
List<String> result = new ArrayList<>(descriptions.size());
|
||||
for (DependencyDescription dependency : descriptions) {
|
||||
Class<?> annotation = getRelevantAnnotationClass(dependency.getAnnotations());
|
||||
if (annotation != null) {
|
||||
result.add("@" + annotation.getSimpleName());
|
||||
} else {
|
||||
result.add(mapToSuper(dependencies[i]).getSimpleName());
|
||||
Class<?> clazz = unwrapGenericClass(dependency.getType(), dependency.getGenericType());
|
||||
result.add(mapToSuper(clazz).getSimpleName());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -169,12 +187,26 @@ public class DrawDependency implements ToolTask {
|
||||
dependencies.put(entry.getValue(), Boolean.TRUE);
|
||||
}
|
||||
|
||||
Iterator<Class<?>> it = foundDependencies.keys().iterator();
|
||||
while (it.hasNext()) {
|
||||
Class<?> clazz = it.next();
|
||||
if (Boolean.FALSE.equals(dependencies.get(clazz.getSimpleName()))) {
|
||||
it.remove();
|
||||
}
|
||||
foundDependencies.keys().removeIf(
|
||||
clazz -> Boolean.FALSE.equals(dependencies.get(clazz.getSimpleName())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list of classes in AuthMe which have multiple extensions
|
||||
*/
|
||||
private static List<Class<?>> buildSuperTypesList() {
|
||||
try {
|
||||
// Get package-private classes
|
||||
Class<?> debugSectionClass = Class.forName(
|
||||
DebugCommand.class.getPackage().getName() + ".DebugSection");
|
||||
Class<?> limboPersistenceClass = Class.forName(
|
||||
LimboPersistence.class.getPackage().getName() + ".LimboPersistenceHandler");
|
||||
|
||||
return ImmutableList.of(ExecutableCommand.class, SynchronousProcess.class, AsynchronousProcess.class,
|
||||
EncryptionMethod.class, Converter.class, Listener.class, RegistrationExecutor.class, debugSectionClass,
|
||||
limboPersistenceClass);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user