blob: 29efdeb0866e3e8570b6316953ecc13d2ca123cf [file] [log] [blame]
David Jencksbae44842014-06-21 20:15:24 +00001/*
2 * Copyright (c) OSGi Alliance (2014). All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.osgi.util.promise;
18
19import static org.osgi.util.promise.PromiseImpl.requireNonNull;
20
21/**
22 * A Deferred Promise resolution.
23 *
24 * <p>
25 * Instances of this class can be used to create a {@link Promise} that can be
26 * resolved in the future. The {@link #getPromise() associated} Promise can be
27 * successfully resolved with {@link #resolve(Object)} or resolved with a
28 * failure with {@link #fail(Throwable)}. It can also be resolved with the
29 * resolution of another promise using {@link #resolveWith(Promise)}.
30 *
31 * <p>
32 * The associated Promise can be provided to any one, but the Deferred object
33 * should be made available only to the party that will responsible for
34 * resolving the Promise.
35 *
36 * @param <T> The value type associated with the created Promise.
37 *
38 * @Immutable
39 * @author $Id: b12288b7edc994f615dc1305d6aeaeeb56208df7 $
40 */
41public class Deferred<T> {
42 private final PromiseImpl<T> promise;
43
44 /**
45 * Create a new Deferred with an associated Promise.
46 */
47 public Deferred() {
48 promise = new PromiseImpl<T>();
49 }
50
51 /**
52 * Returns the Promise associated with this Deferred.
53 *
54 * @return The Promise associated with this Deferred.
55 */
56 public Promise<T> getPromise() {
57 return promise;
58 }
59
60 /**
61 * Successfully resolve the Promise associated with this Deferred.
62 *
63 * <p>
64 * After the associated Promise is resolved with the specified value, all
65 * registered {@link Promise#onResolve(Runnable) callbacks} are called and
66 * any {@link Promise#then(Success, Failure) chained} Promises are resolved.
67 *
68 * <p>
69 * Resolving the associated Promise <i>happens-before</i> any registered
70 * callback is called. That is, in a registered callback,
71 * {@link Promise#isDone()} must return {@code true} and
72 * {@link Promise#getValue()} and {@link Promise#getFailure()} must not
73 * block.
74 *
75 * @param value The value of the resolved Promise.
76 * @throws IllegalStateException If the associated Promise was already
77 * resolved.
78 */
79 public void resolve(T value) {
80 promise.resolve(value, null);
81 }
82
83 /**
84 * Fail the Promise associated with this Deferred.
85 *
86 * <p>
87 * After the associated Promise is resolved with the specified failure, all
88 * registered {@link Promise#onResolve(Runnable) callbacks} are called and
89 * any {@link Promise#then(Success, Failure) chained} Promises are resolved.
90 *
91 * <p>
92 * Resolving the associated Promise <i>happens-before</i> any registered
93 * callback is called. That is, in a registered callback,
94 * {@link Promise#isDone()} must return {@code true} and
95 * {@link Promise#getValue()} and {@link Promise#getFailure()} must not
96 * block.
97 *
98 * @param failure The failure of the resolved Promise. Must not be
99 * {@code null}.
100 * @throws IllegalStateException If the associated Promise was already
101 * resolved.
102 */
103 public void fail(Throwable failure) {
104 promise.resolve(null, requireNonNull(failure));
105 }
106
107 /**
108 * Resolve the Promise associated with this Deferred with the specified
109 * Promise.
110 *
111 * <p>
112 * If the specified Promise is successfully resolved, the associated Promise
113 * is resolved with the value of the specified Promise. If the specified
114 * Promise is resolved with a failure, the associated Promise is resolved
115 * with the failure of the specified Promise.
116 *
117 * <p>
118 * After the associated Promise is resolved with the specified Promise, all
119 * registered {@link Promise#onResolve(Runnable) callbacks} are called and
120 * any {@link Promise#then(Success, Failure) chained} Promises are resolved.
121 *
122 * <p>
123 * Resolving the associated Promise <i>happens-before</i> any registered
124 * callback is called. That is, in a registered callback,
125 * {@link Promise#isDone()} must return {@code true} and
126 * {@link Promise#getValue()} and {@link Promise#getFailure()} must not
127 * block.
128 *
129 * @param with A Promise whose value or failure will be used to resolve the
130 * associated Promise. Must not be {@code null}.
131 * @return A Promise that is resolved only when the associated Promise is
132 * resolved by the specified Promise. The returned Promise will be
133 * successfully resolved, with the value {@code null}, if the
134 * associated Promise was resolved by the specified Promise. The
135 * returned Promise will be resolved with a failure of
136 * {@link IllegalStateException} if the associated Promise was
137 * already resolved when the specified Promise was resolved.
138 */
139 public Promise<Void> resolveWith(Promise<? extends T> with) {
140 return promise.resolveWith(with);
141 }
142}