diff --git a/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java b/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java index 01af59e4..31acaf03 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java +++ b/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java @@ -275,7 +275,7 @@ public Cffu newIncompleteCffu() { public Cffu toCffu(CompletionStage stage) { requireNonNull(stage, "stage is null"); - if ("java.util.concurrent.CompletableFuture$MinimalStage".equals(stage.getClass().getName())) { + if (CompletableFutureUtils.isMinimalStageCf(stage)) { return newMin((CompletableFuture) stage); } else if (stage instanceof CompletableFuture) { return new0((CompletableFuture) stage); @@ -433,10 +433,10 @@ public final Cffu> allResultsOfFastFail(CompletionStage * If the given stage is successful, its result is the completed value; Otherwise the given valueIfNotSuccess. * (aka the result extraction logic is {@link Cffu#getSuccessNow(Object)}). * - * @param timeout how long to wait in units of {@code unit} - * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter + * @param timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter * @param valueIfNotSuccess the value to return if not completed successfully - * @param cfs the stages + * @param cfs the stages * @see Cffu#getSuccessNow(Object) */ // TODO * @see CompletableFutureUtils#MGetSuccessNow(Object, CompletionStage[]) diff --git a/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java b/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java index fea4462a..66885aaa 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java +++ b/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java @@ -208,7 +208,7 @@ public static CompletableFuture> mostResultsOfSuccess( if (cfs.length == 0) return CompletableFuture.completedFuture(arrayList()); if (cfs.length == 1) { - final CompletableFuture f = copy(toNonMinCf(cfs[0])); + final CompletableFuture f = toCfCopy(cfs[0]); return orTimeout(f, timeout, unit).handle((unused, ex) -> arrayList(getSuccessNow(f, valueIfNotSuccess))); } @@ -310,11 +310,11 @@ private static CompletableFuture[] toCfArray0( * so the returned CF instances MUST NOT be written(e.g. {@link CompletableFuture#complete(Object)}). * Otherwise, the caller should defensive copy instead of writing it directly. */ - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings("unchecked") private static CompletableFuture toCf(CompletionStage s) { if (s instanceof CompletableFuture) return (CompletableFuture) s; - else if (s instanceof Cffu) return ((Cffu) s).cffuUnwrap(); - else return (CompletableFuture) s.toCompletableFuture(); + else if (s instanceof Cffu) return ((Cffu) s).cffuUnwrap(); + else return (CompletableFuture) s.toCompletableFuture(); } /** @@ -324,15 +324,26 @@ private static CompletableFuture toCf(CompletionStage s) { * so the returned CF instances MUST NOT be written(e.g. {@link CompletableFuture#complete(Object)}). * Otherwise, the caller should defensive copy instead of writing it directly. */ - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings("unchecked") private static CompletableFuture toNonMinCf(CompletionStage s) { final CompletableFuture f; if (s instanceof CompletableFuture) f = (CompletableFuture) s; - else if (s instanceof Cffu) f = ((Cffu) s).cffuUnwrap(); - else return (CompletableFuture) s.toCompletableFuture(); + else if (s instanceof Cffu) f = ((Cffu) s).cffuUnwrap(); + else return (CompletableFuture) s.toCompletableFuture(); + + return isMinimalStageCf(f) ? f.toCompletableFuture() : f; + } + + /** + * Converts CompletionStage to CompletableFuture copy. + */ + private static CompletableFuture toCfCopy(CompletionStage s) { + final CompletableFuture f = toCf(s); + return isMinimalStageCf(f) ? f.toCompletableFuture() : copy(f); + } - return "java.util.concurrent.CompletableFuture$MinimalStage".equals(s.getClass().getName()) - ? f.toCompletableFuture() : f; + static boolean isMinimalStageCf(CompletionStage s) { + return "java.util.concurrent.CompletableFuture$MinimalStage".equals(s.getClass().getName()); } //////////////////////////////////////////////////////////////////////////////// @@ -385,7 +396,7 @@ public static CompletableFuture anyOfSuccess(CompletionStage requireCfsAndEleNonNull(cfs); final int size = cfs.length; if (size == 0) return failedFuture(new NoCfsProvidedException()); - if (size == 1) return copy(toCf(cfs[0])); + if (size == 1) return toCfCopy(cfs[0]); // NOTE: fill ONE MORE element of successOrBeIncompleteCfs LATER final CompletableFuture[] successOrBeIncomplete = new CompletableFuture[size + 1]; diff --git a/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CffuExtensions.kt b/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CffuExtensions.kt index c2e11073..12aa52fb 100644 --- a/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CffuExtensions.kt +++ b/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CffuExtensions.kt @@ -2,7 +2,6 @@ package io.foldright.cffu.kotlin import io.foldright.cffu.Cffu import io.foldright.cffu.CffuFactory -import io.foldright.cffu.CompletableFutureUtils import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletionStage import java.util.concurrent.TimeUnit