001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2015-2016 ForgeRock AS.
015 */
016package org.forgerock.util.promise;
017
018import java.util.concurrent.ExecutionException;
019import java.util.concurrent.Future;
020import java.util.concurrent.TimeUnit;
021import java.util.concurrent.TimeoutException;
022
023import org.forgerock.util.AsyncFunction;
024import org.forgerock.util.Function;
025
026/**
027 * A {@code Promise} represents the result of an asynchronous task.
028 *
029 * @param <V>
030 *            The type of the task's result, or {@link Void} if the task does
031 *            not return anything (i.e. it only has side-effects).
032 * @param <E>
033 *            The type of the exception thrown by the task if it fails, or
034 *            {@link NeverThrowsException} if the task cannot fail.
035 * @see PromiseImpl
036 * @see Promises
037 */
038public interface Promise<V, E extends Exception> extends Future<V> {
039    // TODO: progressible promise
040
041    /**
042     * Attempts to cancel the asynchronous task associated with this
043     * {@code Promise}. Cancellation will fail if this {@code Promise} has
044     * already completed or has already been cancelled. If successful, then
045     * cancellation will complete this {@code Promise} with an appropriate
046     * exception and notify any registered functions and completion handlers.
047     * <p>
048     * After this method returns, subsequent calls to {@link #isDone} will
049     * always return {@code true}. Subsequent calls to {@link #isCancelled} will
050     * always return {@code true} if this method returned {@code true}.
051     *
052     * @param mayInterruptIfRunning
053     *            {@code true} if the thread executing executing the response
054     *            handler should be interrupted; otherwise, in-progress response
055     *            handlers are allowed to complete.
056     * @return {@code false} if {@code Promise} could not be cancelled,
057     *         typically because it has already completed normally; {@code true}
058     *         otherwise.
059     */
060    @Override
061    boolean cancel(boolean mayInterruptIfRunning);
062
063    /**
064     * Waits if necessary for this {@code Promise} to complete, and then returns
065     * the result if it completed successfully, or throws an
066     * {@code ExecutionException} containing the cause of the failure.
067     *
068     * @return The result, but only if this {@code Promise} completed
069     *         successfully.
070     * @throws ExecutionException
071     *             If this {@code Promise} was cancelled or did not complete
072     *             successfully. The {@code ExecutionException} will contain the
073     *             cause of the failure.
074     * @throws InterruptedException
075     *             If the current thread was interrupted while waiting.
076     */
077    @Override
078    V get() throws ExecutionException, InterruptedException;
079
080    /**
081     * Waits if necessary for at most the given time for this {@code Promise} to
082     * complete, and then returns the result if it completed successfully, or
083     * throws an {@code ExecutionException} containing the cause of the failure.
084     *
085     * @param timeout
086     *            The maximum time to wait.
087     * @param unit
088     *            The time unit of the timeout argument.
089     * @return The result, but only if this {@code Promise} completed
090     *         successfully.
091     * @throws ExecutionException
092     *             If this {@code Promise} was cancelled or did not complete
093     *             successfully. The {@code ExecutionException} will contain the
094     *             cause of the failure.
095     * @throws TimeoutException
096     *             If the wait timed out.
097     * @throws InterruptedException
098     *             If the current thread was interrupted while waiting.
099     */
100    @Override
101    V get(long timeout, TimeUnit unit) throws ExecutionException, TimeoutException,
102            InterruptedException;
103
104    /**
105     * Waits if necessary for this {@code Promise} to complete, and then returns
106     * the result if it completed successfully, or throws an exception
107     * representing the cause of the failure.
108     *
109     * @return The result, but only if this {@code Promise} completed
110     *         successfully.
111     * @throws E
112     *             If this {@code Promise} was cancelled or did not complete
113     *             successfully.
114     * @throws InterruptedException
115     *             If the current thread was interrupted while waiting.
116     */
117    V getOrThrow() throws InterruptedException, E;
118
119    /**
120     * Waits if necessary for at most the given time for this {@code Promise} to
121     * complete, and then returns the result if it completed successfully, or
122     * throws an exception representing the cause of the failure.
123     *
124     * @param timeout
125     *            The maximum time to wait.
126     * @param unit
127     *            The time unit of the timeout argument.
128     * @return The result, but only if this {@code Promise} completed
129     *         successfully.
130     * @throws E
131     *             If this {@code Promise} was cancelled or did not complete
132     *             successfully.
133     * @throws TimeoutException
134     *             If the wait timed out.
135     * @throws InterruptedException
136     *             If the current thread was interrupted while waiting.
137     */
138    V getOrThrow(long timeout, TimeUnit unit) throws InterruptedException, E, TimeoutException;
139
140    /**
141     * Waits if necessary for this {@code Promise} to complete, and then returns
142     * the result if it completed successfully, or throws an exception
143     * representing the cause of the failure.
144     * <p>
145     * This method is similar to {@link #getOrThrow()} except that it will
146     * ignore thread interrupts. When this method returns the status of the
147     * current thread will be interrupted if an interrupt was received while
148     * waiting.
149     *
150     * @return The result, but only if this {@code Promise} completed
151     *         successfully.
152     * @throws E
153     *             If this {@code Promise} was cancelled or did not complete
154     *             successfully.
155     */
156    V getOrThrowUninterruptibly() throws E;
157
158    /**
159     * Waits if necessary for at most the given time for this {@code Promise} to
160     * complete, and then returns the result if it completed successfully, or
161     * throws an exception representing the cause of the failure.
162     * <p>
163     * This method is similar to {@link #getOrThrow(long, TimeUnit)} except that
164     * it will ignore thread interrupts. When this method returns the status of
165     * the current thread will be interrupted if an interrupt was received while
166     * waiting.
167     *
168     * @param timeout
169     *            The maximum time to wait.
170     * @param unit
171     *            The time unit of the timeout argument.
172     * @return The result, but only if this {@code Promise} completed
173     *         successfully.
174     * @throws E
175     *             If this {@code Promise} was cancelled or did not complete
176     *             successfully.
177     * @throws TimeoutException
178     *             If the wait timed out.
179     */
180    V getOrThrowUninterruptibly(long timeout, TimeUnit unit) throws E, TimeoutException;
181
182    /**
183     * Returns {@code true} if this {@code Promise} was cancelled before it
184     * completed normally.
185     *
186     * @return {@code true} if this {@code Promise} was cancelled before it
187     *         completed normally, otherwise {@code false}.
188     */
189    @Override
190    boolean isCancelled();
191
192    /**
193     * Returns {@code true} if this {@code Promise} has completed.
194     * <p>
195     * Completion may be due to normal termination, an exception, or
196     * cancellation. In all of these cases, this method will return {@code true}.
197     *
198     * @return {@code true} if this {@code Promise} has completed, otherwise
199     *         {@code false}.
200     */
201    @Override
202    boolean isDone();
203
204    /**
205     * Registers the provided completion handler for notification if this
206     * {@code Promise} cannot be completed due to an exception. If this
207     * {@code Promise} completes with a result then the completion handler
208     * will not be notified.
209     * <p>
210     * This method can be used for asynchronous completion notification.
211     *
212     * @param onException
213     *            The completion handler which will be notified upon failure
214     *            completion of this {@code Promise}.
215     * @return This {@code Promise}.
216     */
217    Promise<V, E> thenOnException(ExceptionHandler<? super E> onException);
218
219    /**
220     * Registers the provided completion handler for notification once this
221     * {@code Promise} has completed with a result. If this {@code Promise}
222     * completes with an exception then the completion handler will not be
223     * notified.
224     * <p>
225     * This method can be used for asynchronous completion notification and is
226     * equivalent to {@link #then(Function)}.
227     *
228     * @param onResult
229     *            The completion handler which will be notified upon successful
230     *            completion of this {@code Promise}.
231     * @return This {@code Promise}.
232     */
233    Promise<V, E> thenOnResult(ResultHandler<? super V> onResult);
234
235    /**
236     * Registers the provided completion handlers for notification once this
237     * {@code Promise} has completed (with a result or an exception). If this
238     * {@code Promise} completes with a result then {@code onResult} will be
239     * notified with the result, otherwise {@code onException} will be notified
240     * with the exception that occurred.
241     * <p>
242     * This method can be used for asynchronous completion notification.
243     *
244     * @param onResult
245     *            The completion handler which will be notified upon completion
246     *            with a result of this {@code Promise}.
247     * @param onException
248     *            The completion handler which will be notified upon failure of
249     *            this {@code Promise}.
250     * @return This {@code Promise}.
251     */
252    Promise<V, E> thenOnResultOrException(ResultHandler<? super V> onResult, ExceptionHandler<? super E> onException);
253
254    /**
255     * Submits the provided runnable for execution once this {@code Promise} has
256     * completed, and regardless of whether it has a result or an exception.
257     * <p>
258     * This method can be used for resource cleanup after a series of
259     * asynchronous tasks have completed. More specifically, this method should
260     * be used in a similar manner to {@code finally} statements in
261     * {@code try...catch} expressions.
262     * <p>
263     * This method is equivalent to {@link #thenAlways(Runnable)}.
264     *
265     * @param onResultOrException
266     *            The runnable which will be notified regardless of the final
267     *            outcome of this {@code Promise}.
268     * @return This {@code Promise}.
269     */
270    Promise<V, E> thenOnResultOrException(Runnable onResultOrException);
271
272    /**
273     * Submits the provided function for execution once this {@code Promise} has
274     * completed with a result, and returns a new {@code Promise} representing
275     * the outcome of the function. If this {@code Promise} does not
276     * complete with a result then the function will not be invoked and the exception
277     * will be forwarded to the returned {@code Promise}.
278     * <p>
279     * This method can be used for transforming the result of an asynchronous
280     * task.
281     *
282     * @param <VOUT>
283     *            The type of the function's result, or {@link Void} if the
284     *            function does not return anything (i.e. it only has
285     *            side-effects). Note that the type may be different to the type
286     *            of this {@code Promise}.
287     * @param onResult
288     *            The function which will be executed upon successful completion
289     *            of this {@code Promise}.
290     * @return A new {@code Promise} representing the outcome of the
291     *         function.
292     */
293    <VOUT> Promise<VOUT, E> then(Function<? super V, VOUT, E> onResult);
294
295    /**
296     * Submits the provided function for execution once this {@code Promise} has
297     * not completed with a result (has completed with an exception), and returns
298     * a new {@code Promise} representing the outcome of the function.
299     * If this {@code Promise} completes with a result then the function will not
300     * be invoked and the result notification will be forwarded to the returned
301     * {@code Promise}.
302     * <p>
303     * This method can be used for transforming the result of an asynchronous
304     * task.
305     *
306     * @param <EOUT>
307     *            The type of the exception thrown by the function if it
308     *            fails, or {@link NeverThrowsException} if it cannot fails.
309     *            Note that the type may be different to the type of this
310     *            {@code Promise}.
311     * @param onException
312     *            The function which will be executed upon failure completion
313     *            of this {@code Promise}.
314     * @return A new {@code Promise} representing the outcome of the
315     *         function.
316     */
317    <EOUT extends Exception> Promise<V, EOUT> thenCatch(Function<? super E, V, EOUT> onException);
318
319    /**
320     * Submits the provided function for execution once this {@code Promise} has
321     * not completed with a result nor with an exception but with a {@link RuntimeException}, and returns
322     * a new {@code Promise} representing the outcome of the function.
323     * If this {@code Promise} completes with a result or an exception then the function will not
324     * be invoked and the result notification will be forwarded to the returned
325     * {@code Promise}.
326     * <p>
327     * This method can be used for transforming the result of an asynchronous
328     * task.
329     *
330     * @param onRuntimeException
331     *            The function which will be executed upon failure completion
332     *            of this {@code Promise}.
333     * @return A new {@code Promise} representing the outcome of the
334     *         function.
335     */
336    Promise<V, E> thenCatchRuntimeException(Function<? super RuntimeException, V, E> onRuntimeException);
337
338    /**
339     * Submits the provided asynchronous function for execution once this
340     * {@code Promise} has completed with a {@link RuntimeException}, and returns a new
341     * {@code Promise} representing the outcome of the function. If this
342     * {@code Promise} completes with a result or the typed exception then the
343     * completion asynchronous function will not be called.
344     * <p>
345     * This method may be used for chaining together a series of asynchronous
346     * tasks.
347     *
348     * @param onRuntimeException
349     *            The asynchronous function which will be executed upon failure completion
350     *            with a {@link RuntimeException} of this {@code Promise}.
351     *
352     * @return A new {@code Promise} representing the outcome of the
353     *         function.
354     */
355    Promise<V, E> thenCatchRuntimeExceptionAsync(AsyncFunction<? super RuntimeException, V, E> onRuntimeException);
356
357    /**
358     * Submits the provided functions for execution once this {@code Promise}
359     * has completed (with a result or an exception), and returns a new
360     * {@code Promise} representing the outcome of the invoked function. If
361     * this {@code Promise} completes with a result then {@code onResult}
362     * will be invoked with the result, otherwise {@code onException} will
363     * be invoked with the exception that occurred.
364     * <p>
365     * This method can be used for transforming the outcome of an
366     * asynchronous task.
367     *
368     * @param <VOUT>
369     *            The type of the functions' result, or {@link Void} if the
370     *            functions do not return anything (i.e. they only have
371     *            side-effects). Note that the type may be different to the type
372     *            of this {@code Promise}.
373     * @param <EOUT>
374     *            The type of the exception thrown by the functions if they
375     *            fail, or {@link NeverThrowsException} if they cannot fail.
376     *            Note that the type may be different to the type of this
377     *            {@code Promise}.
378     * @param onResult
379     *            The function which will be executed upon successful completion
380     *            of this {@code Promise}.
381     * @param onException
382     *            The function which will be executed upon failure of this
383     *            {@code Promise}.
384     * @return A new {@code Promise} representing the outcome of the
385     *         invoked function.
386     */
387    <VOUT, EOUT extends Exception> Promise<VOUT, EOUT> then(
388            Function<? super V, VOUT, EOUT> onResult, Function<? super E, VOUT, EOUT> onException);
389
390    /**
391     * Submits the provided functions for execution once this {@code Promise}
392     * has completed (with a result or an exception or a {@link RuntimeException}), and returns a new
393     * {@code Promise} representing the outcome of the invoked function. If
394     * this {@code Promise} completes with a result then {@code onResult}
395     * will be invoked with the result, with a {@link RuntimeException} then {@code onRuntimeException}
396     * will be invoked with the runtime exception that occurred, otherwise {@code onException} will
397     * be invoked with the exception that occurred.
398     * <p>
399     * This method can be used for transforming the outcome of an
400     * asynchronous task.
401     *
402     * @param <VOUT>
403     *            The type of the functions' result, or {@link Void} if the
404     *            functions do not return anything (i.e. they only have
405     *            side-effects). Note that the type may be different to the type
406     *            of this {@code Promise}.
407     * @param <EOUT>
408     *            The type of the exception thrown by the functions if they
409     *            fail, or {@link NeverThrowsException} if they cannot fail.
410     *            Note that the type may be different to the type of this
411     *            {@code Promise}.
412     * @param onResult
413     *            The function which will be executed upon successful completion
414     *            of this {@code Promise}.
415     * @param onException
416     *            The function which will be executed upon failure of this
417     *            {@code Promise}.
418     * @param onRuntimeException
419     *            The function which will be executed upon failure with
420     *            {@link RuntimeException} of this {@code Promise}.
421     * @return A new {@code Promise} representing the outcome of the
422     *         invoked function.
423     */
424    <VOUT, EOUT extends Exception> Promise<VOUT, EOUT> then(
425            Function<? super V, VOUT, EOUT> onResult, Function<? super E, VOUT, EOUT> onException,
426            Function<? super RuntimeException, VOUT, EOUT> onRuntimeException);
427
428
429    /**
430     * Submits the provided runnable for execution once this {@code Promise} has
431     * completed, and regardless of whether it has a result or an exception.
432     * <p>
433     * This method can be used for resource cleanup after a series of
434     * asynchronous tasks have completed. More specifically, this method should
435     * be used in a similar manner to {@code finally} statements in
436     * {@code try...catch} expressions.
437     * <p>
438     * This method is equivalent to {@link #thenOnResultOrException(Runnable)}.
439     *
440     * @param onResultOrException
441     *            The runnable which will be notified regardless of the final
442     *            outcome of this {@code Promise}.
443     * @return This {@code Promise}.
444     */
445    Promise<V, E> thenAlways(Runnable onResultOrException);
446
447    /**
448     * Submits the provided runnable for execution once this {@code Promise} has
449     * completed, and regardless of whether of its outcome.
450     * <p>
451     * This method can be used for resource cleanup after a series of
452     * asynchronous tasks have completed. More specifically, this method should
453     * be used in a similar manner to {@code finally} statements in
454     * {@code try...catch} expressions.
455     * <p>
456     * This method is equivalent to {@link #thenAlways(Runnable)}.
457     *
458     * @param onResultOrException
459     *            The runnable which will be notified regardless of the final
460     *            outcome of this {@code Promise}.
461     * @return This {@code Promise}.
462     */
463    Promise<V, E> thenFinally(Runnable onResultOrException);
464
465    /**
466     * Submits the provided asynchronous function for execution once this
467     * {@code Promise} has completed with a result, and returns a new
468     * {@code Promise} representing the outcome of the function. If
469     * this {@code Promise} complete with an exception then the function
470     * will not be invoked and the error will be forwarded to the returned
471     * {@code Promise}.
472     * <p>
473     * This method may be used for chaining together a series of asynchronous
474     * tasks.
475     *
476     * @param <VOUT>
477     *            The type of the function's result, or {@link Void} if the
478     *            function does not return anything (i.e. it only has
479     *            side-effects). Note that the type may be different to the type
480     *            of this {@code Promise}.
481     * @param onResult
482     *            The asynchronous function which will be executed upon
483     *            successful completion of this {@code Promise}.
484     * @return A new {@code Promise} representing the outcome of the
485     *         function.
486     */
487    <VOUT> Promise<VOUT, E> thenAsync(AsyncFunction<? super V, VOUT, E> onResult);
488
489    /**
490     * Submits the provided asynchronous function for execution once this
491     * {@code Promise} has completed with an exception, and returns a new
492     * {@code Promise} representing the outcome of the function. If
493     * this {@code Promise} completes with a result then the function
494     * will not be invoked and the exception will be forwarded to the returned
495     * {@code Promise}.
496     * <p>
497     * This method may be used for chaining together a series of asynchronous
498     * tasks.
499     *
500     * @param <EOUT>
501     *            The type of the exception thrown by the function if it
502     *            fails, or {@link NeverThrowsException} if it cannot fails.
503     *            Note that the type may be different to the type of this
504     *            {@code Promise}.
505     * @param onException
506     *            The asynchronous function which will be executed upon failure completion
507     *            of this {@code Promise}.
508     *
509     * @return A new {@code Promise} representing the outcome of the
510     *         function.
511     */
512    <EOUT extends Exception> Promise<V, EOUT> thenCatchAsync(AsyncFunction<? super E, V, EOUT> onException);
513
514    /**
515     * Submits the provided asynchronous functions for execution once this
516     * {@code Promise} has completed, and returns a new {@code Promise}
517     * representing the outcome of the invoked function. If this
518     * {@code Promise} completes with a result then {@code onResult} will be
519     * invoked with the result, otherwise {@code onException} will be invoked with
520     * the exception that occurred.
521     * <p>
522     * This method may be used for chaining together a series of asynchronous
523     * tasks.
524     *
525     * @param <VOUT>
526     *            The type of the functions' result, or {@link Void} if the
527     *            functions do not return anything (i.e. they only have
528     *            side-effects). Note that the type may be different to the type
529     *            of this {@code Promise}.
530     * @param <EOUT>
531     *            The type of the exception thrown by the functions if they
532     *            fail, or {@link NeverThrowsException} if they cannot fail.
533     *            Note that the type may be different to the type of this
534     *            {@code Promise}.
535     * @param onResult
536     *            The asynchronous function which will be executed upon
537     *            successful completion of this {@code Promise}.
538     * @param onException
539     *            The asynchronous function which will be executed upon failure
540     *            of this {@code Promise}.
541     * @return A new {@code Promise} representing the outcome of the
542     *         invoked function.
543     */
544    <VOUT, EOUT extends Exception> Promise<VOUT, EOUT> thenAsync(
545            AsyncFunction<? super V, VOUT, EOUT> onResult,
546            AsyncFunction<? super E, VOUT, EOUT> onException);
547
548    /**
549     * Submits the provided asynchronous functions for execution once this
550     * {@code Promise} has completed, and returns a new {@code Promise}
551     * representing the outcome of the invoked function. If this
552     * {@code Promise} completes with a result then {@code onResult} will be
553     * invoked with the result, otherwise {@code onException} will be invoked with
554     * the exception that occurred, or {@code onRuntimeException} will be invoked with
555     * the runtime exception that occurred.
556     * <p>
557     * This method may be used for chaining together a series of asynchronous
558     * tasks.
559     *
560     * @param <VOUT>
561     *            The type of the functions' result, or {@link Void} if the
562     *            functions do not return anything (i.e. they only have
563     *            side-effects). Note that the type may be different to the type
564     *            of this {@code Promise}.
565     * @param <EOUT>
566     *            The type of the exception thrown by the functions if they
567     *            fail, or {@link NeverThrowsException} if they cannot fail.
568     *            Note that the type may be different to the type of this
569     *            {@code Promise}.
570     * @param onResult
571     *            The asynchronous function which will be executed upon
572     *            successful completion of this {@code Promise}.
573     * @param onException
574     *            The asynchronous function which will be executed upon failure
575     *            of this {@code Promise}.
576     * @param onRuntimeException
577     *            The asynchronous function which will be executed upon failure
578     *            with {@link RuntimeException} of this {@code Promise}.
579     * @return A new {@code Promise} representing the outcome of the
580     *         invoked function.
581     */
582    <VOUT, EOUT extends Exception> Promise<VOUT, EOUT> thenAsync(
583            AsyncFunction<? super V, VOUT, EOUT> onResult,
584            AsyncFunction<? super E, VOUT, EOUT> onException,
585            AsyncFunction<? super RuntimeException, VOUT, EOUT> onRuntimeException);
586
587    /**
588     * Registers the provided completion handler for notification if this
589     * {@code Promise} cannot be completed due to an runtime exception. If this
590     * {@code Promise} completes with a result or the typed exception then the
591     * completion handler will not be notified.
592     * <p>
593     * This method can be used for asynchronous completion notification.
594     *
595     * @param onRuntimeException
596     *            The completion handler which will be notified upon an
597     *            uncaught runtime exception completion of this
598     *            {@code Promise}.
599     * @return This {@code Promise}.
600     */
601    Promise<V, E> thenOnRuntimeException(RuntimeExceptionHandler onRuntimeException);
602}