001    /**
002     * Copyright (C) 2011-2012 Barchart, Inc. <http://www.barchart.com/>
003     *
004     * All rights reserved. Licensed under the OSI BSD License.
005     *
006     * http://www.opensource.org/licenses/bsd-license.php
007     */
008    package com.barchart.util.concurrent;
009    
010    import java.util.concurrent.Future;
011    
012    /**
013     * <p>
014     * Adds listener notification methods to {@link Future} to allow immediate
015     * notification when a result is available.
016     * </p>
017     * 
018     * <p>
019     * Example:
020     * </p>
021     * 
022     * <p>
023     * 
024     * <pre>
025     * FutureListener&lt;Employee&gt; listener = new FutureListener&lt;Employee&gt; {
026     *   public void resultAvailable(Future&ltEmployee&gt; result) {
027     *     System.out.println("Got deferred result: " + result.get());
028     *   }
029     * }
030     * 
031     * FutureCallback&lt;Employee&gt; result = myDataStore.getEmployee(id);
032     * result.addResultListener(listener);
033     * </pre>
034     * 
035     * </p>
036     * 
037     * <p>
038     * In this example, getEmployee() returns a FutureCallback object that it will
039     * later use to return a result asynchronously. When it has a result, it calls
040     * result.succeed(Employee e), which in turn notifies any listeners registered
041     * with result.addResultListener(). If the call fails, the owner may call
042     * result.fail(Exception ex) to report the error. If a FutureCallback has
043     * failed, any future calls to result.get() throw an ExecutionException with the
044     * original exception as its cause.
045     * </p>
046     * 
047     * <p>
048     * This class is thread-safe.
049     * </p>
050     * 
051     * @author jeremy
052     * @see Future
053     * @see FutureListener
054     * @see FutureCallbackTask
055     * @param <E>
056     *            The result type
057     */
058    public interface FutureCallback<V, T extends FutureCallback<V, T>> extends
059                    Future<V> {
060    
061            /**
062             * Register a listener for this deferred result. If the result is already
063             * available, the listener may be called synchronously, so you should
064             * generally avoid any blocking code in the callback.
065             * 
066             * @param listener
067             *            The listener object
068             */
069            public T addResultListener(FutureListener<V> listener);
070    
071            /**
072             * Notify listeners that a result is available. Returns the current
073             * FutureCallbackTask instance to allow simple synchronous returns when the
074             * result is already available:<br />
075             * <code>return new FutureCallbackTask<Object>().succeed(result);</code>
076             * 
077             * @param result_
078             *            The deferred result
079             * @return This FutureCallbackTask object (for chaining calls)
080             */
081            public T succeed(V result);
082    
083            /**
084             * Notify listeners that an error occurred. Returns the current
085             * FutureCallbackTask instance to allow simple synchronous returns when an
086             * error has already occurred:<br />
087             * <code>return new FutureCallbackTask<Object>().fail(exception);</code>
088             * 
089             * @param error_
090             *            The deferred error
091             */
092            public T fail(Throwable error);
093    
094            /**
095             * Get the return value, or null if a checked exception was caught.
096             */
097            public V getUnchecked();
098    
099    }