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