diff options
Diffstat (limited to 'bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Deferred.java')
-rw-r--r-- | bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Deferred.java | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Deferred.java b/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Deferred.java new file mode 100644 index 000000000..e9ff0a6fa --- /dev/null +++ b/bundles/org.eclipse.osgi.util/src/org/osgi/util/promise/Deferred.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) OSGi Alliance (2014). 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.osgi.util.promise; + +import static org.osgi.util.promise.PromiseImpl.requireNonNull; + +/** + * A Deferred Promise resolution. + * + * <p> + * Instances of this class can be used to create a {@link Promise} that can be + * resolved in the future. The {@link #getPromise() associated} Promise can be + * successfully resolved with {@link #resolve(Object)} or resolved with a + * failure with {@link #fail(Throwable)}. It can also be resolved with the + * resolution of another promise using {@link #resolveWith(Promise)}. + * + * <p> + * The associated Promise can be provided to any one, but the Deferred object + * should be made available only to the party that will responsible for + * resolving the Promise. + * + * @param <T> The value type associated with the created Promise. + * + * @Immutable + * @author $Id$ + */ +public class Deferred<T> { + private final PromiseImpl<T> promise; + + /** + * Create a new Deferred with an associated Promise. + */ + public Deferred() { + promise = new PromiseImpl<T>(); + } + + /** + * Returns the Promise associated with this Deferred. + * + * @return The Promise associated with this Deferred. + */ + public Promise<T> getPromise() { + return promise; + } + + /** + * Successfully resolve the Promise associated with this Deferred. + * + * <p> + * After the associated Promise is resolved with the specified value, all + * registered {@link Promise#onResolve(Runnable) callbacks} are called and + * any {@link Promise#then(Success, Failure) chained} Promises are resolved. + * + * <p> + * Resolving the associated Promise <i>happens-before</i> any registered + * callback is called. That is, in a registered callback, + * {@link Promise#isDone()} must return {@code true} and + * {@link Promise#getValue()} and {@link Promise#getFailure()} must not + * block. + * + * @param value The value of the resolved Promise. + * @throws IllegalStateException If the associated Promise was already + * resolved. + */ + public void resolve(T value) { + promise.resolve(value, null); + } + + /** + * Fail the Promise associated with this Deferred. + * + * <p> + * After the associated Promise is resolved with the specified failure, all + * registered {@link Promise#onResolve(Runnable) callbacks} are called and + * any {@link Promise#then(Success, Failure) chained} Promises are resolved. + * + * <p> + * Resolving the associated Promise <i>happens-before</i> any registered + * callback is called. That is, in a registered callback, + * {@link Promise#isDone()} must return {@code true} and + * {@link Promise#getValue()} and {@link Promise#getFailure()} must not + * block. + * + * @param failure The failure of the resolved Promise. Must not be + * {@code null}. + * @throws IllegalStateException If the associated Promise was already + * resolved. + */ + public void fail(Throwable failure) { + promise.resolve(null, requireNonNull(failure)); + } + + /** + * Resolve the Promise associated with this Deferred with the specified + * Promise. + * + * <p> + * If the specified Promise is successfully resolved, the associated Promise + * is resolved with the value of the specified Promise. If the specified + * Promise is resolved with a failure, the associated Promise is resolved + * with the failure of the specified Promise. + * + * <p> + * After the associated Promise is resolved with the specified Promise, all + * registered {@link Promise#onResolve(Runnable) callbacks} are called and + * any {@link Promise#then(Success, Failure) chained} Promises are resolved. + * + * <p> + * Resolving the associated Promise <i>happens-before</i> any registered + * callback is called. That is, in a registered callback, + * {@link Promise#isDone()} must return {@code true} and + * {@link Promise#getValue()} and {@link Promise#getFailure()} must not + * block. + * + * @param with A Promise whose value or failure must be used to resolve the + * associated Promise. Must not be {@code null}. + * @return A Promise that is resolved only when the associated Promise is + * resolved by the specified Promise. The returned Promise must be + * successfully resolved with the value {@code null}, if the + * associated Promise was resolved by the specified Promise. The + * returned Promise must be resolved with a failure of + * {@link IllegalStateException}, if the associated Promise was + * already resolved when the specified Promise was resolved. + */ + public Promise<Void> resolveWith(Promise<? extends T> with) { + return promise.resolveWith(with); + } +} |