001/*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2008-2012 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * Sonar is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
019 */
020package org.sonar.server.charts;
021
022import com.google.common.collect.Maps;
023import com.google.common.io.Closeables;
024import org.jfree.chart.encoders.KeypointPNGEncoderAdapter;
025import org.slf4j.Logger;
026import org.slf4j.LoggerFactory;
027import org.sonar.api.charts.Chart;
028import org.sonar.api.charts.ChartParameters;
029import org.sonar.server.charts.deprecated.BarChart;
030import org.sonar.server.charts.deprecated.BaseChartWeb;
031import org.sonar.server.charts.deprecated.CustomBarChart;
032import org.sonar.server.charts.deprecated.DeprecatedChart;
033import org.sonar.server.charts.deprecated.PieChart;
034import org.sonar.server.charts.deprecated.SparkLinesChart;
035import org.sonar.server.platform.Platform;
036
037import javax.servlet.ServletException;
038import javax.servlet.http.HttpServlet;
039import javax.servlet.http.HttpServletRequest;
040import javax.servlet.http.HttpServletResponse;
041
042import java.awt.image.BufferedImage;
043import java.io.IOException;
044import java.io.OutputStream;
045import java.util.Enumeration;
046import java.util.Map;
047
048public class ChartsServlet extends HttpServlet {
049
050  private static final Logger LOG = LoggerFactory.getLogger(ChartsServlet.class);
051  private static final long serialVersionUID = 669857447198433893L;
052
053  @Override
054  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
055    if (isDeprecatedChart(request)) {
056      deprecatedDoGet(request, response);
057
058    } else {
059      ChartFactory chartFactory = Platform.getInstance().getContainer().getComponentByType(ChartFactory.class);
060      Chart chart = chartFactory.getChart(request.getParameter("ck"));
061      if (chart != null) {
062        BufferedImage image = chart.generateImage(getParams(request));
063        OutputStream out = response.getOutputStream();
064        try {
065          response.setContentType("image/png");
066          exportAsPNG(image, out);
067
068        } catch (Exception e) {
069          LOG.error("Generating chart " + chart.getClass().getName(), e);
070
071        } finally {
072          out.close();
073        }
074      }
075    }
076  }
077
078  private ChartParameters getParams(HttpServletRequest request) {
079    Map<String, String> map = Maps.newHashMap();
080    Enumeration keys = request.getParameterNames();
081    while (keys.hasMoreElements()) {
082      String key = (String) keys.nextElement();
083      String value = request.getParameter(key);
084      map.put(key, value);
085    }
086    return new ChartParameters(map);
087  }
088
089  private void exportAsPNG(BufferedImage image, OutputStream out) throws IOException {
090    KeypointPNGEncoderAdapter encoder = new KeypointPNGEncoderAdapter();
091    encoder.setEncodingAlpha(true);
092    encoder.encode(image, out);
093  }
094
095  public boolean isDeprecatedChart(HttpServletRequest request) {
096    String chartType = request.getParameter(BaseChartWeb.CHART_PARAM_TYPE);
097    if (BaseChartWeb.BAR_CHART_HORIZONTAL.equals(chartType) || BaseChartWeb.BAR_CHART_VERTICAL.equals(chartType) || BaseChartWeb.STACKED_BAR_CHART.equals(chartType)) {
098      return true;
099    }
100    if (BaseChartWeb.BAR_CHART_VERTICAL_CUSTOM.equals(chartType)) {
101      return true;
102    }
103    if (BaseChartWeb.PIE_CHART.equals(chartType)) {
104      return true;
105    }
106    if (BaseChartWeb.SPARKLINES_CHART.equals(chartType)) {
107      return true;
108    }
109    return false;
110  }
111
112  public void deprecatedDoGet(HttpServletRequest request, HttpServletResponse response) {
113    Map<String, String> params = Maps.newHashMap();
114    params.put(BaseChartWeb.CHART_PARAM_TYPE, request.getParameter(BaseChartWeb.CHART_PARAM_TYPE));
115    params.put(BaseChartWeb.CHART_PARAM_VALUES, request.getParameter(BaseChartWeb.CHART_PARAM_VALUES));
116    params.put(BaseChartWeb.CHART_PARAM_COLORS, request.getParameter(BaseChartWeb.CHART_PARAM_COLORS));
117    params.put(BaseChartWeb.CHART_PARAM_RANGEMAX, request.getParameter(BaseChartWeb.CHART_PARAM_RANGEMAX));
118    params.put(BaseChartWeb.CHART_PARAM_TITLE, request.getParameter(BaseChartWeb.CHART_PARAM_TITLE));
119    params.put(BaseChartWeb.CHART_PARAM_DIMENSIONS, request.getParameter(BaseChartWeb.CHART_PARAM_DIMENSIONS));
120    params.put(BaseChartWeb.CHART_PARAM_CATEGORIES_AXISMARGIN_VISIBLE, request.getParameter(BaseChartWeb.CHART_PARAM_CATEGORIES_AXISMARGIN_VISIBLE));
121    params.put(BaseChartWeb.CHART_PARAM_RANGEAXIS_VISIBLE, request.getParameter(BaseChartWeb.CHART_PARAM_RANGEAXIS_VISIBLE));
122    params.put(BaseChartWeb.CHART_PARAM_SERIES, request.getParameter(BaseChartWeb.CHART_PARAM_SERIES));
123    params.put(BaseChartWeb.CHART_PARAM_CATEGORIES, request.getParameter(BaseChartWeb.CHART_PARAM_CATEGORIES));
124    params.put(BaseChartWeb.CHART_PARAM_CATEGORIES_AXISMARGIN_LOWER, request.getParameter(BaseChartWeb.CHART_PARAM_CATEGORIES_AXISMARGIN_LOWER));
125    params.put(BaseChartWeb.CHART_PARAM_CATEGORIES_AXISMARGIN_UPPER, request.getParameter(BaseChartWeb.CHART_PARAM_CATEGORIES_AXISMARGIN_UPPER));
126    params.put(BaseChartWeb.CHART_PARAM_SERIES_AXISMARGIN_LOWER, request.getParameter(BaseChartWeb.CHART_PARAM_SERIES_AXISMARGIN_LOWER));
127    params.put(BaseChartWeb.CHART_PARAM_SERIES_AXISMARGIN_UPPER, request.getParameter(BaseChartWeb.CHART_PARAM_SERIES_AXISMARGIN_UPPER));
128    params.put(BaseChartWeb.CHART_PARAM_SERIES_AXISMARGIN_TICKUNIT, request.getParameter(BaseChartWeb.CHART_PARAM_SERIES_AXISMARGIN_TICKUNIT));
129    params.put(BaseChartWeb.CHART_PARAM_INSETS, request.getParameter(BaseChartWeb.CHART_PARAM_INSETS));
130    params.put(BaseChartWeb.CHART_PARAM_OUTLINE_RANGEGRIDLINES_VISIBLE, request.getParameter(BaseChartWeb.CHART_PARAM_OUTLINE_RANGEGRIDLINES_VISIBLE));
131    params.put(BaseChartWeb.CHART_PARAM_OUTLINE_VISIBLE, request.getParameter(BaseChartWeb.CHART_PARAM_OUTLINE_VISIBLE));
132
133    String chartType = params.get(BaseChartWeb.CHART_PARAM_TYPE);
134
135    DeprecatedChart chart = null;
136
137    if (BaseChartWeb.BAR_CHART_HORIZONTAL.equals(chartType) || BaseChartWeb.BAR_CHART_VERTICAL.equals(chartType) || BaseChartWeb.STACKED_BAR_CHART.equals(chartType)) {
138      chart = new BarChart(params);
139    } else if (BaseChartWeb.BAR_CHART_VERTICAL_CUSTOM.equals(chartType)) {
140      chart = new CustomBarChart(params);
141    } else if (BaseChartWeb.PIE_CHART.equals(chartType)) {
142      chart = new PieChart(params);
143    } else if (BaseChartWeb.SPARKLINES_CHART.equals(chartType)) {
144      chart = new SparkLinesChart(params);
145    }
146
147    if (chart != null) {
148      OutputStream out = null;
149      try {
150        out = response.getOutputStream();
151        response.setContentType("image/png");
152        chart.exportChartAsPNG(out);
153      } catch (Exception e) {
154        LOG.error("Generating chart " + chart.getClass().getName(), e);
155      } finally {
156        Closeables.closeQuietly(out);
157      }
158    }
159  }
160}