001: /*
002: * Copyright 2001-2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package wicket.util.file;
017:
018: import java.io.File;
019: import java.lang.ref.PhantomReference;
020: import java.lang.ref.ReferenceQueue;
021: import java.util.Collection;
022: import java.util.Vector;
023:
024: /**
025: * Keeps track of files awaiting deletion, and deletes them when an associated marker
026: * object is reclaimed by the garbage collector.
027: * @author Noel Bergman
028: * @author Martin Cooper
029: * @version $Id: FileCleaner.java 458651 2006-01-14 22:56:50Z jonl $
030: */
031: public class FileCleaner {
032: /**
033: * Queue of <code>Tracker</code> instances being watched.
034: */
035: private static ReferenceQueue /* Tracker */q = new ReferenceQueue();
036:
037: /**
038: * Collection of <code>Tracker</code> instances in existence.
039: */
040: private static Collection /* Tracker */trackers = new Vector();
041:
042: /**
043: * The thread that will clean up registered files.
044: */
045: private static Thread reaper = new Thread("File Reaper") {
046: /**
047: * Run the reaper thread that will delete files as their associated marker objects
048: * are reclaimed by the garbage collector.
049: */
050: public void run() {
051: for (;;) {
052: Tracker tracker = null;
053: try {
054: // Wait for a tracker to remove.
055: tracker = (Tracker) q.remove();
056: } catch (Exception e) {
057: continue;
058: }
059:
060: tracker.delete();
061: tracker.clear();
062: trackers.remove(tracker);
063: }
064: }
065: };
066:
067: /**
068: * The static initializer that starts the reaper thread.
069: */
070: static {
071: reaper.setPriority(Thread.MAX_PRIORITY);
072: reaper.setDaemon(true);
073: reaper.start();
074: }
075:
076: /**
077: * Track the specified file, using the provided marker, deleting the file when the
078: * marker instance is garbage collected.
079: * @param file The file to be tracked.
080: * @param marker The marker object used to track the file.
081: */
082: public static void track(File file, Object marker) {
083: trackers.add(new Tracker(file, marker, q));
084: }
085:
086: /**
087: * Track the specified file, using the provided marker, deleting the file when the
088: * marker instance is garbage collected.
089: * @param path The full path to the file to be tracked.
090: * @param marker The marker object used to track the file.
091: */
092: public static void track(String path, Object marker) {
093: trackers.add(new Tracker(path, marker, q));
094: }
095:
096: /**
097: * Retrieve the number of files currently being tracked, and therefore awaiting
098: * deletion.
099: * @return the number of files being tracked.
100: */
101: public static int getTrackCount() {
102: return trackers.size();
103: }
104:
105: /**
106: * Inner class which acts as the reference for a file pending deletion.
107: */
108: private static class Tracker extends PhantomReference {
109:
110: /**
111: * The full path to the file being tracked.
112: */
113: private String path;
114:
115: /**
116: * Constructs an instance of this class from the supplied parameters.
117: * @param file The file to be tracked.
118: * @param marker The marker object used to track the file.
119: * @param queue The queue on to which the tracker will be pushed.
120: */
121: public Tracker(File file, Object marker, ReferenceQueue queue) {
122: this (file.getPath(), marker, queue);
123: }
124:
125: /**
126: * Constructs an instance of this class from the supplied parameters.
127: * @param path The full path to the file to be tracked.
128: * @param marker The marker object used to track the file.
129: * @param queue The queue on to which the tracker will be pushed.
130: */
131: public Tracker(String path, Object marker, ReferenceQueue queue) {
132: super (marker, queue);
133: this .path = path;
134: }
135:
136: /**
137: * Deletes the file associated with this tracker instance.
138: * @return <code>true</code> if the file was deleted successfully;
139: * <code>false</code> otherwise.
140: */
141: public boolean delete() {
142: return new File(path).delete();
143: }
144: }
145: }
|