2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libjava / java / util / logging / MemoryHandler.java
blob825a6fa86d648cb934c93c338db2baa6cfd2a34e
1 /* MemoryHandler.java
2 -- a class for buffering log messages in a memory buffer
4 Copyright (C) 2002 Free Software Foundation, Inc.
6 This file is part of GNU Classpath.
8 GNU Classpath is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GNU Classpath is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Classpath; see the file COPYING. If not, write to the
20 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 02111-1307 USA.
23 Linking this library statically or dynamically with other modules is
24 making a combined work based on this library. Thus, the terms and
25 conditions of the GNU General Public License cover the whole
26 combination.
28 As a special exception, the copyright holders of this library give you
29 permission to link this library with independent modules to produce an
30 executable, regardless of the license terms of these independent
31 modules, and to copy and distribute the resulting executable under
32 terms of your choice, provided that you also meet, for each linked
33 independent module, the terms and conditions of the license of that
34 module. An independent module is a module which is not derived from
35 or based on this library. If you modify this library, you may extend
36 this exception to your version of the library, but you are not
37 obligated to do so. If you do not wish to do so, delete this
38 exception statement from your version.
43 package java.util.logging;
45 /**
46 * A <code>MemoryHandler</code> maintains a circular buffer of
47 * log records.
49 * <p><strong>Configuration:</strong> Values of the subsequent
50 * <code>LogManager</code> properties are taken into consideration
51 * when a <code>MemoryHandler</code> is initialized.
52 * If a property is not defined, or if it has an invalid
53 * value, a default is taken without an exception being thrown.
55 * <ul>
57 * <li><code>java.util.MemoryHandler.level</code> - specifies
58 * the initial severity level threshold. Default value:
59 * <code>Level.ALL</code>.</li>
61 * <li><code>java.util.MemoryHandler.filter</code> - specifies
62 * the name of a Filter class. Default value: No Filter.</li>
64 * <li><code>java.util.MemoryHandler.size</code> - specifies the
65 * maximum number of log records that are kept in the circular
66 * buffer. Default value: 1000.</li>
68 * <li><code>java.util.MemoryHandler.push</code> - specifies the
69 * <code>pushLevel</code>. Default value:
70 * <code>Level.SEVERE</code>.</li>
72 * <li><code>java.util.MemoryHandler.target</code> - specifies the
73 * name of a subclass of {@link Handler} that will be used as the
74 * target handler. There is no default value for this property;
75 * if it is not set, the no-argument MemoryHandler constructor
76 * will throw an exception.</li>
78 * </ul>
80 * @author Sascha Brawer (brawer@acm.org)
82 public class MemoryHandler
83 extends Handler
85 /**
86 * The storage area used for buffering the unpushed log records in
87 * memory.
89 private final LogRecord[] buffer;
92 /**
93 * The current position in the circular buffer. For a new
94 * MemoryHandler, or immediately after {@link #push()} was called,
95 * the value of this variable is zero. Each call to {@link
96 * #publish(LogRecord)} will store the published LogRecord into
97 * <code>buffer[position]</code> before position is incremented by
98 * one. If position becomes greater than the size of the buffer, it
99 * is reset to zero.
101 private int position;
105 * The number of log records which have been published, but not
106 * pushed yet to the target handler.
108 private int numPublished;
112 * The push level threshold for this <code>Handler</code>. When a
113 * record is published whose severity level is greater than or equal
114 * to the <code>pushLevel</code> of this <code>MemoryHandler</code>,
115 * the {@link #push()} method will be invoked for pushing the buffer
116 * contents to the target <code>Handler</code>.
118 private Level pushLevel;
122 * The Handler to which log records are forwarded for actual
123 * publication.
125 private final Handler target;
129 * Constructs a <code>MemoryHandler</code> for keeping a circular
130 * buffer of LogRecords; the initial configuration is determined by
131 * the <code>LogManager</code> properties described above.
133 public MemoryHandler()
135 this((Handler) LogManager.getInstanceProperty(
136 "java.util.logging.MemoryHandler.target",
137 Handler.class, /* default */ null),
138 LogManager.getIntPropertyClamped(
139 "java.util.logging.MemoryHandler.size",
140 /* default */ 1000,
141 /* minimum value */ 1,
142 /* maximum value */ Integer.MAX_VALUE),
143 LogManager.getLevelProperty(
144 "java.util.logging.MemoryHandler.push",
145 /* default push level */ Level.SEVERE));
150 * Constructs a <code>MemoryHandler</code> for keeping a circular
151 * buffer of LogRecords, given some parameters. The values of the
152 * other parameters are taken from LogManager properties, as
153 * described above.
155 * @param target the target handler that will receive those
156 * log records that are passed on for publication.
158 * @param size the number of log records that are kept in the buffer.
159 * The value must be a at least one.
161 * @param pushLevel the push level threshold for this
162 * <code>MemoryHandler</code>. When a record is published whose
163 * severity level is greater than or equal to
164 * <code>pushLevel</code>, the {@link #push()} method will be
165 * invoked in order to push the bufffer contents to
166 * <code>target</code>.
168 * @throws java.lang.IllegalArgumentException if <code>size</code>
169 * is negative or zero. The GNU implementation also throws
170 * an IllegalArgumentException if <code>target</code> or
171 * <code>pushLevel</code> are <code>null</code>, but the
172 * API specification does not prescribe what should happen
173 * in those cases.
175 public MemoryHandler(Handler target, int size, Level pushLevel)
177 if ((target == null) || (size <= 0) || (pushLevel == null))
178 throw new IllegalArgumentException();
180 buffer = new LogRecord[size];
181 this.pushLevel = pushLevel;
182 this.target = target;
184 setLevel(LogManager.getLevelProperty(
185 "java.util.logging.MemoryHandler.level",
186 /* default value */ Level.ALL));
188 setFilter((Filter) LogManager.getInstanceProperty(
189 "java.util.logging.MemoryHandler.filter",
190 /* must be instance of */ Filter.class,
191 /* default value */ null));
196 * Stores a <code>LogRecord</code> in a fixed-size circular buffer,
197 * provided the record passes all tests for being loggable. If the
198 * buffer is full, the oldest record will be discarded.
200 * <p>If the record has a severity level which is greater than or
201 * equal to the <code>pushLevel</code> of this
202 * <code>MemoryHandler</code>, the {@link #push()} method will be
203 * invoked for pushing the buffer contents to the target
204 * <code>Handler</code>.
206 * <p>Most applications do not need to call this method directly.
207 * Instead, they will use use a {@link Logger}, which will create
208 * LogRecords and distribute them to registered handlers.
210 * @param record the log event to be published.
212 public void publish(LogRecord record)
214 if (!isLoggable(record))
215 return;
217 buffer[position] = record;
218 position = (position + 1) % buffer.length;
219 numPublished = numPublished + 1;
221 if (record.getLevel().intValue() >= pushLevel.intValue())
222 push();
227 * Pushes the contents of the memory buffer to the target
228 * <code>Handler</code> and clears the buffer. Note that
229 * the target handler will discard those records that do
230 * not satisfy its own severity level threshold, or that are
231 * not considered loggable by an installed {@link Filter}.
233 * <p>In case of an I/O failure, the {@link ErrorManager} of the
234 * target <code>Handler</code> will be notified, but the caller of
235 * this method will not receive an exception.
237 public void push()
239 int i;
241 if (numPublished < buffer.length)
243 for (i = 0; i < position; i++)
244 target.publish(buffer[i]);
246 else
248 for (i = position; i < buffer.length; i++)
249 target.publish(buffer[i]);
250 for (i = 0; i < position; i++)
251 target.publish(buffer[i]);
254 numPublished = 0;
255 position = 0;
260 * Forces any data that may have been buffered by the target
261 * <code>Handler</code> to the underlying output device, but
262 * does <em>not</em> push the contents of the circular memory
263 * buffer to the target handler.
265 * <p>In case of an I/O failure, the {@link ErrorManager} of the
266 * target <code>Handler</code> will be notified, but the caller of
267 * this method will not receive an exception.
269 * @see #push()
271 public void flush()
273 target.flush();
278 * Closes this <code>MemoryHandler</code> and its associated target
279 * handler, discarding the contents of the memory buffer. However,
280 * any data that may have been buffered by the target
281 * <code>Handler</code> is forced to the underlying output device.
283 * <p>As soon as <code>close</code> has been called,
284 * a <code>Handler</code> should not be used anymore. Attempts
285 * to publish log records, to flush buffers, or to modify the
286 * <code>Handler</code> in any other way may throw runtime
287 * exceptions after calling <code>close</code>.</p>
289 * <p>In case of an I/O failure, the <code>ErrorManager</code> of
290 * the associated target <code>Handler</code> will be informed, but
291 * the caller of this method will not receive an exception.</p>
293 * @throws SecurityException if a security manager exists and
294 * the caller is not granted the permission to control
295 * the logging infrastructure.
297 * @see #push()
299 public void close()
300 throws SecurityException
302 push();
304 /* This will check for LoggingPermission("control"). If the
305 * current security context does not grant this permission,
306 * push() has been executed, but this does not impose a
307 * security risk.
309 target.close();
315 * Returns the push level threshold for this <code>Handler</code>.
316 * When a record is published whose severity level is greater
317 * than or equal to the <code>pushLevel</code> of this
318 * <code>MemoryHandler</code>, the {@link #push()} method will be
319 * invoked for pushing the buffer contents to the target
320 * <code>Handler</code>.
322 * @return the push level threshold for automatic pushing.
324 public Level getPushLevel()
326 return pushLevel;
331 * Sets the push level threshold for this <code>Handler</code>.
332 * When a record is published whose severity level is greater
333 * than or equal to the <code>pushLevel</code> of this
334 * <code>MemoryHandler</code>, the {@link #push()} method will be
335 * invoked for pushing the buffer contents to the target
336 * <code>Handler</code>.
338 * @param pushLevel the push level threshold for automatic pushing.
340 * @exception SecurityException if a security manager exists and
341 * the caller is not granted the permission to control
342 * the logging infrastructure.
344 * @exception NullPointerException if <code>pushLevel</code> is
345 * <code>null</code>.
347 public void setPushLevel(Level pushLevel)
349 LogManager.getLogManager().checkAccess();
351 /* Throws a NullPointerException if pushLevel is null. */
352 pushLevel.getClass();
354 this.pushLevel = pushLevel;