From 792fa1f11dbbba13fcbbe5ea43e9094d02fbad38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 17 May 2020 12:55:07 +0200 Subject: [PATCH] Improve design --- .../plotsquared/core/uuid/ServiceFailure.java | 49 ---------- .../plotsquared/core/uuid/UUIDPipeline.java | 89 ++++++------------- .../plotsquared/core/uuid/UUIDService.java | 12 +-- .../uuid/offline/OfflineModeUUIDService.java | 12 ++- 4 files changed, 36 insertions(+), 126 deletions(-) delete mode 100644 Core/src/main/java/com/plotsquared/core/uuid/ServiceFailure.java diff --git a/Core/src/main/java/com/plotsquared/core/uuid/ServiceFailure.java b/Core/src/main/java/com/plotsquared/core/uuid/ServiceFailure.java deleted file mode 100644 index a2ce41555..000000000 --- a/Core/src/main/java/com/plotsquared/core/uuid/ServiceFailure.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * _____ _ _ _____ _ - * | __ \| | | | / ____| | | - * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | - * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | - * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | - * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| - * | | - * |_| - * PlotSquared plot management system for Minecraft - * Copyright (C) 2020 IntellectualSites - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.plotsquared.core.uuid; - -import java.util.concurrent.CompletableFuture; - -/** - * Thrown by a {@link UUIDService} when it cannot - * complete a request. This is not an error and - * will be dealt with silently. - */ -public class ServiceFailure extends Throwable { - - private static final ServiceFailure instance = new ServiceFailure(); - - public static CompletableFuture getFuture() { - final CompletableFuture completableFuture = new CompletableFuture<>(); - completableFuture.completeExceptionally(instance); - return completableFuture; - } - - @Override public Throwable fillInStackTrace() { - return this; - } - -} diff --git a/Core/src/main/java/com/plotsquared/core/uuid/UUIDPipeline.java b/Core/src/main/java/com/plotsquared/core/uuid/UUIDPipeline.java index 022bb687a..87ef3f529 100644 --- a/Core/src/main/java/com/plotsquared/core/uuid/UUIDPipeline.java +++ b/Core/src/main/java/com/plotsquared/core/uuid/UUIDPipeline.java @@ -28,8 +28,11 @@ package com.plotsquared.core.uuid; import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; -import java.util.ListIterator; +import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; @@ -79,9 +82,7 @@ public class UUIDPipeline { * @return Copy of service list */ public List getServiceListInstance() { - final List serviceList = Lists.newLinkedList(this.serviceList); - serviceList.add(EndOfPipeline.instance); - return serviceList; + return Collections.unmodifiableList(this.serviceList); } private void consume(@NotNull final UUIDMapping mapping) { @@ -93,74 +94,34 @@ public class UUIDPipeline { /** * Asynchronously attempt to fetch the mapping from a given UUID or username * - * @param request UUID or username + * @param requests UUIDs or usernames * @return Future that may complete with the mapping */ - public CompletableFuture get(@NotNull final Object request) { - if (!(request instanceof String) && !(request instanceof UUID)) { - throw new IllegalArgumentException("Request has to be either a username or UUID"); - } - final CompletableFuture future = new CompletableFuture<>(); - final ListIterator serviceListIterator - = this.getServiceListInstance().listIterator(); - final Runnable[] runnable = new Runnable[1]; - runnable[0] = () -> { - if (serviceListIterator.hasNext()) { - final UUIDService uuidService = serviceListIterator.next(); - uuidService.get(request).whenCompleteAsync(((result, throwable) -> { - if (throwable != null) { - if (throwable instanceof ServiceFailure) { - try { - runnable[0].run(); - } catch (final Throwable inner) { - future.completeExceptionally(inner); - } - } else { - future.completeExceptionally(throwable); - } - } else { + public CompletableFuture> get(@NotNull final Collection requests) { + final List serviceList = this.getServiceListInstance(); + return CompletableFuture.supplyAsync(() -> { + final List mappings = new ArrayList<>(requests.size()); + outer: for (final Object request : requests) { + if (!(request instanceof String) && !(request instanceof UUID)) { + throw new IllegalArgumentException("Request has to be either a username or UUID"); + } + for (final UUIDService service : serviceList) { + final Optional result = service.get(request); + if (result.isPresent()) { final String username = request instanceof String ? (String) request - : (String) result; + : (String) result.get(); final UUID uuid = request instanceof UUID ? (UUID) request - : (UUID) result; + : (UUID) result.get(); final UUIDMapping mapping = new UUIDMapping(uuid, username); - future.complete(mapping); this.consume(mapping); + mappings.add(mapping); + continue outer; } - }), this.executor); - } else { - throw new ServiceError("Pipeline is incomplete"); + } + throw new ServiceError("End of pipeline"); } - }; - try { - // Start the pipeline traversal - runnable[0].run(); - } catch (final Throwable throwable) { - future.completeExceptionally(throwable); - } - return future; - } - - /** - * Indicates that the end of the pipeline has been reached, this - * will cause the request to fail, as no service was able to - * fulfil the request - */ - private static class EndOfPipeline implements UUIDService { - - public static final EndOfPipeline instance = new EndOfPipeline(); - - @Override @NotNull public CompletableFuture get(@NotNull final UUID uuid) { - final CompletableFuture future = new CompletableFuture<>(); - future.completeExceptionally(new ServiceError("End of pipeline")); - return future; - } - - @Override @NotNull public CompletableFuture get(@NotNull final String username) { - final CompletableFuture future = new CompletableFuture<>(); - future.completeExceptionally(new ServiceError("End of pipeline")); - return future; - } + return mappings; + }, this.executor); } } diff --git a/Core/src/main/java/com/plotsquared/core/uuid/UUIDService.java b/Core/src/main/java/com/plotsquared/core/uuid/UUIDService.java index 98f58b9c4..db29480d7 100644 --- a/Core/src/main/java/com/plotsquared/core/uuid/UUIDService.java +++ b/Core/src/main/java/com/plotsquared/core/uuid/UUIDService.java @@ -27,15 +27,15 @@ package com.plotsquared.core.uuid; import org.jetbrains.annotations.NotNull; +import java.util.Optional; import java.util.UUID; -import java.util.concurrent.CompletableFuture; /** * Service used to provide usernames from player UUIDs */ public interface UUIDService { - default CompletableFuture get(@NotNull final Object request) { + default Optional get(@NotNull final Object request) { if (request instanceof UUID) { return get((UUID) request); } else if (request instanceof String) { @@ -54,9 +54,9 @@ public interface UUIDService { * this completes with an empty optional. * * @param uuid Player UUID - * @return Future that may contain the username if it exists + * @return Optional that may contain the username if it exists */ - @NotNull CompletableFuture get(@NotNull final UUID uuid); + @NotNull Optional get(@NotNull final UUID uuid); /** * Get a stored UUID from the service if it exists. @@ -67,8 +67,8 @@ public interface UUIDService { * this completes with an empty optional. * * @param username Player username - * @return Future that may contain the UUID if it exists + * @return Optional that may contain the UUID if it exists */ - @NotNull CompletableFuture get(@NotNull final String username); + @NotNull Optional get(@NotNull final String username); } diff --git a/Core/src/main/java/com/plotsquared/core/uuid/offline/OfflineModeUUIDService.java b/Core/src/main/java/com/plotsquared/core/uuid/offline/OfflineModeUUIDService.java index a58ab0863..7e397119e 100644 --- a/Core/src/main/java/com/plotsquared/core/uuid/offline/OfflineModeUUIDService.java +++ b/Core/src/main/java/com/plotsquared/core/uuid/offline/OfflineModeUUIDService.java @@ -27,13 +27,12 @@ package com.plotsquared.core.uuid.offline; import com.google.common.base.Charsets; import com.plotsquared.core.configuration.Settings; -import com.plotsquared.core.uuid.ServiceFailure; import com.plotsquared.core.uuid.UUIDService; import org.jetbrains.annotations.NotNull; import java.util.Locale; +import java.util.Optional; import java.util.UUID; -import java.util.concurrent.CompletableFuture; /** * Name provider service that creates UUIDs from usernames @@ -47,13 +46,12 @@ public class OfflineModeUUIDService implements UUIDService { return UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(Charsets.UTF_8)); } - @Override @NotNull public CompletableFuture get(@NotNull final UUID uuid) { - // This service can only get UUIDs from usernames - return ServiceFailure.getFuture(); + @Override @NotNull public Optional get(@NotNull final UUID uuid) { + return Optional.empty(); } - @Override @NotNull public CompletableFuture get(@NotNull final String username) { - return CompletableFuture.completedFuture(this.getFromUsername(username)); + @Override @NotNull public Optional get(@NotNull final String username) { + return Optional.of(this.getFromUsername(username)); } }