EMMA Coverage Report (generated Sun Mar 01 22:06:14 CET 2015)
[all classes][org.h2.util]

COVERAGE SUMMARY FOR SOURCE FILE [CloseWatcher.java]

nameclass, %method, %block, %line, %
CloseWatcher.java100% (1/1)100% (8/8)90%  (97/108)86%  (31/36)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class CloseWatcher100% (1/1)100% (8/8)90%  (97/108)86%  (31/36)
register (Object, Closeable, boolean): CloseWatcher 100% (1/1)83%  (40/48)79%  (11/14)
pollUnclosed (): CloseWatcher 100% (1/1)88%  (23/26)82%  (9/11)
<static initializer> 100% (1/1)100% (7/7)100% (2/2)
CloseWatcher (Object, ReferenceQueue, Closeable): void 100% (1/1)100% (8/8)100% (3/3)
createSet (): Set 100% (1/1)100% (5/5)100% (1/1)
getCloseable (): Closeable 100% (1/1)100% (3/3)100% (1/1)
getOpenStackTrace (): String 100% (1/1)100% (3/3)100% (1/1)
unregister (CloseWatcher): void 100% (1/1)100% (8/8)100% (3/3)

1/*
2 * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
3 * and the EPL 1.0 (http://h2database.com/html/license.html).
4 * Initial Developer: H2 Group
5 * Iso8601:
6 * Initial Developer: Robert Rathsack (firstName dot lastName at gmx dot de)
7 */
8package org.h2.util;
9 
10import java.io.Closeable;
11import java.io.PrintWriter;
12import java.io.StringWriter;
13import java.lang.ref.PhantomReference;
14import java.lang.ref.ReferenceQueue;
15import java.util.Collections;
16import java.util.HashSet;
17import java.util.Set;
18 
19/**
20 * A phantom reference to watch for unclosed objects.
21 */
22public class CloseWatcher extends PhantomReference<Object> {
23 
24    /**
25     * The queue (might be set to null at any time).
26     */
27    private static ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
28 
29    /**
30     * The reference set. Must keep it, otherwise the references are garbage
31     * collected first and thus never enqueued.
32     */
33    private static Set<CloseWatcher> refs = createSet();
34 
35    /**
36     * The stack trace of when the object was created. It is converted to a
37     * string early on to avoid classloader problems (a classloader can't be
38     * garbage collected if there is a static reference to one of its classes).
39     */
40    private String openStackTrace;
41 
42    /**
43     * The closeable object.
44     */
45    private Closeable closeable;
46 
47    public CloseWatcher(Object referent, ReferenceQueue<Object> q,
48            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,
92            boolean stackTrace) {
93        ReferenceQueue<Object> q = queue;
94        if (q == null) {
95            q = new ReferenceQueue<Object>();
96            queue = q;
97        }
98        CloseWatcher cw = new CloseWatcher(o, q, closeable);
99        if (stackTrace) {
100            Exception e = new Exception("Open Stack Trace");
101            StringWriter s = new StringWriter();
102            e.printStackTrace(new PrintWriter(s));
103            cw.openStackTrace = s.toString();
104        }
105        if (refs == null) {
106            refs = createSet();
107        }
108        refs.add(cw);
109        return cw;
110    }
111 
112    /**
113     * Unregister an object, so it is no longer tracked.
114     *
115     * @param w the reference
116     */
117    public static void unregister(CloseWatcher w) {
118        w.closeable = null;
119        refs.remove(w);
120    }
121 
122    /**
123     * Get the open stack trace or null if none.
124     *
125     * @return the open stack trace
126     */
127    public String getOpenStackTrace() {
128        return openStackTrace;
129    }
130 
131    public Closeable getCloseable() {
132        return closeable;
133    }
134 
135}

[all classes][org.h2.util]
EMMA 2.0.5312 (C) Vladimir Roubtsov