1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.archive.io;
23
24 import java.util.Iterator;
25 import java.util.Vector;
26 import java.util.logging.Handler;
27 import java.util.logging.Level;
28 import java.util.logging.LogManager;
29 import java.util.logging.LogRecord;
30 import java.util.logging.Logger;
31
32
33
34 /***
35 * A handler that keeps an in-memory vector of all events deemed loggable by
36 * configuration.
37 * Use it to iterate over logged events long after their occurance. One such
38 * use is as a sink for WARNING+SEVERE loggable events. Has support for
39 * whether a log record has been already-read.
40 * TODO: Add being able to get LogRecords by log level: i.e. return all
41 * Level.SEVERE, etc.
42 * TODO: Back the vector with a bdbje collection.
43 * @author stack
44 * @version $Date: 2006-09-22 17:23:04 +0000 (Fri, 22 Sep 2006) $ $Revision: 4646 $
45 */
46 public class SinkHandler extends Handler {
47 /***
48 * Alerts that have occured.
49 */
50 private Vector<SinkHandlerLogRecord> sink
51 = new Vector<SinkHandlerLogRecord>();
52
53 public SinkHandler() {
54 LogManager manager = LogManager.getLogManager();
55 String className = getClass().getName();
56 String tmp = manager.getProperty(className + ".level");
57 if (tmp != null) {
58 setLevel(Level.parse(tmp));
59 }
60 }
61
62 public void publish(LogRecord record) {
63 if (!isLoggable(record)) {
64 return;
65 }
66 this.sink.add(new SinkHandlerLogRecord(record));
67 }
68
69 public void flush() {
70
71 }
72
73 public void close() throws SecurityException {
74 flush();
75 }
76
77 /***
78 * @return SinkHandler instance if one registered or null.
79 */
80 public static SinkHandler getInstance() {
81 SinkHandler h = null;
82 Handler[] handlers = Logger.getLogger("").getHandlers();
83 for (int i = 0; i < handlers.length; i++) {
84 if (handlers[i] instanceof SinkHandler) {
85 h = (SinkHandler) handlers[i];
86 break;
87 }
88 }
89 if (h == null) {
90
91
92
93 h = new SinkHandler();
94 h.setLevel(Level.WARNING);
95 Logger.getLogger("").addHandler(h);
96 }
97 return h;
98 }
99
100 /***
101 * @return all SinkHandlerLogRecords.
102 */
103 public Vector getAll() {
104 return this.sink;
105 }
106
107 /***
108 * @return Return all unread SinkHandlerLogRecords or null if none unread
109 */
110 public Vector<SinkHandlerLogRecord> getAllUnread() {
111 if (this.sink == null) {
112 return null;
113 }
114 Vector<SinkHandlerLogRecord> newLogRecords;
115 newLogRecords = new Vector<SinkHandlerLogRecord>();
116 for (final Iterator i = this.sink.iterator(); i.hasNext();) {
117 SinkHandlerLogRecord lr = (SinkHandlerLogRecord) i.next();
118 if (!lr.isRead()) {
119 newLogRecords.add(lr);
120 }
121 }
122 return (newLogRecords.size() == 0) ? null : newLogRecords;
123 }
124
125 /***
126 * @return Count of all records.
127 */
128 public int getCount() {
129 return this.sink != null? this.sink.size(): 0;
130 }
131
132 /***
133 * @return The count of unread log records.
134 */
135 public int getUnreadCount() {
136 if (this.sink == null) {
137 return 0;
138 }
139 int n = 0;
140 for (final Iterator i = this.sink.iterator(); i.hasNext();) {
141 SinkHandlerLogRecord lr = (SinkHandlerLogRecord)i.next();
142 if (!lr.isRead()) {
143 n++;
144 }
145 }
146 return n;
147 }
148
149 /***
150 * @param id The <code>sequenceNumber</code> ID of the log record to find.
151 * @return A SinkHandlerLogRecord of the given ID or null if not found.
152 */
153 public SinkHandlerLogRecord get(long id) {
154 if (this.sink == null) {
155 return null;
156 }
157 for (final Iterator i = this.sink.iterator(); i.hasNext();) {
158 SinkHandlerLogRecord lr = (SinkHandlerLogRecord)i.next();
159 if (lr.getSequenceNumber() == id) {
160 return lr;
161 }
162 }
163 return null;
164 }
165
166 /***
167 * @param id The <code>sequenceNumber</code> ID of the log record to find.
168 * @return The removed SinkHandlerLogRecord or null if none removed.
169 */
170 public SinkHandlerLogRecord remove(final long id) {
171 SinkHandlerLogRecord shlr = null;
172 if (this.sink == null) {
173 return shlr;
174 }
175 for (final Iterator i = this.sink.iterator(); i.hasNext();) {
176 SinkHandlerLogRecord lr = (SinkHandlerLogRecord)i.next();
177 if (lr.getSequenceNumber() == id) {
178 i.remove();
179 shlr = lr;
180 break;
181 }
182 }
183 return shlr;
184 }
185
186 /***
187 * @param id The <code>sequenceNumber</code> ID of the log record to find
188 * and mark as read.
189 */
190 public void read(final long id) {
191 for (final Iterator i = this.sink.iterator(); i.hasNext();) {
192 SinkHandlerLogRecord lr = (SinkHandlerLogRecord)i.next();
193 if (lr.getSequenceNumber() == id) {
194 lr.setRead();
195 break;
196 }
197 }
198 }
199 }