-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements. See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License. You may obtain a copy of the License at\r
- * \r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- * \r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.util.http.fileupload;\r
-\r
-import java.io.File;\r
-import java.lang.ref.PhantomReference;\r
-import java.lang.ref.ReferenceQueue;\r
-import java.util.Collection;\r
-import java.util.Vector;\r
-\r
-/**\r
- * Keeps track of files awaiting deletion, and deletes them when an associated\r
- * marker object is reclaimed by the garbage collector.\r
- * <p>\r
- * This utility creates a background thread to handle file deletion.\r
- * Each file to be deleted is registered with a handler object.\r
- * When the handler object is garbage collected, the file is deleted.\r
- * <p>\r
- * In an environment with multiple class loaders (a servlet container, for\r
- * example), you should consider stopping the background thread if it is no\r
- * longer needed. This is done by invoking the method\r
- * {@link #exitWhenFinished}, typically in\r
- * {@link javax.servlet.ServletContextListener#contextDestroyed} or similar.\r
- *\r
- * @author Noel Bergman\r
- * @author Martin Cooper\r
- * @version $Id: FileCleaner.java 490987 2006-12-29 12:11:48Z scolebourne $\r
- */\r
-public class FileCleaningTracker {\r
- /**\r
- * Queue of <code>Tracker</code> instances being watched.\r
- */\r
- ReferenceQueue /* Tracker */ q = new ReferenceQueue();\r
- /**\r
- * Collection of <code>Tracker</code> instances in existence.\r
- */\r
- final Collection<Tracker> trackers = new Vector<Tracker>(); // synchronized\r
- /**\r
- * Whether to terminate the thread when the tracking is complete.\r
- */\r
- volatile boolean exitWhenFinished = false;\r
- /**\r
- * The thread that will clean up registered files.\r
- */\r
- Thread reaper;\r
-\r
- //-----------------------------------------------------------------------\r
- /**\r
- * Track the specified file, using the provided marker, deleting the file\r
- * when the marker instance is garbage collected.\r
- * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used.\r
- *\r
- * @param file the file to be tracked, not null\r
- * @param marker the marker object used to track the file, not null\r
- * @throws NullPointerException if the file is null\r
- */\r
- public void track(File file, Object marker) {\r
- track(file, marker, (FileDeleteStrategy) null);\r
- }\r
-\r
- /**\r
- * Track the specified file, using the provided marker, deleting the file\r
- * when the marker instance is garbage collected.\r
- * The speified deletion strategy is used.\r
- *\r
- * @param file the file to be tracked, not null\r
- * @param marker the marker object used to track the file, not null\r
- * @param deleteStrategy the strategy to delete the file, null means normal\r
- * @throws NullPointerException if the file is null\r
- */\r
- public void track(File file, Object marker, FileDeleteStrategy deleteStrategy) {\r
- if (file == null) {\r
- throw new NullPointerException("The file must not be null");\r
- }\r
- addTracker(file.getPath(), marker, deleteStrategy);\r
- }\r
-\r
- /**\r
- * Track the specified file, using the provided marker, deleting the file\r
- * when the marker instance is garbage collected.\r
- * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used.\r
- *\r
- * @param path the full path to the file to be tracked, not null\r
- * @param marker the marker object used to track the file, not null\r
- * @throws NullPointerException if the path is null\r
- */\r
- public void track(String path, Object marker) {\r
- track(path, marker, (FileDeleteStrategy) null);\r
- }\r
-\r
- /**\r
- * Track the specified file, using the provided marker, deleting the file\r
- * when the marker instance is garbage collected.\r
- * The speified deletion strategy is used.\r
- *\r
- * @param path the full path to the file to be tracked, not null\r
- * @param marker the marker object used to track the file, not null\r
- * @param deleteStrategy the strategy to delete the file, null means normal\r
- * @throws NullPointerException if the path is null\r
- */\r
- public void track(String path, Object marker, FileDeleteStrategy deleteStrategy) {\r
- if (path == null) {\r
- throw new NullPointerException("The path must not be null");\r
- }\r
- addTracker(path, marker, deleteStrategy);\r
- }\r
-\r
- /**\r
- * Adds a tracker to the list of trackers.\r
- * \r
- * @param path the full path to the file to be tracked, not null\r
- * @param marker the marker object used to track the file, not null\r
- * @param deleteStrategy the strategy to delete the file, null means normal\r
- */\r
- private synchronized void addTracker(String path, Object marker, FileDeleteStrategy deleteStrategy) {\r
- // synchronized block protects reaper\r
- if (exitWhenFinished) {\r
- throw new IllegalStateException("No new trackers can be added once exitWhenFinished() is called");\r
- }\r
- if (reaper == null) {\r
- reaper = new Reaper();\r
- reaper.start();\r
- }\r
- trackers.add(new Tracker(path, deleteStrategy, marker, q));\r
- }\r
-\r
- //-----------------------------------------------------------------------\r
- /**\r
- * Retrieve the number of files currently being tracked, and therefore\r
- * awaiting deletion.\r
- *\r
- * @return the number of files being tracked\r
- */\r
- public int getTrackCount() {\r
- return trackers.size();\r
- }\r
-\r
- /**\r
- * Call this method to cause the file cleaner thread to terminate when\r
- * there are no more objects being tracked for deletion.\r
- * <p>\r
- * In a simple environment, you don't need this method as the file cleaner\r
- * thread will simply exit when the JVM exits. In a more complex environment,\r
- * with multiple class loaders (such as an application server), you should be\r
- * aware that the file cleaner thread will continue running even if the class\r
- * loader it was started from terminates. This can consitute a memory leak.\r
- * <p>\r
- * For example, suppose that you have developed a web application, which\r
- * contains the commons-io jar file in your WEB-INF/lib directory. In other\r
- * words, the FileCleaner class is loaded through the class loader of your\r
- * web application. If the web application is terminated, but the servlet\r
- * container is still running, then the file cleaner thread will still exist,\r
- * posing a memory leak.\r
- * <p>\r
- * This method allows the thread to be terminated. Simply call this method\r
- * in the resource cleanup code, such as {@link javax.servlet.ServletContextListener#contextDestroyed}.\r
- * One called, no new objects can be tracked by the file cleaner.\r
- */\r
- public synchronized void exitWhenFinished() {\r
- // synchronized block protects reaper\r
- exitWhenFinished = true;\r
- if (reaper != null) {\r
- synchronized (reaper) {\r
- reaper.interrupt();\r
- }\r
- }\r
- }\r
-\r
- //-----------------------------------------------------------------------\r
- /**\r
- * The reaper thread.\r
- */\r
- private final class Reaper extends Thread {\r
- /** Construct a new Reaper */\r
- Reaper() {\r
- super("File Reaper");\r
- setPriority(Thread.MAX_PRIORITY);\r
- setDaemon(true);\r
- }\r
-\r
- /**\r
- * Run the reaper thread that will delete files as their associated\r
- * marker objects are reclaimed by the garbage collector.\r
- */\r
- @Override\r
- public void run() {\r
- // thread exits when exitWhenFinished is true and there are no more tracked objects\r
- while (exitWhenFinished == false || trackers.size() > 0) {\r
- Tracker tracker = null;\r
- try {\r
- // Wait for a tracker to remove.\r
- tracker = (Tracker) q.remove();\r
- } catch (Exception e) {\r
- continue;\r
- }\r
- if (tracker != null) {\r
- tracker.delete();\r
- tracker.clear();\r
- trackers.remove(tracker);\r
- }\r
- }\r
- }\r
- }\r
-\r
- //-----------------------------------------------------------------------\r
- /**\r
- * Inner class which acts as the reference for a file pending deletion.\r
- */\r
- private static final class Tracker extends PhantomReference {\r
-\r
- /**\r
- * The full path to the file being tracked.\r
- */\r
- private final String path;\r
- /**\r
- * The strategy for deleting files.\r
- */\r
- private final FileDeleteStrategy deleteStrategy;\r
-\r
- /**\r
- * Constructs an instance of this class from the supplied parameters.\r
- *\r
- * @param path the full path to the file to be tracked, not null\r
- * @param deleteStrategy the strategy to delete the file, null means normal\r
- * @param marker the marker object used to track the file, not null\r
- * @param queue the queue on to which the tracker will be pushed, not null\r
- */\r
- Tracker(String path, FileDeleteStrategy deleteStrategy, Object marker, ReferenceQueue queue) {\r
- super(marker, queue);\r
- this.path = path;\r
- this.deleteStrategy = (deleteStrategy == null ? FileDeleteStrategy.NORMAL : deleteStrategy);\r
- }\r
-\r
- /**\r
- * Deletes the file associated with this tracker instance.\r
- *\r
- * @return <code>true</code> if the file was deleted successfully;\r
- * <code>false</code> otherwise.\r
- */\r
- public boolean delete() {\r
- return deleteStrategy.deleteQuietly(new File(path));\r
- }\r
- }\r
-\r
-}\r
+/*
+ * 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.tomcat.util.http.fileupload;
+
+import java.io.File;
+import java.lang.ref.PhantomReference;
+import java.lang.ref.ReferenceQueue;
+import java.util.Collection;
+import java.util.Vector;
+
+/**
+ * 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: FileCleaner.java 490987 2006-12-29 12:11:48Z scolebourne $
+ */
+public class FileCleaningTracker {
+ /**
+ * Queue of <code>Tracker</code> instances being watched.
+ */
+ ReferenceQueue /* Tracker */ q = new ReferenceQueue();
+ /**
+ * Collection of <code>Tracker</code> instances in existence.
+ */
+ final Collection<Tracker> trackers = new Vector<Tracker>(); // synchronized
+ /**
+ * 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();
+ }
+
+ /**
+ * 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}.
+ * One 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) {
+ Tracker tracker = null;
+ try {
+ // Wait for a tracker to remove.
+ tracker = (Tracker) q.remove();
+ } catch (Exception e) {
+ continue;
+ }
+ if (tracker != null) {
+ tracker.delete();
+ tracker.clear();
+ trackers.remove(tracker);
+ }
+ }
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Inner class which acts as the reference for a file pending deletion.
+ */
+ private static final class Tracker extends PhantomReference {
+
+ /**
+ * 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 queue) {
+ super(marker, queue);
+ this.path = path;
+ this.deleteStrategy = (deleteStrategy == null ? FileDeleteStrategy.NORMAL : deleteStrategy);
+ }
+
+ /**
+ * 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));
+ }
+ }
+
+}
-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements. See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License. You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.util.http.fileupload;\r
-\r
-import java.util.Iterator;\r
-\r
-/**\r
- * <p> This class provides support for accessing the headers for a file or form\r
- * item that was received within a <code>multipart/form-data</code> POST\r
- * request.</p>\r
- *\r
- * @author Michael C. Macaluso\r
- * @since 1.3\r
- */\r
-public interface FileItemHeaders {\r
- /**\r
- * Returns the value of the specified part header as a <code>String</code>.\r
- * If the part did not include a header of the specified name, this method\r
- * return <code>null</code>. If there are multiple headers with the same\r
- * name, this method returns the first header in the item. The header\r
- * name is case insensitive.\r
- *\r
- * @param name a <code>String</code> specifying the header name\r
- * @return a <code>String</code> containing the value of the requested\r
- * header, or <code>null</code> if the item does not have a header\r
- * of that name\r
- */\r
- String getHeader(String name);\r
-\r
- /**\r
- * <p>\r
- * Returns all the values of the specified item header as an\r
- * <code>Enumeration</code> of <code>String</code> objects.\r
- * </p>\r
- * <p>\r
- * If the item did not include any headers of the specified name, this\r
- * method returns an empty <code>Enumeration</code>. The header name is\r
- * case insensitive.\r
- * </p>\r
- *\r
- * @param name a <code>String</code> specifying the header name\r
- * @return an <code>Enumeration</code> containing the values of the\r
- * requested header. If the item does not have any headers of\r
- * that name, return an empty <code>Enumeration</code>\r
- */\r
- Iterator<String> getHeaders(String name);\r
-\r
- /**\r
- * <p>\r
- * Returns an <code>Enumeration</code> of all the header names.\r
- * </p>\r
- * <p>\r
- * If the item did not include any headers of the specified name, this\r
- * method returns an empty <code>Enumeration</code>. The header name is\r
- * case insensitive.\r
- * </p>\r
- *\r
- * @return an <code>Enumeration</code> containing the values of the\r
- * requested header. If the item does not have any headers of\r
- * that name return an empty <code>Enumeration</code>\r
- */\r
- Iterator<String> getHeaderNames();\r
-}\r
+/*
+ * 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.tomcat.util.http.fileupload;
+
+import java.util.Iterator;
+
+/**
+ * <p> This class provides support for accessing the headers for a file or form
+ * item that was received within a <code>multipart/form-data</code> POST
+ * request.</p>
+ *
+ * @author Michael C. Macaluso
+ * @since 1.3
+ */
+public interface FileItemHeaders {
+ /**
+ * Returns the value of the specified part header as a <code>String</code>.
+ * If the part did not include a header of the specified name, this method
+ * return <code>null</code>. If there are multiple headers with the same
+ * name, this method returns the first header in the item. The header
+ * name is case insensitive.
+ *
+ * @param name a <code>String</code> specifying the header name
+ * @return a <code>String</code> containing the value of the requested
+ * header, or <code>null</code> if the item does not have a header
+ * of that name
+ */
+ String getHeader(String name);
+
+ /**
+ * <p>
+ * Returns all the values of the specified item header as an
+ * <code>Enumeration</code> of <code>String</code> objects.
+ * </p>
+ * <p>
+ * If the item did not include any headers of the specified name, this
+ * method returns an empty <code>Enumeration</code>. The header name is
+ * case insensitive.
+ * </p>
+ *
+ * @param name a <code>String</code> specifying the header name
+ * @return an <code>Enumeration</code> containing the values of the
+ * requested header. If the item does not have any headers of
+ * that name, return an empty <code>Enumeration</code>
+ */
+ Iterator<String> getHeaders(String name);
+
+ /**
+ * <p>
+ * Returns an <code>Enumeration</code> of all the header names.
+ * </p>
+ * <p>
+ * If the item did not include any headers of the specified name, this
+ * method returns an empty <code>Enumeration</code>. The header name is
+ * case insensitive.
+ * </p>
+ *
+ * @return an <code>Enumeration</code> containing the values of the
+ * requested header. If the item does not have any headers of
+ * that name return an empty <code>Enumeration</code>
+ */
+ Iterator<String> getHeaderNames();
+}