Source code: de/laures/cewolf/CewolfRenderer.java
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 Configuration config = null;
61
62 public void init( ServletConfig servletCfg ) throws ServletException
63 {
64 super.init(servletCfg);
65
66 //Store init config params for processing by the Configuration
67 servletCfg.getServletContext().setAttribute(INIT_CONFIG, servletCfg);
68 config = Configuration.getInstance(servletCfg.getServletContext());
69
70 if (config != null)
71 this.debugged = config.isDebugged();
72 else
73 this.debugged = false;
74 }
75
76 /**
77 * Processes HTTP <code>GET</code> request. Renders the chart or the lengend
78 * into the client's response stream.
79 *
80 * @param request
81 * servlet request
82 * @param response
83 * servlet response
84 * @throws ServletException
85 * when the production of data could not be handled by the
86 * configured DatasetProcuder
87 */
88
89 public synchronized void printParameters(HttpServletRequest request)
90 {
91 Enumeration enumeration = request.getParameterNames();
92 while (enumeration.hasMoreElements())
93 {
94 String cur = (String)enumeration.nextElement();
95 Object obj = request.getParameter(cur);
96
97 log("Request Parameter -> " + cur + " Value -> " + obj.toString());
98 }
99 }
100
101 protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException
102 {
103 if ( debugged )
104 {
105 logRequest(request);
106 }
107 addHeaders(response);
108 if ( request.getParameter(STATE) != null || !request.getParameterNames().hasMoreElements() )
109 {
110 requestState(response);
111 return;
112 }
113 requestCount++;
114 int width = 400;
115 int height = 400;
116 if ( request.getParameter(WIDTH_PARAM) != null )
117 {
118 width = Integer.parseInt(request.getParameter(WIDTH_PARAM));
119 }
120 if ( request.getParameter(HEIGHT_PARAM) != null )
121 {
122 height = Integer.parseInt(request.getParameter(HEIGHT_PARAM));
123 }
124
125 // determine the cache key
126 String imgKey = request.getParameter(IMG_PARAM);
127 if ( imgKey == null )
128 {
129 logAndRenderException(new ServletException("no '" + IMG_PARAM + "' parameter provided for Cewolf servlet."), response, width, height);
130 return;
131 }
132 Storage storage = config.getStorage();
133 ChartImage chartImage = storage.getChartImage(imgKey, request);
134 if ( chartImage == null )
135 {
136 renderImageExpiry(response, width, height);
137 return;
138 }
139 // send the img
140 try
141 {
142 long start = System.currentTimeMillis();
143 // response.setContentType(cid.getMimeType());
144 final int size = chartImage.getSize();
145 response.setContentType(chartImage.getMimeType());
146 response.setContentLength(size);
147 response.setBufferSize(size);
148 response.setStatus(HttpServletResponse.SC_OK);
149 response.getOutputStream().write(chartImage.getBytes());
150 long last = System.currentTimeMillis() - start;
151 if ( debugged )
152 {
153 log("creation time for chart " + imgKey + ": " + last + "ms.");
154 }
155 }
156 catch (Throwable t)
157 {
158 logAndRenderException(t, response, width, height);
159 }
160 }
161
162 /**
163 * Method addHeaders.
164 *
165 * @param response
166 */
167 private void addHeaders( HttpServletResponse response )
168 {
169 response.setDateHeader("Expires", System.currentTimeMillis());
170 }
171
172 /**
173 * Method requestState.
174 *
175 * @param request
176 * @param response
177 */
178 private void requestState( HttpServletResponse response ) throws IOException
179 {
180 Writer writer = response.getWriter();
181 writer.write("<HTML><BODY>");
182 /*
183 * StateDescriptor sd = (StateDescriptor)
184 * ChartImageCacheFactory.getChartImageBase( getServletContext());
185 * writer.write(HTMLStateTable.getStateTable(sd));
186 */
187 writer.write("<b>Cewolf servlet up and running.</b><br>");
188 writer.write("Requests served so far: " + requestCount);
189 writer.write("</HTML></BODY>");
190 writer.close();
191 }
192
193 private void logAndRenderException( Throwable ex, HttpServletResponse response, int width, int height ) throws IOException
194 {
195 log(ex.getMessage(), ex);
196 response.setContentType("image/jpg");
197 OutputStream out = response.getOutputStream();
198 RenderingHelper.renderException(ex, width, height, out);
199 out.close();
200 }
201
202 /**
203 * Method renderImageExpiry.
204 *
205 * @param response
206 * @param width
207 * @param height
208 */
209 private void renderImageExpiry( HttpServletResponse response, int width, int height ) throws IOException
210 {
211 response.setContentType("image/jpg");
212 OutputStream out = response.getOutputStream();
213 RenderingHelper.renderMessage("This chart has expired. Please reload.", width, height, out);
214 out.close();
215 }
216
217 private void logRequest( HttpServletRequest request ) throws IOException
218 {
219 log("Cewolf request:");
220 log("Actual Request values:");
221 printParameters(request);
222 Enumeration headerNames = request.getHeaderNames();
223 while ( headerNames.hasMoreElements() )
224 {
225 String name = (String) headerNames.nextElement();
226 Enumeration values = request.getHeaders(name);
227 StringBuffer value = new StringBuffer();
228 while ( values.hasMoreElements() )
229 {
230 value.append((String) values.nextElement() + ",");
231 }
232 // cut last comma
233 if ( value.length() > 0 )
234 value.setLength(value.length() - 1);
235 log(name + ": " + value);
236 }
237 // InputStream body = request.getInputStream();
238 // byte[] bodyData = new byte[body.available()];
239 // body.read(bodyData);
240 // body.close();
241 // log(new String(bodyData));
242
243 }
244
245 }