While building an application for my company, I needed a way to make
large sections of the application sit behind a split point. After
organizing my application into "modules" of related functionality, I
came up with slick, easy way to make those "modules" split out
automatically: by using a proxy presenter.

My application uses gin and a hand-made MVP framework based loosely
off of gwt-presenter. Some adaptation may be necessary to fit your
particular frameworks, but here goes:

public class ProxyPresenter<T extends Presenter> implements Presenter
{

    private static class ProxyView implements View {

        SimplePanel proxy = new SimplePanel();

        ProxyView() {

        }

        @Override
        public Widget asWidget() {
            return this.proxy;
        }

        protected void setView(View view) {
            this.proxy.setWidget(view.asWidget());
        }

    }

    private boolean asyncCalled;
    private boolean bound;

    private HandlerManager bus;
    private T impl;
    private Provider<T> provider;
    private Queue<Command> queue;
    private ProxyView view;

    public ProxyPresenter(HandlerManager bus, Provider<T> provider) {
        this(bus, provider, false);
    }

    public ProxyPresenter(HandlerManager bus, Provider<T> provider,
            boolean eager) {
        this.bus = bus;
        this.provider = provider;
        this.queue = new LinkedList<Command>();
        this.view = new ProxyView();
        if (eager) {
            ensurePresenter();
        }
    }

    @Override
    public void bind() {
        this.bound = true;
        queue(new Command() {

            @Override
            public void execute() {
                ProxyPresenter.this.impl.bind();
            }

        });
    }

    @Override
    public View getView() {
        return this.view;
    }

    @Override
    public void handleHistory(final HistoryItem item) {
        queue(new Command() {

            @Override
            public void execute() {
                ProxyPresenter.this.impl.handleHistory(item);
            }

        });
    }

    @Override
    public boolean isBound() {
        return this.bound;
    }

    @Override
    public void release() {
        queue(new Command() {

            @Override
            public void execute() {
                ProxyPresenter.this.impl.release();
            }
        });
        this.bound = false;
    }

    protected void ensurePresenter() {
        if (!this.asyncCalled) {
            this.asyncCalled = true;
            GWT.runAsync(new RunAsyncCallback() {

                @Override
                public void onFailure(Throwable reason) {
                    ProxyPresenter.this.bus
                            .fireEvent(new ApplicationExceptionEvent
(reason));
                }

                @Override
                public void onSuccess() {

                    // get impl instance
                    ProxyPresenter.this.impl =
ProxyPresenter.this.provider
                            .get();

                    // fill-in proxy view
                    ProxyPresenter.this.view.setView
(ProxyPresenter.this.impl
                            .getView());

                    // execute any queued commands
                    while (ProxyPresenter.this.queue.peek() != null) {
                        Command cmd = ProxyPresenter.this.queue.poll
();
                        cmd.execute();
                    }

                }
            });
        }
    }

    protected void queue(Command command) {
        ensurePresenter();
        if (this.impl != null) {
            command.execute();
        } else {
            this.queue.offer(command);
        }
    }

    T getPresenter() {
        return this.impl;
    }

}



Then, in my gin module, instead of using an explicit bind, I use a
@Provides method, like so:

    @Provides
    Presenter getRealPresenter(HandlerManager bus,
            Provider<RealPresenter> provider) {
        return new ProxyPresenter<RealPresenter>(bus, provider);
    }


The rest is automagic!

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-web-toolkit?hl=en.

Reply via email to