1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.dbforms.servlets.reports;
25
26
27 import org.apache.commons.lang.StringUtils;
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30
31 import org.dbforms.servlets.base.AbstractServletBase;
32
33 import org.dbforms.config.DbFormsConfig;
34 import org.dbforms.config.DbFormsConfigRegistry;
35 import org.dbforms.config.ResultSetVector;
36 import org.dbforms.config.Table;
37
38 import org.dbforms.event.AbstractWebEvent;
39
40 import org.dbforms.taglib.DbFormTag;
41
42 import org.dbforms.util.MessageResourcesInternal;
43 import org.dbforms.util.PageContextBuffer;
44 import org.dbforms.util.ParseUtil;
45 import org.dbforms.util.Util;
46 import org.dbforms.util.external.FileUtil;
47
48 import java.io.IOException;
49 import java.io.PrintWriter;
50
51 import java.util.Collection;
52 import java.util.Iterator;
53 import java.util.Vector;
54
55 import javax.servlet.ServletContext;
56 import javax.servlet.ServletException;
57 import javax.servlet.ServletOutputStream;
58 import javax.servlet.http.HttpServletRequest;
59 import javax.servlet.http.HttpServletResponse;
60 import javax.servlet.jsp.PageContext;
61
62 /***
63 * This is the abstract base class for generating reports.
64 *
65 * @author Henner Kollmann
66 */
67 public abstract class AbstractReportServlet extends AbstractServletBase {
68
69 private static Log logCat = LogFactory.getLog(AbstractReportServlet.class
70 .getName());
71
72 private static final String REPORTCONFIGDIR = "reportdirs";
73 private static final String REPORTNAMEPARAM = "reportname";
74
75 private String[] reportdirs;
76
77
78 /***
79 * Initialize this servlet.
80 *
81 * @exception ServletException
82 * if we cannot configure ourselves correctly
83 */
84 public void init() throws ServletException {
85 super.init();
86 String value = getServletConfig().getInitParameter(REPORTCONFIGDIR);
87 if (value == null) {
88 value = "WEB-INF/reports/";
89 }
90 reportdirs = StringUtils.split(value, ',');
91 }
92
93 /***
94 * generates a report.
95 *
96 * @param reportFileFullName
97 * filename of report to process reportHTTPServletRequest
98 * generated by getReportFile! getReportFile should be called
99 * before fetching data, so that error handling of report not
100 * found e.g. could be processed first!
101 * @param dataSource
102 * data for the report
103 * @param context
104 * ServletContext
105 * @param request
106 * HTTPServletRequest
107 * @param response
108 * HTTPServletResponse
109 */
110 protected abstract ReportWriter processReport(String reportFileFullName,
111 AbstractJRDataSource dataSource, ServletContext context,
112 HttpServletRequest request, HttpServletResponse response);
113
114 protected abstract String getReportFileExtension();
115
116 protected final void handleException(HttpServletRequest request,
117 HttpServletResponse response, Exception e) {
118 sendErrorMessage(request, response, MessageResourcesInternal
119 .getMessage("dbforms.reports.exception", request.getLocale(),
120 new String[] { e.getMessage() }));
121 }
122
123 private final void handleNoData(HttpServletRequest request,
124 HttpServletResponse response) {
125 sendErrorMessage(request, response, MessageResourcesInternal
126 .getMessage("dbforms.reports.nodata", request.getLocale()));
127 }
128
129 private final void sendErrorMessage(HttpServletRequest request,
130 HttpServletResponse response, String message) {
131 try {
132 Vector errors = (Vector) request.getAttribute("errors");
133
134
135
136
137
138
139
140 if (errors == null)
141 {
142 errors = new Vector();
143 }
144
145 errors.add(new Exception(message));
146
147 String fue = ParseUtil.getParameter(request, "source");
148 String contextPath = request.getContextPath();
149
150 if (!Util.isNull(fue)) {
151 fue = fue.substring(contextPath.length());
152 }
153
154 if (Util.isNull(fue)) {
155 sendErrorMessageText(response, message);
156 } else {
157 request.getRequestDispatcher(fue).forward(request, response);
158 }
159 } catch (Exception ex) {
160 logCat.error("sendErrorMessage", ex);
161 sendErrorMessageText(response, message);
162 }
163 }
164
165 protected void compileReport(ServletContext context,
166 String reportFile) throws Exception {
167 };
168
169 /***
170 * generates a report from request. Tries to get data from DbForms.
171 *
172 * @param request
173 * HTTPServletRequest
174 * @param response
175 * HTTPServletResponse
176 */
177 protected void process(HttpServletRequest request,
178 HttpServletResponse response) {
179
180 try {
181 String reportFile = getReportFileFullName(request.getPathInfo(),
182 getServletContext(), request, response);
183
184 if (!Util.isNull(reportFile)) {
185 compileReport(getServletContext(), reportFile);
186 AbstractJRDataSource dataSource = getDataForReport(request, response);
187 if (!response.isCommitted()) {
188 if (dataSource == null) {
189 handleNoData(request, response);
190 } else {
191 ReportWriter res = processReport(reportFile,
192 dataSource, getServletContext(), request,
193 response);
194 if (!response.isCommitted()) {
195 if (res == null) {
196 handleNoOutput(request, response);
197 } else {
198 processOutput(res, request, response);
199 }
200 }
201 }
202 }
203 }
204 } catch (Exception e) {
205 logCat.error("process", e);
206 handleException(request, response, e);
207 }
208 }
209
210 private void processOutput(ReportWriter out, HttpServletRequest request,
211 HttpServletResponse response) throws Exception {
212 if ((out.data == null) && (out.data.size() == 0)) {
213 handleNoOutput(request, response);
214 return;
215 }
216 response.setHeader("Expires", "0");
217 response.setHeader("Cache-Control",
218 "must-revalidate, post-check=0, pre-check=0");
219 response.setHeader("Pragma", "public");
220 out.fileName = ParseUtil.getParameter(request, REPORTNAMEPARAM, out.fileName);
221 if (!Util.isNull(out.fileName)) {
222 response.setHeader("Content-disposition", "inline; filename="
223 + out.fileName);
224 }
225 if (!Util.isNull(out.mimeType)) {
226 response.setContentType(out.mimeType);
227 }
228
229 response.setContentLength(out.data.size());
230 ServletOutputStream outputStream = response.getOutputStream();
231 try {
232 out.data.writeTo(outputStream);
233 outputStream.flush();
234 } finally {
235 outputStream.close();
236 }
237 }
238
239 private String getReportFileFullName(String reportFileName,
240 ServletContext context, HttpServletRequest request,
241 HttpServletResponse response) {
242 String reportFile = null;
243
244 try {
245 boolean found = false;
246 for (int i = 0; i < reportdirs.length; i++) {
247 reportFile = context
248 .getRealPath(reportdirs[i] + reportFileName) ;
249 String testName = reportFile + getReportFileExtension();
250 if (FileUtil.fileExists(testName)) {
251 found = true;
252 break;
253 }
254 }
255 if (!found) {
256 handleNoReport(request, response);
257 reportFile = null;
258 }
259 } catch (Exception e) {
260 handleException(request, response, e);
261 }
262
263 return reportFile;
264 }
265
266 private void handleNoReport(HttpServletRequest request,
267 HttpServletResponse response) {
268 sendErrorMessage(request, response, MessageResourcesInternal
269 .getMessage("dbforms.reports.noreport", request.getLocale(),
270 new String[] { request.getPathInfo() }));
271 }
272
273 /***
274 * get a JRDataSource for report data. Source can be a Collection, an rsv,
275 * or dbform if session variable "jasper.input" is set, it must point to a
276 * Collection object if session variable "jasper.rsv" is set, it must point
277 * to a ResultSetVector object otherwise the enclosing dbform is used for
278 * data
279 *
280 * @param context
281 * @param request
282 * @param response
283 *
284 * @return
285 */
286 private AbstractJRDataSource getDataForReport(HttpServletRequest request, HttpServletResponse response) {
287 AbstractJRDataSource dataSource = null;
288 Table table = null;
289 ResultSetVector rsv = null;
290
291 try {
292
293 Object input = request.getAttribute("jasper.input");
294 if (input == null)
295 input = request.getSession().getAttribute("jasper.input");
296 if ((input != null) && (input instanceof Collection)) {
297 Iterator iter = ((Collection) input).iterator();
298 dataSource = new JRDataSourceIter(null, iter);
299 return dataSource;
300 }
301
302
303 rsv = (ResultSetVector) request.getAttribute("jasper.rsv");
304 if (rsv == null)
305 rsv = (ResultSetVector) request.getSession().getAttribute("jasper.rsv");
306 if (rsv != null) {
307 logCat.info("get resultsetvector rsv= " + rsv.size());
308 if (rsv.size() == 0) {
309 handleNoData(request, response);
310 } else {
311 dataSource = new JRDataSourceRSV(rsv.getAttributes(), rsv);
312 }
313 return dataSource;
314 }
315
316 PageContext pageContext = new PageContextBuffer();
317 pageContext
318 .initialize(this, request, response, null, true, 0, true);
319
320
321 AbstractWebEvent webEvent = (AbstractWebEvent) request.getAttribute("webEvent");
322 table = webEvent.getTable();
323
324 if (table == null) {
325 logCat.error("table==null");
326 }
327
328 if ((webEvent != null) && (table != null) && (table.getId() != -1)) {
329
330 DbFormsConfig config = null;
331
332 try {
333 config = DbFormsConfigRegistry.instance().lookup();
334 } catch (Exception e) {
335 logCat.error(e);
336 throw new ServletException(e);
337 }
338
339 String tableName = config.getTable(webEvent.getTable().getId())
340 .getName();
341
342
343 DbFormTag form = new DbFormTag();
344 form.setPageContext(pageContext);
345 form.setTableName(tableName);
346
347 String maxRows = ParseUtil
348 .getParameter(request, "maxRows", "*");
349 form.setMaxRows(maxRows);
350 form.setFollowUp("");
351 form.setAutoUpdate("false");
352 String sqlFilter = ParseUtil.getParameter(request, "sqlFilter", "");
353 form.setSqlFilter(sqlFilter);
354
355
356
357
358
359
360 String saveSource = (String) request.getAttribute("source");
361 String refSource = request.getRequestURI();
362
363 if (request.getQueryString() != null) {
364 refSource += ("?" + request.getQueryString());
365 }
366
367 request.setAttribute("source", refSource);
368 form.doStartTag();
369 request.setAttribute("source", saveSource);
370
371 rsv = form.getResultSetVector();
372 logCat.info("get resultsetvector rsv= " + rsv.size());
373
374 if (rsv.size() == 0) {
375 handleNoData(request, response);
376 } else {
377 dataSource = new JRDataSourceRSV(rsv.getAttributes(), rsv);
378 }
379
380 form.doFinally();
381 }
382 } catch (Exception e) {
383 logCat.error(e);
384 }
385
386 return dataSource;
387 }
388
389 private void sendErrorMessageText(HttpServletResponse response,
390 String message) {
391 try {
392 PrintWriter out = response.getWriter();
393 response.setContentType("text/html");
394 out.println("<html><body><h1>ERROR</h1><p>");
395 out.println(message);
396 out.println("</p></body></html>");
397 out.flush();
398 out.close();
399 } catch (IOException ioe2) {
400 logCat.error("sendErrorMessageText", ioe2);
401 }
402 }
403
404 private void handleNoOutput(HttpServletRequest request,
405 HttpServletResponse response) {
406 sendErrorMessage(request, response, MessageResourcesInternal
407 .getMessage("dbforms.reports.nooutput", request.getLocale()));
408 }
409
410 }