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