com.googlesource.gerrit.plugins.labelui.client.LabelPanel.java Source code

Java tutorial

Introduction

Here is the source code for com.googlesource.gerrit.plugins.labelui.client.LabelPanel.java

Source

// Copyright (C) 2015 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.googlesource.gerrit.plugins.labelui.client;

import com.google.gerrit.client.GerritUiExtensionPoint;
import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.client.info.AccountInfo.AvatarInfo;
import com.google.gerrit.client.info.ChangeInfo;
import com.google.gerrit.client.info.ChangeInfo.ApprovalInfo;
import com.google.gerrit.client.info.ChangeInfo.LabelInfo;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.plugin.client.Plugin;
import com.google.gerrit.plugin.client.extension.Panel;
import com.google.gerrit.plugin.client.rpc.RestApi;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Cursor;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.TextAlign;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

public class LabelPanel extends VerticalPanel {
    static class Factory implements Panel.EntryPoint {
        @Override
        public void onLoad(Panel panel) {
            panel.setWidget(new LabelPanel(panel));
        }
    }

    private final static String COLOR_GREEN = "#060";
    private final static String COLOR_RED = "#F00";

    LabelPanel(final Panel panel) {
        new RestApi("accounts").id("self").view(Plugin.get().getPluginName(), "preferences")
                .get(new AsyncCallback<PreferencesInfo>() {
                    @Override
                    public void onSuccess(PreferencesInfo result) {
                        LabelUIPlugin.refreshDefaultLabelUi(result.ui());
                        ChangeInfo change = panel.getObject(GerritUiExtensionPoint.Key.CHANGE_INFO).cast();
                        switch (result.ui()) {
                        case LABEL_USER_TABLE:
                            displayLabelUserTable(change);
                            break;
                        case USER_LABEL_TABLE:
                            displayUserLabelTable(change);
                            break;
                        case DEFAULT:
                        default:
                            return;
                        }
                    }

                    @Override
                    public void onFailure(Throwable caught) {
                        // never invoked
                    }
                });
    }

    private void displayLabelUserTable(ChangeInfo change) {
        Set<String> labelNames = getLabelNames(change);
        Map<String, AccountInfo> users = getUserMap(labelNames, change);
        Map<Integer, VotableInfo> votable = votable(change);
        Grid g = createGrid(labelNames.size() + 1, users.size() + 1);

        int i = 1;
        for (AccountInfo account : users.values()) {
            g.setWidget(0, i, createUserWidget(account));
            i++;
        }

        i = 1;
        for (String labelName : labelNames) {
            g.setWidget(i, 0, createLabelLabel(change.label(labelName)));

            int j = 1;
            for (AccountInfo account : users.values()) {
                LabelInfo label = change.label(labelName);
                ApprovalInfo ai = label.forUser(account._accountId());
                g.setWidget(i, j, createLabelValueWidget(label, ai));

                if (!votable.get(account._accountId()).isVotable(labelName)) {
                    formatNonVotable(g, i, j);
                }
                j++;
            }
            i++;
        }

        add(g);
    }

    private void displayUserLabelTable(ChangeInfo change) {
        Set<String> labelNames = getLabelNames(change);
        Map<String, AccountInfo> users = getUserMap(labelNames, change);
        Map<Integer, VotableInfo> votable = votable(change);
        Grid g = createGrid(users.size() + 1, labelNames.size() + 1);

        int i = 1;
        for (String labelName : labelNames) {
            g.setWidget(0, i, createLabelLabel(change.label(labelName)));
            i++;
        }

        i = 1;
        for (AccountInfo account : users.values()) {
            g.setWidget(i, 0, createUserWidget(account));

            int j = 1;
            for (String labelName : labelNames) {
                LabelInfo label = change.label(labelName);
                ApprovalInfo ai = label.forUser(account._accountId());
                g.setWidget(i, j, createLabelValueWidget(label, ai));

                if (!votable.get(account._accountId()).isVotable(labelName)) {
                    formatNonVotable(g, i, j);
                }
                j++;
            }
            i++;
        }

        add(g);
    }

    private static Grid createGrid(int rows, int columns) {
        Grid g = new Grid(rows, columns);
        g.addStyleName("infoBlock");
        g.addStyleName("changeTable");

        CellFormatter fmt = g.getCellFormatter();
        fmt.addStyleName(0, 0, "leftMostCell");
        fmt.addStyleName(0, 0, "topmost");

        for (int c = 1; c < columns; c++) {
            fmt.addStyleName(0, c, "header");
            fmt.addStyleName(0, c, "topmost");
        }

        for (int r = 1; r < rows; r++) {
            fmt.addStyleName(r, 0, "leftMostCell");
            fmt.addStyleName(r, 0, "header");

            for (int c = 1; c < columns; c++) {
                fmt.addStyleName(r, c, "dataCell");
            }
        }

        for (int c = 0; c < columns; c++) {
            fmt.addStyleName(rows - 1, c, "bottomheader");
        }

        return g;
    }

    private static Set<String> getLabelNames(ChangeInfo change) {
        return new TreeSet<String>(change.labels());
    }

