001: /* ================================================================
002: * Cewolf : Chart enabling Web Objects Framework
003: * ================================================================
004: *
005: * Project Info: http://cewolf.sourceforge.net
006: * Project Lead: Guido Laures (guido@laures.de);
007: *
008: * (C) Copyright 2002, by Guido Laures
009: *
010: * This library is free software; you can redistribute it and/or modify it under the terms
011: * of the GNU Lesser General Public License as published by the Free Software Foundation;
012: * either version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016: * See the GNU Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public License along with this
019: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: */
022:
023: package de.laures.cewolf;
024:
025: import java.io.IOException;
026: import java.io.OutputStream;
027: import java.io.Writer;
028: import java.util.Enumeration;
029:
030: import javax.servlet.ServletConfig;
031: import javax.servlet.ServletException;
032: import javax.servlet.http.HttpServlet;
033: import javax.servlet.http.HttpServletRequest;
034: import javax.servlet.http.HttpServletResponse;
035:
036: import de.laures.cewolf.util.RenderingHelper;
037:
038: /**
039: * The rendering servlet of Cewolf. It is resposible for writing an entire chart
040: * img into the response stream of the client. Everything needed for this is
041: * prepared already by the ChartImgTag resp. LegendTag. The ID of a chart image
042: * is passed to this servlet as a request parameter. After that the image object
043: * is retrieved from the server side session based image cache. This servlet
044: * must be configured in web.xml of the web application in order to use Cewolf
045: * services. The servlet's URL relative to the web apps root is used as the
046: * renderer attribute of the ChartImgTag resp. LegendTag in the JSP page.
047: *
048: * @see de.laures.cewolf.taglib.tags.ChartImgTag
049: * @see de.laures.cewolf.taglib.tags.LegendTag
050: * @author Guido Laures
051: * @since 0.1
052: */
053: public class CewolfRenderer extends HttpServlet implements WebConstants {
054:
055: public static final String INIT_CONFIG = "CewolfRenderer_Init_Config";
056: private static final String STATE = "state";
057: private boolean debugged = false;
058: private int requestCount = 0;
059: private Byte lock = Byte.valueOf("0");
060: private Configuration config = null;
061:
062: public void init(ServletConfig servletCfg) throws ServletException {
063: super .init(servletCfg);
064:
065: //Store init config params for processing by the Configuration
066: servletCfg.getServletContext().setAttribute(INIT_CONFIG,
067: servletCfg);
068: config = Configuration.getInstance(servletCfg
069: .getServletContext());
070:
071: if (config != null)
072: this .debugged = config.isDebugged();
073: else
074: this .debugged = false;
075: }
076:
077: /**
078: * Processes HTTP <code>GET</code> request. Renders the chart or the lengend
079: * into the client's response stream.
080: *
081: * @param request
082: * servlet request
083: * @param response
084: * servlet response
085: * @throws ServletException
086: * when the production of data could not be handled by the
087: * configured DatasetProcuder
088: */
089:
090: public void printParameters(HttpServletRequest request) {
091: Enumeration enumeration = request.getParameterNames();
092: while (enumeration.hasMoreElements()) {
093: String cur = (String) enumeration.nextElement();
094: Object obj = request.getParameter(cur);
095:
096: log("Request Parameter -> " + cur + " Value -> "
097: + obj.toString());
098: }
099: }
100:
101: protected void doGet(HttpServletRequest request,
102: HttpServletResponse response) throws ServletException,
103: IOException {
104: if (debugged) {
105: logRequest(request);
106: }
107: addHeaders(response);
108: if (request.getParameter(STATE) != null
109: || !request.getParameterNames().hasMoreElements()) {
110: requestState(response);
111: return;
112: }
113: synchronized (lock) {
114: requestCount++;
115: }
116:
117: int width = 400;
118: int height = 400;
119: boolean removeAfterRendering = false;
120: if (request.getParameter(REMOVE_AFTER_RENDERING) != null) {
121: removeAfterRendering = true;
122: }
123: if (request.getParameter(WIDTH_PARAM) != null) {
124: width = Integer.parseInt(request.getParameter(WIDTH_PARAM));
125: }
126: if (request.getParameter(HEIGHT_PARAM) != null) {
127: height = Integer.parseInt(request
128: .getParameter(HEIGHT_PARAM));
129: }
130:
131: // determine the cache key
132: String imgKey = request.getParameter(IMG_PARAM);
133: if (imgKey == null) {
134: logAndRenderException(new ServletException("no '"
135: + IMG_PARAM
136: + "' parameter provided for Cewolf servlet."),
137: response, width, height);
138: return;
139: }
140: Storage storage = config.getStorage();
141: ChartImage chartImage = storage.getChartImage(imgKey, request);
142: if (chartImage == null) {
143: renderImageExpiry(response, width, height);
144: return;
145: }
146: // send the img
147: try {
148: long start = System.currentTimeMillis();
149: // response.setContentType(cid.getMimeType());
150: final int size = chartImage.getSize();
151: response.setContentType(chartImage.getMimeType());
152: response.setContentLength(size);
153: response.setBufferSize(size);
154: response.setStatus(HttpServletResponse.SC_OK);
155: response.getOutputStream().write(chartImage.getBytes());
156: long last = System.currentTimeMillis() - start;
157: if (debugged) {
158: log("creation time for chart " + imgKey + ": " + last
159: + "ms.");
160: }
161: } catch (Throwable t) {
162: logAndRenderException(t, response, width, height);
163: } finally {
164: if (removeAfterRendering) {
165: try {
166: storage.removeChartImage(imgKey, request);
167: } catch (CewolfException e) {
168: log("Removal of image failed", e);
169: }
170: }
171: }
172: }
173:
174: /**
175: * Method addHeaders.
176: *
177: * @param response
178: */
179: private void addHeaders(HttpServletResponse response) {
180: response.setDateHeader("Expires", System.currentTimeMillis());
181: }
182:
183: /**
184: * Method requestState.
185: *
186: * @param request
187: * @param response
188: */
189: private void requestState(HttpServletResponse response)
190: throws IOException {
191: Writer writer = response.getWriter();
192: writer.write("<HTML><BODY>");
193: /*
194: * StateDescriptor sd = (StateDescriptor)
195: * ChartImageCacheFactory.getChartImageBase( getServletContext());
196: * writer.write(HTMLStateTable.getStateTable(sd));
197: */
198: writer.write("<b>Cewolf servlet up and running.</b><br>");
199: writer.write("Requests served so far: " + requestCount);
200: writer.write("</HTML></BODY>");
201: writer.close();
202: }
203:
204: private void logAndRenderException(Throwable ex,
205: HttpServletResponse response, int width, int height)
206: throws IOException {
207: log(ex.getMessage(), ex);
208: response.setContentType("image/jpg");
209: OutputStream out = response.getOutputStream();
210: RenderingHelper.renderException(ex, width, height, out);
211: out.close();
212: }
213:
214: /**
215: * Method renderImageExpiry.
216: *
217: * @param response
218: * @param width
219: * @param height
220: */
221: private void renderImageExpiry(HttpServletResponse response,
222: int width, int height) throws IOException {
223: response.setContentType("image/jpg");
224: OutputStream out = response.getOutputStream();
225: RenderingHelper.renderMessage(
226: "This chart has expired. Please reload.", width,
227: height, out);
228: out.close();
229: }
230:
231: private void logRequest(HttpServletRequest request)
232: throws IOException {
233: log("Cewolf request:");
234: log("Actual Request values:");
235: printParameters(request);
236: Enumeration headerNames = request.getHeaderNames();
237: while (headerNames.hasMoreElements()) {
238: String name = (String) headerNames.nextElement();
239: Enumeration values = request.getHeaders(name);
240: StringBuffer value = new StringBuffer();
241: while (values.hasMoreElements()) {
242: value.append((String) values.nextElement() + ",");
243: }
244: // cut last comma
245: if (value.length() > 0)
246: value.setLength(value.length() - 1);
247: log(name + ": " + value);
248: }
249: // InputStream body = request.getInputStream();
250: // byte[] bodyData = new byte[body.available()];
251: // body.read(bodyData);
252: // body.close();
253: // log(new String(bodyData));
254:
255: }
256:
257: }
|