001: /* ===========================================================
002: * JFreeChart : a free chart library for the Java(tm) platform
003: * ===========================================================
004: *
005: * (C) Copyright 2000-2006, by Object Refinery Limited and Contributors.
006: *
007: * Project Info: http://www.jfree.org/jfreechart/index.html
008: *
009: * This library is free software; you can redistribute it and/or modify it
010: * under the terms of the GNU Lesser General Public License as published by
011: * the Free Software Foundation; either version 2.1 of the License, or
012: * (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but
015: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
016: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
017: * License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
022: * USA.
023: *
024: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
025: * in the United States and other countries.]
026: *
027: * ---------------------
028: * ServletUtilities.java
029: * ---------------------
030: * (C) Copyright 2002-2006, by Richard Atkinson and Contributors.
031: *
032: * Original Author: Richard Atkinson;
033: * Contributor(s): J?rgen Hoffman;
034: * David Gilbert (for Object Refinery Limited);
035: * Douglas Clayton;
036: *
037: * $Id: ServletUtilities.java,v 1.3.2.3 2006/09/13 15:42:38 mungady Exp $
038: *
039: * Changes
040: * -------
041: * 19-Aug-2002 : Version 1;
042: * 20-Apr-2003 : Added additional sendTempFile method to allow MIME type
043: * specification and modified original sendTempFile method to
044: * automatically set MIME type for JPEG and PNG files
045: * 23-Jun-2003 : Added additional sendTempFile method at the request of
046: * J?rgen Hoffman;
047: * 07-Jul-2003 : Added more header information to streamed images;
048: * 19-Aug-2003 : Forced images to be stored in the temporary directory defined
049: * by System property java.io.tmpdir, rather than default (RA);
050: * 24-Mar-2004 : Added temp filename prefix attribute (DG);
051: * 09-Mar-2005 : Added "one time" file option (DG);
052: * ------------- JFREECHART 1.0.0 RELEASED ------------------------------------
053: * 10-Jan-2006 : Updated API docs and reformatted (DG);
054: * 13-Sep-2006 : Format date in response header in English, not locale default
055: * (see bug 1557141) (DG);
056: *
057: */
058:
059: package org.jfree.chart.servlet;
060:
061: import java.io.BufferedInputStream;
062: import java.io.BufferedOutputStream;
063: import java.io.File;
064: import java.io.FileInputStream;
065: import java.io.FileNotFoundException;
066: import java.io.IOException;
067: import java.text.SimpleDateFormat;
068: import java.util.Date;
069: import java.util.Locale;
070: import java.util.TimeZone;
071:
072: import javax.servlet.http.HttpServletResponse;
073: import javax.servlet.http.HttpSession;
074:
075: import org.jfree.chart.ChartRenderingInfo;
076: import org.jfree.chart.ChartUtilities;
077: import org.jfree.chart.JFreeChart;
078:
079: /**
080: * Utility class used for servlet related JFreeChart operations.
081: */
082: public class ServletUtilities {
083:
084: /** The filename prefix. */
085: private static String tempFilePrefix = "jfreechart-";
086:
087: /** A prefix for "one time" charts. */
088: private static String tempOneTimeFilePrefix = "jfreechart-onetime-";
089:
090: /**
091: * Returns the prefix for the temporary file names generated by this class.
092: *
093: * @return The prefix (never <code>null</code>).
094: */
095: public static String getTempFilePrefix() {
096: return ServletUtilities.tempFilePrefix;
097: }
098:
099: /**
100: * Sets the prefix for the temporary file names generated by this class.
101: *
102: * @param prefix the prefix (<code>null</code> not permitted).
103: */
104: public static void setTempFilePrefix(String prefix) {
105: if (prefix == null) {
106: throw new IllegalArgumentException(
107: "Null 'prefix' argument.");
108: }
109: ServletUtilities.tempFilePrefix = prefix;
110: }
111:
112: /**
113: * Returns the prefix for "one time" temporary file names generated by
114: * this class.
115: *
116: * @return The prefix.
117: */
118: public static String getTempOneTimeFilePrefix() {
119: return ServletUtilities.tempOneTimeFilePrefix;
120: }
121:
122: /**
123: * Sets the prefix for the "one time" temporary file names generated by
124: * this class.
125: *
126: * @param prefix the prefix (<code>null</code> not permitted).
127: */
128: public static void setTempOneTimeFilePrefix(String prefix) {
129: if (prefix == null) {
130: throw new IllegalArgumentException(
131: "Null 'prefix' argument.");
132: }
133: ServletUtilities.tempOneTimeFilePrefix = prefix;
134: }
135:
136: /**
137: * Saves the chart as a PNG format file in the temporary directory.
138: *
139: * @param chart the JFreeChart to be saved.
140: * @param width the width of the chart.
141: * @param height the height of the chart.
142: * @param session the HttpSession of the client (if <code>null</code>, the
143: * temporary file is marked as "one-time" and deleted by
144: * the {@link DisplayChart} servlet right after it is
145: * streamed to the client).
146: *
147: * @return The filename of the chart saved in the temporary directory.
148: *
149: * @throws IOException if there is a problem saving the file.
150: */
151: public static String saveChartAsPNG(JFreeChart chart, int width,
152: int height, HttpSession session) throws IOException {
153:
154: return ServletUtilities.saveChartAsPNG(chart, width, height,
155: null, session);
156:
157: }
158:
159: /**
160: * Saves the chart as a PNG format file in the temporary directory and
161: * populates the {@link ChartRenderingInfo} object which can be used to
162: * generate an HTML image map.
163: *
164: * @param chart the chart to be saved (<code>null</code> not permitted).
165: * @param width the width of the chart.
166: * @param height the height of the chart.
167: * @param info the ChartRenderingInfo object to be populated
168: * (<code>null</code> permitted).
169: * @param session the HttpSession of the client (if <code>null</code>, the
170: * temporary file is marked as "one-time" and deleted by
171: * the {@link DisplayChart} servlet right after it is
172: * streamed to the client).
173: *
174: * @return The filename of the chart saved in the temporary directory.
175: *
176: * @throws IOException if there is a problem saving the file.
177: */
178: public static String saveChartAsPNG(JFreeChart chart, int width,
179: int height, ChartRenderingInfo info, HttpSession session)
180: throws IOException {
181:
182: if (chart == null) {
183: throw new IllegalArgumentException("Null 'chart' argument.");
184: }
185: ServletUtilities.createTempDir();
186: String prefix = ServletUtilities.tempFilePrefix;
187: if (session == null) {
188: prefix = ServletUtilities.tempOneTimeFilePrefix;
189: }
190: File tempFile = File.createTempFile(prefix, ".png", new File(
191: System.getProperty("java.io.tmpdir")));
192: ChartUtilities.saveChartAsPNG(tempFile, chart, width, height,
193: info);
194: if (session != null) {
195: ServletUtilities
196: .registerChartForDeletion(tempFile, session);
197: }
198: return tempFile.getName();
199:
200: }
201:
202: /**
203: * Saves the chart as a JPEG format file in the temporary directory.
204: * <p>
205: * SPECIAL NOTE: Please avoid using JPEG as an image format for charts,
206: * it is a "lossy" format that introduces visible distortions in the
207: * resulting image - use PNG instead. In addition, note that JPEG output
208: * is supported by JFreeChart only for JRE 1.4.2 or later.
209: *
210: * @param chart the JFreeChart to be saved.
211: * @param width the width of the chart.
212: * @param height the height of the chart.
213: * @param session the HttpSession of the client (if <code>null</code>, the
214: * temporary file is marked as "one-time" and deleted by
215: * the {@link DisplayChart} servlet right after it is
216: * streamed to the client).
217: *
218: * @return The filename of the chart saved in the temporary directory.
219: *
220: * @throws IOException if there is a problem saving the file.
221: */
222: public static String saveChartAsJPEG(JFreeChart chart, int width,
223: int height, HttpSession session) throws IOException {
224:
225: return ServletUtilities.saveChartAsJPEG(chart, width, height,
226: null, session);
227:
228: }
229:
230: /**
231: * Saves the chart as a JPEG format file in the temporary directory and
232: * populates the <code>ChartRenderingInfo</code> object which can be used
233: * to generate an HTML image map.
234: * <p>
235: * SPECIAL NOTE: Please avoid using JPEG as an image format for charts,
236: * it is a "lossy" format that introduces visible distortions in the
237: * resulting image - use PNG instead. In addition, note that JPEG output
238: * is supported by JFreeChart only for JRE 1.4.2 or later.
239: *
240: * @param chart the chart to be saved (<code>null</code> not permitted).
241: * @param width the width of the chart
242: * @param height the height of the chart
243: * @param info the ChartRenderingInfo object to be populated
244: * @param session the HttpSession of the client (if <code>null</code>, the
245: * temporary file is marked as "one-time" and deleted by
246: * the {@link DisplayChart} servlet right after it is
247: * streamed to the client).
248: *
249: * @return The filename of the chart saved in the temporary directory
250: *
251: * @throws IOException if there is a problem saving the file.
252: */
253: public static String saveChartAsJPEG(JFreeChart chart, int width,
254: int height, ChartRenderingInfo info, HttpSession session)
255: throws IOException {
256:
257: if (chart == null) {
258: throw new IllegalArgumentException("Null 'chart' argument.");
259: }
260:
261: ServletUtilities.createTempDir();
262: String prefix = ServletUtilities.tempFilePrefix;
263: if (session == null) {
264: prefix = ServletUtilities.tempOneTimeFilePrefix;
265: }
266: File tempFile = File.createTempFile(prefix, ".jpeg", new File(
267: System.getProperty("java.io.tmpdir")));
268: ChartUtilities.saveChartAsJPEG(tempFile, chart, width, height,
269: info);
270: if (session != null) {
271: ServletUtilities
272: .registerChartForDeletion(tempFile, session);
273: }
274: return tempFile.getName();
275:
276: }
277:
278: /**
279: * Creates the temporary directory if it does not exist. Throws a
280: * <code>RuntimeException</code> if the temporary directory is
281: * <code>null</code>. Uses the system property <code>java.io.tmpdir</code>
282: * as the temporary directory. This sounds like a strange thing to do but
283: * my temporary directory was not created on my default Tomcat 4.0.3
284: * installation. Could save some questions on the forum if it is created
285: * when not present.
286: */
287: protected static void createTempDir() {
288: String tempDirName = System.getProperty("java.io.tmpdir");
289: if (tempDirName == null) {
290: throw new RuntimeException(
291: "Temporary directory system property "
292: + "(java.io.tmpdir) is null.");
293: }
294:
295: // create the temporary directory if it doesn't exist
296: File tempDir = new File(tempDirName);
297: if (!tempDir.exists()) {
298: tempDir.mkdirs();
299: }
300: }
301:
302: /**
303: * Adds a {@link ChartDeleter} object to the session object with the name
304: * <code>JFreeChart_Deleter</code> if there is not already one bound to the
305: * session and adds the filename to the list of charts to be deleted.
306: *
307: * @param tempFile the file to be deleted.
308: * @param session the HTTP session of the client.
309: */
310: protected static void registerChartForDeletion(File tempFile,
311: HttpSession session) {
312:
313: // Add chart to deletion list in session
314: if (session != null) {
315: ChartDeleter chartDeleter = (ChartDeleter) session
316: .getAttribute("JFreeChart_Deleter");
317: if (chartDeleter == null) {
318: chartDeleter = new ChartDeleter();
319: session
320: .setAttribute("JFreeChart_Deleter",
321: chartDeleter);
322: }
323: chartDeleter.addChart(tempFile.getName());
324: } else {
325: System.out
326: .println("Session is null - chart will not be deleted");
327: }
328: }
329:
330: /**
331: * Binary streams the specified file in the temporary directory to the
332: * HTTP response in 1KB chunks.
333: *
334: * @param filename the name of the file in the temporary directory.
335: * @param response the HTTP response object.
336: *
337: * @throws IOException if there is an I/O problem.
338: */
339: public static void sendTempFile(String filename,
340: HttpServletResponse response) throws IOException {
341:
342: File file = new File(System.getProperty("java.io.tmpdir"),
343: filename);
344: ServletUtilities.sendTempFile(file, response);
345: }
346:
347: /**
348: * Binary streams the specified file to the HTTP response in 1KB chunks.
349: *
350: * @param file the file to be streamed.
351: * @param response the HTTP response object.
352: *
353: * @throws IOException if there is an I/O problem.
354: */
355: public static void sendTempFile(File file,
356: HttpServletResponse response) throws IOException {
357:
358: String mimeType = null;
359: String filename = file.getName();
360: if (filename.length() > 5) {
361: if (filename.substring(filename.length() - 5,
362: filename.length()).equals(".jpeg")) {
363: mimeType = "image/jpeg";
364: } else if (filename.substring(filename.length() - 4,
365: filename.length()).equals(".png")) {
366: mimeType = "image/png";
367: }
368: }
369: ServletUtilities.sendTempFile(file, response, mimeType);
370: }
371:
372: /**
373: * Binary streams the specified file to the HTTP response in 1KB chunks.
374: *
375: * @param file the file to be streamed.
376: * @param response the HTTP response object.
377: * @param mimeType the mime type of the file, null allowed.
378: *
379: * @throws IOException if there is an I/O problem.
380: */
381: public static void sendTempFile(File file,
382: HttpServletResponse response, String mimeType)
383: throws IOException {
384:
385: if (file.exists()) {
386: BufferedInputStream bis = new BufferedInputStream(
387: new FileInputStream(file));
388:
389: // Set HTTP headers
390: if (mimeType != null) {
391: response.setHeader("Content-Type", mimeType);
392: }
393: response.setHeader("Content-Length", String.valueOf(file
394: .length()));
395: SimpleDateFormat sdf = new SimpleDateFormat(
396: "EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH);
397: sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
398: response.setHeader("Last-Modified", sdf.format(new Date(
399: file.lastModified())));
400:
401: BufferedOutputStream bos = new BufferedOutputStream(
402: response.getOutputStream());
403: byte[] input = new byte[1024];
404: boolean eof = false;
405: while (!eof) {
406: int length = bis.read(input);
407: if (length == -1) {
408: eof = true;
409: } else {
410: bos.write(input, 0, length);
411: }
412: }
413: bos.flush();
414: bis.close();
415: bos.close();
416: } else {
417: throw new FileNotFoundException(file.getAbsolutePath());
418: }
419: return;
420: }
421:
422: /**
423: * Perform a search/replace operation on a String
424: * There are String methods to do this since (JDK 1.4)
425: *
426: * @param inputString the String to have the search/replace operation.
427: * @param searchString the search String.
428: * @param replaceString the replace String.
429: *
430: * @return The String with the replacements made.
431: */
432: public static String searchReplace(String inputString,
433: String searchString, String replaceString) {
434:
435: int i = inputString.indexOf(searchString);
436: if (i == -1) {
437: return inputString;
438: }
439:
440: String r = "";
441: r += inputString.substring(0, i) + replaceString;
442: if (i + searchString.length() < inputString.length()) {
443: r += searchReplace(inputString.substring(i
444: + searchString.length()), searchString,
445: replaceString);
446: }
447:
448: return r;
449: }
450:
451: }
|