org.activityinfo.ui.client.page.report.ExportDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.activityinfo.ui.client.page.report.ExportDialog.java

Source

package org.activityinfo.ui.client.page.report;

/*
 * #%L
 * ActivityInfo Server
 * %%
 * Copyright (C) 2009 - 2013 UNICEF
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public 
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/gpl-3.0.html>.
 * #L%
 */

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.core.El;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.ProgressBar;
import com.extjs.gxt.ui.client.widget.Text;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.layout.VBoxLayout;
import com.extjs.gxt.ui.client.widget.layout.VBoxLayout.VBoxLayoutAlign;
import com.extjs.gxt.ui.client.widget.layout.VBoxLayoutData;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.http.client.*;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.RootPanel;
import org.activityinfo.i18n.shared.I18N;
import org.activityinfo.legacy.client.Dispatcher;
import org.activityinfo.legacy.shared.command.Filter;
import org.activityinfo.legacy.shared.command.FilterUrlSerializer;
import org.activityinfo.legacy.shared.command.RenderElement;
import org.activityinfo.legacy.shared.command.RenderElement.Format;
import org.activityinfo.legacy.shared.command.result.UrlResult;
import org.activityinfo.legacy.shared.reports.model.ReportElement;
import org.activityinfo.promise.Promise;

public class ExportDialog extends Dialog {

    private final Dispatcher dispatcher;
    private ProgressBar bar;
    private Text downloadLink;
    private boolean canceled = false;
    private Button button;

    public ExportDialog(Dispatcher dispatcher) {
        this.dispatcher = dispatcher;

        setWidth(350);
        setHeight(175);
        setHeadingText(I18N.CONSTANTS.export());
        setClosable(false);
        setButtonAlign(HorizontalAlignment.CENTER);

        VBoxLayout layout = new VBoxLayout();
        layout.setVBoxLayoutAlign(VBoxLayoutAlign.LEFT);

        setLayout(layout);

        bar = new ProgressBar();
        bar.setWidth(300);
        add(bar, new VBoxLayoutData(new Margins(20, 15, 25, 15)));

        downloadLink = new Text(I18N.CONSTANTS.clickToDownload());
        downloadLink.setTagName("a");
        downloadLink.setVisible(false);
        add(downloadLink, new VBoxLayoutData(0, 15, 0, 15));

    }

    @Override
    protected void createButtons() {

        button = new Button();
        button.setText(I18N.CONSTANTS.cancel());
        button.addSelectionListener(new SelectionListener<ButtonEvent>() {

            @Override
            public void componentSelected(ButtonEvent ce) {
                ExportDialog.this.canceled = true;
                bar.reset();
                hide();
            }
        });
        getButtonBar().add(button);
    }

    public void export(String filename, ReportElement model, Format format) {
        showStartProgress();

        RenderElement command = new RenderElement(model, format);
        command.setFilename(filename);

        dispatcher.execute(command, new AsyncCallback<UrlResult>() {

            @Override
            public void onFailure(Throwable caught) {
                showError();
            }

            @Override
            public void onSuccess(UrlResult result) {
                if (!canceled) {
                    initiateDownload(result.getUrl());
                }
            }
        });
    }

    private void showStartProgress() {
        show();
        bar.updateText(I18N.CONSTANTS.exportProgress());
        bar.auto();
    }

    private void showError() {
        MessageBox.alert(I18N.CONSTANTS.export(), I18N.CONSTANTS.serverError(), new Listener<MessageBoxEvent>() {

            @Override
            public void handleEvent(MessageBoxEvent be) {
                ExportDialog.this.hide();
            }
        });
    }

    private void initiateDownload(String url) {
        bar.reset();
        bar.updateProgress(1.0, I18N.CONSTANTS.downloadReady());
        button.setText(I18N.CONSTANTS.close());
        tryStartDownloadWithIframe(url);
        downloadLink.getElement().setAttribute("href", url);
        downloadLink.setVisible(true);
        layout(true);
    }

    public void exportSites(Filter filter) {

        showStartProgress();

        RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.POST, "/ActivityInfo/export");
        requestBuilder.setHeader("Content-type", "application/x-www-form-urlencoded");
        requestBuilder.setRequestData("filter=" + FilterUrlSerializer.toUrlFragment(filter));
        requestBuilder.setCallback(new RequestCallback() {
            @Override
            public void onResponseReceived(Request request, Response response) {
                final String exportId = response.getText();
                getDownloadUrl(exportId).then(new AsyncCallback<String>() {
                    @Override
                    public void onFailure(Throwable caught) {
                        showError();
                    }

                    @Override
                    public void onSuccess(String downloadUrl) {
                        initiateDownload(downloadUrl);
                    }
                });
            }

            @Override
            public void onError(Request request, Throwable exception) {
                showError();
            }
        });
        try {
            requestBuilder.send();
        } catch (RequestException e) {
            showError();
        }
    }

    private Promise<String> getDownloadUrl(String exportId) {
        final Promise<String> url = new Promise<>();
        schedulePoll(exportId, url);
        return url;
    }

    private void schedulePoll(final String exportId, final Promise<String> downloadUrl) {
        Scheduler.get().scheduleFixedDelay(new Scheduler.RepeatingCommand() {
            @Override
            public boolean execute() {
                pollServer(exportId, downloadUrl);
                return false;
            }
        }, 1000);
    }

    private void pollServer(final String exportId, final Promise<String> downloadUrl) {
        RequestBuilder request = new RequestBuilder(RequestBuilder.GET, "/ActivityInfo/export?id=" + exportId);
        request.setCallback(new RequestCallback() {
            @Override
            public void onResponseReceived(Request request, Response response) {
                if (response.getStatusCode() == 200) {
                    downloadUrl.onSuccess(response.getText());
                } else {
                    schedulePoll(exportId, downloadUrl);
                }
            }

            @Override
            public void onError(Request request, Throwable exception) {
                downloadUrl.onFailure(exception);
            }
        });
        try {
            request.send();
        } catch (RequestException e) {
            downloadUrl.onFailure(e);
        }
    }

    private void tryStartDownloadWithIframe(String url) {
        com.google.gwt.user.client.ui.Frame frame = new com.google.gwt.user.client.ui.Frame(url);
        El el = El.fly(frame.getElement());
        el.setStyleAttribute("width", 0);
        el.setStyleAttribute("height", 0);
        el.setStyleAttribute("position", "absolute");
        el.setStyleAttribute("border", 0);
        RootPanel.get().add(frame);
    }
}