java/cewolf-1.0/src/main/java/de/laures/cewolf/CewolfRenderer.java
author František Kučera <franta-hg@frantovo.cz>
Sat, 28 Feb 2009 21:31:02 +0100
changeset 1 639991d0808a
permissions -rw-r--r--
Rozbalená knihovna verze 1.0
     1 /* ================================================================
     2  * Cewolf : Chart enabling Web Objects Framework
     3  * ================================================================
     4  *
     5  * Project Info:  http://cewolf.sourceforge.net
     6  * Project Lead:  Guido Laures (guido@laures.de);
     7  *
     8  * (C) Copyright 2002, by Guido Laures
     9  *
    10  * This library is free software; you can redistribute it and/or modify it under the terms
    11  * of the GNU Lesser General Public License as published by the Free Software Foundation;
    12  * either version 2.1 of the License, or (at your option) any later version.
    13  *
    14  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
    15  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    16  * See the GNU Lesser General Public License for more details.
    17  *
    18  * You should have received a copy of the GNU Lesser General Public License along with this
    19  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
    20  * Boston, MA 02111-1307, USA.
    21  */
    22 
    23 package de.laures.cewolf;
    24 
    25 import java.io.IOException;
    26 import java.io.OutputStream;
    27 import java.io.Writer;
    28 import java.util.Enumeration;
    29 
    30 import javax.servlet.ServletConfig;
    31 import javax.servlet.ServletException;
    32 import javax.servlet.http.HttpServlet;
    33 import javax.servlet.http.HttpServletRequest;
    34 import javax.servlet.http.HttpServletResponse;
    35 
    36 import de.laures.cewolf.util.RenderingHelper;
    37 
    38 /**
    39  * The rendering servlet of Cewolf. It is resposible for writing an entire chart
    40  * img into the response stream of the client. Everything needed for this is
    41  * prepared already by the ChartImgTag resp. LegendTag. The ID of a chart image
    42  * is passed to this servlet as a request parameter. After that the image object
    43  * is retrieved from the server side session based image cache. This servlet
    44  * must be configured in web.xml of the web application in order to use Cewolf
    45  * services. The servlet's URL relative to the web apps root is used as the
    46  * renderer attribute of the ChartImgTag resp. LegendTag in the JSP page.
    47  * 
    48  * @see de.laures.cewolf.taglib.tags.ChartImgTag
    49  * @see de.laures.cewolf.taglib.tags.LegendTag
    50  * @author Guido Laures
    51  * @since 0.1
    52  */
    53 public class CewolfRenderer extends HttpServlet implements WebConstants
    54 {
    55 
    56   public static final String  INIT_CONFIG  = "CewolfRenderer_Init_Config";
    57   private static final String STATE        = "state";
    58   private boolean             debugged     = false;
    59   private int                 requestCount = 0;
    60   private Byte 					lock = Byte.valueOf("0");
    61   private Configuration       config       = null;
    62 
    63   public void init( ServletConfig servletCfg ) throws ServletException
    64   {
    65     super.init(servletCfg);
    66     
    67     //Store init config params for processing by the Configuration
    68     servletCfg.getServletContext().setAttribute(INIT_CONFIG, servletCfg);
    69     config = Configuration.getInstance(servletCfg.getServletContext());
    70     
    71     if (config != null)
    72       this.debugged = config.isDebugged();
    73     else
    74       this.debugged = false;
    75   }
    76 
    77   /**
    78    * Processes HTTP <code>GET</code> request. Renders the chart or the lengend
    79    * into the client's response stream.
    80    * 
    81    * @param request
    82    *          servlet request
    83    * @param response
    84    *          servlet response
    85    * @throws ServletException
    86    *           when the production of data could not be handled by the
    87    *           configured DatasetProcuder
    88    */
    89   
    90   public void printParameters(HttpServletRequest request)
    91   {
    92     Enumeration enumeration = request.getParameterNames();
    93     while (enumeration.hasMoreElements())
    94     {
    95       String cur = (String)enumeration.nextElement();
    96       Object obj = request.getParameter(cur);
    97       
    98       log("Request Parameter -> " + cur + " Value -> " + obj.toString());
    99     }
   100   }
   101   
   102   protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException
   103   {
   104     if ( debugged )
   105     {
   106       logRequest(request);
   107     }
   108     addHeaders(response);
   109     if ( request.getParameter(STATE) != null || !request.getParameterNames().hasMoreElements() )
   110     {
   111       requestState(response);
   112       return;
   113     }
   114     synchronized (lock) {
   115     	requestCount++;
   116 	}
   117     
   118     int width = 400;
   119     int height = 400;
   120     boolean removeAfterRendering = false;
   121     if ( request.getParameter(REMOVE_AFTER_RENDERING) != null )
   122     {
   123     	removeAfterRendering = true;
   124     }
   125     if ( request.getParameter(WIDTH_PARAM) != null )
   126     {
   127       width = Integer.parseInt(request.getParameter(WIDTH_PARAM));
   128     }
   129     if ( request.getParameter(HEIGHT_PARAM) != null )
   130     {
   131       height = Integer.parseInt(request.getParameter(HEIGHT_PARAM));
   132     }
   133 
   134     // determine the cache key
   135     String imgKey = request.getParameter(IMG_PARAM);
   136     if ( imgKey == null )
   137     {
   138       logAndRenderException(new ServletException("no '" + IMG_PARAM + "' parameter provided for Cewolf servlet."), response, width, height);
   139       return;
   140     }
   141     Storage storage = config.getStorage();
   142     ChartImage chartImage = storage.getChartImage(imgKey, request);
   143     if ( chartImage == null )
   144     {
   145       renderImageExpiry(response, width, height);
   146       return;
   147     }
   148     // send the img
   149     try
   150     {
   151       long start = System.currentTimeMillis();
   152       // response.setContentType(cid.getMimeType());
   153       final int size = chartImage.getSize();
   154       response.setContentType(chartImage.getMimeType());
   155       response.setContentLength(size);
   156       response.setBufferSize(size);
   157       response.setStatus(HttpServletResponse.SC_OK);
   158       response.getOutputStream().write(chartImage.getBytes());
   159       long last = System.currentTimeMillis() - start;
   160       if ( debugged )
   161       {
   162         log("creation time for chart " + imgKey + ": " + last + "ms.");
   163       }
   164     }
   165     catch (Throwable t)
   166     {
   167       logAndRenderException(t, response, width, height);
   168     }
   169     finally
   170     {
   171     	if (removeAfterRendering)
   172     	{
   173     		try {
   174 				storage.removeChartImage(imgKey , request);
   175 			} catch (CewolfException e) {
   176 				log("Removal of image failed", e);
   177 			}
   178     	}
   179     }
   180   }
   181 
   182   /**
   183    * Method addHeaders.
   184    * 
   185    * @param response
   186    */
   187   private void addHeaders( HttpServletResponse response )
   188   {
   189     response.setDateHeader("Expires", System.currentTimeMillis());
   190   }
   191 
   192   /**
   193    * Method requestState.
   194    * 
   195    * @param request
   196    * @param response
   197    */
   198   private void requestState( HttpServletResponse response ) throws IOException
   199   {
   200     Writer writer = response.getWriter();
   201     writer.write("<HTML><BODY>");
   202     /*
   203      * StateDescriptor sd = (StateDescriptor)
   204      * ChartImageCacheFactory.getChartImageBase( getServletContext());
   205      * writer.write(HTMLStateTable.getStateTable(sd));
   206      */
   207     writer.write("<b>Cewolf servlet up and running.</b><br>");
   208     writer.write("Requests served so far: " + requestCount);
   209     writer.write("</HTML></BODY>");
   210     writer.close();
   211   }
   212 
   213   private void logAndRenderException( Throwable ex, HttpServletResponse response, int width, int height ) throws IOException
   214   {
   215     log(ex.getMessage(), ex);
   216     response.setContentType("image/jpg");
   217     OutputStream out = response.getOutputStream();
   218     RenderingHelper.renderException(ex, width, height, out);
   219     out.close();
   220   }
   221 
   222   /**
   223    * Method renderImageExpiry.
   224    * 
   225    * @param response
   226    * @param width
   227    * @param height
   228    */
   229   private void renderImageExpiry( HttpServletResponse response, int width, int height ) throws IOException
   230   {
   231     response.setContentType("image/jpg");
   232     OutputStream out = response.getOutputStream();
   233     RenderingHelper.renderMessage("This chart has expired. Please reload.", width, height, out);
   234     out.close();
   235   }
   236 
   237   private void logRequest( HttpServletRequest request ) throws IOException
   238   {
   239     log("Cewolf request:");
   240     log("Actual Request values:");
   241     printParameters(request);
   242     Enumeration headerNames = request.getHeaderNames();
   243     while ( headerNames.hasMoreElements() )
   244     {
   245       String name = (String) headerNames.nextElement();
   246       Enumeration values = request.getHeaders(name);
   247       StringBuffer value = new StringBuffer();
   248       while ( values.hasMoreElements() )
   249       {
   250         value.append((String) values.nextElement() + ",");
   251       }
   252       // cut last comma
   253       if ( value.length() > 0 )
   254         value.setLength(value.length() - 1);
   255       log(name + ": " + value);
   256     }
   257   //  InputStream body = request.getInputStream();
   258  //   byte[] bodyData = new byte[body.available()];
   259  //   body.read(bodyData);
   260  //   body.close();
   261  //   log(new String(bodyData));
   262 
   263   }
   264 
   265 }