001/* ====================================================== 002 * JFreeChart : a chart library for the Java(tm) platform 003 * ====================================================== 004 * 005 * (C) Copyright 2000-present, by David Gilbert and Contributors. 006 * 007 * Project Info: https://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 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 025 * Other names may be trademarks of their respective owners.] 026 * 027 * --------------------- 028 * ServletUtilities.java 029 * --------------------- 030 * (C) Copyright 2002-present, by Richard Atkinson and Contributors. 031 * 032 * Original Author: Richard Atkinson; 033 * Contributor(s): J?rgen Hoffman; 034 * David Gilbert; 035 * Douglas Clayton; 036 * 037 */ 038 039package org.jfree.chart.servlet; 040 041import java.io.BufferedInputStream; 042import java.io.BufferedOutputStream; 043import java.io.File; 044import java.io.FileInputStream; 045import java.io.FileNotFoundException; 046import java.io.IOException; 047import java.text.SimpleDateFormat; 048import java.util.Date; 049import java.util.Locale; 050import java.util.TimeZone; 051 052import javax.servlet.http.HttpServletResponse; 053import javax.servlet.http.HttpSession; 054 055import org.jfree.chart.ChartRenderingInfo; 056import org.jfree.chart.ChartUtils; 057import org.jfree.chart.JFreeChart; 058import org.jfree.chart.util.Args; 059 060/** 061 * Utility class used for servlet related JFreeChart operations. 062 * 063 * @deprecated To be removed in JFreeChart 2.0 064 */ 065public class ServletUtilities { 066 067 /** The filename prefix. */ 068 private static String tempFilePrefix = "jfreechart-"; 069 070 /** A prefix for "one time" charts. */ 071 private static String tempOneTimeFilePrefix = "jfreechart-onetime-"; 072 073 /** 074 * Returns the prefix for the temporary file names generated by this class. 075 * 076 * @return The prefix (never {@code null}). 077 */ 078 public static String getTempFilePrefix() { 079 return ServletUtilities.tempFilePrefix; 080 } 081 082 private ServletUtilities() { 083 // no requirement to instantiate 084 } 085 086 /** 087 * Sets the prefix for the temporary file names generated by this class. 088 * 089 * @param prefix the prefix ({@code null} not permitted). 090 */ 091 public static void setTempFilePrefix(String prefix) { 092 Args.nullNotPermitted(prefix, "prefix"); 093 ServletUtilities.tempFilePrefix = prefix; 094 } 095 096 /** 097 * Returns the prefix for "one time" temporary file names generated by 098 * this class. 099 * 100 * @return The prefix. 101 */ 102 public static String getTempOneTimeFilePrefix() { 103 return ServletUtilities.tempOneTimeFilePrefix; 104 } 105 106 /** 107 * Sets the prefix for the "one time" temporary file names generated by 108 * this class. 109 * 110 * @param prefix the prefix ({@code null} not permitted). 111 */ 112 public static void setTempOneTimeFilePrefix(String prefix) { 113 Args.nullNotPermitted(prefix, "prefix"); 114 ServletUtilities.tempOneTimeFilePrefix = prefix; 115 } 116 117 /** 118 * Saves the chart as a PNG format file in the temporary directory. 119 * 120 * @param chart the JFreeChart to be saved. 121 * @param width the width of the chart. 122 * @param height the height of the chart. 123 * @param session the HttpSession of the client (if {@code null}, the 124 * temporary file is marked as "one-time" and deleted by 125 * the {@link DisplayChart} servlet right after it is 126 * streamed to the client). 127 * 128 * @return The filename of the chart saved in the temporary directory. 129 * 130 * @throws IOException if there is a problem saving the file. 131 */ 132 public static String saveChartAsPNG(JFreeChart chart, int width, int height, 133 HttpSession session) throws IOException { 134 135 return ServletUtilities.saveChartAsPNG(chart, width, height, null, 136 session); 137 138 } 139 140 /** 141 * Saves the chart as a PNG format file in the temporary directory and 142 * populates the {@link ChartRenderingInfo} object which can be used to 143 * generate an HTML image map. 144 * 145 * @param chart the chart to be saved ({@code null} not permitted). 146 * @param width the width of the chart. 147 * @param height the height of the chart. 148 * @param info the ChartRenderingInfo object to be populated 149 * ({@code null} permitted). 150 * @param session the HttpSession of the client (if {@code null}, the 151 * temporary file is marked as "one-time" and deleted by 152 * the {@link DisplayChart} servlet right after it is 153 * streamed to the client). 154 * 155 * @return The filename of the chart saved in the temporary directory. 156 * 157 * @throws IOException if there is a problem saving the file. 158 */ 159 public static String saveChartAsPNG(JFreeChart chart, int width, int height, 160 ChartRenderingInfo info, HttpSession session) throws IOException { 161 162 Args.nullNotPermitted(chart, "chart"); 163 ServletUtilities.createTempDir(); 164 String prefix = ServletUtilities.tempFilePrefix; 165 if (session == null) { 166 prefix = ServletUtilities.tempOneTimeFilePrefix; 167 } 168 File tempFile = File.createTempFile(prefix, ".png", 169 new File(System.getProperty("java.io.tmpdir"))); 170 ChartUtils.saveChartAsPNG(tempFile, chart, width, height, info); 171 if (session != null) { 172 ServletUtilities.registerChartForDeletion(tempFile, session); 173 } 174 return tempFile.getName(); 175 176 } 177 178 /** 179 * Saves the chart as a JPEG format file in the temporary directory. 180 * <p> 181 * SPECIAL NOTE: Please avoid using JPEG as an image format for charts, 182 * it is a "lossy" format that introduces visible distortions in the 183 * resulting image - use PNG instead. In addition, note that JPEG output 184 * is supported by JFreeChart only for JRE 1.4.2 or later. 185 * 186 * @param chart the JFreeChart to be saved. 187 * @param width the width of the chart. 188 * @param height the height of the chart. 189 * @param session the HttpSession of the client (if {@code null}, the 190 * temporary file is marked as "one-time" and deleted by 191 * the {@link DisplayChart} servlet right after it is 192 * streamed to the client). 193 * 194 * @return The filename of the chart saved in the temporary directory. 195 * 196 * @throws IOException if there is a problem saving the file. 197 */ 198 public static String saveChartAsJPEG(JFreeChart chart, int width, 199 int height, HttpSession session) 200 throws IOException { 201 202 return ServletUtilities.saveChartAsJPEG(chart, width, height, null, 203 session); 204 205 } 206 207 /** 208 * Saves the chart as a JPEG format file in the temporary directory and 209 * populates the {@code ChartRenderingInfo} object which can be used 210 * to generate an HTML image map. 211 * <p> 212 * SPECIAL NOTE: Please avoid using JPEG as an image format for charts, 213 * it is a "lossy" format that introduces visible distortions in the 214 * resulting image - use PNG instead. In addition, note that JPEG output 215 * is supported by JFreeChart only for JRE 1.4.2 or later. 216 * 217 * @param chart the chart to be saved ({@code null} not permitted). 218 * @param width the width of the chart 219 * @param height the height of the chart 220 * @param info the ChartRenderingInfo object to be populated 221 * @param session the HttpSession of the client (if {@code null}, the 222 * temporary file is marked as "one-time" and deleted by 223 * the {@link DisplayChart} servlet right after it is 224 * streamed to the client). 225 * 226 * @return The filename of the chart saved in the temporary directory 227 * 228 * @throws IOException if there is a problem saving the file. 229 */ 230 public static String saveChartAsJPEG(JFreeChart chart, int width, 231 int height, ChartRenderingInfo info, HttpSession session) 232 throws IOException { 233 234 Args.nullNotPermitted(chart, "chart"); 235 ServletUtilities.createTempDir(); 236 String prefix = ServletUtilities.tempFilePrefix; 237 if (session == null) { 238 prefix = ServletUtilities.tempOneTimeFilePrefix; 239 } 240 File tempFile = File.createTempFile(prefix, ".jpeg", 241 new File(System.getProperty("java.io.tmpdir"))); 242 ChartUtils.saveChartAsJPEG(tempFile, chart, width, height, info); 243 if (session != null) { 244 ServletUtilities.registerChartForDeletion(tempFile, session); 245 } 246 return tempFile.getName(); 247 248 } 249 250 /** 251 * Creates the temporary directory if it does not exist. Throws a 252 * {@code RuntimeException} if the temporary directory is 253 * {@code null}. Uses the system property {@code java.io.tmpdir} 254 * as the temporary directory. This sounds like a strange thing to do but 255 * my temporary directory was not created on my default Tomcat 4.0.3 256 * installation. Could save some questions on the forum if it is created 257 * when not present. 258 */ 259 protected static void createTempDir() { 260 String tempDirName = System.getProperty("java.io.tmpdir"); 261 if (tempDirName == null) { 262 throw new RuntimeException("Temporary directory system property " 263 + "(java.io.tmpdir) is null."); 264 } 265 266 // create the temporary directory if it doesn't exist 267 File tempDir = new File(tempDirName); 268 if (!tempDir.exists()) { 269 tempDir.mkdirs(); 270 } 271 } 272 273 /** 274 * Adds a {@link ChartDeleter} object to the session object with the name 275 * {@code JFreeChart_Deleter} if there is not already one bound to the 276 * session and adds the filename to the list of charts to be deleted. 277 * 278 * @param tempFile the file to be deleted. 279 * @param session the HTTP session of the client. 280 */ 281 protected static void registerChartForDeletion(File tempFile, 282 HttpSession session) { 283 284 // Add chart to deletion list in session 285 if (session != null) { 286 ChartDeleter chartDeleter 287 = (ChartDeleter) session.getAttribute("JFreeChart_Deleter"); 288 if (chartDeleter == null) { 289 chartDeleter = new ChartDeleter(); 290 session.setAttribute("JFreeChart_Deleter", chartDeleter); 291 } 292 chartDeleter.addChart(tempFile.getName()); 293 } 294 else { 295 System.out.println("Session is null - chart will not be deleted"); 296 } 297 } 298 299 /** 300 * Binary streams the specified file in the temporary directory to the 301 * HTTP response in 1KB chunks. 302 * 303 * @param filename the name of the file in the temporary directory. 304 * @param response the HTTP response object. 305 * 306 * @throws IOException if there is an I/O problem. 307 */ 308 public static void sendTempFile(String filename, 309 HttpServletResponse response) throws IOException { 310 311 File file = new File(System.getProperty("java.io.tmpdir"), filename); 312 ServletUtilities.sendTempFile(file, response); 313 } 314 315 /** 316 * Binary streams the specified file to the HTTP response in 1KB chunks. 317 * 318 * @param file the file to be streamed. 319 * @param response the HTTP response object. 320 * 321 * @throws IOException if there is an I/O problem. 322 */ 323 public static void sendTempFile(File file, HttpServletResponse response) 324 throws IOException { 325 326 String mimeType = null; 327 String filename = file.getName(); 328 if (filename.length() > 5) { 329 if (filename.endsWith(".jpeg")) { 330 mimeType = "image/jpeg"; 331 } 332 else if (filename.endsWith(".png")) { 333 mimeType = "image/png"; 334 } 335 } 336 ServletUtilities.sendTempFile(file, response, mimeType); 337 } 338 339 /** 340 * Binary streams the specified file to the HTTP response in 1KB chunks. 341 * 342 * @param file the file to be streamed. 343 * @param response the HTTP response object. 344 * @param mimeType the mime type of the file, null allowed. 345 * 346 * @throws IOException if there is an I/O problem. 347 */ 348 public static void sendTempFile(File file, HttpServletResponse response, 349 String mimeType) throws IOException { 350 351 if (file.exists()) { 352 BufferedInputStream bis = new BufferedInputStream( 353 new FileInputStream(file)); 354 355 // Set HTTP headers 356 if (mimeType != null) { 357 response.setHeader("Content-Type", mimeType); 358 } 359 response.setHeader("Content-Length", String.valueOf(file.length())); 360 SimpleDateFormat sdf = new SimpleDateFormat( 361 "EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH); 362 sdf.setTimeZone(TimeZone.getTimeZone("GMT")); 363 response.setHeader("Last-Modified", 364 sdf.format(new Date(file.lastModified()))); 365 366 BufferedOutputStream bos = new BufferedOutputStream( 367 response.getOutputStream()); 368 byte[] input = new byte[1024]; 369 boolean eof = false; 370 while (!eof) { 371 int length = bis.read(input); 372 if (length == -1) { 373 eof = true; 374 } 375 else { 376 bos.write(input, 0, length); 377 } 378 } 379 bos.flush(); 380 bis.close(); 381 bos.close(); 382 } 383 else { 384 throw new FileNotFoundException(file.getAbsolutePath()); 385 } 386 } 387 388 /** 389 * Perform a search/replace operation on a String 390 * There are String methods to do this since (JDK 1.4) 391 * 392 * @param inputString the String to have the search/replace operation. 393 * @param searchString the search String. 394 * @param replaceString the replace String. 395 * 396 * @return The String with the replacements made. 397 */ 398 public static String searchReplace(String inputString, 399 String searchString, 400 String replaceString) { 401 402 int i = inputString.indexOf(searchString); 403 if (i == -1) { 404 return inputString; 405 } 406 407 String r = ""; 408 r += inputString.substring(0, i) + replaceString; 409 if (i + searchString.length() < inputString.length()) { 410 r += searchReplace(inputString.substring(i + searchString.length()), 411 searchString, replaceString); 412 } 413 414 return r; 415 } 416 417}