View Javadoc

1   /*
2    * $Header: /cvsroot/jdbforms/dbforms/src/org/dbforms/servlets/reports/AbstractLineReportServlet.java,v 1.2 2005/12/03 08:09:47 hkollmann Exp $
3    * $Revision: 1.2 $
4    * $Date: 2005/12/03 08:09:47 $
5    *
6    * DbForms - a Rapid Application Development Framework
7    * Copyright (C) 2001 Joachim Peer <joepeer@excite.com>
8    *
9    * This library is free software; you can redistribute it and/or
10   * modify it under the terms of the GNU Lesser General Public
11   * License as published by the Free Software Foundation; either
12   * 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,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this library; if not, write to the Free Software
21   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
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: &lt;db:gotoButton destTable="web_parts"
54   * destination=" /reports/Artikel"/&gt; or for one record: &lt;db:gotoButton
55   * destTable="web_parts" keyToDestPos="currentRow"
56   * destination="/reports/Artikel" /&gt; Servlet mapping must be set to handle
57   * all /reports by this servlet!!! &lt;servlet/&gt;
58   * &lt;servlet-name/&gt;startreport&lt;/servlet-name/&gt;
59   * &lt;display-name/&gt;startreport&lt;/display-name/&gt;
60   * &lt;servlet-class/&gt;org.dbforms.StartReportServlet&lt;/servlet-class/&gt;
61   * &lt;/servlet&gt; &lt;servlet-mapping/&gt;
62   * &lt;servlet-name/&gt;startreport&lt;/servlet-name/&gt;
63   * &lt;url-pattern/&gt;/reports/&lt;/url-pattern/&gt; &lt;/servlet-mapping&gt;
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 &ltc:set var="jasper.rsv" value="${rsv_xxxxx}"
70   * scope="session" /&gt
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 				// simple type, 'search' is an object in the session
157 				obj = request.getAttribute(search);
158 			} else {
159 				// complex, 'search' is really a bean
160 				// complex, 'search' is really a bean
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 				// simple type, 'search' is an object in the session
184 				obj = session.getAttribute(search);
185 			} else {
186 				// complex, 'search' is really a bean
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 		// Write out the data
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 }