/*
* Copyright 2013 Julien Viet
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package vietj.promises;
import com.google.common.base.Function;
import java.util.concurrent.Callable;
/**
* A promise.
*
* @param <V> the value
* @author Julien Viet
*/
public abstract class Promise<V> {
public static <V> Promise<V> wrap(V value) {
final Deferred<V> deferred = new Deferred<V>();
deferred.resolve(value);
return new Promise<V>() {
@Override
public <R> Promise<R> then(PromisingCallback<V, R> onFulfilled, PromisingCallback<Exception, R> onRejected) {
return deferred.promise.then(onFulfilled, onRejected);
}
};
}
public abstract <R> Promise<R> then(PromisingCallback<V, R> onFulfilled, PromisingCallback<Exception, R> onRejected);
public <R> Promise<R> then(PromisingCallback<V, R> onFulfilled) {
return then(onFulfilled, new PromisingCallback<Exception, R>() {
public Promise<R> call(Exception arg) throws Exception {
throw arg;
}
});
}
private static class CallbackAdapter<V, R> implements PromisingCallback<V, R> {
private final Callback<V, R> callback;
private CallbackAdapter(Callback<V, R> callback) {
this.callback = callback;
}
public Promise<R> call(V arg) throws Exception {
return wrap(callback.call(arg));
}
}
public <R> Promise<R> then(Callback<V, R> onFulfilled, Callback<Exception, R> onRejected) {
return then(new CallbackAdapter<V, R>(onFulfilled), new CallbackAdapter<Exception, R>(onRejected));
}
public <R> Promise<R> then(Callback<V, R> onFulfilled) {
return then(onFulfilled, new Callback<Exception, R>() {
public R call(Exception arg) throws Exception {
throw arg;
}
});
}
private static class FunctionAdapter<V, R> implements PromisingCallback<V, R> {
private final Function<V, R> handler ;
private FunctionAdapter(Function<V, R> handler) {
this.handler = handler;
}
public Promise<R> call(V arg) throws Exception {
return wrap(handler.apply(arg));
}
}
public <R> Promise<R> then(Function<V, R> onFulfilled, Function<Exception, R> onRejected) {
return then(new FunctionAdapter<V, R>(onFulfilled), new FunctionAdapter<Exception, R>(onRejected));
}
public <R> Promise<R> then(Function<V, R> onFulfilled) {
return then(new FunctionAdapter<V, R>(onFulfilled));
}
private static class CallableAdapter<V, R> implements PromisingCallback<V, R> {
private final Callable<R> handler ;
private CallableAdapter(Callable<R> handler) {
this.handler = handler;
}
public Promise<R> call(V arg) throws Exception {
return wrap(handler.call());
}
}
public <R> Promise<R> then(Callable<R> onFulfilled, Callable<R> onRejected) {
return then(new CallableAdapter<V, R>(onFulfilled), new CallableAdapter<Exception, R>(onRejected));
}
public <R> Promise<R> then(Callable<R> onFulfilled) {
return then(new CallableAdapter<V, R>(onFulfilled));
}
private static class RunnableAdapter<V, R> implements PromisingCallback<V, R> {
private final Runnable handler ;
private RunnableAdapter(Runnable handler) {
this.handler = handler;
}
public Promise<R> call(V arg) throws Exception {
handler.run();
return wrap(null);
}
}
public <R> Promise<R> then(Runnable onFulfilled, Runnable onRejected) {
return then(new RunnableAdapter<V, R>(onFulfilled), new RunnableAdapter<Exception, R>(onRejected));
}
public <R> Promise<R> then(Runnable onFulfilled) {
return then(new RunnableAdapter<V, R>(onFulfilled));
}
}