package com.asayama.gwt.angular.client.q;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.asayama.gwt.jsni.client.Function;
import com.asayama.gwt.jsni.client.JSFunction;
import com.google.gwt.core.client.JavaScriptObject;
public class Promise<V> extends JavaScriptObject {
private static final String CLASS = Promise.class.getName();
private static final Logger LOG = Logger.getLogger(CLASS);
protected Promise() {
}
public static interface Done<V> {
void call(V value);
}
public static interface Continue<X, V> {
X call(V value);
}
public static interface Fail {
void call(Throwable cause);
}
public static interface Notify {
void call(Progress progress);
}
public final <X> Promise<X> then(Continue<X, V> success) {
return then(success, null, null);
}
public final Promise<V> then(Fail fail) {
return then(null, fail, null);
}
public final Promise<V> then(Notify notify) {
return then(null, null, notify);
}
public final Promise<V> then(final Done<V> success) {
then(new Continue<Object, V>() {
@Override
public Object call(V value) {
success.call(value);
return null;
}
}, null, null);
return this;
}
public final <X> Promise<X> then(final Continue<X, V> success, final Fail fail, final Notify notify) {
Promise<X> p = _then(
success == null ? null : JSFunction.create(new Function<Object>() {
@Override
public Object call(Object... args) {
try {
Object object = (args == null || args.length == 0) ? null : args[0];
V value = HostedModeEnvelope.unwrap(object);
return HostedModeEnvelope.wrap(success.call(value));
} catch (Throwable e) {
LOG.log(Level.WARNING, "Exception while calling promise success", e);
return null; //FIXME Determine the suitable behavior.
}
}
}),
fail == null ? null : JSFunction.create(new Function<Object>() {
@Override
public Object call(Object... args) {
try {
Object object = (args == null || args.length == 0) ? null : args[0];
Throwable value = HostedModeEnvelope.unwrap(object);
fail.call(value);
return HostedModeEnvelope.wrap(value);
} catch (Throwable e) {
LOG.log(Level.WARNING, "Exception while calling promise fail", e);
return null; //FIXME Determine the suitable behavior.
}
}
}),
notify == null ? null : JSFunction.create(new Function<Object>() {
@Override
public Object call(Object... args) {
try {
Object object = (args == null || args.length == 0) ? null : args[0];
Progress value = HostedModeEnvelope.unwrap(object);
notify.call(value);
return HostedModeEnvelope.wrap(value);
} catch (Throwable e) {
LOG.log(Level.WARNING, "Exception while calling promise notify", e);
return null; //FIXME Determine the suitable behavior.
}
}
}));
return p;
}
private final native <X> Promise<X> _then(JSFunction<?> fn1, JSFunction<?> fn2, JSFunction<?> fn3) /*-{
return this.then(fn1, fn2, fn3);
}-*/;
}