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 2014 ForgeRock Inc.
015 */
016package org.forgerock.util;
017
018import org.forgerock.util.promise.Promise;
019
020/**
021 * An asynchronous {@link Function} which returns a result at some point in the
022 * future.
023 * <p>
024 * <b>Exception handling</b>: implementations may fail immediately if an error
025 * is encountered before asynchronous processing begins (e.g. if the function
026 * parameter is invalid). Implementations which do not throw any exceptions
027 * should declare that they throw an exception of type
028 * {@link org.forgerock.util.promise.NeverThrowsException}.
029 * <p>
030 * Example usage:
031 *
032 * <pre>
033 * public class IsPossiblePrime implements AsyncFunction&lt;String, Boolean, IllegalArgumentException&gt; {
034 *     // Executor for asynchronously computing primeness.
035 *     private ExecutorService executor = Executors.newCachedThreadPool();
036 *
037 *     public Promise&lt;Boolean, IllegalArgumentException&gt; apply(String value)
038 *             throws IllegalArgumentException {
039 *         // Create a promise which will hold the asynchronous result.
040 *         final PromiseImpl&lt;Boolean, IllegalArgumentException&gt; promise = PromiseImpl.create();
041 *
042 *         // Parse the parameter now and potentially immediately throw an
043 *         // exception. Parsing could be deferred to the executor in which
044 *         // case the exception should be trapped and promise.handleException()
045 *         // invoked.
046 *         final BigInteger possiblePrime = new BigInteger(value);
047 *
048 *         // Use an executor to asynchronously determine if the parameter is a
049 *         // prime number.
050 *         executor.execute(new Runnable() {
051 *             &#064;Override
052 *             public void run() {
053 *                 // Set the promised result.
054 *                 promise.handleResult(possiblePrime.isProbablePrime(1000));
055 *             }
056 *         });
057 *         return promise;
058 *     }
059 * }
060 * </pre>
061 *
062 * @param <VIN>
063 *            The type of the function parameter, or {@link Void} if the
064 *            function does not expect a parameter.
065 * @param <VOUT>
066 *            The type of the function result, or {@link Void} if the function
067 *            does not return anything (i.e. it only has side-effects).
068 * @param <E>
069 *            The type of the exception thrown by the function, or
070 *            {@link org.forgerock.util.promise.NeverThrowsException} if no exception is thrown by the
071 *            function.
072 * @see Function
073 * @see org.forgerock.util.promise.NeverThrowsException
074 */
075// @FunctionalInterface
076public interface AsyncFunction<VIN, VOUT, E extends Exception> extends
077        Function<VIN, Promise<? extends VOUT, ? extends E>, E> {
078
079    /**
080     * Asynchronously applies this function to the input parameter {@code value}
081     * and returns a {@link Promise} for the result.
082     *
083     * @param value
084     *            The input parameter.
085     * @return The {@link Promise} representing the result of applying this
086     *         function to {@code value}.
087     * @throws E
088     *             If this function cannot be applied to {@code value}.
089     */
090    @Override
091    Promise<? extends VOUT, ? extends E> apply(VIN value) throws E;
092
093}