Java tutorial
/* * 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); } }