    private static Map<String, AccountInfo> getUserMap(Set<String> labelNames, ChangeInfo change) {
        Map<String, AccountInfo> users = new TreeMap<>();
        for (String labelName : labelNames) {
            LabelInfo label = change.label(labelName);
            for (ApprovalInfo ai : Natives.asList(label.all())) {
                users.put(ai.name(), ai);
            }
        }
        return users;
    }

    private static Widget createLabelValueWidget(LabelInfo label, ApprovalInfo ai) {
        int accountId = ai._accountId();
        String formattedValue = formatValue(ai.value());
        String valueText = label.valueText(formattedValue);
        if (label.approved() != null && label.approved()._accountId() == accountId) {
            return createImage(LabelUIPlugin.RESOURCES.greenCheck(), valueText);
        } else if (label.rejected() != null && label.rejected()._accountId() == accountId) {
            return createImage(LabelUIPlugin.RESOURCES.redNot(), valueText);
        } else {
            return createValueLabel(formattedValue, valueText, ai.value());
        }
    }

    private static Label createLabelLabel(LabelInfo label) {
        Label l = new Label(label.name());
        Style s = l.getElement().getStyle();
        s.setCursor(Cursor.DEFAULT);
        if (label.rejected() != null) {
            s.setColor(COLOR_RED);
            l.setTitle("Rejected by " + label.rejected().name());
        } else if (label.approved() != null) {
            s.setColor(COLOR_GREEN);
            l.setTitle("Approved by " + label.approved().name());
        }
        return l;
    }

    private static Widget createUserWidget(AccountInfo account) {
        HorizontalPanel p = new HorizontalPanel();
        Label l = new Label(account.name());
        if (account.hasAvatarInfo()) {
            p.add(createAvatar(account));
            l.getElement().getStyle().setMarginTop(3, Unit.PX);
        }

        l.getElement().getStyle().setCursor(Cursor.DEFAULT);
        l.setTitle(formatToolTip(account));
        p.add(l);
        return p;
    }

    private static Image createAvatar(AccountInfo account) {
        int size = 16;
        AvatarInfo avatar = account.avatar(size);
        if (avatar == null) {
            avatar = account.avatar(AvatarInfo.DEFAULT_SIZE);
        }
        String url;
        if (avatar == null) {
            RestApi api = new RestApi("/accounts/").id(account._accountId()).view("avatar").addParameter("s", size);
            url = GWT.getHostPageBaseURL() + api.path().substring(1);
        } else {
            url = avatar.url();
        }
        Image avatarImage = new Image(url);
        avatarImage.setSize("", size + "px");
        return avatarImage;
    }

    private static String formatToolTip(AccountInfo ai) {
        StringBuilder b = new StringBuilder();
        b.append(ai.name());
        if (ai.email() != null) {
            b.append(" <");
            b.append(ai.email());
            b.append(">");
        }
        return b.toString();
    }

    private static Image createImage(ImageResource imageResource, String valueText) {
        Image image = new Image(imageResource);
        if (valueText != null) {
            image.setTitle(valueText);
        }
        center(image);
        return image;
    }

    private static void center(Image image) {
        Style s = image.getElement().getStyle();
        s.setProperty("margin-left", "auto");
        s.setProperty("margin-right", "auto");
        s.setDisplay(Display.BLOCK);
    }

    public static Label createValueLabel(String formattedValue, String valueText, short value) {
        Label l = new Label(formattedValue);
        if (valueText != null) {
            l.setTitle(valueText);
        }
        Style s = l.getElement().getStyle();
        s.setTextAlign(TextAlign.CENTER);
        s.setCursor(Cursor.DEFAULT);
        if (value > 0) {
            s.setColor(COLOR_GREEN);
        } else if (value < 0) {
            s.setColor(COLOR_RED);
        } else {
            // make label invisible, we cannot omit it since we need the label to show
            // a tooltip
            s.setColor("transparent");
        }
        return l;
    }

    private static String formatValue(short value) {
        if (value < 0) {
            return Short.toString(value);
        } else if (value == 0) {
            return " 0";
        } else {
            return "+" + Short.toString(value);
        }
    }

    private static void formatNonVotable(Grid g, int row, int column) {
        Widget w = g.getWidget(row, column);
        g.getCellFormatter().addStyleName(row, column, "header");
        w.setTitle("cannot vote on this label");
    }

    private static Map<Integer, VotableInfo> votable(ChangeInfo change) {
        Map<Integer, VotableInfo> d = new HashMap<>();
        for (String name : change.labels()) {
            LabelInfo label = change.label(name);
            if (label.all() != null) {
                for (ApprovalInfo ai : Natives.asList(label.all())) {
                    int id = ai._accountId();
                    VotableInfo ad = d.get(id);
                    if (ad == null) {
                        ad = new VotableInfo();
                        d.put(id, ad);
                    }
                    if (ai.hasValue()) {
                        ad.votable(name);
                    }
                }
            }
        }
        return d;
    }

    private static class VotableInfo {
        private Set<String> votable;

        void votable(String label) {
            if (votable == null) {
                votable = new HashSet<>();
            }
            votable.add(label);
        }

        Set<String> votableLabels() {
            Set<String> s = new HashSet<>();
            if (votable != null) {
                s.addAll(votable);
            }
            return s;
        }

        boolean isVotable(String label) {
            return votableLabels().contains(label);
        }
    }
}