com.google.testing.testify.risk.frontend.client.view.impl.CapabilityDetailsViewImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.google.testing.testify.risk.frontend.client.view.impl.CapabilityDetailsViewImpl.java

Source

// Copyright 2011 Google Inc. All Rights Reseved.
//
// 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.testing.testify.risk.frontend.client.view.impl;

import com.google.common.collect.Lists;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
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.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.testing.testify.risk.frontend.client.view.CapabilityDetailsView;
import com.google.testing.testify.risk.frontend.client.view.widgets.EditCapabilityWidget;
import com.google.testing.testify.risk.frontend.client.view.widgets.PageSectionVerticalPanel;
import com.google.testing.testify.risk.frontend.model.Attribute;
import com.google.testing.testify.risk.frontend.model.Bug;
import com.google.testing.testify.risk.frontend.model.Capability;
import com.google.testing.testify.risk.frontend.model.Checkin;
import com.google.testing.testify.risk.frontend.model.Component;
import com.google.testing.testify.risk.frontend.model.UploadedDatum;
import com.google.testing.testify.risk.frontend.model.TestCase;

import java.util.Collection;
import java.util.List;

/**
 * View the details of a Capability, including attached data artifacts.
 *
 * @author jimr@google.com (Jim Reardon)
 */
public class CapabilityDetailsViewImpl extends Composite implements CapabilityDetailsView {

    private static final String HEADER_TEXT = "Details for Capability: ";

    /**
     * Used to wire parent class to associated UI Binder.
     */
    interface CapabilityDetailsViewImplUiBinder extends UiBinder<Widget, CapabilityDetailsViewImpl> {
    }

    private static final CapabilityDetailsViewImplUiBinder uiBinder = GWT
            .create(CapabilityDetailsViewImplUiBinder.class);

    @UiField
    public PageSectionVerticalPanel detailsSection;
    @UiField
    public CheckBox signoffBox;
    @UiField
    public Image testChart;
    @UiField
    public Grid testGrid;
    @UiField
    public HTML testNotRunCount;
    @UiField
    public HTML testPassedCount;
    @UiField
    public HTML testFailedCount;
    @UiField
    public Grid bugGrid;
    @UiField
    public Grid changeGrid;

    // Will be constructed and added to the above panel once we know what capability we're showing.
    public EditCapabilityWidget capabilityWidget;

    boolean isEditable = false;

    private CapabilityDetailsView.Presenter presenter;

    // TODO(jimr): Reconsider this data model.  Keeping each data item stored twice is not awesome.
    private List<Attribute> attributes;
    private List<Component> components;
    private List<Bug> bugs;
    private List<Bug> otherBugs = Lists.newArrayList();
    private List<Bug> capabilityBugs = Lists.newArrayList();
    private List<TestCase> tests;
    private List<TestCase> otherTests = Lists.newArrayList();
    private List<TestCase> capabilityTests = Lists.newArrayList();
    private List<Checkin> checkins;
    private List<Checkin> otherCheckins = Lists.newArrayList();
    private List<Checkin> capabilityCheckins = Lists.newArrayList();
    private Collection<String> projectLabels = Lists.newArrayList();

    private Anchor addBugAnchor;
    private Anchor addCheckinAnchor;
    private Anchor addTestAnchor;

    private Capability capability = null;

    public CapabilityDetailsViewImpl() {
        initWidget(uiBinder.createAndBindUi(this));
        detailsSection.setHeaderText(HEADER_TEXT);
    }

    @UiHandler("signoffBox")
    public void addSignoffClickHandler(ClickEvent click) {
        presenter.setSignoff(capability.getCapabilityId(), signoffBox.getValue());
    }

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

    @Override
    public void setPresenter(Presenter presenter) {
        this.presenter = presenter;
        refresh();
    }

    @Override
    public void setCapability(Capability capability) {
        this.capability = capability;
        refresh();
    }

    @Override
    public void setAttributes(List<Attribute> attributes) {
        this.attributes = attributes;
        refresh();
    }

    @Override
    public void setBugs(List<Bug> bugs) {
        this.bugs = bugs;
        refresh();
    }

    @Override
    public void setCheckins(List<Checkin> checkins) {
        this.checkins = checkins;
        refresh();
    }

    @Override
    public void setProjectLabels(Collection<String> labels) {
        projectLabels.clear();
        projectLabels.addAll(labels);
        if (capabilityWidget != null) {
            capabilityWidget.setLabelSuggestions(labels);
        }
    }

