196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project/*
296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more
396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * contributor license agreements.  See the NOTICE file distributed with
496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * this work for additional information regarding copyright ownership.
596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0
696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * (the "License"); you may not use this file except in compliance with
796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * the License.  You may obtain a copy of the License at
844de127691c5e0d1479f1976c1d69d03ee21d94eTodd Kennedy *
996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
1044de127691c5e0d1479f1976c1d69d03ee21d94eTodd Kennedy *
1196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * See the License for the specific language governing permissions and
1596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * limitations under the License.
1696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */
1796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectpackage org.apache.commons.io;
1896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
1996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.io.File;
2096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.lang.ref.PhantomReference;
2196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.lang.ref.ReferenceQueue;
2296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.util.Collection;
2396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.util.Vector;
2496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
2596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project/**
2696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Keeps track of files awaiting deletion, and deletes them when an associated
2796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * marker object is reclaimed by the garbage collector.
2896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <p>
2996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * This utility creates a background thread to handle file deletion.
3096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Each file to be deleted is registered with a handler object.
3196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * When the handler object is garbage collected, the file is deleted.
3296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * <p>
3396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * In an environment with multiple class loaders (a servlet container, for
3496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * example), you should consider stopping the background thread if it is no
3596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * longer needed. This is done by invoking the method
3696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * {@link #exitWhenFinished}, typically in
3796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * {@link javax.servlet.ServletContextListener#contextDestroyed} or similar.
3896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project *
3996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @author Noel Bergman
4096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @author Martin Cooper
4196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @version $Id: FileCleaner.java 490987 2006-12-29 12:11:48Z scolebourne $
4296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */
4396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectpublic class FileCleaningTracker {
4496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
4596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Queue of <code>Tracker</code> instances being watched.
4696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
4744de127691c5e0d1479f1976c1d69d03ee21d94eTodd Kennedy    ReferenceQueue<Object> /* Tracker */ q = new ReferenceQueue<Object>();
4896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
4996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Collection of <code>Tracker</code> instances in existence.
5096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
5144de127691c5e0d1479f1976c1d69d03ee21d94eTodd Kennedy    final Collection<Tracker> /* Tracker */ trackers = new Vector<Tracker>();  // synchronized
5296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
5396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Whether to terminate the thread when the tracking is complete.
5496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
5596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    volatile boolean exitWhenFinished = false;
5696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
5796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * The thread that will clean up registered files.
5896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
5996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    Thread reaper;
6096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
6196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    //-----------------------------------------------------------------------
6296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
6396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Track the specified file, using the provided marker, deleting the file
6496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * when the marker instance is garbage collected.
6596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used.
6696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
6796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param file  the file to be tracked, not null
6896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param marker  the marker object used to track the file, not null
6996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @throws NullPointerException if the file is null
7096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
7196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public void track(File file, Object marker) {
7296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        track(file, marker, (FileDeleteStrategy) null);
7396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
7496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
7596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
7696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Track the specified file, using the provided marker, deleting the file
7796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * when the marker instance is garbage collected.
7896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * The speified deletion strategy is used.
7996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
8096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param file  the file to be tracked, not null
8196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param marker  the marker object used to track the file, not null
8296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param deleteStrategy  the strategy to delete the file, null means normal
8396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @throws NullPointerException if the file is null
8496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
8596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public void track(File file, Object marker, FileDeleteStrategy deleteStrategy) {
8696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        if (file == null) {
8796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            throw new NullPointerException("The file must not be null");
8896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
8996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        addTracker(file.getPath(), marker, deleteStrategy);
9096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
9196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
9296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
9396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Track the specified file, using the provided marker, deleting the file
9496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * when the marker instance is garbage collected.
9596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used.
9696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
9796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param path  the full path to the file to be tracked, not null
9896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param marker  the marker object used to track the file, not null
9996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @throws NullPointerException if the path is null
10096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
10196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public void track(String path, Object marker) {
10296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        track(path, marker, (FileDeleteStrategy) null);
10396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
10496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
10596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
10696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Track the specified file, using the provided marker, deleting the file
10796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * when the marker instance is garbage collected.
10896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * The speified deletion strategy is used.
10996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
11096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param path  the full path to the file to be tracked, not null
11196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param marker  the marker object used to track the file, not null
11296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param deleteStrategy  the strategy to delete the file, null means normal
11396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @throws NullPointerException if the path is null
11496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
11596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public void track(String path, Object marker, FileDeleteStrategy deleteStrategy) {
11696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        if (path == null) {
11796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            throw new NullPointerException("The path must not be null");
11896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
11996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        addTracker(path, marker, deleteStrategy);
12096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
12196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
12296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
12396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Adds a tracker to the list of trackers.
12444de127691c5e0d1479f1976c1d69d03ee21d94eTodd Kennedy     *
12596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param path  the full path to the file to be tracked, not null
12696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param marker  the marker object used to track the file, not null
12796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param deleteStrategy  the strategy to delete the file, null means normal
12896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
12996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private synchronized void addTracker(String path, Object marker, FileDeleteStrategy deleteStrategy) {
13096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // synchronized block protects reaper
13196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        if (exitWhenFinished) {
13296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            throw new IllegalStateException("No new trackers can be added once exitWhenFinished() is called");
13396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
13496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        if (reaper == null) {
13596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            reaper = new Reaper();
13696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            reaper.start();
13796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
13896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        trackers.add(new Tracker(path, deleteStrategy, marker, q));
13996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
14096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
14196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    //-----------------------------------------------------------------------
14296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
14396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Retrieve the number of files currently being tracked, and therefore
14496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * awaiting deletion.
14596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
14696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return the number of files being tracked
14796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
14896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public int getTrackCount() {
14996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return trackers.size();
15096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
15196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
15296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
15396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Call this method to cause the file cleaner thread to terminate when
15496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * there are no more objects being tracked for deletion.
15596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * <p>
15696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * In a simple environment, you don't need this method as the file cleaner
15796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * thread will simply exit when the JVM exits. In a more complex environment,
15896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * with multiple class loaders (such as an application server), you should be
15996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * aware that the file cleaner thread will continue running even if the class
16096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * loader it was started from terminates. This can consitute a memory leak.
16196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * <p>
16296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * For example, suppose that you have developed a web application, which
16396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * contains the commons-io jar file in your WEB-INF/lib directory. In other
16496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * words, the FileCleaner class is loaded through the class loader of your
16596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * web application. If the web application is terminated, but the servlet
16696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * container is still running, then the file cleaner thread will still exist,
16796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * posing a memory leak.
16896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * <p>
16996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * This method allows the thread to be terminated. Simply call this method
17096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * in the resource cleanup code, such as {@link javax.servlet.ServletContextListener#contextDestroyed}.
17196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * One called, no new objects can be tracked by the file cleaner.
17296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
17396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public synchronized void exitWhenFinished() {
17496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // synchronized block protects reaper
17596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        exitWhenFinished = true;
17696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        if (reaper != null) {
17796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            synchronized (reaper) {
17896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                reaper.interrupt();
17996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            }
18096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
18196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
18296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
18396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    //-----------------------------------------------------------------------
18496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
18596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * The reaper thread.
18696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
18796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private final class Reaper extends Thread {
18896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        /** Construct a new Reaper */
18996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        Reaper() {
19096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            super("File Reaper");
19196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            setPriority(Thread.MAX_PRIORITY);
19296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            setDaemon(true);
19396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
19496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
19596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        /**
19696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         * Run the reaper thread that will delete files as their associated
19796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         * marker objects are reclaimed by the garbage collector.
19896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         */
19944de127691c5e0d1479f1976c1d69d03ee21d94eTodd Kennedy        @Override
20096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        public void run() {
20196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            // thread exits when exitWhenFinished is true and there are no more tracked objects
20296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            while (exitWhenFinished == false || trackers.size() > 0) {
20396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                Tracker tracker = null;
20496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                try {
20596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                    // Wait for a tracker to remove.
20696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                    tracker = (Tracker) q.remove();
20796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                } catch (Exception e) {
20896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                    continue;
20996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                }
21096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                if (tracker != null) {
21196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                    tracker.delete();
21296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                    tracker.clear();
21396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                    trackers.remove(tracker);
21496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                }
21596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            }
21696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
21796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
21896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
21996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    //-----------------------------------------------------------------------
22096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
22196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Inner class which acts as the reference for a file pending deletion.
22296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
22344de127691c5e0d1479f1976c1d69d03ee21d94eTodd Kennedy    private static final class Tracker extends PhantomReference<Object> {
22496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
22596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        /**
22696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         * The full path to the file being tracked.
22796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         */
22896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        private final String path;
22996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        /**
23096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         * The strategy for deleting files.
23196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         */
23296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        private final FileDeleteStrategy deleteStrategy;
23396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
23496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        /**
23596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         * Constructs an instance of this class from the supplied parameters.
23696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         *
23796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         * @param path  the full path to the file to be tracked, not null
23896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         * @param deleteStrategy  the strategy to delete the file, null means normal
23996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         * @param marker  the marker object used to track the file, not null
24096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         * @param queue  the queue on to which the tracker will be pushed, not null
24196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         */
24244de127691c5e0d1479f1976c1d69d03ee21d94eTodd Kennedy        Tracker(String path, FileDeleteStrategy deleteStrategy, Object marker, ReferenceQueue<Object> queue) {
24396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            super(marker, queue);
24496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            this.path = path;
24596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            this.deleteStrategy = (deleteStrategy == null ? FileDeleteStrategy.NORMAL : deleteStrategy);
24696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
24796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
24896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        /**
24996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         * Deletes the file associated with this tracker instance.
25096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         *
25196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         * @return <code>true</code> if the file was deleted successfully;
25296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         *         <code>false</code> otherwise.
25396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         */
25496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        public boolean delete() {
25596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            return deleteStrategy.deleteQuietly(new File(path));
25696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
25796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
25896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
25996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project}
260