File D:\maven-qcr-plugin-testsunitaires\qcr4java\h2-1.3.170-sources\target\site\qc\lecode\util\CloseWatcher.java.html

1 /*
2 * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
3 * Version 1.0, and under the Eclipse Public License, Version 1.0
4 * (http://h2database.com/html/license.html).
5 * Initial Developer: H2 Group
6 * Iso8601:
7 * Initial Developer: Robert Rathsack (firstName dot lastName at gmx dot de)
8 */
9 package org.h2.util;
10
11 import java.io.Closeable;
12 import java.io.PrintWriter;
13 import java.io.StringWriter;
14 import java.lang.ref.PhantomReference;
15 import java.lang.ref.ReferenceQueue;
16 import java.util.Collections;
17 import java.util.HashSet;
18 import java.util.Set;
19
20 /**
21 * A phantom reference to watch for unclosed objects.
22 */
23 public class CloseWatcher extends PhantomReference<Object> {
24
25 /**
26 * The queue (might be set to null at any time).
27 */
28 private static ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
29
30 /**
31 * The reference set. Must keep it, otherwise the references are garbage
32 * collected first and thus never enqueued.
33 */
34 private static Set<CloseWatcher> refs = createSet();
35
36 /**
37 * The stack trace of when the object was created. It is converted to a
38 * string early on to avoid classloader problems (a classloader can't be
39 * garbage collected if there is a static reference to one of its classes).
40 */
41 private String openStackTrace;
42
43 /**
44 * The closeable object.
45 */
46 private Closeable closeable;
47
48 public CloseWatcher(Object referent, ReferenceQueue<Object> q, Closeable closeable) {
49 super(referent, q);
50 this.closeable = closeable;
51 }
52
53 private static Set<CloseWatcher> createSet() {
54 return Collections.synchronizedSet(new HashSet<CloseWatcher>());
55 }
56
57 /**
58 * Check for an collected object.
59 *
60 * @return the first watcher
61 */
62 public static CloseWatcher pollUnclosed() {
63 ReferenceQueue<Object> q = queue;
64 if (q == null) {
65 return null;
66 }
67 while (true) {
68 CloseWatcher cw = (CloseWatcher) q.poll();
69 if (cw == null) {
70 return null;
71 }
72 if (refs != null) {
73 refs.remove(cw);
74 }
75 if (cw.closeable != null) {
76 return cw;
77 }
78 }
79 }
80
81 /**
82 * Register an object. Before calling this method, pollUnclosed() should be
83 * called in a loop to remove old references.
84 *
85 * @param o the object
86 * @param closeable the object to close
87 * @param stackTrace whether the stack trace should be registered (this is
88 * relatively slow)
89 * @return the close watcher
90 */
91 public static CloseWatcher register(Object o, Closeable closeable, boolean stackTrace) {
92 ReferenceQueue<Object> q = queue;
93 if (q == null) {
94 q = new ReferenceQueue<Object>();
95 queue = q;
96 }
97 CloseWatcher cw = new CloseWatcher(o, q, closeable);
98 if (stackTrace) {
99 Exception e = new Exception("Open Stack Trace");
100 StringWriter s = new StringWriter();
101 e.printStackTrace(new PrintWriter(s));
102 cw.openStackTrace = s.toString();
103 }
104 if (refs == null) {
105 refs = createSet();
106 }
107 refs.add(cw);
108 return cw;
109 }
110
111 /**
112 * Unregister an object, so it is no longer tracked.
113 *
114 * @param w the reference
115 */
116 public static void unregister(CloseWatcher w) {
117 w.closeable = null;
118 refs.remove(w);
119 }
120
121 /**
122 * Get the open stack trace or null if none.
123 *
124 * @return the open stack trace
125 */
126 public String getOpenStackTrace() {
127 return openStackTrace;
128 }
129
130 public Closeable getCloseable() {
131 return closeable;
132 }
133
134 }
135