Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Promises.java')
-rw-r--r--bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Promises.java138
1 files changed, 104 insertions, 34 deletions
diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Promises.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Promises.java
index 7067fe50a..394bce4bb 100644
--- a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Promises.java
+++ b/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Promises.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2014, 2016). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2014, 2017). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@
package org.osgi.util.promise;
-import static org.osgi.util.promise.PromiseImpl.requireNonNull;
+import static java.util.Objects.requireNonNull;
import java.util.ArrayList;
import java.util.Arrays;
@@ -38,43 +38,42 @@ public class Promises {
}
/**
- * Create a new Promise that has been resolved with the specified value.
+ * Returns a new Promise that has been resolved with the specified value.
*
* @param <T> The value type associated with the returned Promise.
* @param value The value of the resolved Promise.
* @return A new Promise that has been resolved with the specified value.
*/
public static <T> Promise<T> resolved(T value) {
- return new PromiseImpl<>(value, null);
+ return new PromiseImpl<>(value, null, null, null);
}
/**
- * Create a new Promise that has been resolved with the specified failure.
+ * Returns a new Promise that has been resolved with the specified failure.
*
* @param <T> The value type associated with the returned Promise.
* @param failure The failure of the resolved Promise. Must not be
- * {@code null}.
+ * {@code null}.
* @return A new Promise that has been resolved with the specified failure.
*/
public static <T> Promise<T> failed(Throwable failure) {
- return new PromiseImpl<>(null, requireNonNull(failure));
+ return new PromiseImpl<>(null, requireNonNull(failure), null, null);
}
/**
- * Create a new Promise that is a latch on the resolution of the specified
+ * Returns a new Promise that is a latch on the resolution of the specified
* Promises.
- *
* <p>
- * The new Promise acts as a gate and must be resolved after all of the
+ * The returned Promise acts as a gate and must be resolved after all of the
* specified Promises are resolved.
*
* @param <T> The value type of the List value associated with the returned
- * Promise.
+ * Promise.
* @param <S> A subtype of the value type of the List value associated with
- * the returned Promise.
+ * the returned Promise.
* @param promises The Promises which must be resolved before the returned
- * Promise must be resolved. Must not be {@code null} and all of the
- * elements in the collection must not be {@code null}.
+ * Promise must be resolved. Must not be {@code null} and all of
+ * the elements in the collection must not be {@code null}.
* @return A Promise that is resolved only when all the specified Promises
* are resolved. The returned Promise must be successfully resolved
* with a List of the values in the order of the specified Promises
@@ -87,33 +86,67 @@ public class Promises {
* Promises which resolved with a failure.
*/
public static <T, S extends T> Promise<List<T>> all(Collection<Promise<S>> promises) {
+ return all(new Deferred<List<T>>(), promises);
+ }
+
+ /**
+ * Resolves the Promise returned by the specified Deferred when the
+ * specified Promises are all resolved.
+ * <p>
+ * The returned Promise acts as a gate and must be resolved after all of the
+ * specified Promises are resolved.
+ *
+ * @param <T> The value type of the List value associated with the returned
+ * Promise.
+ * @param <S> A subtype of the value type of the List value associated with
+ * the returned Promise.
+ * @param deferred The specified Deferred is used to obtain and resolve the
+ * returned Promise. Must not be {@code null} and must not have
+ * already resolved the returned Promise.
+ * @param promises The Promises which must be resolved before the returned
+ * Promise must be resolved. Must not be {@code null} and all of
+ * the elements in the collection must not be {@code null}.
+ * @return The Promise from the specified Deferred. It is resolved only when
+ * all the specified Promises are resolved. The returned Promise
+ * must be successfully resolved with a List of the values in the
+ * order of the specified Promises if all the specified Promises are
+ * successfully resolved. The List in the returned Promise is the
+ * property of the caller and is modifiable. The returned Promise
+ * must be resolved with a failure of
+ * {@link FailedPromisesException} if any of the specified Promises
+ * are resolved with a failure. The failure
+ * {@link FailedPromisesException} must contain all of the specified
+ * Promises which resolved with a failure.
+ * @since 1.1
+ */
+ public static <T, S extends T> Promise<List<T>> all(
+ Deferred<List<T>> deferred, Collection<Promise<S>> promises) {
if (promises.isEmpty()) {
List<T> result = new ArrayList<>();
- return resolved(result);
- }
- /* make a copy and capture the ordering */
- List<Promise< ? extends T>> list = new ArrayList<Promise< ? extends T>>(
- promises);
- PromiseImpl<List<T>> chained = new PromiseImpl<>();
- All<T> all = new All<>(chained, list);
- for (Promise<? extends T> promise : list) {
- promise.onResolve(all);
+ deferred.resolve(result);
+ } else {
+ /* make a copy and capture the ordering */
+ List<Promise< ? extends T>> list = new ArrayList<Promise< ? extends T>>(
+ promises);
+ All<T> all = new All<>(deferred, list);
+ for (Promise< ? extends T> promise : list) {
+ promise.onResolve(all);
+ }
}
- return chained;
+ return deferred.getPromise();
}
/**
- * Create a new Promise that is a latch on the resolution of the specified
+ * Returns a new Promise that is a latch on the resolution of the specified
* Promises.
- *
* <p>
* The new Promise acts as a gate and must be resolved after all of the
* specified Promises are resolved.
*
* @param <T> The value type associated with the specified Promises.
* @param promises The Promises which must be resolved before the returned
- * Promise must be resolved. Must not be {@code null} and all of the
- * arguments must not be {@code null}.
+ * Promise must be resolved. Must not be {@code null} and all of
+ * the arguments must not be {@code null}.
* @return A Promise that is resolved only when all the specified Promises
* are resolved. The returned Promise must be successfully resolved
* with a List of the values in the order of the specified Promises
@@ -133,17 +166,55 @@ public class Promises {
}
/**
- * A callback used to resolve a Promise when the specified list of Promises
+ * Resolves the Promise returned by the specified Deferred when the
+ * specified Promises are all resolved.
+ * <p>
+ * The new Promise acts as a gate and must be resolved after all of the
+ * specified Promises are resolved.
+ *
+ * @param <T> The value type associated with the specified Promises.
+ * @param deferred The specified Deferred is used to obtain and resolve the
+ * returned Promise. Must not be {@code null} and must not have
+ * already resolved the returned Promise.
+ * @param promises The Promises which must be resolved before the returned
+ * Promise must be resolved. Must not be {@code null} and all of
+ * the arguments must not be {@code null}.
+ * @return The Promise from the specified Deferred. It is resolved only when
+ * all the specified Promises are resolved. The returned Promise
+ * must be successfully resolved with a List of the values in the
+ * order of the specified Promises if all the specified Promises are
+ * successfully resolved. The List in the returned Promise is the
+ * property of the caller and is modifiable. The returned Promise
+ * must be resolved with a failure of
+ * {@link FailedPromisesException} if any of the specified Promises
+ * are resolved with a failure. The failure
+ * {@link FailedPromisesException} must contain all of the specified
+ * Promises which resolved with a failure.
+ * @since 1.1
+ */
+ @SafeVarargs
+ public static <T> Promise<List<T>> all(Deferred<List<T>> deferred,
+ Promise< ? extends T>... promises) {
+ @SuppressWarnings("unchecked")
+ List<Promise<T>> list = Arrays.asList((Promise<T>[]) promises);
+ return all(deferred, list);
+ }
+
+ /**
+ * A callback used to resolve a Deferred when the specified list of Promises
* are resolved for the {@link Promises#all(Collection)} method.
*
* @ThreadSafe
*/
private static final class All<T> implements Runnable {
- private final PromiseImpl<List<T>> chained;
+ private final Deferred<List<T>> chained;
private final List<Promise<? extends T>> promises;
private final AtomicInteger promiseCount;
- All(PromiseImpl<List<T>> chained, List<Promise<? extends T>> promises) {
+ All(Deferred<List<T>> chained, List<Promise< ? extends T>> promises) {
+ if (chained.getPromise().isDone()) {
+ throw new IllegalStateException("Already resolved");
+ }
this.chained = chained;
this.promises = promises;
this.promiseCount = new AtomicInteger(promises.size());
@@ -169,10 +240,9 @@ public class Promises {
}
}
if (failed.isEmpty()) {
- chained.tryResolve(value, null);
+ chained.resolve(value);
} else {
- chained.tryResolve(null,
- new FailedPromisesException(failed, cause));
+ chained.fail(new FailedPromisesException(failed, cause));
}
}
}

Back to the top