001/*
002// This software is subject to the terms of the Eclipse Public License v1.0
003// Agreement, available at the following URL:
004// http://www.eclipse.org/legal/epl-v10.html.
005// You must accept the terms of that agreement to use this software.
006//
007// Copyright (C) 2011-2011 Pentaho
008// All Rights Reserved.
009*/
010package mondrian.util;
011
012import java.util.concurrent.*;
013
014/**
015 * Implementation of {@link Future} that has already completed.
016 */
017public class CompletedFuture<V> implements Future<V> {
018    private final V value;
019    private final ExecutionException exception;
020
021    /**
022     * Creates a CompletedFuture.
023     *
024     * <p>If {@code throwable} is not null, the computation is deemed to have
025     * failed. The exception will be thrown (wrapped in a
026     * {@link ExecutionException}) when {@link #get} or
027     * {@link #get(long, java.util.concurrent.TimeUnit)} are invoked.</p>
028     *
029     * <p>If exception is null, the computation is deemed to have succeeded.
030     * In this case, a null value in {@code value} just means that the
031     * computation yielded a null result.</p>
032     *
033     * @param value Value (may be null)
034     * @param exception Exception that occurred while computing result
035     */
036    public CompletedFuture(V value, ExecutionException exception) {
037        if (value != null && exception != null) {
038            throw new IllegalArgumentException(
039                "Value and exception must not both be specified");
040        }
041        this.value = value;
042        this.exception = exception;
043    }
044
045    /**
046     * Creates a completed future indicating success.
047     *
048     * @param t Result of computation
049     * @return Completed future that will yield the result
050     */
051    public static <T> CompletedFuture<T> success(T t) {
052        return new CompletedFuture<T>(t, null);
053    }
054
055    /**
056     * Creates a completed future indicating failure.
057     *
058     * @param e Exception
059     * @return Completed future that will throw
060     */
061    public static <T> CompletedFuture<T> fail(Throwable e) {
062        return new CompletedFuture<T>(null, new ExecutionException(e));
063    }
064
065    public boolean cancel(boolean mayInterruptIfRunning) {
066        // could not be cancelled, because already completed
067        return false;
068    }
069
070    public boolean isCancelled() {
071        // completed before could be cancelled
072        return false;
073    }
074
075    public boolean isDone() {
076        return true;
077    }
078
079    public V get() throws ExecutionException {
080        if (exception != null) {
081            throw exception;
082        }
083        return value;
084    }
085
086    public V get(long timeout, TimeUnit unit) throws ExecutionException {
087        return get();
088    }
089}
090
091// End CompletedFuture.java