1bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/*
2bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Licensed to the Apache Software Foundation (ASF) under one or more
3bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * contributor license agreements.  See the NOTICE file distributed with
4bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * this work for additional information regarding copyright ownership.
5bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * The ASF licenses this file to You under the Apache License, Version 2.0
6bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * (the "License"); you may not use this file except in compliance with
7bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * the License.  You may obtain a copy of the License at
8bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *
9bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *      http://www.apache.org/licenses/LICENSE-2.0
10bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *
11bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Unless required by applicable law or agreed to in writing, software
12bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * distributed under the License is distributed on an "AS IS" BASIS,
13bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * See the License for the specific language governing permissions and
15bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * limitations under the License.
16bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */
17bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookpackage org.apache.commons.io;
18bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
19bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.File;
20bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
21bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/**
22bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Keeps track of files awaiting deletion, and deletes them when an associated
23bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * marker object is reclaimed by the garbage collector.
24bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p>
25bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * This utility creates a background thread to handle file deletion.
26bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Each file to be deleted is registered with a handler object.
27bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * When the handler object is garbage collected, the file is deleted.
28bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p>
29bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * In an environment with multiple class loaders (a servlet container, for
30bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * example), you should consider stopping the background thread if it is no
31bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * longer needed. This is done by invoking the method
32bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * {@link #exitWhenFinished}, typically in
33bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * {@link javax.servlet.ServletContextListener#contextDestroyed} or similar.
34bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *
35bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @author Noel Bergman
36bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @author Martin Cooper
37bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @version $Id: FileCleaner.java 553012 2007-07-03 23:01:07Z ggregory $
38bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @deprecated Use {@link FileCleaningTracker}
39bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */
40bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookpublic class FileCleaner {
41bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
42bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * The instance to use for the deprecated, static methods.
43bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
44bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    static final FileCleaningTracker theInstance = new FileCleaningTracker();
45bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
46bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    //-----------------------------------------------------------------------
47bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
48bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Track the specified file, using the provided marker, deleting the file
49bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * when the marker instance is garbage collected.
50bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used.
51bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
52bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param file  the file to be tracked, not null
53bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param marker  the marker object used to track the file, not null
54bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws NullPointerException if the file is null
55bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @deprecated Use {@link FileCleaningTracker#track(File, Object)}.
56bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
57bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public static void track(File file, Object marker) {
58bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        theInstance.track(file, marker);
59bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
60bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
61bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
62bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Track the specified file, using the provided marker, deleting the file
63bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * when the marker instance is garbage collected.
64bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * The speified deletion strategy is used.
65bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
66bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param file  the file to be tracked, not null
67bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param marker  the marker object used to track the file, not null
68bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param deleteStrategy  the strategy to delete the file, null means normal
69bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws NullPointerException if the file is null
70bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @deprecated Use {@link FileCleaningTracker#track(File, Object, FileDeleteStrategy)}.
71bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
72bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public static void track(File file, Object marker, FileDeleteStrategy deleteStrategy) {
73bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        theInstance.track(file, marker, deleteStrategy);
74bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
75bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
76bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
77bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Track the specified file, using the provided marker, deleting the file
78bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * when the marker instance is garbage collected.
79bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used.
80bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
81bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param path  the full path to the file to be tracked, not null
82bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param marker  the marker object used to track the file, not null
83bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws NullPointerException if the path is null
84bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @deprecated Use {@link FileCleaningTracker#track(String, Object)}.
85bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
86bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public static void track(String path, Object marker) {
87bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        theInstance.track(path, marker);
88bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
89bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
90bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
91bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Track the specified file, using the provided marker, deleting the file
92bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * when the marker instance is garbage collected.
93bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * The speified deletion strategy is used.
94bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
95bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param path  the full path to the file to be tracked, not null
96bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param marker  the marker object used to track the file, not null
97bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param deleteStrategy  the strategy to delete the file, null means normal
98bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws NullPointerException if the path is null
99bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @deprecated Use {@link FileCleaningTracker#track(String, Object, FileDeleteStrategy)}.
100bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
101bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public static void track(String path, Object marker, FileDeleteStrategy deleteStrategy) {
102bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        theInstance.track(path, marker, deleteStrategy);
103bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
104bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
105bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    //-----------------------------------------------------------------------
106bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
107bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Retrieve the number of files currently being tracked, and therefore
108bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * awaiting deletion.
109bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
110bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @return the number of files being tracked
111bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @deprecated Use {@link FileCleaningTracker#getTrackCount()}.
112bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
113bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public static int getTrackCount() {
114bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        return theInstance.getTrackCount();
115bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
116bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
117bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
118bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Call this method to cause the file cleaner thread to terminate when
119bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * there are no more objects being tracked for deletion.
120bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <p>
121bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * In a simple environment, you don't need this method as the file cleaner
122bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * thread will simply exit when the JVM exits. In a more complex environment,
123bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * with multiple class loaders (such as an application server), you should be
124bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * aware that the file cleaner thread will continue running even if the class
125bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * loader it was started from terminates. This can consitute a memory leak.
126bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <p>
127bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * For example, suppose that you have developed a web application, which
128bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * contains the commons-io jar file in your WEB-INF/lib directory. In other
129bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * words, the FileCleaner class is loaded through the class loader of your
130bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * web application. If the web application is terminated, but the servlet
131bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * container is still running, then the file cleaner thread will still exist,
132bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * posing a memory leak.
133bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <p>
134bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * This method allows the thread to be terminated. Simply call this method
135bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * in the resource cleanup code, such as {@link javax.servlet.ServletContextListener#contextDestroyed}.
136bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * One called, no new objects can be tracked by the file cleaner.
137bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @deprecated Use {@link FileCleaningTracker#exitWhenFinished()}.
138bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
139bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public static synchronized void exitWhenFinished() {
140bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        theInstance.exitWhenFinished();
141bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
142bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
143bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
144bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Returns the singleton instance, which is used by the deprecated, static methods.
145bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * This is mainly useful for code, which wants to support the new
146bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * {@link FileCleaningTracker} class while maintain compatibility with the
147bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * deprecated {@link FileCleaner}.
148bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
149bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @return the singleton instance
150bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
151bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public static FileCleaningTracker getInstance() {
152bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        return theInstance;
153bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
154bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook}
155