01: // Copyright (c) 2001 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 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 WriterManager instance = new WriterManager();
17:
18: Writer[] ports;
19: int[] freeList;
20: int freeListHead = -1;
21:
22: public synchronized int register(Writer port) {
23: if (freeListHead < 0) {
24: int oldSize, newSize;
25: if (ports == null) {
26: oldSize = 0;
27: newSize = 20;
28: } else {
29: oldSize = ports.length;
30: newSize = 2 * oldSize;
31: }
32: int[] newFreeList = new int[newSize];
33: Writer[] newPorts = new Writer[newSize];
34: if (oldSize > 0) {
35: System.arraycopy(ports, 0, newPorts, 0, oldSize);
36: System.arraycopy(freeList, 0, newFreeList, 0, oldSize);
37: }
38: for (int i = oldSize; i < newSize; i++) {
39: newFreeList[i] = freeListHead;
40: freeListHead = i;
41: }
42: ports = newPorts;
43: freeList = newFreeList;
44: }
45: int index = freeListHead;
46: ports[index] = port;
47: freeListHead = freeList[index];
48: freeList[index] = -2;
49: return index;
50: }
51:
52: public synchronized void unregister(int index) {
53: ports[index] = null;
54: freeList[index] = freeListHead;
55: freeListHead = index;
56: }
57:
58: public void run() {
59: if (ports == null)
60: return;
61: for (int i = ports.length; --i >= 0;) {
62: Writer port = ports[i];
63: try {
64: if (port != null)
65: port.close();
66: } catch (Exception ex) {
67: // ignore
68: }
69: }
70: }
71:
72: /** Try to register this as a shutdown hook.
73: * @return true on success; false if failure (e.g. if not JDK1.3-compatible).
74: */
75: public boolean registerShutdownHook() {
76: try {
77: Runtime runtime = Runtime.getRuntime();
78: Class rclass = runtime.getClass();
79: Class[] params = { Thread.class };
80: java.lang.reflect.Method method = rclass.getDeclaredMethod(
81: "addShutdownHook", params);
82: Object[] args = { new Thread(this ) };
83: method.invoke(runtime, args);
84: return true;
85: } catch (Throwable ex) {
86: return false;
87: }
88: }
89: }
|