Frames | No Frames |
1: /* =========================================================== 2: * JFreeChart : a free chart library for the Java(tm) platform 3: * =========================================================== 4: * 5: * (C) Copyright 2000-2006, by Object Refinery Limited and Contributors. 6: * 7: * Project Info: http://www.jfree.org/jfreechart/index.html 8: * 9: * This library is free software; you can redistribute it and/or modify it 10: * under the terms of the GNU Lesser General Public License as published by 11: * the Free Software Foundation; either version 2.1 of the License, or 12: * (at your option) any later version. 13: * 14: * This library is distributed in the hope that it will be useful, but 15: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17: * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 22: * USA. 23: * 24: * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 25: * in the United States and other countries.] 26: * 27: * --------------------- 28: * ServletUtilities.java 29: * --------------------- 30: * (C) Copyright 2002-2006, by Richard Atkinson and Contributors. 31: * 32: * Original Author: Richard Atkinson; 33: * Contributor(s): J?rgen Hoffman; 34: * David Gilbert (for Object Refinery Limited); 35: * Douglas Clayton; 36: * 37: * $Id: ServletUtilities.java,v 1.3.2.3 2006/09/13 15:42:38 mungady Exp $ 38: * 39: * Changes 40: * ------- 41: * 19-Aug-2002 : Version 1; 42: * 20-Apr-2003 : Added additional sendTempFile method to allow MIME type 43: * specification and modified original sendTempFile method to 44: * automatically set MIME type for JPEG and PNG files 45: * 23-Jun-2003 : Added additional sendTempFile method at the request of 46: * J?rgen Hoffman; 47: * 07-Jul-2003 : Added more header information to streamed images; 48: * 19-Aug-2003 : Forced images to be stored in the temporary directory defined 49: * by System property java.io.tmpdir, rather than default (RA); 50: * 24-Mar-2004 : Added temp filename prefix attribute (DG); 51: * 09-Mar-2005 : Added "one time" file option (DG); 52: * ------------- JFREECHART 1.0.0 RELEASED ------------------------------------ 53: * 10-Jan-2006 : Updated API docs and reformatted (DG); 54: * 13-Sep-2006 : Format date in response header in English, not locale default 55: * (see bug 1557141) (DG); 56: * 57: */ 58: 59: package org.jfree.chart.servlet; 60: 61: 62: import java.io.BufferedInputStream; 63: import java.io.BufferedOutputStream; 64: import java.io.File; 65: import java.io.FileInputStream; 66: import java.io.FileNotFoundException; 67: import java.io.IOException; 68: import java.text.SimpleDateFormat; 69: import java.util.Date; 70: import java.util.Locale; 71: import java.util.TimeZone; 72: 73: import javax.servlet.http.HttpServletResponse; 74: import javax.servlet.http.HttpSession; 75: 76: import org.jfree.chart.ChartRenderingInfo; 77: import org.jfree.chart.ChartUtilities; 78: import org.jfree.chart.JFreeChart; 79: 80: /** 81: * Utility class used for servlet related JFreeChart operations. 82: */ 83: public class ServletUtilities { 84: 85: /** The filename prefix. */ 86: private static String tempFilePrefix = "jfreechart-"; 87: 88: /** A prefix for "one time" charts. */ 89: private static String tempOneTimeFilePrefix = "jfreechart-onetime-"; 90: 91: /** 92: * Returns the prefix for the temporary file names generated by this class. 93: * 94: * @return The prefix (never <code>null</code>). 95: */ 96: public static String getTempFilePrefix() { 97: return ServletUtilities.tempFilePrefix; 98: } 99: 100: /** 101: * Sets the prefix for the temporary file names generated by this class. 102: * 103: * @param prefix the prefix (<code>null</code> not permitted). 104: */ 105: public static void setTempFilePrefix(String prefix) { 106: if (prefix == null) { 107: throw new IllegalArgumentException("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("Null 'prefix' argument."); 131: } 132: ServletUtilities.tempOneTimeFilePrefix = prefix; 133: } 134: 135: /** 136: * Saves the chart as a PNG format file in the temporary directory. 137: * 138: * @param chart the JFreeChart to be saved. 139: * @param width the width of the chart. 140: * @param height the height of the chart. 141: * @param session the HttpSession of the client (if <code>null</code>, the 142: * temporary file is marked as "one-time" and deleted by 143: * the {@link DisplayChart} servlet right after it is 144: * streamed to the client). 145: * 146: * @return The filename of the chart saved in the temporary directory. 147: * 148: * @throws IOException if there is a problem saving the file. 149: */ 150: public static String saveChartAsPNG(JFreeChart chart, int width, int height, 151: HttpSession session) throws IOException { 152: 153: return ServletUtilities.saveChartAsPNG(chart, width, height, null, 154: session); 155: 156: } 157: 158: /** 159: * Saves the chart as a PNG format file in the temporary directory and 160: * populates the {@link ChartRenderingInfo} object which can be used to 161: * generate an HTML image map. 162: * 163: * @param chart the chart to be saved (<code>null</code> not permitted). 164: * @param width the width of the chart. 165: * @param height the height of the chart. 166: * @param info the ChartRenderingInfo object to be populated 167: * (<code>null</code> permitted). 168: * @param session the HttpSession of the client (if <code>null</code>, the 169: * temporary file is marked as "one-time" and deleted by 170: * the {@link DisplayChart} servlet right after it is 171: * streamed to the client). 172: * 173: * @return The filename of the chart saved in the temporary directory. 174: * 175: * @throws IOException if there is a problem saving the file. 176: */ 177: public static String saveChartAsPNG(JFreeChart chart, int width, int height, 178: ChartRenderingInfo info, HttpSession session) throws IOException { 179: 180: if (chart == null) { 181: throw new IllegalArgumentException("Null 'chart' argument."); 182: } 183: ServletUtilities.createTempDir(); 184: String prefix = ServletUtilities.tempFilePrefix; 185: if (session == null) { 186: prefix = ServletUtilities.tempOneTimeFilePrefix; 187: } 188: File tempFile = File.createTempFile(prefix, ".png", 189: new File(System.getProperty("java.io.tmpdir"))); 190: ChartUtilities.saveChartAsPNG(tempFile, chart, width, height, info); 191: if (session != null) { 192: ServletUtilities.registerChartForDeletion(tempFile, session); 193: } 194: return tempFile.getName(); 195: 196: } 197: 198: /** 199: * Saves the chart as a JPEG format file in the temporary directory. 200: * <p> 201: * SPECIAL NOTE: Please avoid using JPEG as an image format for charts, 202: * it is a "lossy" format that introduces visible distortions in the 203: * resulting image - use PNG instead. In addition, note that JPEG output 204: * is supported by JFreeChart only for JRE 1.4.2 or later. 205: * 206: * @param chart the JFreeChart to be saved. 207: * @param width the width of the chart. 208: * @param height the height of the chart. 209: * @param session the HttpSession of the client (if <code>null</code>, the 210: * temporary file is marked as "one-time" and deleted by 211: * the {@link DisplayChart} servlet right after it is 212: * streamed to the client). 213: * 214: * @return The filename of the chart saved in the temporary directory. 215: * 216: * @throws IOException if there is a problem saving the file. 217: */ 218: public static String saveChartAsJPEG(JFreeChart chart, int width, 219: int height, HttpSession session) 220: throws IOException { 221: 222: return ServletUtilities.saveChartAsJPEG(chart, width, height, null, 223: session); 224: 225: } 226: 227: /** 228: * Saves the chart as a JPEG format file in the temporary directory and 229: * populates the <code>ChartRenderingInfo</code> object which can be used 230: * to generate an HTML image map. 231: * <p> 232: * SPECIAL NOTE: Please avoid using JPEG as an image format for charts, 233: * it is a "lossy" format that introduces visible distortions in the 234: * resulting image - use PNG instead. In addition, note that JPEG output 235: * is supported by JFreeChart only for JRE 1.4.2 or later. 236: * 237: * @param chart the chart to be saved (<code>null</code> not permitted). 238: * @param width the width of the chart 239: * @param height the height of the chart 240: * @param info the ChartRenderingInfo object to be populated 241: * @param session the HttpSession of the client (if <code>null</code>, the 242: * temporary file is marked as "one-time" and deleted by 243: * the {@link DisplayChart} servlet right after it is 244: * streamed to the client). 245: * 246: * @return The filename of the chart saved in the temporary directory 247: * 248: * @throws IOException if there is a problem saving the file. 249: */ 250: public static String saveChartAsJPEG(JFreeChart chart, int width, 251: int height, ChartRenderingInfo info, HttpSession session) 252: throws IOException { 253: 254: if (chart == null) { 255: throw new IllegalArgumentException("Null 'chart' argument."); 256: } 257: 258: ServletUtilities.createTempDir(); 259: String prefix = ServletUtilities.tempFilePrefix; 260: if (session == null) { 261: prefix = ServletUtilities.tempOneTimeFilePrefix; 262: } 263: File tempFile = File.createTempFile(prefix, ".jpeg", 264: new File(System.getProperty("java.io.tmpdir"))); 265: ChartUtilities.saveChartAsJPEG(tempFile, chart, width, height, info); 266: if (session != null) { 267: ServletUtilities.registerChartForDeletion(tempFile, session); 268: } 269: return tempFile.getName(); 270: 271: } 272: 273: /** 274: * Creates the temporary directory if it does not exist. Throws a 275: * <code>RuntimeException</code> if the temporary directory is 276: * <code>null</code>. Uses the system property <code>java.io.tmpdir</code> 277: * as the temporary directory. This sounds like a strange thing to do but 278: * my temporary directory was not created on my default Tomcat 4.0.3 279: * installation. Could save some questions on the forum if it is created 280: * when not present. 281: */ 282: protected static void createTempDir() { 283: String tempDirName = System.getProperty("java.io.tmpdir"); 284: if (tempDirName == null) { 285: throw new RuntimeException("Temporary directory system property " 286: + "(java.io.tmpdir) is null."); 287: } 288: 289: // create the temporary directory if it doesn't exist 290: File tempDir = new File(tempDirName); 291: if (!tempDir.exists()) { 292: tempDir.mkdirs(); 293: } 294: } 295: 296: /** 297: * Adds a {@link ChartDeleter} object to the session object with the name 298: * <code>JFreeChart_Deleter</code> if there is not already one bound to the 299: * session and adds the filename to the list of charts to be deleted. 300: * 301: * @param tempFile the file to be deleted. 302: * @param session the HTTP session of the client. 303: */ 304: protected static void registerChartForDeletion(File tempFile, 305: HttpSession session) { 306: 307: // Add chart to deletion list in session 308: if (session != null) { 309: ChartDeleter chartDeleter 310: = (ChartDeleter) session.getAttribute("JFreeChart_Deleter"); 311: if (chartDeleter == null) { 312: chartDeleter = new ChartDeleter(); 313: session.setAttribute("JFreeChart_Deleter", chartDeleter); 314: } 315: chartDeleter.addChart(tempFile.getName()); 316: } 317: else { 318: System.out.println("Session is null - chart will not be deleted"); 319: } 320: } 321: 322: /** 323: * Binary streams the specified file in the temporary directory to the 324: * HTTP response in 1KB chunks. 325: * 326: * @param filename the name of the file in the temporary directory. 327: * @param response the HTTP response object. 328: * 329: * @throws IOException if there is an I/O problem. 330: */ 331: public static void sendTempFile(String filename, 332: HttpServletResponse response) throws IOException { 333: 334: File file = new File(System.getProperty("java.io.tmpdir"), filename); 335: ServletUtilities.sendTempFile(file, response); 336: } 337: 338: /** 339: * Binary streams the specified file to the HTTP response in 1KB chunks. 340: * 341: * @param file the file to be streamed. 342: * @param response the HTTP response object. 343: * 344: * @throws IOException if there is an I/O problem. 345: */ 346: public static void sendTempFile(File file, HttpServletResponse response) 347: throws IOException { 348: 349: String mimeType = null; 350: String filename = file.getName(); 351: if (filename.length() > 5) { 352: if (filename.substring(filename.length() - 5, 353: filename.length()).equals(".jpeg")) { 354: mimeType = "image/jpeg"; 355: } 356: else if (filename.substring(filename.length() - 4, 357: filename.length()).equals(".png")) { 358: mimeType = "image/png"; 359: } 360: } 361: ServletUtilities.sendTempFile(file, response, mimeType); 362: } 363: 364: /** 365: * Binary streams the specified file to the HTTP response in 1KB chunks. 366: * 367: * @param file the file to be streamed. 368: * @param response the HTTP response object. 369: * @param mimeType the mime type of the file, null allowed. 370: * 371: * @throws IOException if there is an I/O problem. 372: */ 373: public static void sendTempFile(File file, HttpServletResponse response, 374: String mimeType) throws IOException { 375: 376: if (file.exists()) { 377: BufferedInputStream bis = new BufferedInputStream( 378: new FileInputStream(file)); 379: 380: // Set HTTP headers 381: if (mimeType != null) { 382: response.setHeader("Content-Type", mimeType); 383: } 384: response.setHeader("Content-Length", String.valueOf(file.length())); 385: SimpleDateFormat sdf = new SimpleDateFormat( 386: "EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH); 387: sdf.setTimeZone(TimeZone.getTimeZone("GMT")); 388: response.setHeader("Last-Modified", 389: sdf.format(new Date(file.lastModified()))); 390: 391: BufferedOutputStream bos = new BufferedOutputStream( 392: response.getOutputStream()); 393: byte[] input = new byte[1024]; 394: boolean eof = false; 395: while (!eof) { 396: int length = bis.read(input); 397: if (length == -1) { 398: eof = true; 399: } 400: else { 401: bos.write(input, 0, length); 402: } 403: } 404: bos.flush(); 405: bis.close(); 406: bos.close(); 407: } 408: else { 409: throw new FileNotFoundException(file.getAbsolutePath()); 410: } 411: return; 412: } 413: 414: /** 415: * Perform a search/replace operation on a String 416: * There are String methods to do this since (JDK 1.4) 417: * 418: * @param inputString the String to have the search/replace operation. 419: * @param searchString the search String. 420: * @param replaceString the replace String. 421: * 422: * @return The String with the replacements made. 423: */ 424: public static String searchReplace(String inputString, 425: String searchString, 426: String replaceString) { 427: 428: int i = inputString.indexOf(searchString); 429: if (i == -1) { 430: return inputString; 431: } 432: 433: String r = ""; 434: r += inputString.substring(0, i) + replaceString; 435: if (i + searchString.length() < inputString.length()) { 436: r += searchReplace(inputString.substring(i + searchString.length()), 437: searchString, replaceString); 438: } 439: 440: return r; 441: } 442: 443: }