io.yields.plugins.kpi.BuildActionResultsDisplay.java Source code

Java tutorial

Introduction

Here is the source code for io.yields.plugins.kpi.BuildActionResultsDisplay.java

Source

/*
 * Copyright 2014 by Yields.
 *
 * 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 io.yields.plugins.kpi;

import org.apache.commons.lang.StringUtils;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.jfree.ui.HorizontalAlignment;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RectangleInsets;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

import java.awt.*;
import java.io.IOException;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;

import javax.servlet.ServletException;

import hudson.model.AbstractBuild;
import hudson.model.ModelObject;
import hudson.model.TaskListener;
import hudson.util.DataSetBuilder;
import hudson.util.Graph;
import io.yields.math.framework.kpi.ScoreResult;

import static io.yields.plugins.kpi.LocalMessages.REPORT_DISPLAY_NAME;

/**
 * Report displaying Yields KPI results.
 */
public class BuildActionResultsDisplay implements ModelObject {

    /**
     * The {@link io.yields.plugins.kpi.KPIReportBuildAction} this report belongs to
     */
    private transient KPIReportBuildAction buildAction;

    /**
     * The {@link io.yields.plugins.kpi.KPIReport} for this build
     */
    private KPIReport currentReport;

    /**
     * The group tab selected by the user
     */
    private String selectedGroup;

    /**
     * Parses the reports and build a {@link io.yields.plugins.kpi.BuildActionResultsDisplay}.
     *
     * @throws java.io.IOException if a report fails to parse
     */
    BuildActionResultsDisplay(final KPIReportBuildAction buildAction, TaskListener listener) throws IOException {
        this.buildAction = buildAction;
        currentReport = this.buildAction.getKPIReport();
        currentReport.setBuildAction(buildAction);
    }

    public String getDisplayName() {
        return REPORT_DISPLAY_NAME.toString();
    }

    public AbstractBuild<?, ?> getBuild() {
        return buildAction.getBuild();
    }

    public KPIReport getKPIReport() {
        return currentReport;
    }

    public String getSelectedGroup() {
        return selectedGroup;
    }

    public void doBuildGraph(final StaplerRequest request, final StaplerResponse response) throws IOException {

        final String testName = request.getParameter("test");
        final int buildsInTrend = buildAction.getBuildsInTrend();

        final int width = getOrElse(request, "width", 400);
        final int height = getOrElse(request, "height", 300);

        final Graph graph = new BuildKPIGraph("Trend of " + testName, width, height) {

            protected DataSetBuilder<String, Integer> createDataSet() {
                DataSetBuilder<String, Integer> dataSetBuilder = new DataSetBuilder<String, Integer>();

                KPIReport kpiReport = getKPIReport();
                if (kpiReport != null) {

                    Map<Integer, ScoreResult> testResults = new TreeMap<Integer, ScoreResult>();
                    testResults.put(0, kpiReport.getKpiScore(testName));

                    int total = 1;

                    while (total < buildsInTrend) {

                        if (kpiReport != null) {
                            kpiReport = kpiReport.getPrevious();
                        } else {
                            kpiReport = null;
                        }

                        if (kpiReport != null) {
                            testResults.put(total, kpiReport.getKpiScore(testName));
                        }

                        total++;
                    }

                    total = 0;

                    SortedSet<String> kpiNames = getKPINames(buildsInTrend, testName);
                    while (total < buildsInTrend) {
                        ScoreResult scoreResult = testResults.get(total);
                        if (scoreResult != null) {
                            dataSetBuilder.add(scoreResult.getScore(), "Total Score", -total);
                            for (String kpiName : kpiNames) {
                                Map<String, Double> kpiResults = scoreResult.getKpiResults();
                                Double kpiResult = kpiResults.get(kpiName);
                                if (kpiResult != null) {
                                    dataSetBuilder.add(kpiResult, kpiName, -total);
                                }
                            }
                        }
                        total++;
                    }
                }

                return dataSetBuilder;
            }
        };

        graph.doPng(request, response);
    }

    private Integer getOrElse(StaplerRequest request, String parameterName, int defaultValue) {
        String value = request.getParameter(parameterName);
        if (StringUtils.isNotBlank(value)) {
            return Integer.parseInt(value);
        } else {
            return defaultValue;
        }
    }

    private SortedSet<String> getKPINames(int size, String testName) {
        KPIReport kpiReport = getKPIReport();
        if (kpiReport == null) {
            return new TreeSet<String>();
        } else {
            SortedSet<String> kpiNames = new TreeSet<String>();
            ScoreResult kpiScore = kpiReport.getKpiScore(testName);
            if (kpiScore != null) {

                kpiNames.addAll(kpiScore.getKpiResults().keySet());
                int total = 1;

                while (total < size) {
                    KPIReport previous = kpiReport.getPrevious();
                    if (previous == null) {
                        break;
                    }

                    ScoreResult scoreResult = previous.getKpiScore(testName);
                    if (scoreResult != null) {
                        kpiNames.addAll(scoreResult.getKpiResults().keySet());
                    }

                    total++;
                }
            }

            return kpiNames;
        }
    }

    private abstract class BuildKPIGraph extends Graph {

        private final String title;
        private final String xLabel;

        protected BuildKPIGraph(final String title, final int width, final int height) {
            super(-1, width, height);
            this.title = title;
            this.xLabel = "Build Number";
        }

        protected abstract DataSetBuilder<String, Integer> createDataSet();

        protected JFreeChart createGraph() {
            final CategoryDataset dataSet = createDataSet().build();

            double min = 1;
            double max = 0;

            for (int row = 0; row < dataSet.getRowCount(); row++) {
                for (int column = 0; column < dataSet.getColumnCount(); column++) {
                    Number value = dataSet.getValue(row, column);
                    if (value != null) {
                        min = Math.min(min, value.doubleValue());
                        max = Math.max(max, value.doubleValue());
                    }
                }
            }

            final JFreeChart chart = ChartFactory.createLineChart(title, xLabel, null, dataSet,
                    PlotOrientation.VERTICAL, true, true, false);

            chart.setBackgroundPaint(Color.white);

            CategoryPlot plot = ChartUtil.enhanceColors((CategoryPlot) chart.getPlot());

            // if min would be eq to max, this range would render and empty graph
            if (min == max) {
                min = min - (min * 0.1);
                max = max + (max * 0.1);
            }

            NumberAxis yAxis = new NumberAxis("");
            yAxis.setLowerMargin(0.1);
            yAxis.setUpperMargin(0.1);
            yAxis.setRangeWithMargins(min, max);

            plot.setRangeAxis(yAxis);

            chart.getLegend().setPosition(RectangleEdge.RIGHT);
            chart.getLegend().setMargin(new RectangleInsets(0, 10, 0, 0));

            chart.getTitle().setHorizontalAlignment(HorizontalAlignment.LEFT);

            return chart;
        }
    }

    /**
     * Extracts the selected group from the request and sets it to the current bound object.
     * These requests are sent when the user clicks on a group tab in the KPI Report page.
     */
    public void doSelectGroup(final StaplerRequest request, final StaplerResponse response)
            throws IOException, ServletException {
        selectedGroup = request.getParameter("group");
        response.forwardToPreviousPage(request);
    }

}