    private <T extends UploadedDatum> void splitData(List<T> inItems, List<T> otherItems, List<T> capabilityItems) {
        otherItems.clear();
        capabilityItems.clear();
        for (T item : inItems) {
            if (capability.getCapabilityId().equals(item.getTargetCapabilityId())) {
                capabilityItems.add(item);
            } else {
                otherItems.add(item);
            }
        }
    }

    @Override
    public void setTests(List<TestCase> tests) {
        this.tests = tests;
        refresh();
    }

    @Override
    public void setComponents(List<Component> components) {
        this.components = components;
        refresh();
    }

    @SuppressWarnings("unchecked")
    @Override
    public void refresh() {
        // Don't re-draw until all data has successfully loaded.
        if (attributes != null && components != null && capability != null && bugs != null && tests != null
                && checkins != null) {
            splitData(tests, otherTests, capabilityTests);
            splitData(bugs, otherBugs, capabilityBugs);
            splitData(checkins, otherCheckins, capabilityCheckins);
            capabilityWidget = new EditCapabilityWidget(capability);
            capabilityWidget.setLabelSuggestions(projectLabels);
            capabilityWidget.setAttributes(attributes);
            capabilityWidget.setComponents(components);
            capabilityWidget.disableDelete();
            if (isEditable) {
                capabilityWidget.makeEditable();
            }
            capabilityWidget.expand();
            capabilityWidget.addValueChangeHandler(new ValueChangeHandler<Capability>() {
                @Override
                public void onValueChange(ValueChangeEvent<Capability> event) {
                    capability = event.getValue();
                    presenter.updateCapability(capability);
                    refresh();
                    capabilityWidget.showSaved();
                }
            });
            detailsSection.clear();
            detailsSection.add(capabilityWidget);
            updateTestSection();
            updateBugSection();
            updateCheckinsSection();
            detailsSection.setHeaderText(HEADER_TEXT + capability.getName());
        }
    }

    @Override
    public void makeEditable() {
        isEditable = true;
        signoffBox.setEnabled(true);
        if (capabilityWidget != null) {
            capabilityWidget.makeEditable();
        }
        if (addTestAnchor != null) {
            addTestAnchor.setVisible(true);
        }
        if (addBugAnchor != null) {
            addBugAnchor.setVisible(true);
        }
        if (addCheckinAnchor != null) {
            addCheckinAnchor.setVisible(true);
        }
    }

    @Override
    public void reset() {
        attributes = null;
        components = null;
        capabilityWidget = null;
        capability = null;
        bugs = null;
        tests = null;
        checkins = null;
    }

    private TestCase getTestCaseById(long id) {
        for (TestCase test : tests) {
            if (test.getInternalId() == id) {
                return test;
            }
        }
        return null;
    }

