🐛 Fix issue with TypeToken in the service pipeline

This commit is contained in:
Alexander Söderberg 2020-09-30 10:38:45 +02:00 committed by Alexander Söderberg
parent 0fbe1fe6a2
commit bea9c54841
2 changed files with 35 additions and 12 deletions

View file

@ -23,10 +23,11 @@
// //
package cloud.commandframework.services; package cloud.commandframework.services;
import io.leangen.geantyref.TypeToken;
import cloud.commandframework.services.types.Service; import cloud.commandframework.services.types.Service;
import io.leangen.geantyref.TypeToken;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.lang.reflect.Type;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -42,7 +43,7 @@ import java.util.function.Predicate;
public final class ServicePipeline { public final class ServicePipeline {
private final Object lock = new Object(); private final Object lock = new Object();
private final Map<TypeToken<? extends Service<?, ?>>, ServiceRepository<?, ?>> repositories; private final Map<Type, ServiceRepository<?, ?>> repositories;
private final Executor executor; private final Executor executor;
ServicePipeline(@NonNull final Executor executor) { ServicePipeline(@NonNull final Executor executor) {
@ -74,13 +75,13 @@ public final class ServicePipeline {
@NonNull final TypeToken<? extends Service<@NonNull Context, @NonNull Result>> type, @NonNull final TypeToken<? extends Service<@NonNull Context, @NonNull Result>> type,
@NonNull final Service<@NonNull Context, @NonNull Result> defaultImplementation) { @NonNull final Service<@NonNull Context, @NonNull Result> defaultImplementation) {
synchronized (this.lock) { synchronized (this.lock) {
if (repositories.containsKey(type)) { if (repositories.containsKey(type.getType())) {
throw new IllegalArgumentException(String throw new IllegalArgumentException(String
.format("Service of type '%s' has already been registered", type.toString())); .format("Service of type '%s' has already been registered", type.toString()));
} }
final ServiceRepository<Context, Result> repository = new ServiceRepository<>(type); final ServiceRepository<Context, Result> repository = new ServiceRepository<>(type);
repository.registerImplementation(defaultImplementation, Collections.emptyList()); repository.registerImplementation(defaultImplementation, Collections.emptyList());
this.repositories.put(type, repository); this.repositories.put(type.getType(), repository);
return this; return this;
} }
} }
@ -112,7 +113,7 @@ public final class ServicePipeline {
for (final Map.Entry<? extends Service<?, ?>, TypeToken<? extends Service<?, ?>>> serviceEntry : services for (final Map.Entry<? extends Service<?, ?>, TypeToken<? extends Service<?, ?>>> serviceEntry : services
.entrySet()) { .entrySet()) {
final TypeToken<? extends Service<?, ?>> type = serviceEntry.getValue(); final TypeToken<? extends Service<?, ?>> type = serviceEntry.getValue();
final ServiceRepository<?, ?> repository = this.repositories.get(type); final ServiceRepository<?, ?> repository = this.repositories.get(type.getType());
if (repository == null) { if (repository == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
String.format("No service registered for type '%s'", type.toString())); String.format("No service registered for type '%s'", type.toString()));
@ -186,7 +187,7 @@ public final class ServicePipeline {
<Context, Result> ServiceRepository<Context, Result> getRepository( <Context, Result> ServiceRepository<Context, Result> getRepository(
@NonNull final TypeToken<? extends Service<Context, Result>> type) { @NonNull final TypeToken<? extends Service<Context, Result>> type) {
final ServiceRepository<Context, Result> repository = final ServiceRepository<Context, Result> repository =
(ServiceRepository<Context, Result>) this.repositories.get(type); (ServiceRepository<Context, Result>) this.repositories.get(type.getType());
if (repository == null) { if (repository == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
String.format("No service registered for type '%s'", type.toString())); String.format("No service registered for type '%s'", type.toString()));
@ -200,7 +201,7 @@ public final class ServicePipeline {
* @return Returns an Immutable collection of the service types registered. * @return Returns an Immutable collection of the service types registered.
*/ */
@NonNull @NonNull
public Collection<TypeToken<? extends Service<?, ?>>> getRecognizedTypes() { public Collection<Type> getRecognizedTypes() {
return Collections.unmodifiableCollection(this.repositories.keySet()); return Collections.unmodifiableCollection(this.repositories.keySet());
} }

View file

@ -23,14 +23,36 @@
// //
package cloud.commandframework.services; package cloud.commandframework.services;
import cloud.commandframework.services.mock.AnnotatedMethodTest;
import cloud.commandframework.services.mock.CompletingPartialResultService;
import cloud.commandframework.services.mock.DefaultMockService;
import cloud.commandframework.services.mock.DefaultPartialRequestService;
import cloud.commandframework.services.mock.DefaultSideEffectService;
import cloud.commandframework.services.mock.InterruptingMockConsumer;
import cloud.commandframework.services.mock.MockChunkedRequest;
import cloud.commandframework.services.mock.MockConsumerService;
import cloud.commandframework.services.mock.MockOrderedFirst;
import cloud.commandframework.services.mock.MockOrderedLast;
import cloud.commandframework.services.mock.MockPartialResultService;
import cloud.commandframework.services.mock.MockResultConsumer;
import cloud.commandframework.services.mock.MockService;
import cloud.commandframework.services.mock.MockSideEffectService;
import cloud.commandframework.services.mock.SecondaryMockService;
import cloud.commandframework.services.mock.SecondaryMockSideEffectService;
import cloud.commandframework.services.mock.StateSettingConsumerService;
import cloud.commandframework.services.types.Service;
import io.leangen.geantyref.GenericTypeReflector; import io.leangen.geantyref.GenericTypeReflector;
import io.leangen.geantyref.TypeToken; import io.leangen.geantyref.TypeToken;
import cloud.commandframework.services.mock.*;
import cloud.commandframework.services.types.Service;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.*; import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
public class ServicesTest { public class ServicesTest {
@ -133,8 +155,8 @@ public class ServicesTest {
final TypeToken<? extends Service<?, ?>> first = TypeToken.get(MockOrderedFirst.class), final TypeToken<? extends Service<?, ?>> first = TypeToken.get(MockOrderedFirst.class),
last = TypeToken.get(MockOrderedLast.class); last = TypeToken.get(MockOrderedLast.class);
final TypeToken<MockService> mockServiceType = TypeToken.get(MockService.class); final TypeToken<MockService> mockServiceType = TypeToken.get(MockService.class);
for (TypeToken<?> typeToken : servicePipeline.getRecognizedTypes()) { for (Type typeToken : servicePipeline.getRecognizedTypes()) {
Assertions.assertEquals(mockServiceType, typeToken); Assertions.assertEquals(mockServiceType.getType(), typeToken);
} }
final Collection<? extends TypeToken<? extends Service<MockService.MockContext, MockService.MockResult>>> final Collection<? extends TypeToken<? extends Service<MockService.MockContext, MockService.MockResult>>>
impls = servicePipeline.getImplementations(mockServiceType); impls = servicePipeline.getImplementations(mockServiceType);