Author: jochen Date: Thu Mar 15 15:05:19 2007 New Revision: 518775 URL: http://svn.apache.org/viewvc?view=rev&rev=518775 Log: Using the FileCleaningTracker now.
Modified: jakarta/commons/proper/fileupload/trunk/pom.xml jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/disk/DiskFileItem.java jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/disk/DiskFileItemFactory.java jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/servlet/FileCleanerCleanup.java jakarta/commons/proper/fileupload/trunk/xdocs/using.xml Modified: jakarta/commons/proper/fileupload/trunk/pom.xml URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/pom.xml?view=diff&rev=518775&r1=518774&r2=518775 ============================================================================== --- jakarta/commons/proper/fileupload/trunk/pom.xml (original) +++ jakarta/commons/proper/fileupload/trunk/pom.xml Thu Mar 15 15:05:19 2007 @@ -172,7 +172,7 @@ <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> - <version>1.3</version> + <version>1.4-SNAPSHOT</version> <optional>true</optional> </dependency> </dependencies> Modified: jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/disk/DiskFileItem.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/disk/DiskFileItem.java?view=diff&rev=518775&r1=518774&r2=518775 ============================================================================== --- jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/disk/DiskFileItem.java (original) +++ jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/disk/DiskFileItem.java Thu Mar 15 15:05:19 2007 @@ -29,6 +29,8 @@ import java.io.ObjectInputStream; import java.io.UnsupportedEncodingException; import java.util.Map; + +import org.apache.commons.io.FileCleaningTracker; import org.apache.commons.io.IOUtils; import org.apache.commons.io.FileCleaner; import org.apache.commons.io.output.DeferredFileOutputStream; @@ -77,6 +79,11 @@ // ----------------------------------------------------- Manifest constants + /** + * The UID to use when serializing this instance. + */ + private static final long serialVersionUID = 2237570099615271025L; + /** * Default content charset to be used when no explicit charset @@ -163,6 +170,10 @@ */ private File dfosFile; + /** + * The tracker, which is responsible for deleting the temporary file. + */ + private FileCleaningTracker fileCleaningTracker; // ----------------------------------------------------------- Constructors @@ -183,10 +194,38 @@ * @param repository The data repository, which is the directory in * which files will be created, should the item size * exceed the threshold. + * @deprecated Use [EMAIL PROTECTED] #DiskFileItem(FileCleaningTracker, String, String, boolean, String, int, File)}. */ public DiskFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { + this(FileCleaner.getInstance(), fieldName, contentType, + isFormField, fileName, sizeThreshold, + repository); + } + + /** + * Constructs a new <code>DiskFileItem</code> instance. + * + * @param tracker The tracker, which is responsible for deleting + * the temporary file. + * @param fieldName The name of the form field. + * @param contentType The content type passed by the browser or + * <code>null</code> if not specified. + * @param isFormField Whether or not this item is a plain form field, as + * opposed to a file upload. + * @param fileName The original filename in the user's filesystem, or + * <code>null</code> if not specified. + * @param sizeThreshold The threshold, in bytes, below which items will be + * retained in memory and above which they will be + * stored as a file. + * @param repository The data repository, which is the directory in + * which files will be created, should the item size + * exceed the threshold. + */ + private DiskFileItem(FileCleaningTracker tracker, String fieldName, String contentType, + boolean isFormField, String fileName, int sizeThreshold, File repository) { + this.fileCleaningTracker = tracker; this.fieldName = fieldName; this.contentType = contentType; this.isFormField = isFormField; @@ -195,6 +234,25 @@ this.repository = repository; } + /** + * Constructs a new <code>DiskFileItem</code> instance. + * + * @param factory The factory, which is creating this instance. + * @param fieldName The name of the form field. + * @param contentType The content type passed by the browser or + * <code>null</code> if not specified. + * @param isFormField Whether or not this item is a plain form field, as + * opposed to a file upload. + * @param fileName The original filename in the user's filesystem, or + * <code>null</code> if not specified. + */ + public DiskFileItem(DiskFileItemFactory factory, String fieldName, String contentType, + boolean isFormField, String fileName) { + this(factory.getFileCleaningTracker(), fieldName, contentType, + isFormField, fileName, factory.getSizeThreshold(), + factory.getRepository()); + } + // ------------------------------- Methods from javax.activation.DataSource @@ -597,7 +655,12 @@ String tempFileName = "upload_" + UID + "_" + getUniqueId() + ".tmp"; File f = new File(tempDir, tempFileName); - FileCleaner.track(f, this); + if (fileCleaningTracker != null) { + /* If a tracker is present, use it. Otherwise, we've got to trust + * in the [EMAIL PROTECTED] #finalize()} method. + */ + fileCleaningTracker.track(f, this); + } return f; } Modified: jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/disk/DiskFileItemFactory.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/disk/DiskFileItemFactory.java?view=diff&rev=518775&r1=518774&r2=518775 ============================================================================== --- jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/disk/DiskFileItemFactory.java (original) +++ jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/disk/DiskFileItemFactory.java Thu Mar 15 15:05:19 2007 @@ -21,6 +21,7 @@ import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.io.FileCleaner; +import org.apache.commons.io.FileCleaningTracker; /** * <p>The default [EMAIL PROTECTED] org.apache.commons.fileupload.FileItemFactory} @@ -44,10 +45,11 @@ * consider the following: Temporary files are automatically deleted as * soon as they are no longer needed. (More precisely, when the * corresponding instance of [EMAIL PROTECTED] java.io.File} is garbage collected.) - * This is done by the so-called reaper thread, which is started - * automatically when the class [EMAIL PROTECTED] FileCleaner} is loaded. - * It might make sense to terminate that thread, for example, if - * your web application ends. See the section on "Resource cleanup" + * Cleaning up those files is done by an instance of + * [EMAIL PROTECTED] FileCleaningTracker}, and an associated thread. In a complex + * environment, for example in a web application, you should consider + * terminating this thread, for example, when your web application + * ends. See the section on "Resource cleanup" * in the users guide of commons-fileupload.</p> * * @author <a href="mailto:[EMAIL PROTECTED]">Martin Cooper</a> @@ -82,14 +84,22 @@ private int sizeThreshold = DEFAULT_SIZE_THRESHOLD; + /** + * The instance of [EMAIL PROTECTED] FileCleaningTracker}, which is responsible + * for deleting temporary files. + */ + private FileCleaningTracker fileCleaningTracker; + // ----------------------------------------------------------- Constructors /** * Constructs an unconfigured instance of this class. The resulting factory * may be configured by calling the appropriate setter methods. + * @deprecated Use [EMAIL PROTECTED] #DiskFileItemFactory(FileCleaningTracker, int, File)}. */ public DiskFileItemFactory() { + this(FileCleaner.getInstance(), DEFAULT_SIZE_THRESHOLD, null); } @@ -102,13 +112,29 @@ * @param repository The data repository, which is the directory in * which files will be created, should the item size * exceed the threshold. + * @deprecated Use [EMAIL PROTECTED] #DiskFileItemFactory(FileCleaningTracker, int, File)}. */ public DiskFileItemFactory(int sizeThreshold, File repository) { + this(FileCleaner.getInstance(), sizeThreshold, repository); + } + + /** + * Constructs a preconfigured instance of this class. + * + * @param sizeThreshold The threshold, in bytes, below which items will be + * retained in memory and above which they will be + * stored as a file. + * @param repository The data repository, which is the directory in + * which files will be created, should the item size + * exceed the threshold. + * @param tracker The tracker, which is responsible to delete temporary files. + */ + public DiskFileItemFactory(FileCleaningTracker tracker, int sizeThreshold, File repository) { this.sizeThreshold = sizeThreshold; this.repository = repository; + this.fileCleaningTracker = tracker; } - // ------------------------------------------------------------- Properties @@ -188,8 +214,28 @@ boolean isFormField, String fileName ) { - return new DiskFileItem(fieldName, contentType, - isFormField, fileName, sizeThreshold, repository); + return new DiskFileItem(this, fieldName, contentType, + isFormField, fileName); + } + + /** + * Returns the tracker, which is responsible for deleting temporary + * files. + * @return An instance of [EMAIL PROTECTED] FileCleaningTracker}, defaults to + * [EMAIL PROTECTED] FileCleaner#getInstance()}. + */ + public FileCleaningTracker getFileCleaningTracker() { + return fileCleaningTracker; + } + + /** + * Returns the tracker, which is responsible for deleting temporary + * files. + * @param pFileCleaningTracker An instance of [EMAIL PROTECTED] FileCleaningTracker}, + * which will from now on track the created files. + */ + public void setFileCleaningTracker(FileCleaningTracker pFileCleaningTracker) { + fileCleaningTracker = pFileCleaningTracker; } } Modified: jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/servlet/FileCleanerCleanup.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/servlet/FileCleanerCleanup.java?view=diff&rev=518775&r1=518774&r2=518775 ============================================================================== --- jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/servlet/FileCleanerCleanup.java (original) +++ jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/servlet/FileCleanerCleanup.java Thu Mar 15 15:05:19 2007 @@ -16,10 +16,11 @@ */ package org.apache.commons.fileupload.servlet; +import javax.servlet.ServletContext; import javax.servlet.ServletContextListener; import javax.servlet.ServletContextEvent; -import org.apache.commons.io.FileCleaner; +import org.apache.commons.io.FileCleaningTracker; /** @@ -29,20 +30,45 @@ */ public class FileCleanerCleanup implements ServletContextListener { /** + * Attribute name, which is used for storing an instance of + * [EMAIL PROTECTED] FileCleaningTracker} in the web application. + */ + public static final String FILE_CLEANING_TRACKER_ATTRIBUTE + = FileCleanerCleanup.class.getName() + ".FileCleaningTracker"; + + /** + * Returns the instance of [EMAIL PROTECTED] FileCleaningTracker}, which is + * associated with the given [EMAIL PROTECTED] ServletContext}. + */ + public static FileCleaningTracker getFileCleaningTracker(ServletContext pServletContext) { + return (FileCleaningTracker) pServletContext.getAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE); + } + + /** + * Sets the instance of [EMAIL PROTECTED] FileCleaningTracker}, which is + * associated with the given [EMAIL PROTECTED] ServletContext}. + */ + public static void setFileCleaningTracker(ServletContext pServletContext, FileCleaningTracker pTracker) { + pServletContext.setAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE, pTracker); + } + + /** * Called when the web application is initialized. Does * nothing. - * @param sce The servlet context (ignored). + * @param sce The servlet context, used for calling + * [EMAIL PROTECTED] #setFileCleaningTracker(ServletContext, FileCleaningTracker)}. */ public void contextInitialized(ServletContextEvent sce) { - // Does nothing. + setFileCleaningTracker(sce.getServletContext(), new FileCleaningTracker()); } /** * Called when the web application is being destroyed. - * Calls [EMAIL PROTECTED] FileCleaner#exitWhenFinished()}. - * @param sce The servlet context (ignored). + * Calls [EMAIL PROTECTED] FileCleaningTracker#exitWhenFinished()}. + * @param sce The servlet context, used for calling + * [EMAIL PROTECTED] #getFileCleaningTracker(ServletContext)}. */ public void contextDestroyed(ServletContextEvent sce) { - FileCleaner.exitWhenFinished(); + getFileCleaningTracker(sce.getServletContext()).exitWhenFinished(); } } Modified: jakarta/commons/proper/fileupload/trunk/xdocs/using.xml URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/xdocs/using.xml?view=diff&rev=518775&r1=518774&r2=518775 ============================================================================== --- jakarta/commons/proper/fileupload/trunk/xdocs/using.xml (original) +++ jakarta/commons/proper/fileupload/trunk/xdocs/using.xml Thu Mar 15 15:05:19 2007 @@ -283,15 +283,23 @@ <p> Such temporary files are deleted automatically, if they are no longer used (more precisely, if the corresponding instance of <code>java.io.File</code> - is garbage collected. This is done silently by the <code>org.apache.commons.io.FileCleaner</code> - class, which starts a reaper thread. + is garbage collected. This is done silently by an instance of + <code>org.apache.commons.io.FileCleaningTracker</code>, which starts a + reaper thread. </p> <p> - This reaper thread should be stopped, if it is no longer needed. In - a servlet environment, this is done by using a special servlet - context listener, called - <a href="apidocs/org/apache/commons/fileupload/servlet/FileCleanerCleanup.html">FileCleanerCleanup</a>. - To do so, add a section like the following to your <code>web.xml</code>: + In what follows, we assume that you are writing a web application. In + a web application, resource cleanup is controlled by an instance of + <code>javax.servlet.ServletContextListener</code>. In other environments, + similar ideas must be applied. + </p> + + <subsection name="The FileCleanerCleanup"> + <p> + Your web application should use an instance of + <code>org.apache.commons.fileupload.FileCleanerCleanup</code>. + That's very easy, you've simply got to add it to your <code>web.xml</code>: + </p> <source><![CDATA[ <web-app> ... @@ -303,32 +311,27 @@ ... </web-app> ]]></source> - </p> - <p> - Unfortunately, this is not the whole story. The above applies only, if - </p> - <ol> - <li>You are using commons-io 1.3, or later.</li> - <li>You are loading commons-io from your web applications - WEB-INF/lib and not from another location, for example the - common/lib directory of Tomcat. This is not unlikely, because - there are quite a few applications, which do ship commons-io.</li> - </ol> - <p> - If commons-io 1.3 is loaded from your containers class path, then - the following might occur: Suggest that you have two applications, - called A and B running. (It might as well be the same application - with two names aka servlet contexts.) Both applications are using - the <code>FileCleanerCleanup</code>. Now, if you terminate application - A, but B is still running, then A terminates B's reaper thread as - well. - </p> - <p> - In other words, you should consider carefully, whether to use - the <code>FileCleanerCleanup</code>, or not. When unsure, or if you - are happy with commons-fileupload 1.1.1, or before, then you - possibly would like to avoid it. - </p> + </subsection> + + <subsection name="Creating a DiskFileItemFactory"> + <p> + The FileCleanerCleanup provides an instance of + <code>org.apache.commons.io.FileCleaningTracker</code>. This + instance must be used when creating a + <code>org.apache.commons.fileupload.disk.DiskFileItemFactory</code>. + This should be done by calling a method like the following: + </p> +<source><![CDATA[ + public static DiskFileItemFactory newDiskFileItemFactory(ServletContext context, + File repository) { + FileCleaningTracker fileCleaningTracker + = FileCleanerCleanup.getFileCleaningTracker(context); + return new DiskFileItemFactory(fileCleaningTracker, + DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD, + repository); + } +]]></source> + </subsection> </section> <section name="Interaction with virus scanners"> --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]