    private Widget buildTestHeaderWidget(String header, String addText) {
        final ListBox options = new ListBox();
        for (TestCase test : otherTests) {
            options.addItem(test.getExternalId() + " " + test.getTitle(), String.valueOf(test.getInternalId()));
        }
        VerticalPanel addForm = new VerticalPanel();
        addForm.add(options);

        final DisclosurePanel disclosure = new DisclosurePanel();
        Button button = new Button(" Add ", new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                long id = Long.parseLong((options.getValue(options.getSelectedIndex())));
                presenter.assignTestCaseToCapability(capability.getCapabilityId(), id);
                disclosure.setOpen(false);
                TestCase test = getTestCaseById(id);
                test.setTargetCapabilityId(capability.getCapabilityId());
                refresh();
            }
        });
        addForm.add(button);
        disclosure.setAnimationEnabled(true);
        disclosure.setOpen(false);
        disclosure.setContent(addForm);

        HorizontalPanel title = new HorizontalPanel();
        title.add(new Label(header));
        addTestAnchor = new Anchor(addText);
        addTestAnchor.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                disclosure.setOpen(!disclosure.isOpen());
            }
        });
        addTestAnchor.setVisible(isEditable);
        title.add(addTestAnchor);

        VerticalPanel everything = new VerticalPanel();
        everything.add(title);
        everything.add(disclosure);
        return everything;
    }

    private void updateTestSection() {
        testGrid.setTitle("Recent Test Activity");
        testGrid.resize(capabilityTests.size() + 1, 1);
        testGrid.setWidget(0, 0, buildTestHeaderWidget("Recent Test Activity", "add test"));

        int passed = 0, failed = 0, notRun = 0;
        for (int i = 0; i < capabilityTests.size(); i++) {
            TestCase test = capabilityTests.get(i);
            HorizontalPanel panel = new HorizontalPanel();
            panel.add(getTestStateImage(test.getState()));
            Anchor anchor = new Anchor(test.getLinkText(), test.getLinkUrl());
            anchor.setTarget("_blank");
            panel.add(anchor);
            Label statusLabel = new Label();

            int state = getTestState(test.getState());
            if (state < 0) {
                statusLabel.setText(" - failed " + getDateText(test.getStateDate()));
                failed++;
            } else if (state > 0) {
                statusLabel.setText(" - passed " + getDateText(test.getStateDate()));
                passed++;
            } else {
                statusLabel.setText(" - no result");
                notRun++;
            }
            panel.add(statusLabel);
            testGrid.setWidget(i + 1, 0, panel);
        }
        testNotRunCount.setHTML("not run <b>" + notRun + "</b>");
        testPassedCount.setHTML("passed <b>" + passed + "</b>");
        testFailedCount.setHTML("failed <b>" + failed + "</b>");
        String imageUrl = getTestChartUrl(passed, failed, notRun);
        if (imageUrl == null || "".equals(imageUrl)) {
            testChart.setVisible(false);
        } else {
            testChart.setUrl(imageUrl);
            testChart.setVisible(true);
        }
    }

    private Bug getBugById(long id) {
        for (Bug bug : bugs) {
            if (bug.getInternalId() == id) {
                return bug;
            }
        }
        return null;
    }

    private Widget buildBugHeaderWidget(String header, String addText) {
        final ListBox options = new ListBox();
        for (Bug bug : otherBugs) {
            options.addItem(bug.getExternalId() + " " + bug.getTitle(), String.valueOf(bug.getInternalId()));
        }
        VerticalPanel addForm = new VerticalPanel();
        addForm.add(options);

        final DisclosurePanel disclosure = new DisclosurePanel();
        Button button = new Button(" Add ", new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                long id = Long.parseLong((options.getValue(options.getSelectedIndex())));
                presenter.assignBugToCapability(capability.getCapabilityId(), id);
                disclosure.setOpen(false);
                Bug bug = getBugById(id);
                bug.setTargetCapabilityId(capability.getCapabilityId());
                refresh();
            }
        });
        addForm.add(button);
        disclosure.setAnimationEnabled(true);
        disclosure.setOpen(false);
        disclosure.setContent(addForm);

        HorizontalPanel title = new HorizontalPanel();
        title.add(new Label(header));
        addBugAnchor = new Anchor(addText);
        addBugAnchor.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                disclosure.setOpen(!disclosure.isOpen());
            }
        });
        addBugAnchor.setVisible(isEditable);
        title.add(addBugAnchor);

        VerticalPanel everything = new VerticalPanel();
        everything.add(title);
        everything.add(disclosure);
        return everything;
    }

    private void updateBugSection() {
        bugGrid.resize(capabilityBugs.size() + 1, 1);
        bugGrid.setTitle("Bugs (" + capabilityBugs.size() + " total)");
        bugGrid.setWidget(0, 0, buildBugHeaderWidget("Bugs (" + capabilityBugs.size() + " total)", "add bug"));

        for (int i = 0; i < capabilityBugs.size(); i++) {
            Bug bug = capabilityBugs.get(i);
            HorizontalPanel panel = new HorizontalPanel();
            panel.add(getBugStateImage(bug.getState()));
            Anchor anchor = new Anchor(bug.getLinkText(), bug.getLinkUrl());
            anchor.setTarget("_blank");
            panel.add(anchor);
            Label statusLabel = new Label();
            statusLabel.setText(" - filed " + getDateText(bug.getStateDate()));
            panel.add(statusLabel);
            bugGrid.setWidget(i + 1, 0, panel);
        }
    }

    private Checkin getCheckinById(long id) {
        for (Checkin checkin : checkins) {
            if (checkin.getInternalId() == id) {
                return checkin;
            }
        }
        return null;
    }

    private Widget buildCheckinHeaderWidget(String header, String addText) {
        final ListBox options = new ListBox();
        for (Checkin checkin : otherCheckins) {
            options.addItem(checkin.getExternalId() + " " + checkin.getSummary(),
                    String.valueOf(checkin.getInternalId()));
        }
        VerticalPanel addForm = new VerticalPanel();
        addForm.add(options);

        final DisclosurePanel disclosure = new DisclosurePanel();
        Button button = new Button(" Add ", new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                long id = Long.parseLong((options.getValue(options.getSelectedIndex())));
                presenter.assignCheckinToCapability(capability.getCapabilityId(), id);
                disclosure.setOpen(false);
                Checkin checkin = getCheckinById(id);
                checkin.setTargetCapabilityId(capability.getCapabilityId());
                refresh();
            }
        });
        addForm.add(button);
        disclosure.setAnimationEnabled(true);
        disclosure.setOpen(false);
        disclosure.setContent(addForm);

        HorizontalPanel title = new HorizontalPanel();
        title.add(new Label(header));
        addCheckinAnchor = new Anchor(addText);
        addCheckinAnchor.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                disclosure.setOpen(!disclosure.isOpen());
            }
        });
        addCheckinAnchor.setVisible(isEditable);
        title.add(addCheckinAnchor);

        VerticalPanel everything = new VerticalPanel();
        everything.add(title);
        everything.add(disclosure);
        return everything;
    }

    private void updateCheckinsSection() {
        changeGrid.setTitle("Recent Code Changes (" + capabilityCheckins.size() + " total)");
        changeGrid.resize(capabilityCheckins.size() + 1, 1);
        changeGrid.setWidget(0, 0, buildCheckinHeaderWidget(
                "Recent Code Changes (" + capabilityCheckins.size() + " total)", "add code change"));

        for (int i = 0; i < capabilityCheckins.size(); i++) {
            Checkin checkin = capabilityCheckins.get(i);
            HorizontalPanel panel = new HorizontalPanel();
            panel.add(new Image("/images/teststate-passed.png"));
            Anchor anchor = new Anchor(checkin.getLinkText(), checkin.getLinkUrl());
            anchor.setTarget("_blank");
            panel.add(anchor);
            Label statusLabel = new Label();
            statusLabel.setText(" - submitted " + getDateText(checkin.getStateDate()));
            panel.add(statusLabel);
            changeGrid.setWidget(i + 1, 0, panel);
        }
    }

    private Image getBugStateImage(String state) {
        Image image = new Image();
        if (state != null && state.toLowerCase().equals("closed")) {
            image.setUrl("/images/bugstate-closed.png");
        } else {
            image.setUrl("/images/bugstate-active.png");
        }
        return image;
    }

    /**
     * Turns a number of days, eg: 3, into a string like "3 days ago" or "1 day ago" or "today".
     * @param date date reported/filed/etc.
     * @return string representation.
     */
    private String getDateText(Long date) {
        int days = -1;
        if (date != null && date > 0) {
            days = (int) ((double) System.currentTimeMillis() - date) / 86400000;
        }

        if (days == 0) {
            return "today";
        } else if (days == 1) {
            return "1 day ago";
        } else if (days > 1) {
            return days + " days ago";
        }
        return "";
    }

    /**
     * Determine from a text description what state a test is in.
     *
     * @param state the text state.
     * @return -1 for failing test, 0 for unsure/not run, 1 for passing.
     */
    private int getTestState(String state) {
        if (state == null) {
            return 0;
        }
        state = state.toLowerCase();
        if (state.startsWith("pass")) {
            return 1;
        } else if (state.startsWith("fail")) {
            return -1;
        } else {
            return 0;
        }
    }

    private Image getTestStateImage(String state) {
        Image image = new Image();
        int stateVal = getTestState(state);
        if (stateVal > 0) {
            image.setUrl("/images/teststate-passed.png");
        } else if (stateVal < 0) {
            image.setUrl("/images/teststate-failed.png");
        } else {
            image.setUrl("/images/teststate-notrun.png");
        }
        return image;
    }

    private String getTestChartUrl(int passed, int failed, int notRun) {
        int total = passed + failed + notRun;
        if (total < 1) {
            return null;
        }
        passed = passed * 100 / total;
        failed = failed * 100 / total;
        notRun = notRun * 100 / total;
        String pStr = String.valueOf(passed);
        String fStr = String.valueOf(failed);
        String nStr = String.valueOf(notRun);
        return "http://chart.apis.google.com/chart?chs=500x20&cht=bhs&chco=FFFFFF,008000,FF0000&chd=t:" + nStr + "|"
                + pStr + "|" + fStr;
    }

    @Override
    public void setSignoff(boolean signoff) {
        signoffBox.setValue(signoff);
    }
}