com.google.gerrit.client.api.PluginLoader.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gerrit.client.api.PluginLoader.java

Source

// Copyright (C) 2013 The Android Open Source Project
//
// 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 com.google.gerrit.client.api;

import com.google.gerrit.client.ErrorDialog;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.VoidResult;
import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.Natives;
import com.google.gwt.core.client.Callback;
import com.google.gwt.core.client.CodeDownloadException;
import com.google.gwt.core.client.ScriptInjector;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwtexpui.progress.client.ProgressBar;
import java.util.List;
import java.util.stream.Collectors;

/** Loads JavaScript plugins with a progress meter visible. */
public class PluginLoader extends DialogBox {
    private static PluginLoader self;

    public static void load(List<String> plugins, int loadTimeout, AsyncCallback<VoidResult> callback) {
        if (plugins == null || plugins.isEmpty()) {
            callback.onSuccess(VoidResult.create());
        } else {
            plugins = plugins.stream().filter(p -> p.endsWith(".js")).collect(Collectors.toList());
            if (plugins.isEmpty()) {
                callback.onSuccess(VoidResult.create());
            } else {
                self = new PluginLoader(loadTimeout, callback);
                self.load(plugins);
                self.startTimers();
                self.center();
            }
        }
    }

    static void loaded() {
        self.loadedOne();
    }

    private final int loadTimeout;
    private final AsyncCallback<VoidResult> callback;
    private ProgressBar progress;
    private Timer show;
    private Timer update;
    private Timer timeout;
    private boolean visible;

    private PluginLoader(int loadTimeout, AsyncCallback<VoidResult> cb) {
        super(/* auto hide */ false, /* modal */ true);
        callback = cb;
        this.loadTimeout = loadTimeout;
        progress = new ProgressBar(Gerrit.C.loadingPlugins());

        setStyleName(Gerrit.RESOURCES.css().errorDialog());
        addStyleName(Gerrit.RESOURCES.css().loadingPluginsDialog());
    }

    private void load(List<String> pluginUrls) {
        for (String url : pluginUrls) {
            Plugin plugin = Plugin.create(url);
            plugins().put(url, plugin);
            ScriptInjector.fromUrl(url).setWindow(ScriptInjector.TOP_WINDOW).setCallback(new LoadCallback(plugin))
                    .inject();
        }
    }

    private void startTimers() {
        show = new Timer() {
            @Override
            public void run() {
                setText(Window.getTitle());
                setWidget(progress);
                setGlassEnabled(true);
                getGlassElement().addClassName(Gerrit.RESOURCES.css().errorDialogGlass());
                hide(true);
                center();
                visible = true;
            }
        };
        show.schedule(500);

        update = new Timer() {
            private int cycle;

            @Override
            public void run() {
                progress.setValue(100 * ++cycle * 250 / loadTimeout);
            }
        };
        update.scheduleRepeating(250);

        timeout = new Timer() {
            @Override
            public void run() {
                finish();
            }
        };
        timeout.schedule(loadTimeout);
    }

    private void loadedOne() {
        boolean done = true;
        for (Plugin plugin : Natives.asList(plugins().values())) {
            done &= plugin.loaded();
        }
        if (done) {
            finish();
        }
    }

    private void finish() {
        show.cancel();
        update.cancel();
        timeout.cancel();
        self = null;

        if (!hadFailures()) {
            if (visible) {
                progress.setValue(100);
                new Timer() {
                    @Override
                    public void run() {
                        hide(true);
                    }
                }.schedule(250);
            } else {
                hide(true);
            }
        }

        callback.onSuccess(VoidResult.create());
    }

    private boolean hadFailures() {
        boolean failed = false;
        for (Plugin plugin : Natives.asList(plugins().values())) {
            if (!plugin.success()) {
                failed = true;

                Exception e = plugin.failure();
                String msg;
                if (e != null && e instanceof CodeDownloadException) {
                    msg = Gerrit.M.cannotDownloadPlugin(plugin.url());
                } else {
                    msg = Gerrit.M.pluginFailed(plugin.name());
                }
                hide(true);
                new ErrorDialog(msg).center();
            }
        }
        return failed;
    }

    private static native NativeMap<Plugin> plugins() /*-{ return $wnd.Gerrit.plugins }-*/;

    private class LoadCallback implements Callback<Void, Exception> {
        private final Plugin plugin;

        LoadCallback(Plugin plugin) {
            this.plugin = plugin;
        }

        @Override
        public void onSuccess(Void result) {
        }

        @Override
        public void onFailure(Exception reason) {
            plugin.failure(reason);
            loadedOne();
        }
    }
}