franta-hg@1: /* ================================================================ franta-hg@1: * Cewolf : Chart enabling Web Objects Framework franta-hg@1: * ================================================================ franta-hg@1: * franta-hg@1: * Project Info: http://cewolf.sourceforge.net franta-hg@1: * Project Lead: Guido Laures (guido@laures.de); franta-hg@1: * franta-hg@1: * (C) Copyright 2002, by Guido Laures franta-hg@1: * franta-hg@1: * This library is free software; you can redistribute it and/or modify it under the terms franta-hg@1: * of the GNU Lesser General Public License as published by the Free Software Foundation; franta-hg@1: * either version 2.1 of the License, or (at your option) any later version. franta-hg@1: * franta-hg@1: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; franta-hg@1: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. franta-hg@1: * See the GNU Lesser General Public License for more details. franta-hg@1: * franta-hg@1: * You should have received a copy of the GNU Lesser General Public License along with this franta-hg@1: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, franta-hg@1: * Boston, MA 02111-1307, USA. franta-hg@1: */ franta-hg@1: franta-hg@1: package de.laures.cewolf; franta-hg@1: franta-hg@1: import java.io.IOException; franta-hg@1: import java.io.OutputStream; franta-hg@1: import java.io.Writer; franta-hg@1: import java.util.Enumeration; franta-hg@1: franta-hg@1: import javax.servlet.ServletConfig; franta-hg@1: import javax.servlet.ServletException; franta-hg@1: import javax.servlet.http.HttpServlet; franta-hg@1: import javax.servlet.http.HttpServletRequest; franta-hg@1: import javax.servlet.http.HttpServletResponse; franta-hg@1: franta-hg@1: import de.laures.cewolf.util.RenderingHelper; franta-hg@1: franta-hg@1: /** franta-hg@1: * The rendering servlet of Cewolf. It is resposible for writing an entire chart franta-hg@1: * img into the response stream of the client. Everything needed for this is franta-hg@1: * prepared already by the ChartImgTag resp. LegendTag. The ID of a chart image franta-hg@1: * is passed to this servlet as a request parameter. After that the image object franta-hg@1: * is retrieved from the server side session based image cache. This servlet franta-hg@1: * must be configured in web.xml of the web application in order to use Cewolf franta-hg@1: * services. The servlet's URL relative to the web apps root is used as the franta-hg@1: * renderer attribute of the ChartImgTag resp. LegendTag in the JSP page. franta-hg@1: * franta-hg@1: * @see de.laures.cewolf.taglib.tags.ChartImgTag franta-hg@1: * @see de.laures.cewolf.taglib.tags.LegendTag franta-hg@1: * @author Guido Laures franta-hg@1: * @since 0.1 franta-hg@1: */ franta-hg@1: public class CewolfRenderer extends HttpServlet implements WebConstants franta-hg@1: { franta-hg@1: franta-hg@1: public static final String INIT_CONFIG = "CewolfRenderer_Init_Config"; franta-hg@1: private static final String STATE = "state"; franta-hg@1: private boolean debugged = false; franta-hg@1: private int requestCount = 0; franta-hg@1: private Byte lock = Byte.valueOf("0"); franta-hg@1: private Configuration config = null; franta-hg@1: franta-hg@1: public void init( ServletConfig servletCfg ) throws ServletException franta-hg@1: { franta-hg@1: super.init(servletCfg); franta-hg@1: franta-hg@1: //Store init config params for processing by the Configuration franta-hg@1: servletCfg.getServletContext().setAttribute(INIT_CONFIG, servletCfg); franta-hg@1: config = Configuration.getInstance(servletCfg.getServletContext()); franta-hg@1: franta-hg@1: if (config != null) franta-hg@1: this.debugged = config.isDebugged(); franta-hg@1: else franta-hg@1: this.debugged = false; franta-hg@1: } franta-hg@1: franta-hg@1: /** franta-hg@1: * Processes HTTP GET request. Renders the chart or the lengend franta-hg@1: * into the client's response stream. franta-hg@1: * franta-hg@1: * @param request franta-hg@1: * servlet request franta-hg@1: * @param response franta-hg@1: * servlet response franta-hg@1: * @throws ServletException franta-hg@1: * when the production of data could not be handled by the franta-hg@1: * configured DatasetProcuder franta-hg@1: */ franta-hg@1: franta-hg@1: public void printParameters(HttpServletRequest request) franta-hg@1: { franta-hg@1: Enumeration enumeration = request.getParameterNames(); franta-hg@1: while (enumeration.hasMoreElements()) franta-hg@1: { franta-hg@1: String cur = (String)enumeration.nextElement(); franta-hg@1: Object obj = request.getParameter(cur); franta-hg@1: franta-hg@1: log("Request Parameter -> " + cur + " Value -> " + obj.toString()); franta-hg@1: } franta-hg@1: } franta-hg@1: franta-hg@1: protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException franta-hg@1: { franta-hg@1: if ( debugged ) franta-hg@1: { franta-hg@1: logRequest(request); franta-hg@1: } franta-hg@1: addHeaders(response); franta-hg@1: if ( request.getParameter(STATE) != null || !request.getParameterNames().hasMoreElements() ) franta-hg@1: { franta-hg@1: requestState(response); franta-hg@1: return; franta-hg@1: } franta-hg@1: synchronized (lock) { franta-hg@1: requestCount++; franta-hg@1: } franta-hg@1: franta-hg@1: int width = 400; franta-hg@1: int height = 400; franta-hg@1: boolean removeAfterRendering = false; franta-hg@1: if ( request.getParameter(REMOVE_AFTER_RENDERING) != null ) franta-hg@1: { franta-hg@1: removeAfterRendering = true; franta-hg@1: } franta-hg@1: if ( request.getParameter(WIDTH_PARAM) != null ) franta-hg@1: { franta-hg@1: width = Integer.parseInt(request.getParameter(WIDTH_PARAM)); franta-hg@1: } franta-hg@1: if ( request.getParameter(HEIGHT_PARAM) != null ) franta-hg@1: { franta-hg@1: height = Integer.parseInt(request.getParameter(HEIGHT_PARAM)); franta-hg@1: } franta-hg@1: franta-hg@1: // determine the cache key franta-hg@1: String imgKey = request.getParameter(IMG_PARAM); franta-hg@1: if ( imgKey == null ) franta-hg@1: { franta-hg@1: logAndRenderException(new ServletException("no '" + IMG_PARAM + "' parameter provided for Cewolf servlet."), response, width, height); franta-hg@1: return; franta-hg@1: } franta-hg@1: Storage storage = config.getStorage(); franta-hg@1: ChartImage chartImage = storage.getChartImage(imgKey, request); franta-hg@1: if ( chartImage == null ) franta-hg@1: { franta-hg@1: renderImageExpiry(response, width, height); franta-hg@1: return; franta-hg@1: } franta-hg@1: // send the img franta-hg@1: try franta-hg@1: { franta-hg@1: long start = System.currentTimeMillis(); franta-hg@1: // response.setContentType(cid.getMimeType()); franta-hg@1: final int size = chartImage.getSize(); franta-hg@1: response.setContentType(chartImage.getMimeType()); franta-hg@1: response.setContentLength(size); franta-hg@1: response.setBufferSize(size); franta-hg@1: response.setStatus(HttpServletResponse.SC_OK); franta-hg@1: response.getOutputStream().write(chartImage.getBytes()); franta-hg@1: long last = System.currentTimeMillis() - start; franta-hg@1: if ( debugged ) franta-hg@1: { franta-hg@1: log("creation time for chart " + imgKey + ": " + last + "ms."); franta-hg@1: } franta-hg@1: } franta-hg@1: catch (Throwable t) franta-hg@1: { franta-hg@1: logAndRenderException(t, response, width, height); franta-hg@1: } franta-hg@1: finally franta-hg@1: { franta-hg@1: if (removeAfterRendering) franta-hg@1: { franta-hg@1: try { franta-hg@1: storage.removeChartImage(imgKey , request); franta-hg@1: } catch (CewolfException e) { franta-hg@1: log("Removal of image failed", e); franta-hg@1: } franta-hg@1: } franta-hg@1: } franta-hg@1: } franta-hg@1: franta-hg@1: /** franta-hg@1: * Method addHeaders. franta-hg@1: * franta-hg@1: * @param response franta-hg@1: */ franta-hg@1: private void addHeaders( HttpServletResponse response ) franta-hg@1: { franta-hg@1: response.setDateHeader("Expires", System.currentTimeMillis()); franta-hg@1: } franta-hg@1: franta-hg@1: /** franta-hg@1: * Method requestState. franta-hg@1: * franta-hg@1: * @param request franta-hg@1: * @param response franta-hg@1: */ franta-hg@1: private void requestState( HttpServletResponse response ) throws IOException franta-hg@1: { franta-hg@1: Writer writer = response.getWriter(); franta-hg@1: writer.write(""); franta-hg@1: /* franta-hg@1: * StateDescriptor sd = (StateDescriptor) franta-hg@1: * ChartImageCacheFactory.getChartImageBase( getServletContext()); franta-hg@1: * writer.write(HTMLStateTable.getStateTable(sd)); franta-hg@1: */ franta-hg@1: writer.write("Cewolf servlet up and running.
"); franta-hg@1: writer.write("Requests served so far: " + requestCount); franta-hg@1: writer.write(""); franta-hg@1: writer.close(); franta-hg@1: } franta-hg@1: franta-hg@1: private void logAndRenderException( Throwable ex, HttpServletResponse response, int width, int height ) throws IOException franta-hg@1: { franta-hg@1: log(ex.getMessage(), ex); franta-hg@1: response.setContentType("image/jpg"); franta-hg@1: OutputStream out = response.getOutputStream(); franta-hg@1: RenderingHelper.renderException(ex, width, height, out); franta-hg@1: out.close(); franta-hg@1: } franta-hg@1: franta-hg@1: /** franta-hg@1: * Method renderImageExpiry. franta-hg@1: * franta-hg@1: * @param response franta-hg@1: * @param width franta-hg@1: * @param height franta-hg@1: */ franta-hg@1: private void renderImageExpiry( HttpServletResponse response, int width, int height ) throws IOException franta-hg@1: { franta-hg@1: response.setContentType("image/jpg"); franta-hg@1: OutputStream out = response.getOutputStream(); franta-hg@1: RenderingHelper.renderMessage("This chart has expired. Please reload.", width, height, out); franta-hg@1: out.close(); franta-hg@1: } franta-hg@1: franta-hg@1: private void logRequest( HttpServletRequest request ) throws IOException franta-hg@1: { franta-hg@1: log("Cewolf request:"); franta-hg@1: log("Actual Request values:"); franta-hg@1: printParameters(request); franta-hg@1: Enumeration headerNames = request.getHeaderNames(); franta-hg@1: while ( headerNames.hasMoreElements() ) franta-hg@1: { franta-hg@1: String name = (String) headerNames.nextElement(); franta-hg@1: Enumeration values = request.getHeaders(name); franta-hg@1: StringBuffer value = new StringBuffer(); franta-hg@1: while ( values.hasMoreElements() ) franta-hg@1: { franta-hg@1: value.append((String) values.nextElement() + ","); franta-hg@1: } franta-hg@1: // cut last comma franta-hg@1: if ( value.length() > 0 ) franta-hg@1: value.setLength(value.length() - 1); franta-hg@1: log(name + ": " + value); franta-hg@1: } franta-hg@1: // InputStream body = request.getInputStream(); franta-hg@1: // byte[] bodyData = new byte[body.available()]; franta-hg@1: // body.read(bodyData); franta-hg@1: // body.close(); franta-hg@1: // log(new String(bodyData)); franta-hg@1: franta-hg@1: } franta-hg@1: franta-hg@1: }