01: // Copyright (c) 2001, 2006 Per M.A. Bothner.
02: // This is free software; for terms and warranty disclaimer see ./COPYING.
03:
04: package gnu.text;
05:
06: import java.io.*;
07:
08: /** Manages a collection of Writers, handling automatic closing.
09: * This class is useful for making sure that a Writer is closed (and its
10: * buffers flushed) when a VM exits.
11: * A WriterManager can be usefully passed to the JDK 1.3 method
12: * addShutdownHook in Runtime.
13: */
14:
15: public class WriterManager implements Runnable {
16: public static final WriterManager instance = new WriterManager();
17:
18: WriterRef first;
19:
20: /** Register a Writer.
21: * @return an object that can be passed to {@link #unregister}.
22: */
23: public synchronized WriterRef register(Writer port) {
24: WriterRef ref = new WriterRef(port);
25: WriterRef first = this .first; // Copy field to local variable.
26: if (first != null) {
27: ref.next = first.next;
28: first.prev = ref;
29: }
30: this .first = ref;
31: return ref;
32: }
33:
34: /** Unregister a Writer.
35: * @param key the object returned by the correspodning {@link #register}.
36: */
37: public synchronized void unregister(Object key) {
38: if (key == null)
39: return;
40: WriterRef ref = (WriterRef) key;
41: WriterRef next = ref.next;
42: WriterRef prev = ref.prev;
43: if (next != null)
44: next.prev = prev;
45: if (prev != null)
46: prev.next = next;
47: if (ref == first)
48: first = next;
49: }
50:
51: public synchronized void run() {
52: for (WriterRef ref = first; ref != null; ref = ref.next) {
53: Object port = ref.get();
54: if (port != null) {
55: try {
56: ((Writer) port).close();
57: } catch (Exception ex) {
58: // ignore
59: }
60: }
61: }
62: first = null;
63: }
64:
65: /** Try to register this as a shutdown hook.
66: * @return true on success; false if failure (e.g. if not JDK1.3-compatible).
67: */
68: public boolean registerShutdownHook() {
69: try {
70: Runtime runtime = Runtime.getRuntime();
71: Class rclass = runtime.getClass();
72: Class[] params = { Thread.class };
73: java.lang.reflect.Method method = rclass.getDeclaredMethod(
74: "addShutdownHook", params);
75: Object[] args = { new Thread(this ) };
76: method.invoke(runtime, args);
77: return true;
78: } catch (Throwable ex) {
79: return false;
80: }
81: }
82: }
83:
84: class WriterRef
85: /* #ifdef JAVA2 */
86: extends java.lang.ref.WeakReference
87: /* #endif */
88: {
89: WriterRef next;
90: WriterRef prev;
91:
92: public WriterRef(Writer wr) {
93: super(wr);
94: }
95: }
|