package com.dragome.forms.bindings.client.command; import com.dragome.forms.bindings.client.binding.Disposable; import com.dragome.forms.bindings.client.channel.Channel; import com.dragome.forms.bindings.client.channel.DefaultChannel; import com.dragome.forms.bindings.client.channel.Destination; import com.dragome.forms.bindings.client.channel.Publisher; import com.dragome.forms.bindings.client.util.SubscriptionList; import com.dragome.forms.bindings.client.value.ValueTarget; import com.dragome.forms.bindings.extra.user.client.Command; /** * AbstractAsyncEvents provides a the default implementation of {@link com.pietschy.gwt.pectin.client.command.AsyncEvents}. */ public class AsyncEventsImpl<R, E> extends AbstractEvents implements AsyncEvents<R, E> { private DefaultChannel<R> resultChannel= new DefaultChannel<R>(); private DefaultChannel<E> errorChannel= new DefaultChannel<E>(); protected AsyncEventsImpl() { } protected Channel<R> getResultChannel() { return resultChannel; } protected Channel<E> getErrorChannel() { return errorChannel; } protected void fireSuccess(final R result) { resultChannel.publish(result); visitAsyncSubscribers(new SubscriptionList.Visitor<AsyncLifeCycleCallback<R, E>>() { public void visit(AsyncLifeCycleCallback<R, E> subscriber) { subscriber.onSuccess(result); } }); } protected void fireError(final E error) { errorChannel.publish(error); visitAsyncSubscribers(new SubscriptionList.Visitor<AsyncLifeCycleCallback<R, E>>() { public void visit(AsyncLifeCycleCallback<R, E> subscriber) { subscriber.onError(error); } }); } public <T> SendToBuilder<T> onSuccessSend(final T value) { return new SendToBuilderImpl<T>(resultChannel, value); } public <T> SendToBuilder<T> onErrorSend(final T value) { return new SendToBuilderImpl<T>(errorChannel, value); } public Disposable sendResultTo(Destination<? super R> destination) { return resultChannel.sendTo(destination); } public Disposable sendResultTo(ValueTarget<? super R> destination) { return resultChannel.sendTo(destination); } public Disposable sendResultTo(Publisher<? super R> publisher) { return resultChannel.sendTo(publisher); } public Disposable onSuccessInvoke(final Command command) { if (command == null) { throw new NullPointerException("command is null"); } return resultChannel.sendTo(new Destination<R>() { public void receive(R value) { command.execute(); } }); } public Disposable onSuccessInvoke(final ParameterisedCommand<? super R> command) { return resultChannel.sendTo(command); } public Disposable sendErrorTo(Destination<? super E> destination) { return errorChannel.sendTo(destination); } public Disposable sendErrorTo(ValueTarget<? super E> destination) { return errorChannel.sendTo(destination); } public Disposable sendErrorTo(Publisher<? super E> publisher) { return errorChannel.sendTo(publisher); } public Disposable onErrorInvoke(final ParameterisedCommand<? super E> command) { return errorChannel.sendTo(command); } public Disposable onErrorInvoke(final Command command) { if (command == null) { throw new NullPointerException("command is null"); } return errorChannel.sendTo(new Destination<E>() { public void receive(E value) { command.execute(); } }); } public Disposable sendAllEventsTo(AsyncLifeCycleCallback<R, E> callback) { // we all all our async subscribers as regulars subscribers so they // automatically pickup the start and finished events. return super.sendAllEventsTo(callback); } protected void visitAsyncSubscribers(final SubscriptionList.Visitor<AsyncLifeCycleCallback<R, E>> visitor) { // now we fire async events to those subscribers that implement AsyncLifeCycleCallback super.visitSubscribers(new SubscriptionList.Visitor<LifeCycleCallback>() { public void visit(LifeCycleCallback subscriber) { if (visitor instanceof AsyncLifeCycleCallback) { visitor.visit((AsyncLifeCycleCallback<R, E>) subscriber); } } }); } }