Source for org.jfree.chart.servlet.ServletUtilities

   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: }