blob: 74e4b59b57390338f3b510e4d10fb1b063bc71e0 [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 java.lang.reflect.InvocationTargetException;
20import org.osgi.annotation.versioning.ProviderType;
21import org.osgi.util.function.Function;
22import org.osgi.util.function.Predicate;
23
24/**
25 * A Promise of a value.
26 *
27 * <p>
28 * A Promise represents a future value. It handles the interactions for
29 * asynchronous processing. A {@link Deferred} object can be used to create a
30 * Promise and later resolve the Promise. A Promise is used by the caller of an
31 * asynchronous function to get the result or handle the error. The caller can
32 * either get a callback when the Promise is resolved with a value or an error,
33 * or the Promise can be used in chaining. In chaining, callbacks are provided
34 * that receive the resolved Promise, and a new Promise is generated that
35 * resolves based upon the result of a callback.
36 *
37 * <p>
38 * Both {@link #onResolve(Runnable) callbacks} and
39 * {@link #then(Success, Failure) chaining} can be repeated any number of times,
40 * even after the Promise has been resolved.
41 * <p>
42 * Example callback usage:
43 *
44 * <pre>
45 * final Promise&lt;String&gt; foo = foo();
46 * foo.onResolve(new Runnable() {
47 * public void run() {
48 * System.out.println(foo.getValue());
49 * }
50 * });
51 * </pre>
52 *
53 * Example chaining usage;
54 *
55 * <pre>
56 * Success&lt;String,String&gt; doubler = new Success&lt;String,String&gt;() {
57 * public Promise&lt;String&gt; call(Promise&lt;String&gt; p) throws Exception {
58 * return Promises.resolved(p.getValue()+p.getValue());
59 * }
60 * };
61 * final Promise&lt;String&gt; foo = foo().then(doubler).then(doubler);
62 * foo.onResolve(new Runnable() {
63 * public void run() {
64 * System.out.println(foo.getValue());
65 * }
66 * });
67 * </pre>
68 *
69 * @param <T> The value type associated with this Promise.
70 *
71 * @ThreadSafe
72 * @author $Id: 8a24f66339967ecdd03def57f31ac8c371a7f4cd $
73 */
74@ProviderType
75public interface Promise<T> {
76
77 /**
78 * Returns whether this Promise has been resolved.
79 *
80 * <p>
81 * This Promise may be successfully resolved or resolved with a failure.
82 *
83 * @return {@code true} if this Promise was resolved either successfully or
84 * with a failure; {@code false} if this Promise is unresolved.
85 */
86 boolean isDone();
87
88 /**
89 * Returns the value of this Promise.
90 *
91 * <p>
92 * If this Promise is not {@link #isDone() resolved}, this method must block
93 * and wait for this Promise to be resolved before completing.
94 *
95 * <p>
96 * If this Promise was successfully resolved, this method returns with the
97 * value of this Promise. If this Promise was resolved with a failure, this
98 * method must throw an {@code InvocationTargetException} with the
99 * {@link #getFailure() failure exception} as the cause.
100 *
101 * @return The value of this resolved Promise.
102 * @throws InvocationTargetException If this Promise was resolved with a
103 * failure. The cause of the {@code InvocationTargetException} is
104 * the failure exception.
105 * @throws InterruptedException If the current thread was interrupted while
106 * waiting.
107 */
108 T getValue() throws InvocationTargetException, InterruptedException;
109
110 /**
111 * Returns the failure of this Promise.
112 *
113 * <p>
114 * If this Promise is not {@link #isDone() resolved}, this method must block
115 * and wait for this Promise to be resolved before completing.
116 *
117 * <p>
118 * If this Promise was resolved with a failure, this method returns with the
119 * failure of this Promise. If this Promise was successfully resolved, this
120 * method must return {@code null}.
121 *
122 * @return The failure of this resolved Promise or {@code null} if this
123 * Promise was successfully resolved.
124 * @throws InterruptedException If the current thread was interrupted while
125 * waiting.
126 */
127 Throwable getFailure() throws InterruptedException;
128
129 /**
130 * Register a callback to be called when this Promise is resolved.
131 *
132 * <p>
133 * The specified callback is called when this Promise is resolved either
134 * successfully or with a failure.
135 *
136 * <p>
137 * This method may be called at any time including before and after this
138 * Promise has been resolved.
139 *
140 * <p>
141 * Resolving this Promise <i>happens-before</i> any registered callback is
142 * called. That is, in a registered callback, {@link #isDone()} must return
143 * {@code true} and {@link #getValue()} and {@link #getFailure()} must not
144 * block.
145 *
146 * <p>
147 * A callback may be called on a different thread than the thread which
148 * registered the callback. So the callback must be thread safe but can rely
149 * upon that the registration of the callback <i>happens-before</i> the
150 * registered callback is called.
151 *
152 * @param callback A callback to be called when this Promise is resolved.
153 * Must not be {@code null}.
154 * @return This Promise.
155 */
156 Promise<T> onResolve(Runnable callback);
157
158 /**
159 * Chain a new Promise to this Promise with Success and Failure callbacks.
160 *
161 * <p>
162 * The specified {@link Success} callback is called when this Promise is
163 * successfully resolved and the specified {@link Failure} callback is
164 * called when this Promise is resolved with a failure.
165 *
166 * <p>
167 * This method returns a new Promise which is chained to this Promise. The
168 * returned Promise must be resolved when this Promise is resolved after the
169 * specified Success or Failure callback is executed. The result of the
170 * executed callback must be used to resolve the returned Promise. Multiple
171 * calls to this method can be used to create a chain of promises which are
172 * resolved in sequence.
173 *
174 * <p>
175 * If this Promise is successfully resolved, the Success callback is
176 * executed and the result Promise, if any, or thrown exception is used to
177 * resolve the returned Promise from this method. If this Promise is
178 * resolved with a failure, the Failure callback is executed and the
179 * returned Promise from this method is failed.
180 *
181 * <p>
182 * This method may be called at any time including before and after this
183 * Promise has been resolved.
184 *
185 * <p>
186 * Resolving this Promise <i>happens-before</i> any registered callback is
187 * called. That is, in a registered callback, {@link #isDone()} must return
188 * {@code true} and {@link #getValue()} and {@link #getFailure()} must not
189 * block.
190 *
191 * <p>
192 * A callback may be called on a different thread than the thread which
193 * registered the callback. So the callback must be thread safe but can rely
194 * upon that the registration of the callback <i>happens-before</i> the
195 * registered callback is called.
196 *
197 * @param <R> The value type associated with the returned Promise.
198 * @param success A Success callback to be called when this Promise is
199 * successfully resolved. May be {@code null} if no Success callback
200 * is required. In this case, the returned Promise must be resolved
201 * with the value {@code null} when this Promise is successfully
202 * resolved.
203 * @param failure A Failure callback to be called when this Promise is
204 * resolved with a failure. May be {@code null} if no Failure
205 * callback is required.
206 * @return A new Promise which is chained to this Promise. The returned
207 * Promise must be resolved when this Promise is resolved after the
208 * specified Success or Failure callback, if any, is executed.
209 */
210 <R> Promise<R> then(Success<? super T, ? extends R> success, Failure failure);
211
212 /**
213 * Chain a new Promise to this Promise with a Success callback.
214 *
215 * <p>
216 * This method performs the same function as calling
217 * {@link #then(Success, Failure)} with the specified Success callback and
218 * {@code null} for the Failure callback.
219 *
220 * @param <R> The value type associated with the returned Promise.
221 * @param success A Success callback to be called when this Promise is
222 * successfully resolved. May be {@code null} if no Success callback
223 * is required. In this case, the returned Promise must be resolved
224 * with the value {@code null} when this Promise is successfully
225 * resolved.
226 * @return A new Promise which is chained to this Promise. The returned
227 * Promise must be resolved when this Promise is resolved after the
228 * specified Success, if any, is executed.
229 * @see #then(Success, Failure)
230 */
231 <R> Promise<R> then(Success<? super T, ? extends R> success);
232
233 /**
234 * Filter the value of this Promise.
235 *
236 * <p>
237 * If this Promise is successfully resolved, the returned Promise will
238 * either be resolved with the value of this Promise if the specified
239 * Predicate accepts that value or failed with a
240 * {@code NoSuchElementException} if the specified Predicate does not accept
241 * that value. If the specified Predicate throws an exception, the returned
242 * Promise will be failed with the exception.
243 *
244 * <p>
245 * If this Promise is resolved with a failure, the returned Promise will be
246 * failed with that failure.
247 *
248 * <p>
249 * This method may be called at any time including before and after this
250 * Promise has been resolved.
251 *
252 * @param predicate The Predicate to evaluate the value of this Promise.
253 * Must not be {@code null}.
254 * @return A Promise that filters the value of this Promise.
255 */
256 Promise<T> filter(Predicate<? super T> predicate);
257
258 /**
259 * Map the value of this Promise.
260 *
261 * <p>
262 * If this Promise is successfully resolved, the returned Promise will be
263 * resolved with the value of specified Function as applied to the value of
264 * this Promise. If the specified Function throws an exception, the returned
265 * Promise will be failed with the exception.
266 *
267 * <p>
268 * If this Promise is resolved with a failure, the returned Promise will be
269 * failed with that failure.
270 *
271 * <p>
272 * This method may be called at any time including before and after this
273 * Promise has been resolved.
274 *
275 * @param <R> The value type associated with the returned Promise.
276 * @param mapper The Function that will map the value of this Promise to the
277 * value that will be used to resolve the returned Promise. Must not
278 * be {@code null}.
279 * @return A Promise that returns the value of this Promise as mapped by the
280 * specified Function.
281 */
282 <R> Promise<R> map(Function<? super T, ? extends R> mapper);
283
284 /**
285 * FlatMap the value of this Promise.
286 *
287 * <p>
288 * If this Promise is successfully resolved, the returned Promise will be
289 * resolved with the Promise from the specified Function as applied to the
290 * value of this Promise. If the specified Function throws an exception, the
291 * returned Promise will be failed with the exception.
292 *
293 * <p>
294 * If this Promise is resolved with a failure, the returned Promise will be
295 * failed with that failure.
296 *
297 * <p>
298 * This method may be called at any time including before and after this
299 * Promise has been resolved.
300 *
301 * @param <R> The value type associated with the returned Promise.
302 * @param mapper The Function that will flatMap the value of this Promise to
303 * a Promise that will be used to resolve the returned Promise. Must
304 * not be {@code null}.
305 * @return A Promise that returns the value of this Promise as mapped by the
306 * specified Function.
307 */
308 <R> Promise<R> flatMap(Function<? super T, Promise<? extends R>> mapper);
309
310 /**
311 * Recover from a failure of this Promise with a recovery value.
312 *
313 * <p>
314 * If this Promise is successfully resolved, the returned Promise will be
315 * resolved with the value of this Promise.
316 *
317 * <p>
318 * If this Promise is resolved with a failure, the specified Function is
319 * applied to this Promise to produce a recovery value.
320 * <ul>
321 * <li>If the recovery value is not {@code null}, the returned Promise will
322 * be resolved with the recovery value.</li>
323 * <li>If the recovery value is {@code null}, the returned Promise will be
324 * failed with the failure of this Promise.</li>
325 * <li>If the specified Function throws an exception, the returned Promise
326 * will be failed with that exception.</li>
327 * </ul>
328 *
329 * <p>
330 * To recover from a failure of this Promise with a recovery value of
331 * {@code null}, the {@link #recoverWith(Function)} method must be used. The
332 * specified Function for {@link #recoverWith(Function)} can return
333 * {@code Promises.resolved(null)} to supply the desired {@code null} value.
334 *
335 * <p>
336 * This method may be called at any time including before and after this
337 * Promise has been resolved.
338 *
339 * @param recovery If this Promise resolves with a failure, the specified
340 * Function is called to produce a recovery value to be used to
341 * resolve the returned Promise. Must not be {@code null}.
342 * @return A Promise that resolves with the value of this Promise or
343 * recovers from the failure of this Promise.
344 */
345 Promise<T> recover(Function<Promise<?>, ? extends T> recovery);
346
347 /**
348 * Recover from a failure of this Promise with a recovery Promise.
349 *
350 * <p>
351 * If this Promise is successfully resolved, the returned Promise will be
352 * resolved with the value of this Promise.
353 *
354 * <p>
355 * If this Promise is resolved with a failure, the specified Function is
356 * applied to this Promise to produce a recovery Promise.
357 * <ul>
358 * <li>If the recovery Promise is not {@code null}, the returned Promise
359 * will be resolved with the recovery Promise.</li>
360 * <li>If the recovery Promise is {@code null}, the returned Promise will be
361 * failed with the failure of this Promise.</li>
362 * <li>If the specified Function throws an exception, the returned Promise
363 * will be failed with that exception.</li>
364 * </ul>
365 *
366 * <p>
367 * This method may be called at any time including before and after this
368 * Promise has been resolved.
369 *
370 * @param recovery If this Promise resolves with a failure, the specified
371 * Function is called to produce a recovery Promise to be used to
372 * resolve the returned Promise. Must not be {@code null}.
373 * @return A Promise that resolves with the value of this Promise or
374 * recovers from the failure of this Promise.
375 */
376 Promise<T> recoverWith(Function<Promise<?>, Promise<? extends T>> recovery);
377
378 /**
379 * Fall back to the value of the specified Promise if this Promise fails.
380 *
381 * <p>
382 * If this Promise is successfully resolved, the returned Promise will be
383 * resolved with the value of this Promise.
384 *
385 * <p>
386 * If this Promise is resolved with a failure, the successful result of the
387 * specified Promise is used to resolve the returned Promise. If the
388 * specified Promise is resolved with a failure, the returned Promise will
389 * be failed with the failure of this Promise rather than the failure of the
390 * specified Promise.
391 *
392 * <p>
393 * This method may be called at any time including before and after this
394 * Promise has been resolved.
395 *
396 * @param fallback The Promise whose value will be used to resolve the
397 * returned Promise if this Promise resolves with a failure. Must not
398 * be {@code null}.
399 * @return A Promise that returns the value of this Promise or falls back to
400 * the value of the specified Promise.
401 */
402 Promise<T> fallbackTo(Promise<? extends T> fallback);
403}