Author: mgrigorov
Date: Tue Dec  7 19:53:29 2010
New Revision: 1043182

URL: http://svn.apache.org/viewvc?rev=1043182&view=rev
Log:
WICKET-3124 FileCleaner issues

Upgrade Apache Commons-IO FileCleaner to its latest version (renamed to 
FileCleaningTracker).
Since it starts a thread to do its stuff and this is not allowed in some 
environments (like Google AppEngine) not it is possible to disable it by using 
"getResourceSettings().setFileUploadCleaner(null)" in MyApp#init().

Added:
    
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileCleaningTracker.java
   (with props)
    
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileDeleteStrategy.java
   (with props)
    
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileUploadCleaner.java
   (with props)
    
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/IFileUploadCleaner.java
   (with props)
Removed:
    
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileCleaner.java
Modified:
    
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/upload/DiskFileItem.java
    
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/upload/DiskFileItemFactory.java
    
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
    
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/MultipartServletWebRequestImpl.java
    
wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/IResourceSettings.java
    
wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/def/ResourceSettings.java
    
wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/FileUploadTest.java

Added: 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileCleaningTracker.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileCleaningTracker.java?rev=1043182&view=auto
==============================================================================
--- 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileCleaningTracker.java
 (added)
+++ 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileCleaningTracker.java
 Tue Dec  7 19:53:29 2010
