Update to injector 1.0

- Includes Factory and SingletonStore so our custom implementation is removed
This commit is contained in:
ljacqu 2017-11-25 21:27:18 +01:00
parent 86a07771d7
commit 7932c1bf90
27 changed files with 64 additions and 209 deletions

View File

@ -302,7 +302,7 @@
<dependency>
<groupId>ch.jalu</groupId>
<artifactId>injector</artifactId>
<version>0.4.1</version>
<version>1.0</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>

View File

@ -12,8 +12,6 @@ import fr.xephi.authme.initialization.OnShutdownPlayerSaver;
import fr.xephi.authme.initialization.OnStartupTasks;
import fr.xephi.authme.initialization.SettingsProvider;
import fr.xephi.authme.initialization.TaskCloser;
import fr.xephi.authme.initialization.factory.FactoryDependencyHandler;
import fr.xephi.authme.initialization.factory.SingletonStoreDependencyHandler;
import fr.xephi.authme.listener.BlockListener;
import fr.xephi.authme.listener.EntityListener;
import fr.xephi.authme.listener.PlayerListener;
@ -201,7 +199,6 @@ public class AuthMe extends JavaPlugin {
// Create injector, provide elements from the Bukkit environment and register providers
injector = new InjectorBuilder()
.addHandlers(new FactoryDependencyHandler(), new SingletonStoreDependencyHandler())
.addDefaultHandlers("fr.xephi.authme")
.create();
injector.register(AuthMe.class, this);

View File

@ -1,8 +1,8 @@
package fr.xephi.authme.command;
import ch.jalu.injector.factory.Factory;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.help.HelpProvider;
import fr.xephi.authme.initialization.factory.Factory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.permission.PermissionsManager;

View File

@ -1,5 +1,6 @@
package fr.xephi.authme.command.executable.authme;
import ch.jalu.injector.factory.Factory;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSortedMap;
import fr.xephi.authme.ConsoleLogger;
@ -13,7 +14,6 @@ import fr.xephi.authme.datasource.converter.RoyalAuthConverter;
import fr.xephi.authme.datasource.converter.SqliteToSql;
import fr.xephi.authme.datasource.converter.VAuthConverter;
import fr.xephi.authme.datasource.converter.XAuthConverter;
import fr.xephi.authme.initialization.factory.Factory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.CommonService;

View File

@ -1,12 +1,12 @@
package fr.xephi.authme.command.executable.authme;
import ch.jalu.injector.factory.SingletonStore;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.initialization.SettingsDependent;
import fr.xephi.authme.initialization.factory.SingletonStore;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.settings.Settings;

View File

@ -1,5 +1,6 @@
package fr.xephi.authme.command.executable.authme.debug;
import ch.jalu.injector.factory.SingletonStore;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.datasource.CacheDataSource;
@ -7,7 +8,6 @@ import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.HasCleanup;
import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.initialization.SettingsDependent;
import fr.xephi.authme.initialization.factory.SingletonStore;
import fr.xephi.authme.permission.DebugSectionPermissions;
import fr.xephi.authme.permission.PermissionNode;
import org.bukkit.ChatColor;

View File

@ -1,8 +1,8 @@
package fr.xephi.authme.command.executable.authme.debug;
import ch.jalu.injector.factory.Factory;
import com.google.common.collect.ImmutableSet;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.initialization.factory.Factory;
import fr.xephi.authme.permission.PermissionsManager;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;

View File

@ -1,9 +1,9 @@
package fr.xephi.authme.data.limbo.persistence;
import ch.jalu.injector.factory.Factory;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.limbo.LimboPlayer;
import fr.xephi.authme.initialization.SettingsDependent;
import fr.xephi.authme.initialization.factory.Factory;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.LimboSettings;
import org.bukkit.entity.Player;

View File

@ -1,19 +0,0 @@
package fr.xephi.authme.initialization.factory;
/**
* Injectable factory that creates new instances of a certain type.
*
* @param <P> the parent type to which the factory is limited to
*/
public interface Factory<P> {
/**
* Creates an instance of the given class.
*
* @param clazz the class to instantiate
* @param <C> the class type
* @return new instance of the class
*/
<C extends P> C newInstance(Class<C> clazz);
}

View File

@ -1,46 +0,0 @@
package fr.xephi.authme.initialization.factory;
import ch.jalu.injector.Injector;
import ch.jalu.injector.context.ResolvedInstantiationContext;
import ch.jalu.injector.handlers.dependency.DependencyHandler;
import ch.jalu.injector.handlers.instantiation.DependencyDescription;
import ch.jalu.injector.utils.ReflectionUtils;
/**
* Dependency handler that builds {@link Factory} objects.
*/
public class FactoryDependencyHandler implements DependencyHandler {
@Override
public Object resolveValue(ResolvedInstantiationContext<?> context, DependencyDescription dependencyDescription) {
if (dependencyDescription.getType() == Factory.class) {
Class<?> genericType = ReflectionUtils.getGenericType(dependencyDescription.getGenericType());
if (genericType == null) {
throw new IllegalStateException("Factory fields must have concrete generic type. "
+ "Cannot get generic type for field in '" + context.getMappedClass() + "'");
}
return new FactoryImpl<>(genericType, context.getInjector());
}
return null;
}
private static final class FactoryImpl<P> implements Factory<P> {
private final Injector injector;
private final Class<P> parentClass;
FactoryImpl(Class<P> parentClass, Injector injector) {
this.parentClass = parentClass;
this.injector = injector;
}
@Override
public <C extends P> C newInstance(Class<C> clazz) {
if (parentClass.isAssignableFrom(clazz)) {
return injector.newInstance(clazz);
}
throw new IllegalArgumentException(clazz + " not child of " + parentClass);
}
}
}

View File

@ -1,37 +0,0 @@
package fr.xephi.authme.initialization.factory;
import java.util.Collection;
/**
* Injectable object to retrieve and create singletons of a common parent.
*
* @param <P> the parent class to which this store is limited to
*/
public interface SingletonStore<P> {
/**
* Returns the singleton of the given type, creating it if it hasn't been yet created.
*
* @param clazz the class to get the singleton for
* @param <C> type of the singleton
* @return the singleton of type {@code C}
*/
<C extends P> C getSingleton(Class<C> clazz);
/**
* Returns all existing singletons of this store's type.
*
* @return all registered singletons of type {@code P}
*/
Collection<P> retrieveAllOfType();
/**
* Returns all existing singletons of the given type.
*
* @param clazz the type to get singletons for
* @param <C> class type
* @return all registered singletons of type {@code C}
*/
<C extends P> Collection<C> retrieveAllOfType(Class<C> clazz);
}

View File

@ -1,61 +0,0 @@
package fr.xephi.authme.initialization.factory;
import ch.jalu.injector.Injector;
import ch.jalu.injector.context.ResolvedInstantiationContext;
import ch.jalu.injector.handlers.dependency.DependencyHandler;
import ch.jalu.injector.handlers.instantiation.DependencyDescription;
import ch.jalu.injector.utils.ReflectionUtils;
import java.util.Collection;
/**
* Dependency handler that builds {@link SingletonStore} objects.
*/
public class SingletonStoreDependencyHandler implements DependencyHandler {
@Override
public Object resolveValue(ResolvedInstantiationContext<?> context, DependencyDescription dependencyDescription) {
if (dependencyDescription.getType() == SingletonStore.class) {
Class<?> genericType = ReflectionUtils.getGenericType(dependencyDescription.getGenericType());
if (genericType == null) {
throw new IllegalStateException("Singleton store fields must have concrete generic type. "
+ "Cannot get generic type for field in '" + context.getMappedClass() + "'");
}
return new SingletonStoreImpl<>(genericType, context.getInjector());
}
return null;
}
private static final class SingletonStoreImpl<P> implements SingletonStore<P> {
private final Injector injector;
private final Class<P> parentClass;
SingletonStoreImpl(Class<P> parentClass, Injector injector) {
this.parentClass = parentClass;
this.injector = injector;
}
@Override
public <C extends P> C getSingleton(Class<C> clazz) {
if (parentClass.isAssignableFrom(clazz)) {
return injector.getSingleton(clazz);
}
throw new IllegalArgumentException(clazz + " not child of " + parentClass);
}
@Override
public Collection<P> retrieveAllOfType() {
return retrieveAllOfType(parentClass);
}
@Override
public <C extends P> Collection<C> retrieveAllOfType(Class<C> clazz) {
if (parentClass.isAssignableFrom(clazz)) {
return injector.retrieveAllOfType(clazz);
}
throw new IllegalArgumentException(clazz + " not child of " + parentClass);
}
}
}

View File

@ -1,9 +1,9 @@
package fr.xephi.authme.process.register;
import ch.jalu.injector.factory.SingletonStore;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.factory.SingletonStore;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.process.AsynchronousProcess;

View File

@ -1,9 +1,9 @@
package fr.xephi.authme.security;
import ch.jalu.injector.factory.Factory;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.PasswordEncryptionEvent;
import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.initialization.factory.Factory;
import fr.xephi.authme.security.crypts.EncryptionMethod;
import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.settings.Settings;

View File

@ -1,7 +1,7 @@
package fr.xephi.authme.task;
import ch.jalu.injector.factory.SingletonStore;
import fr.xephi.authme.initialization.HasCleanup;
import fr.xephi.authme.initialization.factory.SingletonStore;
import org.bukkit.scheduler.BukkitRunnable;
import javax.inject.Inject;

View File

@ -8,8 +8,6 @@ import fr.xephi.authme.api.v3.AuthMeApi;
import fr.xephi.authme.command.CommandHandler;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.initialization.factory.FactoryDependencyHandler;
import fr.xephi.authme.initialization.factory.SingletonStoreDependencyHandler;
import fr.xephi.authme.listener.BlockListener;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.process.Management;
@ -96,7 +94,6 @@ public class AuthMeInitializationTest {
new Settings(dataFolder, mock(PropertyResource.class), null, buildConfigurationData());
Injector injector = new InjectorBuilder()
.addHandlers(new FactoryDependencyHandler(), new SingletonStoreDependencyHandler())
.addDefaultHandlers("fr.xephi.authme")
.create();
injector.provide(DataFolder.class, dataFolder);

View File

@ -1,12 +1,12 @@
package fr.xephi.authme.command;
import ch.jalu.injector.Injector;
import ch.jalu.injector.factory.Factory;
import com.google.common.collect.Sets;
import fr.xephi.authme.command.TestCommandsUtil.TestLoginCommand;
import fr.xephi.authme.command.TestCommandsUtil.TestRegisterCommand;
import fr.xephi.authme.command.TestCommandsUtil.TestUnregisterCommand;
import fr.xephi.authme.command.help.HelpProvider;
import fr.xephi.authme.initialization.factory.Factory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.permission.PermissionsManager;

View File

@ -1,8 +1,8 @@
package fr.xephi.authme.command.executable.authme;
import ch.jalu.injector.factory.Factory;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.datasource.converter.Converter;
import fr.xephi.authme.initialization.factory.Factory;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.CommonService;

View File

@ -1,12 +1,12 @@
package fr.xephi.authme.command.executable.authme;
import ch.jalu.injector.factory.SingletonStore;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.datasource.DataSourceType;
import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.initialization.SettingsDependent;
import fr.xephi.authme.initialization.factory.SingletonStore;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.output.LogLevel;
import fr.xephi.authme.service.CommonService;

View File

@ -1,5 +1,6 @@
package fr.xephi.authme.command.executable.authme.debug;
import ch.jalu.injector.factory.SingletonStore;
import com.google.common.cache.LoadingCache;
import fr.xephi.authme.ReflectionTestUtils;
import fr.xephi.authme.data.auth.PlayerAuth;
@ -11,7 +12,6 @@ import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.HasCleanup;
import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.initialization.SettingsDependent;
import fr.xephi.authme.initialization.factory.SingletonStore;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.junit.Before;

View File

@ -1,6 +1,6 @@
package fr.xephi.authme.command.executable.authme.debug;
import fr.xephi.authme.initialization.factory.Factory;
import ch.jalu.injector.factory.Factory;
import fr.xephi.authme.permission.DebugSectionPermissions;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.permission.PermissionsManager;

View File

@ -1,12 +1,12 @@
package fr.xephi.authme.data.limbo.persistence;
import ch.jalu.injector.factory.Factory;
import ch.jalu.injector.testing.BeforeInjecting;
import ch.jalu.injector.testing.DelayedInjectionRunner;
import ch.jalu.injector.testing.InjectDelayed;
import fr.xephi.authme.ReflectionTestUtils;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.data.limbo.LimboPlayer;
import fr.xephi.authme.initialization.factory.Factory;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.LimboSettings;
import org.bukkit.entity.Player;

View File

@ -1,9 +1,9 @@
package fr.xephi.authme.process.register;
import ch.jalu.injector.factory.SingletonStore;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.factory.SingletonStore;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.process.register.executors.PasswordRegisterParams;

View File

@ -2,6 +2,7 @@ package fr.xephi.authme.security;
import ch.jalu.injector.Injector;
import ch.jalu.injector.InjectorBuilder;
import ch.jalu.injector.factory.Factory;
import ch.jalu.injector.testing.BeforeInjecting;
import ch.jalu.injector.testing.DelayedInjectionRunner;
import ch.jalu.injector.testing.InjectDelayed;
@ -9,7 +10,6 @@ import fr.xephi.authme.ReflectionTestUtils;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.PasswordEncryptionEvent;
import fr.xephi.authme.initialization.factory.Factory;
import fr.xephi.authme.security.crypts.EncryptionMethod;
import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.security.crypts.Joomla;

View File

@ -1,7 +1,7 @@
package fr.xephi.authme.task;
import ch.jalu.injector.factory.SingletonStore;
import fr.xephi.authme.initialization.HasCleanup;
import fr.xephi.authme.initialization.factory.SingletonStore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;

View File

@ -1,7 +1,9 @@
package tools.dependencygraph;
import ch.jalu.injector.handlers.instantiation.DependencyDescription;
import ch.jalu.injector.handlers.instantiation.Instantiation;
import ch.jalu.injector.context.ObjectIdentifier;
import ch.jalu.injector.factory.Factory;
import ch.jalu.injector.factory.SingletonStore;
import ch.jalu.injector.handlers.instantiation.Resolution;
import ch.jalu.injector.handlers.instantiation.StandardInjectionProvider;
import ch.jalu.injector.utils.ReflectionUtils;
import com.google.common.collect.HashMultimap;
@ -14,13 +16,12 @@ 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.InjectorUtils;
import tools.utils.ToolTask;
import tools.utils.ToolsConstants;
@ -124,21 +125,20 @@ public class DrawDependency implements ToolTask {
* 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) {
private Class<?> unwrapGenericClass(Type genericType) {
if (genericType == Factory.class || genericType == SingletonStore.class) {
Class<?> parameterType = ReflectionUtils.getGenericType(genericType);
Objects.requireNonNull(parameterType, "Parameter type for '" + clazz + "' should be a concrete class");
Objects.requireNonNull(parameterType, "Parameter type for '" + genericType + "' should be a concrete class");
return parameterType;
}
return clazz;
return InjectorUtils.convertToClass(genericType);
}
private List<String> getDependencies(Class<?> clazz) {
Instantiation<?> instantiation = new StandardInjectionProvider().safeGet(clazz);
Resolution<?> instantiation = new StandardInjectionProvider().safeGet(clazz);
return instantiation == null ? null : formatInjectionDependencies(instantiation);
}
@ -150,22 +150,22 @@ public class DrawDependency implements ToolTask {
* @param injection the injection whose dependencies should be formatted
* @return list of dependencies in a friendly format
*/
private List<String> formatInjectionDependencies(Instantiation<?> injection) {
List<DependencyDescription> descriptions = injection.getDependencies();
List<String> result = new ArrayList<>(descriptions.size());
for (DependencyDescription dependency : descriptions) {
private List<String> formatInjectionDependencies(Resolution<?> injection) {
List<ObjectIdentifier> dependencies = injection.getDependencies();
List<String> result = new ArrayList<>(dependencies.size());
for (ObjectIdentifier dependency : dependencies) {
Class<?> annotation = getRelevantAnnotationClass(dependency.getAnnotations());
if (annotation != null) {
result.add("@" + annotation.getSimpleName());
} else {
Class<?> clazz = unwrapGenericClass(dependency.getType(), dependency.getGenericType());
Class<?> clazz = unwrapGenericClass(dependency.getType());
result.add(mapToSuper(clazz).getSimpleName());
}
}
return result;
}
private static Class<? extends Annotation> getRelevantAnnotationClass(Annotation[] annotations) {
private static Class<? extends Annotation> getRelevantAnnotationClass(List<Annotation> annotations) {
for (Annotation annotation : annotations) {
if (ANNOTATION_TYPES.contains(annotation.annotationType())) {
return annotation.annotationType();

View File

@ -1,9 +1,11 @@
package tools.utils;
import ch.jalu.injector.handlers.instantiation.DependencyDescription;
import ch.jalu.injector.handlers.instantiation.Instantiation;
import ch.jalu.injector.context.ObjectIdentifier;
import ch.jalu.injector.handlers.instantiation.Resolution;
import ch.jalu.injector.handlers.instantiation.StandardInjectionProvider;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;
@ -22,15 +24,37 @@ public final class InjectorUtils {
* @return the class' dependencies, or null if no instantiation method found
*/
public static Set<Class<?>> getDependencies(Class<?> clazz) {
Instantiation<?> instantiation = new StandardInjectionProvider().safeGet(clazz);
Resolution<?> instantiation = new StandardInjectionProvider().safeGet(clazz);
if (instantiation == null) {
return null;
}
Set<Class<?>> dependencies = new HashSet<>();
for (DependencyDescription description : instantiation.getDependencies()) {
dependencies.add(description.getType());
for (ObjectIdentifier description : instantiation.getDependencies()) {
dependencies.add(convertToClass(description.getType()));
}
return dependencies;
}
/**
* Returns the given type as a {@link Class}.
*
* @param type the type to convert
* @return class corresponding to the provided type
*/
public static Class<?> convertToClass(Type type) {
if (type instanceof Class<?>) {
return (Class<?>) type;
} else if (type instanceof ParameterizedType) {
Type rawType = ((ParameterizedType) type).getRawType();
if (rawType instanceof Class<?>) {
return (Class<?>) rawType;
} else {
throw new IllegalStateException("Got raw type '" + rawType + "' of type '"
+ rawType.getClass() + "' for genericType '" + type + "'");
}
}
Class<?> typeClass = type == null ? null : type.getClass();
throw new IllegalStateException("Unknown type implementation '" + typeClass + "' for '" + type + "'");
}
}