/* * NOTE: This copyright does *not* cover user programs that use HQ * program services by normal system calls through the application * program interfaces provided as part of the Hyperic Plug-in Development * Kit or the Hyperic Client Development Kit - this is merely considered * normal use of the program, and does *not* fall under the heading of * "derived work". * * Copyright (C) [2004, 2005, 2006], Hyperic, Inc. * This file is part of HQ. * * HQ is free software; you can redistribute it and/or modify * it under the terms version 2 of the GNU General Public License as * published by the Free Software Foundation. This program is distributed * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. */ package org.hyperic.hq.ui.servlet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hyperic.hq.ui.beans.ChartDataBean; import org.hyperic.image.chart.Chart; import org.hyperic.util.units.UnitsConstants; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.io.IOException; /** * <p>This servlet returns a response that contains the binary data of * an image (JPEG or PNG) that can be viewed in a web browser.</p> * * <p>The chart servlet takes the following parameters (any applicable * defaults are in <b>bold</b> and required parameters are in * <i>italics</i>):</p> * * <table border="1"> * <tr><th> key </th><th> value </th></tr> * <tr><td> unitUnits </td><td> <integer <b>UNIT_NONE</b>> </td></tr> * <tr><td> unitScale </td><td> <integer <b>SCALE_NONE</b>> </td></tr> * <tr><td> showPeak </td><td> (<b>false</b> | true) </td></tr> * <tr><td> showHighRange </td><td> (<b>false</b> | true) </td></tr> * <tr><td> showValues </td><td> (false | <b>true</b>) </td></tr> * <tr><td> showAverage </td><td> (<b>false</b> | true) </td></tr> * <tr><td> showLowRange </td><td> (<b>false</b> | true) </td></tr> * <tr><td> showLow </td><td> (<b>false</b> | true) </td></tr> * <tr><td> showBaseline </td><td> (<b>false</b> | true) </td></tr> * <tr><td> baseline* </td><td> <double> </td></tr> * <tr><td> highRange* </td><td> <double> </td></tr> * <tr><td> lowRange* </td><td> <double> </td></tr> * </table> * * <p>* only used and required if corresponding <code>showXXX</code> * parameter is <code>true</code><br></p> * * <p>The <code>unitUnits</code> and <code>unitScale</code> parameters * must be valid integers from <code>{@link * org.hyperic.util.units.UnitsConstants}</code>.</p> * * @see org.hyperic.util.units.UnitsConstants */ public abstract class ChartServlet extends ImageServlet { /** Request parameter for unit scale. */ public static final String UNIT_UNITS_PARAM = "unitUnits"; /** Request parameter for unit scale. */ public static final String UNIT_SCALE_PARAM = "unitScale"; /** Default image width. */ public static final int IMAGE_WIDTH_DEFAULT = 755; /** Default image height. */ public static final int IMAGE_HEIGHT_DEFAULT = 300; /** Request parameter for whether or not to show the peak. */ public static final String SHOW_PEAK_PARAM = "showPeak"; /** Request parameter for whether or not to show high range. */ public static final String SHOW_HIGHRANGE_PARAM = "showHighRange"; /** Request parameter for whether or not to show the actual values. */ public static final String SHOW_VALUES_PARAM = "showValues"; /** Request parameter for whether or not to show average. */ public static final String SHOW_AVERAGE_PARAM = "showAverage"; /** Request parameter for whether or not to show low range. */ public static final String SHOW_LOWRANGE_PARAM = "showLowRange"; /** Request parameter for whether or not to show the low. */ public static final String SHOW_LOW_PARAM = "showLow"; /** Request parameter for whether or not to show baseline. */ public static final String SHOW_BASELINE_PARAM = "showBaseline"; /** Request parameter for baseline. */ public static final String BASELINE_PARAM = "baseline"; /** Request parameter for baseline. */ public static final String HIGHRANGE_PARAM = "highRange"; /** Request parameter for baseline. */ public static final String LOWRANGE_PARAM = "lowRange"; // member data private Log log = LogFactory.getLog( ChartServlet.class.getName() ); private static ThreadLocal chartInfo = new ThreadLocal() { protected Object initialValue() { return new ChartInfo(); } }; private static class ChartInfo { private int unitScale; private int unitUnits; private boolean showPeak; private boolean showHighRange; private boolean showValues; private boolean showAverage; private boolean showLowRange; private boolean showLow; private boolean showBaseline; private double baseline; private double highRange; private double lowRange; } public ChartServlet () {} /** * Create the image being rendered. * * @param request the servlet request */ protected Object createImage(HttpServletRequest request) throws ServletException { // initialize the chart Chart chart = createChart(request, null); initializeChart(chart, request); // the subclass is responsible for plotting the data log.debug("Plotting data."); try { plotData(request, chart, null); } catch(Exception e) { log.error("failed: ", e); } return chart; } /** * Render a PNG version of the image into the output stream. * * @param out the output stream */ protected void renderPngImage(ServletOutputStream out, Object imgObj) throws IOException { Chart chart = (Chart) imgObj; chart.writePngImage(out); } /** * Render a JPEG version of the image into the output stream. * * @param out the output stream */ protected void renderJpegImage(ServletOutputStream out, Object imgObj) throws IOException { Chart chart = (Chart) imgObj; chart.writeJpegImage(out); } /** * This method will be called automatically by the ChartServlet. * It should handle the parsing and error-checking of any specific * parameters for the chart being rendered. * * @param request the HTTP request object */ protected void parseParameters(HttpServletRequest request) { // units / scale ChartInfo info = (ChartInfo)chartInfo.get(); info.unitUnits = parseIntParameter( request, UNIT_UNITS_PARAM, getDefaultUnitUnits() ); info.unitScale = parseIntParameter( request, UNIT_SCALE_PARAM, getDefaultUnitScale() ); // chart flags info.showPeak = parseBooleanParameter( request, SHOW_PEAK_PARAM, getDefaultShowPeak() ); info.showHighRange = parseBooleanParameter( request, SHOW_HIGHRANGE_PARAM, getDefaultShowHighRange() ); info.showValues = parseBooleanParameter( request, SHOW_VALUES_PARAM, getDefaultShowValues() ); info.showAverage = parseBooleanParameter( request, SHOW_AVERAGE_PARAM, getDefaultShowAverage() ); info.showLowRange = parseBooleanParameter( request, SHOW_LOWRANGE_PARAM, getDefaultShowLowRange() ); info.showLow = parseBooleanParameter( request, SHOW_LOW_PARAM, getDefaultShowLow() ); info.showBaseline = parseBooleanParameter( request, SHOW_BASELINE_PARAM, getDefaultShowBaseline() ); // baseline, high range and low range if (info.showBaseline) { try { info.baseline = parseRequiredDoubleParameter(request, BASELINE_PARAM); } catch (IllegalArgumentException e) { if ( log.isDebugEnabled() ) { log.debug("invalid " + BASELINE_PARAM + ", setting " + SHOW_BASELINE_PARAM + " to: " + false); } info.showBaseline = false; } } if (info.showHighRange) { try { info.highRange = parseRequiredDoubleParameter(request, HIGHRANGE_PARAM); } catch (IllegalArgumentException e) { if ( log.isDebugEnabled() ) { log.debug("invalid " + HIGHRANGE_PARAM + ", setting " + SHOW_HIGHRANGE_PARAM + " to: " + false); } info.showHighRange = false; } } if (info.showLowRange) { try { info.lowRange = parseRequiredDoubleParameter(request, LOWRANGE_PARAM); } catch (IllegalArgumentException e) { if ( log.isDebugEnabled() ) { log.debug("invalid " + LOWRANGE_PARAM + ", setting " + SHOW_LOWRANGE_PARAM + " to: " + false); } info.showLowRange = false; } } _logParameters(); } /** * Create and return the chart. This method will be called after * the parameters have been parsed. * @param request TODO * @param dataBean TODO * @return the newly created chart */ protected abstract Chart createChart(HttpServletRequest request, ChartDataBean dataBean); /** * Initialize the chart. This method will be called after the * parameters have been parsed and the chart has been created. * * @param chart the chart * @param request TODO */ protected void initializeChart(Chart chart, HttpServletRequest request) { ChartInfo info = (ChartInfo)chartInfo.get(); chart.setFormat(info.unitUnits, info.unitScale); chart.showPeak = info.showPeak; chart.showHighRange = info.showHighRange; chart.showValues = info.showValues; chart.showAverage = info.showAverage; chart.showLowRange = info.showLowRange; chart.showLow = info.showLow; chart.showBaseline = info.showBaseline; chart.baseline = info.baseline; chart.highRange = info.highRange; chart.lowRange = info.lowRange; } /** * This method will be called automatically by the ChartServlet. * It should handle adding data to the chart, setting up the X and * Y axis labels, etc. * * @param request the HTTP request * @param dataBean TODO */ protected abstract void plotData(HttpServletRequest request, Chart chart, ChartDataBean dataBean) throws ServletException; /** * Return the value of property <code>showLow</code>. */ public boolean getShowLow() { return ((ChartInfo)chartInfo.get()).showLow; } /** * Return the value of property <code>showPeak</code>. */ public boolean getShowPeak() { return ((ChartInfo)chartInfo.get()).showPeak; } /** * Return the value of property <code>showAverage</code>. */ public boolean getShowAvg() { return ((ChartInfo)chartInfo.get()).showAverage; } /** * Return the default <code>unitUnits</code>. */ protected int getDefaultUnitUnits() { return UnitsConstants.UNIT_NONE; } /** * Return the default <code>unitScale</code>. */ protected int getDefaultUnitScale() { return UnitsConstants.SCALE_NONE; } /** * Return the default <code>imageWidth</code>. */ protected int getDefaultImageWidth() { return IMAGE_WIDTH_DEFAULT; } /** * Return the default <code>imageHeight</code>. */ protected int getDefaultImageHeight() { return IMAGE_HEIGHT_DEFAULT; } /** * Return the default <code>showPeak</code>. */ protected boolean getDefaultShowPeak() { return false; } /** * Return the default <code>showHighRange</code>. */ protected boolean getDefaultShowHighRange() { return false; } /** * Return the default <code>showValues</code>. */ protected boolean getDefaultShowValues() { return true; } /** * Return the default <code>showAverage</code>. */ protected boolean getDefaultShowAverage() { return false; } /** * Return the default <code> Range</code>. */ protected boolean getDefaultShowLowRange() { return false; } /** * Return the default <code>showLow</code>. */ protected boolean getDefaultShowLow() { return false; } /** * Return the default <code>showBaseline</code>. */ protected boolean getDefaultShowBaseline() { return false; } //--------------------------------------------------------------- //-- private helpers //--------------------------------------------------------------- private void _logParameters() { if ( log.isDebugEnabled() ) { ChartInfo info = (ChartInfo)chartInfo.get(); StringBuffer sb = new StringBuffer("Parameters:"); sb.append("\n");sb.append("\t"); sb.append(UNIT_UNITS_PARAM); sb.append(": "); sb.append(info.unitUnits); sb.append("\n");sb.append("\t"); sb.append(UNIT_SCALE_PARAM); sb.append(": "); sb.append(info.unitScale); sb.append("\n");sb.append("\t"); sb.append(SHOW_PEAK_PARAM); sb.append(": "); sb.append(info.showPeak); sb.append("\n");sb.append("\t"); sb.append(SHOW_HIGHRANGE_PARAM); sb.append(": "); sb.append(info.showHighRange); sb.append("\n");sb.append("\t"); sb.append(SHOW_VALUES_PARAM); sb.append(": "); sb.append(info.showValues); sb.append("\n");sb.append("\t"); sb.append(SHOW_AVERAGE_PARAM); sb.append(": "); sb.append(info.showAverage); sb.append("\n");sb.append("\t"); sb.append(SHOW_LOWRANGE_PARAM); sb.append(": "); sb.append(info.showLowRange); sb.append("\n");sb.append("\t"); sb.append(SHOW_LOW_PARAM); sb.append(": "); sb.append(info.showLow); sb.append("\n");sb.append("\t"); sb.append(SHOW_BASELINE_PARAM); sb.append(": "); sb.append(info.showBaseline); sb.append("\n");sb.append("\t"); sb.append(BASELINE_PARAM); sb.append(": "); sb.append(info.baseline); sb.append("\n");sb.append("\t"); sb.append(HIGHRANGE_PARAM); sb.append(": "); sb.append(info.highRange); sb.append("\n");sb.append("\t"); sb.append(LOWRANGE_PARAM); sb.append(": "); sb.append(info.lowRange); log.debug( sb.toString() ); } } } // EOF