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 import org.apache.commons.beanutils.PropertyUtils;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29
30 import org.dbforms.util.Util;
31 import org.dbforms.util.external.FileUtil;
32
33 import java.io.BufferedReader;
34 import java.io.ByteArrayOutputStream;
35 import java.io.File;
36 import java.io.FileReader;
37 import java.io.OutputStream;
38
39 import javax.servlet.ServletContext;
40 import javax.servlet.ServletException;
41 import javax.servlet.http.HttpServletRequest;
42 import javax.servlet.http.HttpServletResponse;
43 import javax.servlet.http.HttpSession;
44
45 /***
46 * This servlet generates a comma separated values file (CSV). Data is read from
47 * the current dbForm, a Collection or a ResultSetVector The template file is in
48 * the reports directory with a .cr extension it consists of two lines of text,
49 * the first is a list of stirngs to use as header the second a list of comma
50 * separated field names. both lines must have the same number of elements.
51 * Normally the output file will use the first row as the headers. But if no
52 * header line is provided, then no headers are output and every row is data.
53 * usage: with a simple goto button: <db:gotoButton destTable="web_parts"
54 * destination=" /reports/Artikel"/> or for one record: <db:gotoButton
55 * destTable="web_parts" keyToDestPos="currentRow"
56 * destination="/reports/Artikel" /> Servlet mapping must be set to handle
57 * all /reports by this servlet!!! <servlet/>
58 * <servlet-name/>startreport</servlet-name/>
59 * <display-name/>startreport</display-name/>
60 * <servlet-class/>org.dbforms.StartReportServlet</servlet-class/>
61 * </servlet> <servlet-mapping/>
62 * <servlet-name/>startreport</servlet-name/>
63 * <url-pattern/>/reports/</url-pattern/> </servlet-mapping>
64 * web.xml optional parameters reportdirs list of directories to search for
65 * report file reportMimeType mime type to send to browser Parameters
66 * filename=xyz.csv name the output file Support for grabbing data from a
67 * Collection or an existing ResultSetVector set session variable "jasper.input"
68 * to use a Collection object set session variable "jasper.rsv" to use a
69 * ResultSetVector object ex <c:set var="jasper.rsv" value="${rsv_xxxxx}"
70 * scope="session" />
71 *
72 * @author Neal Katz
73 */
74 public abstract class AbstractLineReportServlet extends AbstractReportServlet {
75 private static Log logCat = LogFactory
76 .getLog(AbstractLineReportServlet.class);
77
78 protected abstract String getMimeType();
79
80 protected abstract String getFileExtension();
81
82 protected abstract void writeData(Object[] data) throws Exception;
83
84 protected abstract void openStream(OutputStream out) throws Exception;
85
86 protected abstract void closeStream(OutputStream out) throws Exception;
87
88 private static final String REPORTMIMETYPEPARAM = "reportMimeType";
89
90 private String mimeType = getMimeType();
91
92 private int rownum = 0;
93
94 public void init() throws ServletException {
95 super.init();
96 String value = getServletConfig().getInitParameter(REPORTMIMETYPEPARAM);
97 if (!Util.isNull(value)) {
98 mimeType = value;
99 }
100 }
101
102 protected String getReportFileExtension() {
103 return ".xr";
104 }
105
106 protected void writeHeader(String[] header) throws Exception {
107 writeData(header);
108 }
109
110 private Object getFieldValue(HttpServletRequest request,
111 AbstractJRDataSource dataSource, String search) {
112 Object o = null;
113 search = search.replaceAll("__", ".");
114
115 if (search.startsWith("internal.")) {
116 search = search.substring(search.indexOf("internal."));
117 logCat.debug("Trying to find data for internal value: " + search);
118 o = getInternalValue(search);
119 } else if (search.startsWith("request.")) {
120 search = search.substring(search.indexOf("request."));
121 logCat.debug("Trying to find data for page context value: "
122 + search);
123 o = getRequestValue(request, search);
124 } else if (search.startsWith("session.")) {
125 search = search.substring(search.indexOf("session."));
126 logCat.debug("Trying to find data for session value: " + search);
127 o = getSessionValue(request.getSession(), search);
128 } else {
129 logCat.debug("Trying to find data for field named: " + search);
130 o = dataSource.getFieldValue(search);
131 }
132 return o;
133
134 }
135
136 private Object getInternalValue(String search) {
137 Object obj = null;
138 try {
139 logCat.debug("Trying to find data for internal var : " + search);
140 if (search.equalsIgnoreCase("rownum")) {
141 return new Integer(rownum);
142 }
143 } catch (Exception e) {
144 logCat.error("getInternalValue: " + e);
145 }
146
147 return obj;
148 }
149
150 private Object getRequestValue(HttpServletRequest request, String search) {
151 Object obj = null;
152 int pos;
153 try {
154 pos = search.indexOf(".");
155 if (pos == -1) {
156
157 obj = request.getAttribute(search);
158 } else {
159
160
161 String search_bean = search.substring(0, pos);
162 search = search.substring(pos + 1);
163 Object bean = request.getAttribute(search_bean);
164 if (bean != null) {
165 logCat.debug("calling PropertyUtils.getProperty "
166 + search_bean + " " + search);
167 obj = PropertyUtils.getProperty(bean, search);
168 }
169 }
170 } catch (Exception e) {
171 logCat.error("getPageContextValue: " + e);
172 }
173
174 return obj;
175 }
176
177 private Object getSessionValue(HttpSession session, String search) {
178 Object obj = null;
179 int pos;
180 try {
181 pos = search.indexOf(".");
182 if (pos == -1) {
183
184 obj = session.getAttribute(search);
185 } else {
186
187 String search_bean = search.substring(0, pos);
188 search = search.substring(pos + 1);
189 Object bean = session.getAttribute(search_bean);
190 if (bean != null) {
191 logCat.debug("calling PropertyUtils.getProperty "
192 + search_bean + " " + search);
193 obj = PropertyUtils.getProperty(bean, search);
194 }
195 }
196 } catch (Exception e) {
197 logCat.error("getSessionValue: " + e);
198 }
199
200 return obj;
201 }
202
203 private ByteArrayOutputStream fillReport(HttpServletRequest request,
204 String[] header, String[] fields, AbstractJRDataSource dataSource)
205 throws Exception {
206 ByteArrayOutputStream res = new ByteArrayOutputStream();
207 openStream(res);
208 writeHeader(header);
209
210 Object[] data = new Object[fields.length];
211 while (dataSource.next()) {
212 rownum++;
213 for (int i = 0; i < fields.length; i++) {
214 data[i] = getFieldValue(request, dataSource, fields[i]);
215 }
216 writeData(data);
217 }
218 closeStream(res);
219 return res;
220 }
221
222 /***
223 * generates a report.
224 *
225 * @param reportFileFullName
226 * filename of report to process reportHTTPServletRequest
227 * generated by getReportFile! getReportFile should be called
228 * before fetching data, so that error handling of report not
229 * found e.g. could be processed first!
230 * @param dataSource
231 * data for the report
232 * @param context
233 * ServletContext
234 * @param request
235 * HTTPServletRequest
236 * @param response
237 * HTTPServletResponse
238 */
239 protected ReportWriter processReport(String reportFileFullName,
240 AbstractJRDataSource dataSource, ServletContext context,
241 HttpServletRequest request, HttpServletResponse response) {
242
243 try {
244 File f = new File(reportFileFullName + getReportFileExtension());
245 BufferedReader in = new BufferedReader(new FileReader(f));
246 try {
247 String line1 = in.readLine();
248 String line2 = in.readLine();
249 String fields = null;
250 String headers = null;
251 if (Util.isNull(line2)) {
252 fields = line1;
253 } else {
254 headers = line1;
255 fields = line2;
256 }
257 if (Util.isNull(fields)) {
258 logCat.error("no fields found");
259 return null;
260 }
261 String[] reportFields = fields.split(",");
262 String[] headerFields;
263 if (headers != null) {
264 headerFields = headers.split(",");
265 } else {
266 headerFields = new String[] {};
267 }
268 if (reportFields.length != headerFields.length) {
269 logCat.error("reportFields.length != headerFields.length");
270 headerFields = reportFields;
271 }
272 if (reportFields.length == 0) {
273 logCat.error("no fields found");
274 return null;
275 }
276
277 ReportWriter res = new ReportWriter();
278 res.data = fillReport(request, headerFields, reportFields,
279 dataSource);
280 if (res.data != null) {
281 res.fileName = FileUtil.filename(reportFileFullName)
282 + getFileExtension();
283 res.mimeType = mimeType;
284 }
285 return res;
286 } finally {
287 in.close();
288 }
289 } catch (Exception e) {
290 logCat.error("read report file", e);
291 handleException(request, response, e);
292 return null;
293 }
294 }
295
296 }