com.hello2morrow.sonargraph.jenkinsplugin.controller.SonargraphChartAction.java Source code

Java tutorial

Introduction

Here is the source code for com.hello2morrow.sonargraph.jenkinsplugin.controller.SonargraphChartAction.java

Source

/*******************************************************************************
 * Jenkins Sonargraph Plugin
 * Copyright (C) 2009-2015 hello2morrow GmbH
 * mailto: info AT hello2morrow DOT com
 *
 * 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.hello2morrow.sonargraph.jenkinsplugin.controller;

import hudson.model.Action;
import hudson.model.ProminentProjectAction;
import hudson.model.AbstractProject;
import hudson.util.Graph;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;

import jenkins.model.JenkinsLocationConfiguration;

import org.jfree.chart.JFreeChart;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

import com.hello2morrow.sonargraph.jenkinsplugin.controller.util.StaplerRequestUtil;
import com.hello2morrow.sonargraph.jenkinsplugin.foundation.SonargraphLogger;
import com.hello2morrow.sonargraph.jenkinsplugin.model.AbstractPlot;
import com.hello2morrow.sonargraph.jenkinsplugin.model.IMetricHistoryProvider;
import com.hello2morrow.sonargraph.jenkinsplugin.model.SonargraphMetrics;
import com.hello2morrow.sonargraph.jenkinsplugin.model.TimeSeriesPlot;
import com.hello2morrow.sonargraph.jenkinsplugin.model.XYLineAndShapePlot;
import com.hello2morrow.sonargraph.jenkinsplugin.persistence.CSVChartsForMetricsHandler;
import com.hello2morrow.sonargraph.jenkinsplugin.persistence.CSVFileHandler;

/**
 * This object is the responsible of managing the action that will take the user to see the graphs generated by sonargraph.
 * @author esteban
 *
 */
public class SonargraphChartAction implements Action, ProminentProjectAction {
    private static final String TYPE_PARAMETER = "type";
    private static final String METRIC_PARAMETER = "metric";

    private static final String SHORT_TERM = "shortterm";
    private static final String LONG_TERM = "longterm";

    /** Project or build that is calling this action. */
    private final AbstractProject<?, ?> project;

    private Integer defaultGraphicWidth = 400;
    private Integer defaultGraphicHeight = 250;

    private static final int MAX_DATA_POINTS_SHORT_TERM = 25;
    private static final int MAX_DATA_POINTS_LONG_TERM = 300;

    private static final String BUILD = "Build";
    private static final String DATE = "Date";

    public SonargraphChartAction(AbstractProject<?, ?> project, AbstractSonargraphRecorder builder) {
        this.project = project;
    }

    public Collection<String> getChartsForMetrics() {
        List<String> chartsForMetrics = new ArrayList<String>();
        CSVChartsForMetricsHandler csvChartsForMetricsHandler = new CSVChartsForMetricsHandler();

        File chartsForMetricsFile = new File(project.getRootDir(),
                ConfigParameters.CHARTS_FOR_METRICS_CSV_FILE_PATH.getValue());
        //File might not exist after updating the plugin
        if (!chartsForMetricsFile.exists()) {
            for (SonargraphMetrics metric : SonargraphMetrics.getDefaultMetrics()) {
                chartsForMetrics.add(metric.getStandardName());
            }
            return chartsForMetrics;
        }

        try {
            String[] chartsForMetricsFromCSV = csvChartsForMetricsHandler
                    .readChartsForMetrics(chartsForMetricsFile);
            for (String chartForMetric : chartsForMetricsFromCSV) {
                if (!chartForMetric.isEmpty()) {
                    chartsForMetrics.add(chartForMetric);
                }
            }
        } catch (IOException e) {
            assert false : "Could not read which metrics were configured to be displayed in charts";
        }

        return chartsForMetrics;
    }

    /**
     * Method that generates the chart and adds it to the response object to allow jenkins to display it.
     * It is called in SonargraphChartAction/index.jelly in the src attribute of an img tag.  
     */
    public void doGetPlot(StaplerRequest req, StaplerResponse rsp) {
        @SuppressWarnings("unchecked")
        Map<String, String[]> parameterMap = (Map<String, String[]>) req.getParameterMap();
        String metricName = StaplerRequestUtil.getSimpleValue(METRIC_PARAMETER, parameterMap);

        if (metricName == null) {
            SonargraphLogger.INSTANCE.log(Level.SEVERE, "No metric specified for creating a plot.");
            return;
        }

        SonargraphMetrics metric = null;
        try {
            metric = SonargraphMetrics.fromStandardName(metricName);
        } catch (IllegalArgumentException ex) {
            SonargraphLogger.INSTANCE.log(Level.SEVERE, "Specified metric '" + metricName + "' is not supported.");
            return;
        }

        File csvFile = new File(project.getRootDir(), ConfigParameters.METRIC_HISTORY_CSV_FILE_PATH.getValue());
        SonargraphLogger.INSTANCE.log(Level.FINE, "Generating chart for metric '" + metricName
                + "'. Reading values from '" + csvFile.getAbsolutePath() + "'");
        IMetricHistoryProvider csvFileHandler = new CSVFileHandler(csvFile);

        String type = StaplerRequestUtil.getSimpleValue(TYPE_PARAMETER, parameterMap);
        AbstractPlot plot = null;
        String xAxisLabel = null;
        int maxDataPoints = 0;
        if ((type == null) || type.equals(SHORT_TERM)) {
            plot = new XYLineAndShapePlot(csvFileHandler);
            xAxisLabel = BUILD;
            maxDataPoints = MAX_DATA_POINTS_SHORT_TERM;
        } else if (type.equals(LONG_TERM)) {
            plot = new TimeSeriesPlot(csvFileHandler, MAX_DATA_POINTS_SHORT_TERM);
            xAxisLabel = DATE;
            maxDataPoints = MAX_DATA_POINTS_LONG_TERM;
        } else {
            SonargraphLogger.INSTANCE.log(Level.SEVERE, "Chart type '" + type + "' is not supported!");
            return;
        }

        final JFreeChart chart = plot.createXYChart(metric, xAxisLabel, maxDataPoints, true);
        try {
            Graph graph = new Graph(plot.getTimestampOfLastDisplayedPoint(), defaultGraphicWidth,
                    defaultGraphicHeight) {

                @Override
                protected JFreeChart createGraph() {
                    return chart;
                }
            };
            graph.doPng(req, rsp);
        } catch (IOException ioe) {
            SonargraphLogger.INSTANCE.log(Level.SEVERE,
                    "Error generating the graphic for metric '" + metric.getStandardName() + "'");
        }
    }

    /**
     * 
     * @return Project or job.
     */
    public AbstractProject<?, ?> getProject() {
        return project;
    }

    /**
     * Icon that will appear next to the link defined by this action.
     */
    public String getIconFileName() {
        return ConfigParameters.SONARGRAPH_ICON.getValue();
    }

    /**
     * Name of the link for this action
     */
    public String getDisplayName() {
        return ConfigParameters.ACTION_DISPLAY_NAME.getValue();
    }

    /**
     * Last segment of the url that will lead to this action.
     * e.g https://localhost:8080/jobName/sonargraph
     */
    public String getUrlName() {
        return ConfigParameters.ACTION_URL_NAME.getValue();
    }

    public String getReportURL() {
        JenkinsLocationConfiguration globalConfig = new JenkinsLocationConfiguration();
        return globalConfig.getUrl() + ConfigParameters.JOB_FOLDER.getValue() + project.getName() + "/"
                + ConfigParameters.HTML_REPORT_ACTION_URL.getValue();
    }
}