Dead
[official-gcc.git] / gomp-20050608-branch / libjava / classpath / java / util / logging / MemoryHandler.java
blobffa589f16684bd54c97f2b563cd2ab9c480d83b2
1 /* MemoryHandler.java -- a class for buffering log messages in a memory buffer
2 Copyright (C) 2002, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package java.util.logging;
40 /**
41 * A <code>MemoryHandler</code> maintains a circular buffer of
42 * log records.
44 * <p><strong>Configuration:</strong> Values of the subsequent
45 * <code>LogManager</code> properties are taken into consideration
46 * when a <code>MemoryHandler</code> is initialized.
47 * If a property is not defined, or if it has an invalid
48 * value, a default is taken without an exception being thrown.
50 * <ul>
51 * <li><code>java.util.MemoryHandler.level</code> - specifies
52 * the initial severity level threshold. Default value:
53 * <code>Level.ALL</code>.</li>
54 * <li><code>java.util.MemoryHandler.filter</code> - specifies
55 * the name of a Filter class. Default value: No Filter.</li>
56 * <li><code>java.util.MemoryHandler.size</code> - specifies the
57 * maximum number of log records that are kept in the circular
58 * buffer. Default value: 1000.</li>
59 * <li><code>java.util.MemoryHandler.push</code> - specifies the
60 * <code>pushLevel</code>. Default value:
61 * <code>Level.SEVERE</code>.</li>
62 * <li><code>java.util.MemoryHandler.target</code> - specifies the
63 * name of a subclass of {@link Handler} that will be used as the
64 * target handler. There is no default value for this property;
65 * if it is not set, the no-argument MemoryHandler constructor
66 * will throw an exception.</li>
67 * </ul>
69 * @author Sascha Brawer (brawer@acm.org)
71 public class MemoryHandler
72 extends Handler
74 /**
75 * The storage area used for buffering the unpushed log records in
76 * memory.
78 private final LogRecord[] buffer;
81 /**
82 * The current position in the circular buffer. For a new
83 * MemoryHandler, or immediately after {@link #push()} was called,
84 * the value of this variable is zero. Each call to {@link
85 * #publish(LogRecord)} will store the published LogRecord into
86 * <code>buffer[position]</code> before position is incremented by
87 * one. If position becomes greater than the size of the buffer, it
88 * is reset to zero.
90 private int position;
93 /**
94 * The number of log records which have been published, but not
95 * pushed yet to the target handler.
97 private int numPublished;
101 * The push level threshold for this <code>Handler</code>. When a
102 * record is published whose severity level is greater than or equal
103 * to the <code>pushLevel</code> of this <code>MemoryHandler</code>,
104 * the {@link #push()} method will be invoked for pushing the buffer
105 * contents to the target <code>Handler</code>.
107 private Level pushLevel;
111 * The Handler to which log records are forwarded for actual
112 * publication.
114 private final Handler target;
118 * Constructs a <code>MemoryHandler</code> for keeping a circular
119 * buffer of LogRecords; the initial configuration is determined by
120 * the <code>LogManager</code> properties described above.
122 public MemoryHandler()
124 this((Handler) LogManager.getInstanceProperty(
125 "java.util.logging.MemoryHandler.target",
126 Handler.class, /* default */ null),
127 LogManager.getIntPropertyClamped(
128 "java.util.logging.MemoryHandler.size",
129 /* default */ 1000,
130 /* minimum value */ 1,
131 /* maximum value */ Integer.MAX_VALUE),
132 LogManager.getLevelProperty(
133 "java.util.logging.MemoryHandler.push",
134 /* default push level */ Level.SEVERE));
139 * Constructs a <code>MemoryHandler</code> for keeping a circular
140 * buffer of LogRecords, given some parameters. The values of the
141 * other parameters are taken from LogManager properties, as
142 * described above.
144 * @param target the target handler that will receive those
145 * log records that are passed on for publication.
147 * @param size the number of log records that are kept in the buffer.
148 * The value must be a at least one.
150 * @param pushLevel the push level threshold for this
151 * <code>MemoryHandler</code>. When a record is published whose
152 * severity level is greater than or equal to
153 * <code>pushLevel</code>, the {@link #push()} method will be
154 * invoked in order to push the bufffer contents to
155 * <code>target</code>.
157 * @throws java.lang.IllegalArgumentException if <code>size</code>
158 * is negative or zero. The GNU implementation also throws
159 * an IllegalArgumentException if <code>target</code> or
160 * <code>pushLevel</code> are <code>null</code>, but the
161 * API specification does not prescribe what should happen
162 * in those cases.
164 public MemoryHandler(Handler target, int size, Level pushLevel)
166 if ((target == null) || (size <= 0) || (pushLevel == null))
167 throw new IllegalArgumentException();
169 buffer = new LogRecord[size];
170 this.pushLevel = pushLevel;
171 this.target = target;
173 setLevel(LogManager.getLevelProperty(
174 "java.util.logging.MemoryHandler.level",
175 /* default value */ Level.ALL));
177 setFilter((Filter) LogManager.getInstanceProperty(
178 "java.util.logging.MemoryHandler.filter",
179 /* must be instance of */ Filter.class,
180 /* default value */ null));
185 * Stores a <code>LogRecord</code> in a fixed-size circular buffer,
186 * provided the record passes all tests for being loggable. If the
187 * buffer is full, the oldest record will be discarded.
189 * <p>If the record has a severity level which is greater than or
190 * equal to the <code>pushLevel</code> of this
191 * <code>MemoryHandler</code>, the {@link #push()} method will be
192 * invoked for pushing the buffer contents to the target
193 * <code>Handler</code>.
195 * <p>Most applications do not need to call this method directly.
196 * Instead, they will use use a {@link Logger}, which will create
197 * LogRecords and distribute them to registered handlers.
199 * @param record the log event to be published.
201 public void publish(LogRecord record)
203 if (!isLoggable(record))
204 return;
206 buffer[position] = record;
207 position = (position + 1) % buffer.length;
208 numPublished = numPublished + 1;
210 if (record.getLevel().intValue() >= pushLevel.intValue())
211 push();
216 * Pushes the contents of the memory buffer to the target
217 * <code>Handler</code> and clears the buffer. Note that
218 * the target handler will discard those records that do
219 * not satisfy its own severity level threshold, or that are
220 * not considered loggable by an installed {@link Filter}.
222 * <p>In case of an I/O failure, the {@link ErrorManager} of the
223 * target <code>Handler</code> will be notified, but the caller of
224 * this method will not receive an exception.
226 public void push()
228 int i;
230 if (numPublished < buffer.length)
232 for (i = 0; i < position; i++)
233 target.publish(buffer[i]);
235 else
237 for (i = position; i < buffer.length; i++)
238 target.publish(buffer[i]);
239 for (i = 0; i < position; i++)
240 target.publish(buffer[i]);
243 numPublished = 0;
244 position = 0;
249 * Forces any data that may have been buffered by the target
250 * <code>Handler</code> to the underlying output device, but
251 * does <em>not</em> push the contents of the circular memory
252 * buffer to the target handler.
254 * <p>In case of an I/O failure, the {@link ErrorManager} of the
255 * target <code>Handler</code> will be notified, but the caller of
256 * this method will not receive an exception.
258 * @see #push()
260 public void flush()
262 target.flush();
267 * Closes this <code>MemoryHandler</code> and its associated target
268 * handler, discarding the contents of the memory buffer. However,
269 * any data that may have been buffered by the target
270 * <code>Handler</code> is forced to the underlying output device.
272 * <p>As soon as <code>close</code> has been called,
273 * a <code>Handler</code> should not be used anymore. Attempts
274 * to publish log records, to flush buffers, or to modify the
275 * <code>Handler</code> in any other way may throw runtime
276 * exceptions after calling <code>close</code>.</p>
278 * <p>In case of an I/O failure, the <code>ErrorManager</code> of
279 * the associated target <code>Handler</code> will be informed, but
280 * the caller of this method will not receive an exception.</p>
282 * @throws SecurityException if a security manager exists and
283 * the caller is not granted the permission to control
284 * the logging infrastructure.
286 * @see #push()
288 public void close()
289 throws SecurityException
291 push();
293 /* This will check for LoggingPermission("control"). If the
294 * current security context does not grant this permission,
295 * push() has been executed, but this does not impose a
296 * security risk.
298 target.close();
304 * Returns the push level threshold for this <code>Handler</code>.
305 * When a record is published whose severity level is greater
306 * than or equal to the <code>pushLevel</code> of this
307 * <code>MemoryHandler</code>, the {@link #push()} method will be
308 * invoked for pushing the buffer contents to the target
309 * <code>Handler</code>.
311 * @return the push level threshold for automatic pushing.
313 public Level getPushLevel()
315 return pushLevel;
320 * Sets the push level threshold for this <code>Handler</code>.
321 * When a record is published whose severity level is greater
322 * than or equal to the <code>pushLevel</code> of this
323 * <code>MemoryHandler</code>, the {@link #push()} method will be
324 * invoked for pushing the buffer contents to the target
325 * <code>Handler</code>.
327 * @param pushLevel the push level threshold for automatic pushing.
329 * @exception SecurityException if a security manager exists and
330 * the caller is not granted the permission to control
331 * the logging infrastructure.
333 * @exception NullPointerException if <code>pushLevel</code> is
334 * <code>null</code>.
336 public void setPushLevel(Level pushLevel)
338 LogManager.getLogManager().checkAccess();
340 /* Throws a NullPointerException if pushLevel is null. */
341 pushLevel.getClass();
343 this.pushLevel = pushLevel;