@@ -0,0 +1,331 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.util.file;
+
+import java.io.File;
+import java.lang.ref.PhantomReference;
+import java.lang.ref.ReferenceQueue;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * Keeps track of files awaiting deletion, and deletes them when an associated 
marker object is
+ * reclaimed by the garbage collector.
+ * <p>
+ * This utility creates a background thread to handle file deletion. Each file 
to be deleted is
+ * registered with a handler object. When the handler object is garbage 
collected, the file is
+ * deleted.
+ * <p>
+ * In an environment with multiple class loaders (a servlet container, for 
example), you should
+ * consider stopping the background thread if it is no longer needed. This is 
done by invoking the
+ * method {...@link #exitWhenFinished}, typically in
+ * {...@link javax.servlet.ServletContextListener#contextDestroyed} or similar.
+ * 
+ * @author Noel Bergman
+ * @author Martin Cooper
+ * @version $Id$
+ */
+public class FileCleaningTracker
+{
+       /**
+        * Queue of <code>Tracker</code> instances being watched.
+        */
+       ReferenceQueue<Object> q = new ReferenceQueue<Object>();
+       /**
+        * Collection of <code>Tracker</code> instances in existence.
+        */
+       final Collection<Tracker> trackers = Collections.synchronizedSet(new 
HashSet<Tracker>()); // synchronized
+       /**
+        * Collection of File paths that failed to delete.
+        */
+       final List<String> deleteFailures = Collections.synchronizedList(new 
ArrayList<String>());
+       /**
+        * Whether to terminate the thread when the tracking is complete.
+        */
+       volatile boolean exitWhenFinished = false;
+       /**
+        * The thread that will clean up registered files.
+        */
+       Thread reaper;
+
+       // 
-----------------------------------------------------------------------
+       /**
+        * Track the specified file, using the provided marker, deleting the 
file when the marker
+        * instance is garbage collected. The {...@link 
FileDeleteStrategy#NORMAL normal} deletion strategy
+        * will be used.
+        * 
+        * @param file
+        *            the file to be tracked, not null
+        * @param marker
+        *            the marker object used to track the file, not null
+        * @throws NullPointerException
+        *             if the file is null
+        */
+       public void track(File file, Object marker)
+       {
+               track(file, marker, (FileDeleteStrategy)null);
+       }
+
+       /**
+        * Track the specified file, using the provided marker, deleting the 
file when the marker
+        * instance is garbage collected. The speified deletion strategy is 
used.
+        * 
+        * @param file
+        *            the file to be tracked, not null
+        * @param marker
+        *            the marker object used to track the file, not null
+        * @param deleteStrategy
+        *            the strategy to delete the file, null means normal
+        * @throws NullPointerException
+        *             if the file is null
+        */
+       public void track(File file, Object marker, FileDeleteStrategy 
deleteStrategy)
+       {
+               if (file == null)
+               {
+                       throw new NullPointerException("The file must not be 
null");
+               }
+               addTracker(file.getPath(), marker, deleteStrategy);
+       }
+
+       /**
+        * Track the specified file, using the provided marker, deleting the 
file when the marker
+        * instance is garbage collected. The {...@link 
FileDeleteStrategy#NORMAL normal} deletion strategy
+        * will be used.
+        * 
+        * @param path
+        *            the full path to the file to be tracked, not null
+        * @param marker
+        *            the marker object used to track the file, not null
+        * @throws NullPointerException
+        *             if the path is null
+        */
+       public void track(String path, Object marker)
+       {
+               track(path, marker, (FileDeleteStrategy)null);
+       }
+
+       /**
+        * Track the specified file, using the provided marker, deleting the 
file when the marker
+        * instance is garbage collected. The speified deletion strategy is 
used.
+        * 
+        * @param path
+        *            the full path to the file to be tracked, not null
+        * @param marker
+        *            the marker object used to track the file, not null
+        * @param deleteStrategy
+        *            the strategy to delete the file, null means normal
+        * @throws NullPointerException
+        *             if the path is null
+        */
+       public void track(String path, Object marker, FileDeleteStrategy 
deleteStrategy)
+       {
+               if (path == null)
+               {
+                       throw new NullPointerException("The path must not be 
null");
+               }
+               addTracker(path, marker, deleteStrategy);
+       }
+
+       /**
+        * Adds a tracker to the list of trackers.
+        * 
+        * @param path
+        *            the full path to the file to be tracked, not null
+        * @param marker
+        *            the marker object used to track the file, not null
+        * @param deleteStrategy
+        *            the strategy to delete the file, null means normal
+        */
+       private synchronized void addTracker(String path, Object marker,
+               FileDeleteStrategy deleteStrategy)
+       {
+               // synchronized block protects reaper
+               if (exitWhenFinished)
+               {
+                       throw new IllegalStateException(
+                               "No new trackers can be added once 
exitWhenFinished() is called");
+               }
+               if (reaper == null)
+               {
+                       reaper = new Reaper();
+                       reaper.start();
+               }
+               trackers.add(new Tracker(path, deleteStrategy, marker, q));
+       }
+
+       // 
-----------------------------------------------------------------------
+       /**
+        * Retrieve the number of files currently being tracked, and therefore 
awaiting deletion.
+        * 
+        * @return the number of files being tracked
+        */
+       public int getTrackCount()
+       {
+               return trackers.size();
+       }
+
+       /**
+        * Return the file paths that failed to delete.
+        * 
+        * @return the file paths that failed to delete
+        * @since Commons IO 2.0
+        */
+       public List<String> getDeleteFailures()
+       {
+               return deleteFailures;
+       }
+
+       /**
+        * Call this method to cause the file cleaner thread to terminate when 
there are no more objects
+        * being tracked for deletion.
+        * <p>
+        * In a simple environment, you don't need this method as the file 
cleaner thread will simply
+        * exit when the JVM exits. In a more complex environment, with 
multiple class loaders (such as
+        * an application server), you should be aware that the file cleaner 
thread will continue
+        * running even if the class loader it was started from terminates. 
This can consitute a memory
+        * leak.
+        * <p>
+        * For example, suppose that you have developed a web application, 
which contains the commons-io
+        * jar file in your WEB-INF/lib directory. In other words, the 
FileCleaner class is loaded
+        * through the class loader of your web application. If the web 
application is terminated, but
+        * the servlet container is still running, then the file cleaner thread 
will still exist, posing
+        * a memory leak.
+        * <p>
+        * This method allows the thread to be terminated. Simply call this 
method in the resource
+        * cleanup code, such as {...@link 
javax.servlet.ServletContextListener#contextDestroyed}. Once
+        * called, no new objects can be tracked by the file cleaner.
+        */
+       public synchronized void exitWhenFinished()
+       {
+               // synchronized block protects reaper
+               exitWhenFinished = true;
+               if (reaper != null)
+               {
+                       synchronized (reaper)
+                       {
+                               reaper.interrupt();
+                       }
+               }
+       }
+
+       // 
-----------------------------------------------------------------------
+       /**
+        * The reaper thread.
+        */
+       private final class Reaper extends Thread
+       {
+               /** Construct a new Reaper */
+               Reaper()
+               {
+                       super("File Reaper");
+                       setPriority(Thread.MAX_PRIORITY);
+                       setDaemon(true);
+               }
+
+               /**
+                * Run the reaper thread that will delete files as their 
associated marker objects are
+                * reclaimed by the garbage collector.
+                */
+               @Override
+               public void run()
+               {
+                       // thread exits when exitWhenFinished is true and there 
are no more tracked objects
+                       while (exitWhenFinished == false || trackers.size() > 0)
+                       {
+                               try
+                               {
+                                       // Wait for a tracker to remove.
+                                       Tracker tracker = (Tracker)q.remove(); 
// cannot return null
+                                       trackers.remove(tracker);
+                                       if (!tracker.delete())
+                                       {
+                                               
deleteFailures.add(tracker.getPath());
+                                       }
+                                       tracker.clear();
+                               }
+                               catch (InterruptedException e)
+                               {
+                                       continue;
+                               }
+                       }
+               }
+       }
+
+       // 
-----------------------------------------------------------------------
+       /**
+        * Inner class which acts as the reference for a file pending deletion.
+        */
+       private static final class Tracker extends PhantomReference<Object>
+       {
+
+               /**
+                * The full path to the file being tracked.
+                */
+               private final String path;
+               /**
+                * The strategy for deleting files.
+                */
+               private final FileDeleteStrategy deleteStrategy;
+
+               /**
+                * Constructs an instance of this class from the supplied 
parameters.
+                * 
+                * @param path
+                *            the full path to the file to be tracked, not null
+                * @param deleteStrategy
+                *            the strategy to delete the file, null means normal
+                * @param marker
+                *            the marker object used to track the file, not null
+                * @param queue
+                *            the queue on to which the tracker will be pushed, 
not null
+                */
+               Tracker(String path, FileDeleteStrategy deleteStrategy, Object 
marker,
+                       ReferenceQueue<? super Object> queue)
+               {
+                       super(marker, queue);
+                       this.path = path;
+                       this.deleteStrategy = (deleteStrategy == null ? 
FileDeleteStrategy.NORMAL
+                               : deleteStrategy);
+               }
+
+               /**
+                * Return the path.
+                * 
+                * @return the path
+                */
+               public String getPath()
+               {
+                       return path;
+               }
+
+               /**
+                * Deletes the file associated with this tracker instance.
+                * 
+                * @return <code>true</code> if the file was deleted 
successfully; <code>false</code>
+                *         otherwise.
+                */
+               public boolean delete()
+               {
+                       return deleteStrategy.deleteQuietly(new File(path));
+               }
+       }
+
+}
\ No newline at end of file

Propchange: 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileCleaningTracker.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileDeleteStrategy.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileDeleteStrategy.java?rev=1043182&view=auto
==============================================================================
--- 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileDeleteStrategy.java
 (added)
+++ 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileDeleteStrategy.java
 Tue Dec  7 19:53:29 2010
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.util.file;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Strategy for deleting files.
+ * <p>
+ * There is more than one way to delete a file. You may want to limit access 
to certain directories,
+ * to only delete directories if they are empty, or maybe to force deletion.
+ * <p>
+ * This class captures the strategy to use and is designed for user 
subclassing.
+ * 
+ * @author Stephen Colebourne
+ * @version $Id$
+ * @since Commons IO 1.3
+ */
+public class FileDeleteStrategy
+{
+
+       /**
+        * The singleton instance for normal file deletion, which does not 
permit the deletion of
+        * directories that are not empty.
+        */
+       public static final FileDeleteStrategy NORMAL = new 
FileDeleteStrategy("Normal");
+
+       /** The name of the strategy. */
+       private final String name;
+
+       // 
-----------------------------------------------------------------------
+       /**
+        * Restricted constructor.
+        * 
+        * @param name
+        *            the name by which the strategy is known
+        */
+       protected FileDeleteStrategy(String name)
+       {
+               this.name = name;
+       }
+
+       // 
-----------------------------------------------------------------------
+       /**
+        * Deletes the file object, which may be a file or a directory. All 
<code>IOException</code>s
+        * are caught and false returned instead. If the file does not exist or 
is null, true is
+        * returned.
+        * <p>
+        * Subclass writers should override {...@link #doDelete(File)}, not 
this method.
+        * 
+        * @param fileToDelete
+        *            the file to delete, null returns true
+        * @return true if the file was deleted, or there was no such file
+        */
+       public boolean deleteQuietly(File fileToDelete)
+       {
+               if (fileToDelete == null || fileToDelete.exists() == false)
+               {
+                       return true;
+               }
+               try
+               {
+                       return doDelete(fileToDelete);
+               }
+               catch (IOException ex)
+               {
+                       return false;
+               }
+       }
+
+       /**
+        * Deletes the file object, which may be a file or a directory. If the 
file does not exist, the
+        * method just returns.
+        * <p>
+        * Subclass writers should override {...@link #doDelete(File)}, not 
this method.
+        * 
+        * @param fileToDelete
+        *            the file to delete, not null
+        * @throws NullPointerException
+        *             if the file is null
+        * @throws IOException
+        *             if an error occurs during file deletion
+        */
+       public void delete(File fileToDelete) throws IOException
+       {
+               if (fileToDelete.exists() && doDelete(fileToDelete) == false)
+               {
+                       throw new IOException("Deletion failed: " + 
fileToDelete);
+               }
+       }
+
+       /**
+        * Actually deletes the file object, which may be a file or a directory.
+        * <p>
+        * This method is designed for subclasses to override. The 
implementation may return either
+        * false or an <code>IOException</code> when deletion fails. The 
{...@link #delete(File)} and
+        * {...@link #deleteQuietly(File)} methods will handle either response 
appropriately. A check has
+        * been made to ensure that the file will exist.
+        * <p>
+        * This implementation uses {...@link File#delete()}.
+        * 
+        * @param fileToDelete
+        *            the file to delete, exists, not null
+        * @return true if the file was deleteds
+        * @throws NullPointerException
+        *             if the file is null
+        * @throws IOException
+        *             if an error occurs during file deletion
+        */
+       protected boolean doDelete(File fileToDelete) throws IOException
+       {
+               return fileToDelete.delete();
+       }
+
+       // 
-----------------------------------------------------------------------
+       /**
+        * Gets a string describing the delete strategy.
+        * 
+        * @return a string describing the delete strategy
+        */
+       @Override
+       public String toString()
+       {
+               return "FileDeleteStrategy[" + name + "]";
+       }
+
+}
\ No newline at end of file

Propchange: 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileDeleteStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileUploadCleaner.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileUploadCleaner.java?rev=1043182&view=auto
==============================================================================
--- 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileUploadCleaner.java
 (added)
+++ 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileUploadCleaner.java
 Tue Dec  7 19:53:29 2010
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.util.file;
+
+import java.io.File;
+
+/**
+ * Default implementation of {...@link IFileUploadCleaner} that uses Apache 
commons-io
+ * {...@link FileCleaningTracker} to track and clean the temporary created 
files.
+ * 
+ * <p>
+ * Note: this implementation starts a daemon thread to do the actual work, so 
it may not be used in
+ * some environments like Google AppEngine.
+ */
+public class FileUploadCleaner implements IFileUploadCleaner
+{
+       private final FileCleaningTracker cleaner;
+
+       /***/
+       public FileUploadCleaner()
+       {
+               cleaner = new FileCleaningTracker();
+       }
+
+       public void track(File file, Object marker)
+       {
+               cleaner.track(file, marker);
+       }
+
+       public void destroy()
+       {
+               cleaner.exitWhenFinished();
+       }
+
+}

Propchange: 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/FileUploadCleaner.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/IFileUploadCleaner.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/IFileUploadCleaner.java?rev=1043182&view=auto
==============================================================================
--- 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/IFileUploadCleaner.java
 (added)
+++ 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/IFileUploadCleaner.java
 Tue Dec  7 19:53:29 2010
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.util.file;
+
+import java.io.File;
+
+/**
+ * Keeps track of files awaiting deletion, and deletes them when an associated 
marker object is
+ * reclaimed by the garbage collector.
+ * 
+ * <p>
+ * Needed to remove files created temporarily for the needs of FileUpload 
functionality.
+ */
+public interface IFileUploadCleaner
+{
+
+       /**
+        * Track the specified file, using the provided marker, deleting the 
file when the marker
+        * instance is garbage collected.
+        * 
+        * @param file
+        *            the file to be tracked, not null
+        * @param marker
+        *            the marker object used to track the file, not null
+        * @throws NullPointerException
+        *             if the file is null
+        */
+       void track(File file, Object marker);
+
+       /**
+        * Call this method to stop the cleaner and to free all allocated 
resources by it
+        */
+       void destroy();
+}

Propchange: 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/IFileUploadCleaner.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/upload/DiskFileItem.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/upload/DiskFileItem.java?rev=1043182&r1=1043181&r2=1043182&view=diff
==============================================================================
--- 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/upload/DiskFileItem.java
 (original)
+++ 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/upload/DiskFileItem.java
 Tue Dec  7 19:53:29 2010
@@ -32,8 +32,8 @@ import java.util.Map;
 import java.util.Random;
 import java.util.UUID;
 
-import org.apache.wicket.util.file.FileCleaner;
 import org.apache.wicket.util.file.Files;
+import org.apache.wicket.util.file.IFileUploadCleaner;
 import org.apache.wicket.util.io.DeferredFileOutputStream;
 import org.apache.wicket.util.io.IOUtils;
 import org.apache.wicket.util.io.Streams;
@@ -172,6 +172,8 @@ public class DiskFileItem implements Fil
         */
        private FileItemHeaders headers;
 
+       private final IFileUploadCleaner fileUploadCleaner;
+
        // ----------------------------------------------------------- 
Constructors
 
 
@@ -196,7 +198,7 @@ public class DiskFileItem implements Fil
         */
        public DiskFileItem(final String fieldName, final String contentType,
                final boolean isFormField, final String fileName, final int 
sizeThreshold,
-               final File repository)
+               final File repository, final IFileUploadCleaner 
fileUploadCleaner)
        {
                this.fieldName = fieldName;
                this.contentType = contentType;
@@ -204,6 +206,7 @@ public class DiskFileItem implements Fil
                this.fileName = fileName;
                this.sizeThreshold = sizeThreshold;
                this.repository = repository;
+               this.fileUploadCleaner = fileUploadCleaner;
        }
 
 
@@ -655,7 +658,10 @@ public class DiskFileItem implements Fil
                                throw new RuntimeException("Could not create 
the temp file for upload", e);
                        }
 
-                       FileCleaner.track(tempFile, this);
+                       if (fileUploadCleaner != null)
+                       {
+                               fileUploadCleaner.track(tempFile, this);
+                       }
                }
                return tempFile;
        }

Modified: 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/upload/DiskFileItemFactory.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/upload/DiskFileItemFactory.java?rev=1043182&r1=1043181&r2=1043182&view=diff
==============================================================================
--- 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/upload/DiskFileItemFactory.java
 (original)
+++ 
wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/upload/DiskFileItemFactory.java
 Tue Dec  7 19:53:29 2010
@@ -18,6 +18,9 @@ package org.apache.wicket.util.upload;
 
 import java.io.File;
 
+import org.apache.wicket.util.file.FileCleaningTracker;
+import org.apache.wicket.util.file.IFileUploadCleaner;
+
 
 /**
  * <p>
@@ -75,6 +78,7 @@ public class DiskFileItemFactory impleme
         */
        private int sizeThreshold = DEFAULT_SIZE_THRESHOLD;
 
+       private final IFileUploadCleaner fileUploadCleaner;
 
        // ----------------------------------------------------------- 
Constructors
 
@@ -83,9 +87,9 @@ public class DiskFileItemFactory impleme
         * Constructs an unconfigured instance of this class. The resulting 
factory may be configured by
         * calling the appropriate setter methods.
         */
-       public DiskFileItemFactory()
+       public DiskFileItemFactory(final IFileUploadCleaner fileUploadCleaner)
        {
-               this(DEFAULT_SIZE_THRESHOLD, null);
+               this(DEFAULT_SIZE_THRESHOLD, null, fileUploadCleaner);
        }
 
 
@@ -99,10 +103,12 @@ public class DiskFileItemFactory impleme
         *            The data repository, which is the directory in which 
files will be created, should
         *            the item size exceed the threshold.
         */
-       public DiskFileItemFactory(final int sizeThreshold, final File 
repository)
+       public DiskFileItemFactory(final int sizeThreshold, final File 
repository,
+               final IFileUploadCleaner fileUploadCleaner)
        {
                this.sizeThreshold = sizeThreshold;
                this.repository = repository;
+               this.fileUploadCleaner = fileUploadCleaner;
        }
 
        // ------------------------------------------------------------- 
Properties
@@ -171,8 +177,8 @@ public class DiskFileItemFactory impleme
        // --------------------------------------------------------- Public 
Methods
 
        /**
-        * Create a new {...@link org.apache.wicket.util.upload.DiskFileItem} 
instance from the
-        * supplied parameters and the local factory configuration.
+        * Create a new {...@link org.apache.wicket.util.upload.DiskFileItem} 
instance from the supplied
+        * parameters and the local factory configuration.
         * 
         * @param fieldName
         *            The name of the form field.
@@ -189,7 +195,7 @@ public class DiskFileItemFactory impleme
                final boolean isFormField, final String fileName)
        {
                return new DiskFileItem(fieldName, contentType, isFormField, 
fileName, sizeThreshold,
-                       repository);
+                       repository, fileUploadCleaner);
        }
 
 }

Modified: 
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WebApplication.java?rev=1043182&r1=1043181&r2=1043182&view=diff
==============================================================================
--- 
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
 (original)
+++ 
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
 Tue Dec  7 19:53:29 2010
@@ -55,7 +55,8 @@ import org.apache.wicket.session.HttpSes
 import org.apache.wicket.session.ISessionStore;
 import org.apache.wicket.util.IProvider;
 import org.apache.wicket.util.collections.MostRecentlyUsedMap;
-import org.apache.wicket.util.file.FileCleaner;
+import org.apache.wicket.util.file.FileUploadCleaner;
+import org.apache.wicket.util.file.IFileUploadCleaner;
 import org.apache.wicket.util.file.IResourceFinder;
 import org.apache.wicket.util.file.WebApplicationPath;
 import org.apache.wicket.util.lang.Args;
@@ -438,7 +439,13 @@ public abstract class WebApplication ext
                        resourceWatcher.destroy();
                }
                bufferedResponses.clear();
-               FileCleaner.destroy();
+
+               IFileUploadCleaner fileUploadCleaner = 
getResourceSettings().getFileUploadCleaner();
+               if (fileUploadCleaner != null)
+               {
+                       fileUploadCleaner.destroy();
+               }
+
                super.internalDestroy();
 
        }
@@ -472,6 +479,8 @@ public abstract class WebApplication ext
                // Set resource finder to web app path
                getResourceSettings().setResourceFinder(getResourceFinder());
 
+               getResourceSettings().setFileUploadCleaner(new 
FileUploadCleaner());
+
                // Add optional sourceFolder for resources.
                String resourceFolder = getInitParameter("sourceFolder");
                if (resourceFolder != null)

Modified: 
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/MultipartServletWebRequestImpl.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/MultipartServletWebRequestImpl.java?rev=1043182&r1=1043181&r2=1043182&view=diff
==============================================================================
--- 
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/MultipartServletWebRequestImpl.java
 (original)
+++ 
wicket/trunk/wicket/src/main/java/org/apache/wicket/protocol/http/servlet/MultipartServletWebRequestImpl.java
 Tue Dec  7 19:53:29 2010
@@ -83,7 +83,9 @@ public class MultipartServletWebRequestI
        public MultipartServletWebRequestImpl(HttpServletRequest request, 
String filterPrefix,
                Bytes maxSize) throws FileUploadException
        {
-               this(request, filterPrefix, maxSize, new DiskFileItemFactory());
+               this(request, filterPrefix, maxSize, new 
DiskFileItemFactory(Application.get()
+                       .getResourceSettings()
+                       .getFileUploadCleaner()));
        }
 
        /**
@@ -119,7 +121,6 @@ public class MultipartServletWebRequestI
                                "ServletRequest does not contain multipart 
content. One possible solution is to explicitly call Form.setMultipart(true), 
Wicket tries its best to auto-detect multipart forms but there are certain 
situation where it cannot.");
                }
 
-
                // Configure the factory here, if desired.
                ServletFileUpload upload = new ServletFileUpload(factory);
 
@@ -131,11 +132,11 @@ public class MultipartServletWebRequestI
                // The encoding can also be null when using multipart/form-data 
encoded forms.
                // In that case we use the [application-encoding] which we 
always demand using
                // the attribute 'accept-encoding' in wicket forms.
-               if(encoding == null)
+               if (encoding == null)
                {
                        encoding = 
Application.get().getRequestCycleSettings().getResponseRequestEncoding();
                }
-               
+
                // set encoding specifically when we found it
                if (encoding != null)
                {

Modified: 
wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/IResourceSettings.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/IResourceSettings.java?rev=1043182&r1=1043181&r2=1043182&view=diff
==============================================================================
--- 
wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/IResourceSettings.java
 (original)
+++ 
wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/IResourceSettings.java
 Tue Dec  7 19:53:29 2010
@@ -26,6 +26,7 @@ import org.apache.wicket.markup.html.Pac
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.resource.IPropertiesFactory;
 import org.apache.wicket.resource.loader.IStringResourceLoader;
+import org.apache.wicket.util.file.IFileUploadCleaner;
 import org.apache.wicket.util.file.IResourceFinder;
 import org.apache.wicket.util.resource.locator.IResourceStreamLocator;
 import org.apache.wicket.util.time.Duration;
@@ -272,6 +273,20 @@ public interface IResourceSettings
        void setResourceWatcher(IModificationWatcher watcher);
 
        /**
+        * Sets a cleaner for the temporary files created by FileUpload 
functionality
+        * 
+        * @param fileUploadCleaner
+        *            the actual cleaner implementation. Can be 
<code>null</code>
+        */
+       void setFileUploadCleaner(IFileUploadCleaner fileUploadCleaner);
+
+       /**
+        * @return the cleaner for the temporary files created by FileUpload 
functionality. Can be
+        *         <code>null</code>
+        */
+       IFileUploadCleaner getFileUploadCleaner();
+
+       /**
         * @param throwExceptionOnMissingResource
         */
        void setThrowExceptionOnMissingResource(final boolean 
throwExceptionOnMissingResource);

Modified: 
wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/def/ResourceSettings.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/def/ResourceSettings.java?rev=1043182&r1=1043181&r2=1043182&view=diff
==============================================================================
--- 
wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/def/ResourceSettings.java
 (original)
+++ 
wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/def/ResourceSettings.java
 Tue Dec  7 19:53:29 2010
@@ -32,6 +32,7 @@ import org.apache.wicket.resource.loader
 import org.apache.wicket.resource.loader.PackageStringResourceLoader;
 import org.apache.wicket.resource.loader.ValidatorStringResourceLoader;
 import org.apache.wicket.settings.IResourceSettings;
+import org.apache.wicket.util.file.IFileUploadCleaner;
 import org.apache.wicket.util.file.IResourceFinder;
 import org.apache.wicket.util.file.IResourcePath;
 import org.apache.wicket.util.file.Path;
@@ -84,6 +85,9 @@ public class ResourceSettings implements
        /** ModificationWatcher to watch for changes in markup files */
        private IModificationWatcher resourceWatcher;
 
+       /** a cleaner for the temporary files created by FileUpload 
functionality */
+       private IFileUploadCleaner fileUploadCleaner;
+
        /** Chain of string resource loaders to use */
        private final List<IStringResourceLoader> stringResourceLoaders = 
Generics.newArrayList(4);
 
@@ -249,6 +253,16 @@ public class ResourceSettings implements
                resourceWatcher = watcher;
        }
 
+       public IFileUploadCleaner getFileUploadCleaner()
+       {
+               return fileUploadCleaner;
+       }
+
+       public void setFileUploadCleaner(IFileUploadCleaner fileUploadCleaner)
+       {
+               this.fileUploadCleaner = fileUploadCleaner;
+       }
+
        /**
         * @see 
org.apache.wicket.settings.IResourceSettings#getStringResourceLoaders()
         */

Modified: 
wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/FileUploadTest.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/FileUploadTest.java?rev=1043182&r1=1043181&r2=1043182&view=diff
==============================================================================
--- 
wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/FileUploadTest.java
 (original)
+++ 
wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/FileUploadTest.java
 Tue Dec  7 19:53:29 2010
@@ -21,6 +21,8 @@ import java.lang.reflect.Field;
 import java.util.List;
 
 import org.apache.wicket.WicketTestCase;
+import org.apache.wicket.util.file.FileUploadCleaner;
+import org.apache.wicket.util.file.IFileUploadCleaner;
 import org.apache.wicket.util.upload.DiskFileItemFactory;
 import org.apache.wicket.util.upload.FileItem;
 
@@ -50,8 +52,10 @@ public class FileUploadTest extends Wick
         */
        public void testGetInputStream() throws Exception
        {
-               FileItem fileItem = new 
DiskFileItemFactory().createItem("dummyFieldName", "text/java",
-                       false, "FileUploadTest.java");
+               IFileUploadCleaner fileUploadCleaner = new FileUploadCleaner();
+
+               FileItem fileItem = new 
DiskFileItemFactory(fileUploadCleaner).createItem("dummyFieldName",
+                       "text/java", false, "FileUploadTest.java");
                // Initialize the upload
                fileItem.getOutputStream();
 
@@ -90,6 +94,8 @@ public class FileUploadTest extends Wick
                inputStreams = (List)inputStreamsField.get(fileUpload);
 
                assertNull(inputStreams);
+
+               fileUploadCleaner.destroy();
        }
 
 }


Reply via email to