1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package org.apache.harmony.luni.util;
19
20
21import java.io.File;
22import java.util.ArrayList;
23import java.util.Collections;
24
25/**
26 * Implements the actual DeleteOnExit mechanism. Is registered as a shutdown
27 * hook in the Runtime, once it is actually being used.
28 */
29public class DeleteOnExit extends Thread {
30
31    /**
32     * Our singleton instance.
33     */
34    private static DeleteOnExit instance;
35
36    /**
37     * Our list of files scheduled for deletion.
38     */
39    private ArrayList<String> files = new ArrayList<String>();
40
41    /**
42     * Returns our singleton instance, creating it if necessary.
43     */
44    public static synchronized DeleteOnExit getInstance() {
45        if (instance == null) {
46            instance = new DeleteOnExit();
47            Runtime.getRuntime().addShutdownHook(instance);
48        }
49
50        return instance;
51    }
52
53    /**
54     * Schedules a file for deletion.
55     *
56     * @param filename The file to delete.
57     */
58    public void addFile(String filename) {
59        synchronized(files) {
60            if (!files.contains(filename)) {
61                files.add(filename);
62            }
63        }
64    }
65
66    /**
67     * Does the actual work. Note we (a) first sort the files lexicographically
68     * and then (b) delete them in reverse order. This is to make sure files
69     * get deleted before their parent directories.
70     */
71    @Override
72    public void run() {
73        Collections.sort(files);
74        for (int i = files.size() - 1; i >= 0; i--) {
75            new File(files.get(i)).delete();
76        }
77    }
78}
79