Major merge with Classpath.

Removed many duplicate files.
	* HACKING: Updated.x
	* classpath: Imported new directory.
	* standard.omit: New file.
	* Makefile.in, aclocal.m4, configure: Rebuilt.
	* sources.am: New file.
	* configure.ac: Run Classpath configure script.  Moved code around
	to support.  Disable xlib AWT peers (temporarily).
	* Makefile.am (SUBDIRS): Added 'classpath'
	(JAVAC): Removed.
	(AM_CPPFLAGS): Added more -I options.
	(BOOTCLASSPATH): Simplified.
	Completely redid how sources are built.
	Include sources.am.
	* include/Makefile.am (tool_include__HEADERS): Removed jni.h.
	* include/jni.h: Removed (in Classpath).
	* scripts/classes.pl: Updated to look at built classes.
	* scripts/makemake.tcl: New file.
	* testsuite/libjava.jni/jni.exp (gcj_jni_compile_c_to_so): Added
	-I options.
	(gcj_jni_invocation_compile_c_to_binary): Likewise.

From-SVN: r102082
This commit is contained in:
Tom Tromey 2005-07-16 01:27:14 +00:00 committed by Tom Tromey
parent ea54b29342
commit b0fa81eea9
2817 changed files with 11656 additions and 643398 deletions

View file

@ -1,125 +0,0 @@
/* ConsoleHandler.java -- a class for publishing log messages to System.err
Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.util.logging;
/**
* A <code>ConsoleHandler</code> publishes log records to
* <code>System.err</code>.
*
* <p><strong>Configuration:</strong> Values of the subsequent
* <code>LogManager</code> properties are taken into consideration
* when a <code>ConsoleHandler</code> is initialized.
* If a property is not defined, or if it has an invalid
* value, a default is taken without an exception being thrown.
*
* <ul>
*
* <li><code>java.util.logging.ConsoleHandler.level</code> - specifies
* the initial severity level threshold. Default value:
* <code>Level.INFO</code>.</li>
*
* <li><code>java.util.logging.ConsoleHandler.filter</code> - specifies
* the name of a Filter class. Default value: No Filter.</li>
*
* <li><code>java.util.logging.ConsoleHandler.formatter</code> - specifies
* the name of a Formatter class. Default value:
* <code>java.util.logging.SimpleFormatter</code>.</li>
*
* <li><code>java.util.logging.ConsoleHandler.encoding</code> - specifies
* the name of the character encoding. Default value:
* the default platform encoding.</li>
*
* </ul>
*
* @author Sascha Brawer (brawer@acm.org)
*/
public class ConsoleHandler
extends StreamHandler
{
/**
* Constructs a <code>StreamHandler</code> that publishes
* log records to <code>System.err</code>. The initial
* configuration is determined by the <code>LogManager</code>
* properties described above.
*/
public ConsoleHandler()
{
super(System.err, "java.util.logging.ConsoleHandler", Level.INFO,
/* formatter */ null, SimpleFormatter.class);
}
/**
* Forces any data that may have been buffered to the underlying
* output device, but does <i>not</i> close <code>System.err</code>.
*
* <p>In case of an I/O failure, the <code>ErrorManager</code>
* of this <code>ConsoleHandler</code> will be informed, but the caller
* of this method will not receive an exception.
*/
public void close()
{
flush();
}
/**
* Publishes a <code>LogRecord</code> to the console, provided the
* record passes all tests for being loggable.
*
* <p>Most applications do not need to call this method directly.
* Instead, they will use use a <code>Logger</code>, which will
* create LogRecords and distribute them to registered handlers.
*
* <p>In case of an I/O failure, the <code>ErrorManager</code>
* of this <code>SocketHandler</code> will be informed, but the caller
* of this method will not receive an exception.
*
* <p>The GNU implementation of <code>ConsoleHandler.publish</code>
* calls flush() for every request to publish a record, so
* they appear immediately on the console.
*
* @param record the log event to be published.
*/
public void publish(LogRecord record)
{
super.publish(record);
flush();
}
}

View file

@ -1,194 +0,0 @@
/* ErrorManager.java --
A class for dealing with errors that a Handler encounters
during logging
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.util.logging;
/**
* An <code>ErrorManager</code> deals with errors that a <code>Handler</code>
* encounters while logging.
*
* @see Handler#setErrorManager(ErrorManager)
*
* @author Sascha Brawer (brawer@acm.org)
*/
public class ErrorManager
{
/* The values have been taken from Sun's public J2SE 1.4 API
* documentation.
* See http://java.sun.com/j2se/1.4/docs/api/constant-values.html
*/
/**
* Indicates that there was a failure that does not readily
* fall into any of the other categories.
*/
public static final int GENERIC_FAILURE = 0;
/**
* Indicates that there was a problem upon writing to
* an output stream.
*/
public static final int WRITE_FAILURE = 1;
/**
* Indicates that there was a problem upon flushing
* an output stream.
*/
public static final int FLUSH_FAILURE = 2;
/**
* Indicates that there was a problem upon closing
* an output stream.
*/
public static final int CLOSE_FAILURE = 3;
/**
* Indicates that there was a problem upon opening
* an output stream.
*/
public static final int OPEN_FAILURE = 4;
/**
* Indicates that there was a problem upon formatting
* the message of a log record.
*/
public static final int FORMAT_FAILURE = 5;
/**
* Indicates whether the {@link #error} method of this ErrorManager
* has ever been used.
*
* Declared volatile in order to correctly support the
* double-checked locking idiom (once the revised Java Memory Model
* gets adopted); see Classpath bug #2944.
*/
private volatile boolean everUsed = false;
public ErrorManager()
{
}
/**
* Reports an error that occured upon logging. The default implementation
* emits the very first error to System.err, ignoring subsequent errors.
*
* @param message a message describing the error, or <code>null</code> if
* there is no suitable description.
*
* @param ex an exception, or <code>null</code> if the error is not
* related to an exception.
*
* @param errorCode one of the defined error codes, for example
* <code>ErrorManager.CLOSE_FAILURE</code>.
*/
public void error(String message, Exception ex, int errorCode)
{
if (everUsed)
return;
synchronized (this)
{
/* The double check is intentional. If the first check was
* omitted, the monitor would have to be entered every time
* error() method was called. If the second check was
* omitted, the code below could be executed by multiple
* threads simultaneously.
*
* This is the 'double-checked locking' idiom, which is broken
* with the current version of the Java memory model. However,
* we assume that JVMs will have adopted a revised version of
* the Java Memory Model by the time GNU Classpath gains
* widespread acceptance. See Classpath bug #2944.
*/
if (everUsed)
return;
everUsed = true;
}
String codeMsg;
switch (errorCode)
{
case GENERIC_FAILURE:
codeMsg = "GENERIC_FAILURE";
break;
case WRITE_FAILURE:
codeMsg = "WRITE_FAILURE";
break;
case FLUSH_FAILURE:
codeMsg = "FLUSH_FAILURE";
break;
case CLOSE_FAILURE:
codeMsg = "CLOSE_FAILURE";
break;
case OPEN_FAILURE:
codeMsg = "OPEN_FAILURE";
break;
case FORMAT_FAILURE:
codeMsg = "FORMAT_FAILURE";
break;
default:
codeMsg = String.valueOf(errorCode);
break;
}
System.err.println("Error upon logging: " + codeMsg);
if ((message != null) && (message.length() > 0))
System.err.println(message);
if (ex != null)
ex.printStackTrace();
}
}

View file

@ -1,506 +0,0 @@
/* FileHandler.java -- a class for publishing log messages to log files
Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.util.logging;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* A <code>FileHandler</code> publishes log records to a set of log
* files. A maximum file size can be specified; as soon as a log file
* reaches the size limit, it is closed and the next file in the set
* is taken.
*
* <p><strong>Configuration:</strong> Values of the subsequent
* <code>LogManager</code> properties are taken into consideration
* when a <code>FileHandler</code> is initialized. If a property is
* not defined, or if it has an invalid value, a default is taken
* without an exception being thrown.
*
* <ul>
*
* <li><code>java.util.FileHandler.level</code> - specifies
* the initial severity level threshold. Default value:
* <code>Level.ALL</code>.</li>
*
* <li><code>java.util.FileHandler.filter</code> - specifies
* the name of a Filter class. Default value: No Filter.</li>
*
* <li><code>java.util.FileHandler.formatter</code> - specifies
* the name of a Formatter class. Default value:
* <code>java.util.logging.XMLFormatter</code>.</li>
*
* <li><code>java.util.FileHandler.encoding</code> - specifies
* the name of the character encoding. Default value:
* the default platform encoding.</li>
*
* <li><code>java.util.FileHandler.limit</code> - specifies the number
* of bytes a log file is approximately allowed to reach before it
* is closed and the handler switches to the next file in the
* rotating set. A value of zero means that files can grow
* without limit. Default value: 0 (unlimited growth).</li>
*
* <li><code>java.util.FileHandler.count</code> - specifies the number
* of log files through which this handler cycles. Default value:
* 1.</li>
*
* <li><code>java.util.FileHandler.pattern</code> - specifies a
* pattern for the location and name of the produced log files.
* See the section on <a href="#filePatterns">file name
* patterns</a> for details. Default value:
* <code>"%h/java%u.log"</code>.</li>
*
* <li><code>java.util.FileHandler.append</code> - specifies
* whether the handler will append log records to existing
* files, or whether the handler will clear log files
* upon switching to them. Default value: <code>false</code>,
* indicating that files will be cleared.</li>
*
* </ul>
*
* <p><a name="filePatterns"><strong>File Name Patterns:</strong></a>
* The name and location and log files are specified with pattern
* strings. The handler will replace the following character sequences
* when opening log files:
*
* <p><ul>
* <li><code>/</code> - replaced by the platform-specific path name
* separator. This value is taken from the system property
* <code>file.separator</code>.</li>
*
* <li><code>%t</code> - replaced by the platform-specific location of
* the directory intended for temporary files. This value is
* taken from the system property <code>java.io.tmpdir</code>.</li>
*
* <li><code>%h</code> - replaced by the location of the home
* directory of the current user. This value is taken from the
* system property <code>file.separator</code>.</li>
*
* <li><code>%g</code> - replaced by a generation number for
* distinguisthing the individual items in the rotating set
* of log files. The generation number cycles through the
* sequence 0, 1, ..., <code>count</code> - 1.</li>
*
* <li><code>%u</code> - replaced by a unique number for
* distinguisthing the output files of several concurrently
* running processes. The <code>FileHandler</code> starts
* with 0 when it tries to open a log file. If the file
* cannot be opened because it is currently in use,
* the unique number is incremented by one and opening
* is tried again. These steps are repeated until the
* opening operation succeeds.
*
* <p>FIXME: Is the following correct? Please review. The unique
* number is determined for each log file individually when it is
* opened upon switching to the next file. Therefore, it is not
* correct to assume that all log files in a rotating set bear the
* same unique number.
*
* <p>FIXME: The Javadoc for the Sun reference implementation
* says: "Note that the use of unique ids to avoid conflicts is
* only guaranteed to work reliably when using a local disk file
* system." Why? This needs to be mentioned as well, in case
* the reviewers decide the statement is true. Otherwise,
* file a bug report with Sun.</li>
*
* <li><code>%%</code> - replaced by a single percent sign.</li>
* </ul>
*
* <p>If the pattern string does not contain <code>%g</code> and
* <code>count</code> is greater than one, the handler will append
* the string <code>.%g</code> to the specified pattern.
*
* <p>If the handler attempts to open a log file, this log file
* is being used at the time of the attempt, and the pattern string
* does not contain <code>%u</code>, the handler will append
* the string <code>.%u</code> to the specified pattern. This
* step is performed after any generation number has been
* appended.
*
* <p><em>Examples for the GNU platform:</em>
*
* <p><ul>
*
* <li><code>%h/java%u.log</code> will lead to a single log file
* <code>/home/janet/java0.log</code>, assuming <code>count</code>
* equals 1, the user's home directory is
* <code>/home/janet</code>, and the attempt to open the file
* succeeds.</li>
*
* <li><code>%h/java%u.log</code> will lead to three log files
* <code>/home/janet/java0.log.0</code>,
* <code>/home/janet/java0.log.1</code>, and
* <code>/home/janet/java0.log.2</code>,
* assuming <code>count</code> equals 3, the user's home
* directory is <code>/home/janet</code>, and all attempts
* to open files succeed.</li>
*
* <li><code>%h/java%u.log</code> will lead to three log files
* <code>/home/janet/java0.log.0</code>,
* <code>/home/janet/java1.log.1</code>, and
* <code>/home/janet/java0.log.2</code>,
* assuming <code>count</code> equals 3, the user's home
* directory is <code>/home/janet</code>, and the attempt
* to open <code>/home/janet/java0.log.1</code> fails.</li>
*
* </ul>
*
* @author Sascha Brawer (brawer@acm.org)
*/
public class FileHandler
extends StreamHandler
{
/**
* The number of bytes a log file is approximately allowed to reach
* before it is closed and the handler switches to the next file in
* the rotating set. A value of zero means that files can grow
* without limit.
*/
private final int limit;
/**
* The number of log files through which this handler cycles.
*/
private final int count;
/**
* The pattern for the location and name of the produced log files.
* See the section on <a href="#filePatterns">file name patterns</a>
* for details.
*/
private final String pattern;
/**
* Indicates whether the handler will append log records to existing
* files (<code>true</code>), or whether the handler will clear log files
* upon switching to them (<code>false</code>).
*/
private final boolean append;
/**
* Constructs a <code>FileHandler</code>, taking all property values
* from the current {@link LogManager LogManager} configuration.
*
* @throws java.io.IOException FIXME: The Sun Javadoc says: "if
* there are IO problems opening the files." This conflicts
* with the general principle that configuration errors do
* not prohibit construction. Needs review.
*
* @throws SecurityException if a security manager exists and
* the caller is not granted the permission to control
* the logging infrastructure.
*/
public FileHandler()
throws IOException, SecurityException
{
this(/* pattern: use configiguration */ null,
LogManager.getIntProperty("java.util.logging.FileHandler.limit",
/* default */ 0),
LogManager.getIntProperty("java.util.logging.FileHandler.count",
/* default */ 1),
LogManager.getBooleanProperty("java.util.logging.FileHandler.append",
/* default */ false));
}
/* FIXME: Javadoc missing. */
public FileHandler(String pattern)
throws IOException, SecurityException
{
this(pattern,
/* limit */ 0,
/* count */ 1,
/* append */ false);
}
/* FIXME: Javadoc missing. */
public FileHandler(String pattern, boolean append)
throws IOException, SecurityException
{
this(pattern,
/* limit */ 0,
/* count */ 1,
append);
}
/* FIXME: Javadoc missing. */
public FileHandler(String pattern, int limit, int count)
throws IOException, SecurityException
{
this(pattern, limit, count,
LogManager.getBooleanProperty(
"java.util.logging.FileHandler.append",
/* default */ false));
}
/**
* Constructs a <code>FileHandler</code> given the pattern for the
* location and name of the produced log files, the size limit, the
* number of log files thorough which the handler will rotate, and
* the <code>append</code> property. All other property values are
* taken from the current {@link LogManager LogManager}
* configuration.
*
* @param pattern The pattern for the location and name of the
* produced log files. See the section on <a
* href="#filePatterns">file name patterns</a> for details.
* If <code>pattern</code> is <code>null</code>, the value is
* taken from the {@link LogManager LogManager} configuration
* property
* <code>java.util.logging.FileHandler.pattern</code>.
* However, this is a pecularity of the GNU implementation,
* and Sun's API specification does not mention what behavior
* is to be expected for <code>null</code>. Therefore,
* applications should not rely on this feature.
*
* @param limit specifies the number of bytes a log file is
* approximately allowed to reach before it is closed and the
* handler switches to the next file in the rotating set. A
* value of zero means that files can grow without limit.
*
* @param count specifies the number of log files through which this
* handler cycles.
*
* @param append specifies whether the handler will append log
* records to existing files (<code>true</code>), or whether the
* handler will clear log files upon switching to them
* (<code>false</code>).
*
* @throws java.io.IOException FIXME: The Sun Javadoc says: "if
* there are IO problems opening the files." This conflicts
* with the general principle that configuration errors do
* not prohibit construction. Needs review.
*
* @throws SecurityException if a security manager exists and
* the caller is not granted the permission to control
* the logging infrastructure.
* <p>FIXME: This seems in contrast to all other handler
* constructors -- verify this by running tests against
* the Sun reference implementation.
*/
public FileHandler(String pattern,
int limit,
int count,
boolean append)
throws IOException, SecurityException
{
super(createFileStream(pattern, limit, count, append,
/* generation */ 0),
"java.util.logging.FileHandler",
/* default level */ Level.ALL,
/* formatter */ null,
/* default formatter */ XMLFormatter.class);
if ((limit <0) || (count < 1))
throw new IllegalArgumentException();
this.pattern = pattern;
this.limit = limit;
this.count = count;
this.append = append;
}
/* FIXME: Javadoc missing. */
private static java.io.OutputStream createFileStream(String pattern,
int limit,
int count,
boolean append,
int generation)
{
String path;
int unique = 0;
/* Throws a SecurityException if the caller does not have
* LoggingPermission("control").
*/
LogManager.getLogManager().checkAccess();
/* Default value from the java.util.logging.FileHandler.pattern
* LogManager configuration property.
*/
if (pattern == null)
pattern = LogManager.getLogManager().getProperty(
"java.util.logging.FileHandler.pattern");
if (pattern == null)
pattern = "%h/java%u.log";
do
{
path = replaceFileNameEscapes(pattern, generation, unique, count);
try
{
File file = new File(path);
if (file.createNewFile())
return new FileOutputStream(path, append);
}
catch (Exception ex)
{
ex.printStackTrace();
}
unique = unique + 1;
if (pattern.indexOf("%u") < 0)
pattern = pattern + ".%u";
}
while (true);
}
/**
* Replaces the substrings <code>"/"</code> by the value of the
* system property <code>"file.separator"</code>, <code>"%t"</code>
* by the value of the system property
* <code>"java.io.tmpdir"</code>, <code>"%h"</code> by the value of
* the system property <code>"user.home"</code>, <code>"%g"</code>
* by the value of <code>generation</code>, <code>"%u"</code> by the
* value of <code>uniqueNumber</code>, and <code>"%%"</code> by a
* single percent character. If <code>pattern</code> does
* <em>not</em> contain the sequence <code>"%g"</code>,
* the value of <code>generation</code> will be appended to
* the result.
*
* @throws NullPointerException if one of the system properties
* <code>"file.separator"</code>,
* <code>"java.io.tmpdir"</code>, or
* <code>"user.home"</code> has no value and the
* corresponding escape sequence appears in
* <code>pattern</code>.
*/
private static String replaceFileNameEscapes(String pattern,
int generation,
int uniqueNumber,
int count)
{
StringBuffer buf = new StringBuffer(pattern);
String replaceWith;
boolean foundGeneration = false;
int pos = 0;
do
{
// Uncomment the next line for finding bugs.
// System.out.println(buf.substring(0,pos) + '|' + buf.substring(pos));
if (buf.charAt(pos) == '/')
{
/* The same value is also provided by java.io.File.separator. */
replaceWith = System.getProperty("file.separator");
buf.replace(pos, pos + 1, replaceWith);
pos = pos + replaceWith.length() - 1;
continue;
}
if (buf.charAt(pos) == '%')
{
switch (buf.charAt(pos + 1))
{
case 't':
replaceWith = System.getProperty("java.io.tmpdir");
break;
case 'h':
replaceWith = System.getProperty("user.home");
break;
case 'g':
replaceWith = Integer.toString(generation);
foundGeneration = true;
break;
case 'u':
replaceWith = Integer.toString(uniqueNumber);
break;
case '%':
replaceWith = "%";
break;
default:
replaceWith = "??";
break; // FIXME: Throw exception?
}
buf.replace(pos, pos + 2, replaceWith);
pos = pos + replaceWith.length() - 1;
continue;
}
}
while (++pos < buf.length() - 1);
if (!foundGeneration && (count > 1))
{
buf.append('.');
buf.append(generation);
}
return buf.toString();
}
/* FIXME: Javadoc missing, implementation incomplete. */
public void publish(LogRecord record)
{
super.publish(record);
/* FIXME: Decide when to switch over. How do we get to
* the number of bytes published so far? Two possibilities:
* 1. File.length, 2. have metering wrapper around
* output stream counting the number of written bytes.
*/
/* FIXME: Switch over if needed! This implementation always
* writes into a single file, i.e. behaves as if limit
* always was zero. So, the implementation is somewhat
* functional but incomplete.
*/
}
}

View file

@ -1,64 +0,0 @@
/* Filter.java -- an interface for filters that decide whether a
LogRecord should be published or discarded
Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.util.logging;
/**
* By implementing the <code>Filter</code> interface, applications
* can control what is being logged based on arbitrary properties,
* not just the severity level. Both <code>Handler</code> and
* <code>Logger</code> allow to register Filters whose
* <code>isLoggable</code> method will be called when a
* <code>LogRecord</code> has passed the test based on the
* severity level.
*
* @author Sascha Brawer (brawer@acm.org)
*/
public interface Filter
{
/**
* Determines whether a LogRecord should be published or discarded.
*
* @param record the <code>LogRecord</code> to be inspected.
*
* @return <code>true</code> if the record should be published,
* <code>false</code> if it should be discarded.
*/
boolean isLoggable(LogRecord record);
}

View file

@ -1,171 +0,0 @@
/* Formatter.java --
A class for formatting log messages by localizing message texts
and performing substitution of parameters
Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.util.logging;
import java.text.MessageFormat;
import java.util.ResourceBundle;
/**
* A <code>Formatter</code> supports handlers by localizing
* message texts and by subsituting parameter values for their
* placeholders.
*
* @author Sascha Brawer (brawer@acm.org)
*/
public abstract class Formatter
{
/**
* Constructs a new Formatter.
*/
protected Formatter()
{
}
/**
* Formats a LogRecord into a string. Usually called by handlers
* which need a string for a log record, for example to append
* a record to a log file or to transmit a record over the network.
*
* @param record the log record for which a string form is requested.
*/
public abstract String format(LogRecord record);
/**
* Returns a string that handlers are supposed to emit before
* the first log record. The base implementation returns an
* empty string, but subclasses such as {@link XMLFormatter}
* override this method in order to provide a suitable header.
*
* @return a string for the header.
*
* @param handler the handler which will prepend the returned
* string in front of the first log record. This method
* may inspect certain properties of the handler, for
* example its encoding, in order to construct the header.
*/
public String getHead(Handler handler)
{
return "";
}
/**
* Returns a string that handlers are supposed to emit after
* the last log record. The base implementation returns an
* empty string, but subclasses such as {@link XMLFormatter}
* override this method in order to provide a suitable tail.
*
* @return a string for the header.
*
* @param handler the handler which will append the returned
* string after the last log record. This method
* may inspect certain properties of the handler
* in order to construct the tail.
*/
public String getTail(Handler handler)
{
return "";
}
/**
* Formats the message part of a log record.
*
* <p>First, the Formatter localizes the record message to the
* default locale by looking up the message in the record's
* localization resource bundle. If this step fails because there
* is no resource bundle associated with the record, or because the
* record message is not a key in the bundle, the raw message is
* used instead.
*
* <p>Second, the Formatter substitutes appropriate strings for
* the message parameters. If the record returns a non-empty
* array for <code>getParameters()</code> and the localized
* message string contains the character sequence "{0", the
* formatter uses <code>java.text.MessageFormat</code> to format
* the message. Otherwise, no parameter substitution is performed.
*
* @param record the log record to be localized and formatted.
*
* @return the localized message text where parameters have been
* substituted by suitable strings.
*
* @throws NullPointerException if <code>record</code>
* is <code>null</code>.
*/
public String formatMessage(LogRecord record)
{
String msg;
ResourceBundle bundle;
Object[] params;
/* This will throw a NullPointerExceptionif record is null. */
msg = record.getMessage();
if (msg == null)
msg = "";
/* Try to localize the message. */
bundle = record.getResourceBundle();
if (bundle != null)
{
try
{
msg = bundle.getString(msg);
}
catch (java.util.MissingResourceException _)
{
}
}
/* Format the message if there are parameters. */
params = record.getParameters();
if ((params != null)
&& (params.length > 0)
&& (msg.indexOf("{0") >= 0))
{
msg = MessageFormat.format(msg, params);
}
return msg;
}
}

View file

@ -1,386 +0,0 @@
/* Handler.java -- a class for publishing log messages
Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.util.logging;
import java.io.UnsupportedEncodingException;
/**
* A <code>Handler</code> publishes <code>LogRecords</code> to
* a sink, for example a file, the console or a network socket.
* There are different subclasses of <code>Handler</code>
* to deal with different kinds of sinks.
*
* <p>FIXME: Are handlers thread-safe, or is the assumption that only
* loggers are, and a handler can belong only to one single logger? If
* the latter, should we enforce it? (Spec not clear). In any
* case, it needs documentation.
*
* @author Sascha Brawer (brawer@acm.org)
*/
public abstract class Handler
{
Formatter formatter;
Filter filter;
Level level;
ErrorManager errorManager;
String encoding;
/**
* Constructs a Handler with a logging severity level of
* <code>Level.ALL</code>, no formatter, no filter, and
* an instance of <code>ErrorManager</code> managing errors.
*
* <p><strong>Specification Note:</strong> The specification of the
* Java<sup>TM</sup> Logging API does not mention which character
* encoding is to be used by freshly constructed Handlers. The GNU
* implementation uses the default platform encoding, but other
* Java implementations might behave differently.
*
* <p><strong>Specification Note:</strong> While a freshly constructed
* Handler is required to have <em>no filter</em> according to the
* specification, <code>null</code> is not a valid parameter for
* <code>Handler.setFormatter</code>. Therefore, the following
* code will throw a <code>java.lang.NullPointerException</code>:
*
* <p><pre>Handler h = new MyConcreteSubclassOfHandler();
h.setFormatter(h.getFormatter());</pre>
*
* It seems strange that a freshly constructed Handler is not
* supposed to provide a Formatter, but this is what the specification
* says.
*/
protected Handler()
{
level = Level.ALL;
}
/**
* Publishes a <code>LogRecord</code> to an appropriate sink,
* provided the record passes all tests for being loggable. The
* <code>Handler</code> will localize the message of the log
* record and substitute any message parameters.
*
* <p>Most applications do not need to call this method directly.
* Instead, they will use use a {@link Logger}, which will
* create LogRecords and distribute them to registered handlers.
*
* <p>In case of an I/O failure, the <code>ErrorManager</code>
* of this <code>Handler</code> will be informed, but the caller
* of this method will not receive an exception.
*
* @param record the log event to be published.
*/
public abstract void publish(LogRecord record);
/**
* Forces any data that may have been buffered to the underlying
* output device.
*
* <p>In case of an I/O failure, the <code>ErrorManager</code>
* of this <code>Handler</code> will be informed, but the caller
* of this method will not receive an exception.
*/
public abstract void flush();
/**
* Closes this <code>Handler</code> after having flushed
* the buffers. As soon as <code>close</code> has been called,
* a <code>Handler</code> should not be used anymore. Attempts
* to publish log records, to flush buffers, or to modify the
* <code>Handler</code> in any other way may throw runtime
* exceptions after calling <code>close</code>.
*
* <p>In case of an I/O failure, the <code>ErrorManager</code>
* of this <code>Handler</code> will be informed, but the caller
* of this method will not receive an exception.
*
* @throws SecurityException if a security manager exists and
* the caller is not granted the permission to control
* the logging infrastructure.
*/
public abstract void close()
throws SecurityException;
/**
* Returns the <code>Formatter</code> which will be used to
* localize the text of log messages and to substitute
* message parameters. A <code>Handler</code> is encouraged,
* but not required to actually use an assigned
* <code>Formatter</code>.
*
* @return the <code>Formatter</code> being used, or
* <code>null</code> if this <code>Handler</code>
* does not use formatters and no formatter has
* ever been set by calling <code>setFormatter</code>.
*/
public Formatter getFormatter()
{
return formatter;
}
/**
* Sets the <code>Formatter</code> which will be used to
* localize the text of log messages and to substitute
* message parameters. A <code>Handler</code> is encouraged,
* but not required to actually use an assigned
* <code>Formatter</code>.
*
* @param formatter the new <code>Formatter</code> to use.
*
* @throws SecurityException if a security manager exists and
* the caller is not granted the permission to control
* the logging infrastructure.
*
* @throws NullPointerException if <code>formatter</code> is
* <code>null</code>.
*/
public void setFormatter(Formatter formatter)
throws SecurityException
{
LogManager.getLogManager().checkAccess();
/* Throws a NullPointerException if formatter is null. */
formatter.getClass();
this.formatter = formatter;
}
/**
* Returns the character encoding which this handler uses for publishing
* log records.
*
* @param encoding the name of a character encoding, or <code>null</code>
* for the default platform encoding.
*/
public String getEncoding()
{
return encoding;
}
/**
* Sets the character encoding which this handler uses for publishing
* log records. The encoding of a <code>Handler</code> must be
* set before any log records have been published.
*
* @param encoding the name of a character encoding, or <code>null</code>
* for the default encoding.
*
* @exception SecurityException if a security manager exists and
* the caller is not granted the permission to control
* the logging infrastructure.
*
*/
public void setEncoding(String encoding)
throws SecurityException, UnsupportedEncodingException
{
/* Should any developer ever change this implementation, they are
* advised to have a look at StreamHandler.setEncoding(String),
* which overrides this method without calling super.setEncoding.
*/
LogManager.getLogManager().checkAccess();
/* Simple check for supported encodings. This is more expensive
* than it could be, but this method is overwritten by StreamHandler
* anyway.
*/
if (encoding != null)
new String(new byte[0], encoding);
this.encoding = encoding;
}
/**
* Returns the <code>Filter</code> that currently controls which
* log records are being published by this <code>Handler</code>.
*
* @return the currently active <code>Filter</code>, or
* <code>null</code> if no filter has been associated.
* In the latter case, log records are filtered purely
* based on their severity level.
*/
public Filter getFilter()
{
return filter;
}
/**
* Sets the <code>Filter</code> for controlling which
* log records will be published by this <code>Handler</code>.
*
* @return the <code>Filter</code> to use, or
* <code>null</code> to filter log records purely based
* on their severity level.
*/
public void setFilter(Filter filter)
throws SecurityException
{
LogManager.getLogManager().checkAccess();
this.filter = filter;
}
/**
* Returns the <code>ErrorManager</code> that currently deals
* with errors originating from this Handler.
*
* @exception SecurityException if a security manager exists and
* the caller is not granted the permission to control
* the logging infrastructure.
*/
public ErrorManager getErrorManager()
{
LogManager.getLogManager().checkAccess();
/* Developers wanting to change the subsequent code should
* have a look at Handler.reportError -- it also can create
* an ErrorManager, but does so without checking permissions
* to control the logging infrastructure.
*/
if (errorManager == null)
errorManager = new ErrorManager();
return errorManager;
}
public void setErrorManager(ErrorManager manager)
{
LogManager.getLogManager().checkAccess();
/* Make sure manager is not null. */
manager.getClass();
this.errorManager = manager;
}
protected void reportError(String message, Exception ex, int code)
{
if (errorManager == null)
errorManager = new ErrorManager();
errorManager.error(message, ex, code);
}
/**
* Returns the severity level threshold for this <code>Handler</code>
* All log records with a lower severity level will be discarded;
* a log record of the same or a higher level will be published
* unless an installed <code>Filter</code> decides to discard it.
*
* @return the severity level below which all log messages
* will be discarded.
*/
public Level getLevel()
{
return level;
}
/**
* Sets the severity level threshold for this <code>Handler</code>.
* All log records with a lower severity level will be discarded;
* a log record of the same or a higher level will be published
* unless an installed <code>Filter</code> decides to discard it.
*
* @param level the severity level below which all log messages
* will be discarded.
*
* @exception SecurityException if a security manager exists and
* the caller is not granted the permission to control
* the logging infrastructure.
*
* @exception NullPointerException if <code>level</code> is
* <code>null</code>.
*/
public void setLevel(Level level)
{
LogManager.getLogManager().checkAccess();
/* Throw NullPointerException if level is null. */
level.getClass();
this.level = level;
}
/**
* Checks whether a <code>LogRecord</code> would be logged
* if it was passed to this <code>Handler</code> for publication.
*
* <p>The <code>Handler</code> implementation considers a record as
* loggable if its level is greater than or equal to the severity
* level threshold. In a second step, if a {@link Filter} has
* been installed, its {@link Filter#isLoggable(LogRecord) isLoggable}
* method is invoked. Subclasses of <code>Handler</code> can override
* this method to impose their own constraints.
*
* @param record the <code>LogRecord</code> to be checked.
*
* @return <code>true</code> if <code>record</code> would
* be published by {@link #publish(LogRecord) publish},
* <code>false</code> if it would be discarded.
*
* @see #setLevel(Level)
* @see #setFilter(Filter)
* @see Filter#isLoggable(LogRecord)
*
* @throws NullPointerException if <code>record</code>
* is <code>null</code>.
*/
public boolean isLoggable(LogRecord record)
{
if (record.getLevel().intValue() < level.intValue())
return false;
if (filter != null)
return filter.isLoggable(record);
else
return true;
}
}

View file

@ -1,414 +0,0 @@
/* Level.java -- a class for indicating logging levels
Copyright (C) 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.util.logging;
import java.io.Serializable;
import java.util.ResourceBundle;
/**
* A class for indicating logging levels. A number of commonly used
* levels is pre-defined (such as <code>java.util.logging.Level.INFO</code>),
* and applications should utilize those whenever possible. For specialized
* purposes, however, applications can sub-class Level in order to define
* custom logging levels.
*
* @author Sascha Brawer (brawer@acm.org)
*/
public class Level implements Serializable
{
/* The integer values are the same as in the Sun J2SE 1.4.
* They have been obtained with a test program. In J2SE 1.4.1,
* Sun has amended the API documentation; these values are now
* publicly documented.
*/
/**
* The <code>OFF</code> level is used as a threshold for filtering
* log records, meaning that no message should be logged.
*
* @see Logger#setLevel(java.util.logging.Level)
*/
public static final Level OFF = new Level ("OFF", Integer.MAX_VALUE);
/**
* Log records whose level is <code>SEVERE</code> indicate a serious
* failure that prevents normal program execution. Messages at this
* level should be understandable to an inexperienced, non-technical
* end user. Ideally, they explain in simple words what actions the
* user can take in order to resolve the problem.
*/
public static final Level SEVERE = new Level ("SEVERE", 1000);
/**
* Log records whose level is <code>WARNING</code> indicate a
* potential problem that does not prevent normal program execution.
* Messages at this level should be understandable to an
* inexperienced, non-technical end user. Ideally, they explain in
* simple words what actions the user can take in order to resolve
* the problem.
*/
public static final Level WARNING = new Level ("WARNING", 900);
/**
* Log records whose level is <code>INFO</code> are used in purely
* informational situations that do not constitute serious errors or
* potential problems. In the default logging configuration, INFO
* messages will be written to the system console. For this reason,
* the INFO level should be used only for messages that are
* important to end users and system administrators. Messages at
* this level should be understandable to an inexperienced,
* non-technical user.
*/
public static final Level INFO = new Level ("INFO", 800);
/**
* Log records whose level is <code>CONFIG</code> are used for
* describing the static configuration, for example the windowing
* environment, the operating system version, etc.
*/
public static final Level CONFIG = new Level ("CONFIG", 700);
/**
* Log records whose level is <code>FINE</code> are typically used
* for messages that are relevant for developers using
* the component generating log messages. Examples include minor,
* recoverable failures, or possible inefficiencies.
*/
public static final Level FINE = new Level ("FINE", 500);
/**
* Log records whose level is <code>FINER</code> are intended for
* rather detailed tracing, for example entering a method, returning
* from a method, or throwing an exception.
*/
public static final Level FINER = new Level ("FINER", 400);
/**
* Log records whose level is <code>FINEST</code> are used for
* highly detailed tracing, for example to indicate that a certain
* point inside the body of a method has been reached.
*/
public static final Level FINEST = new Level ("FINEST", 300);
/**
* The <code>ALL</code> level is used as a threshold for filtering
* log records, meaning that every message should be logged.
*
* @see Logger#setLevel(java.util.logging.Level)
*/
public static final Level ALL = new Level ("ALL", Integer.MIN_VALUE);
private static final Level[] knownLevels = {
ALL, FINEST, FINER, FINE, CONFIG, INFO, WARNING, SEVERE, OFF
};
/**
* The name of the Level without localizing it, for example
* "WARNING".
*/
private String name;
/**
* The integer value of this <code>Level</code>.
*/
private int value;
/**
* The name of the resource bundle used for localizing the level
* name, or <code>null</code> if the name does not undergo
* localization.
*/
private String resourceBundleName;
/**
* Creates a logging level given a name and an integer value.
* It rarely is necessary to create custom levels,
* as most applications should be well served with one of the
* standard levels such as <code>Level.CONFIG</code>,
* <code>Level.INFO</code>, or <code>Level.FINE</code>.
*
* @param name the name of the level.
*
* @param value the integer value of the level. Please note
* that the Java<small><sup>TM</sup></small>
* Logging API does not specify integer
* values for standard levels (such as
* Level.FINE). Therefore, a custom
* level should pass an integer value that
* is calculated at run-time, e.g.
* <code>(Level.FINE.intValue() + Level.CONFIG.intValue())
* / 2</code> for a level between FINE and CONFIG.
*/
protected Level(String name, int value)
{
this(name, value, null);
}
/**
* Create a logging level given a name, an integer value and a name
* of a resource bundle for localizing the level name. It rarely
* is necessary to create custom levels, as most applications
* should be well served with one of the standard levels such as
* <code>Level.CONFIG</code>, <code>Level.INFO</code>, or
* <code>Level.FINE</code>.
*
* @param name the name of the level.
*
* @param value the integer value of the level. Please note
* that the Java<small><sup>TM</sup></small>
* Logging API does not specify integer
* values for standard levels (such as
* Level.FINE). Therefore, a custom
* level should pass an integer value that
* is calculated at run-time, e.g.
* <code>(Level.FINE.intValue() + Level.CONFIG.intValue())
* / 2</code> for a level between FINE and CONFIG.
*
* @param resourceBundleName the name of a resource bundle
* for localizing the level name, or <code>null</code>
* if the name does not need to be localized.
*/
protected Level(String name, int value, String resourceBundleName)
{
this.name = name;
this.value = value;
this.resourceBundleName = resourceBundleName;
}
static final long serialVersionUID = -8176160795706313070L;
/**
* Checks whether the Level has the same intValue as one of the
* pre-defined levels. If so, the pre-defined level object is
* returned.
*
* <br/>Since the resource bundle name is not taken into
* consideration, it is possible to resolve Level objects that have
* been de-serialized by another implementation, even if the other
* implementation uses a different resource bundle for localizing
* the names of pre-defined levels.
*/
private Object readResolve()
{
for (int i = 0; i < knownLevels.length; i++)
if (value == knownLevels[i].intValue())
return knownLevels[i];
return this;
}
/**
* Returns the name of the resource bundle used for localizing the
* level name.
*
* @return the name of the resource bundle used for localizing the
* level name, or <code>null</code> if the name does not undergo
* localization.
*/
public String getResourceBundleName()
{
return resourceBundleName;
}
/**
* Returns the name of the Level without localizing it, for example
* "WARNING".
*/
public String getName()
{
return name;
}
/**
* Returns the name of the Level after localizing it, for example
* "WARNUNG".
*/
public String getLocalizedName()
{
String localizedName = null;
if (resourceBundleName != null)
{
try
{
ResourceBundle b = ResourceBundle.getBundle(resourceBundleName);
localizedName = b.getString(name);
}
catch (Exception _)
{
}
}
if (localizedName != null)
return localizedName;
else
return name;
}
/**
* Returns the name of the Level without localizing it, for example
* "WARNING".
*/
public final String toString()
{
return getName();
}
/**
* Returns the integer value of the Level.
*/
public final int intValue()
{
return value;
}
/**
* Returns one of the standard Levels given either its name or its
* integer value. Custom subclasses of Level will not be returned
* by this method.
*
* @throws IllegalArgumentException if <code>name</code> is neither
* the name nor the integer value of one of the pre-defined standard
* logging levels.
*
* @throws NullPointerException if <code>name</code> is null.
*
*/
public static Level parse(String name)
throws IllegalArgumentException
{
/* This will throw a NullPointerException if name is null,
* as required by the API specification.
*/
name = name.intern();
for (int i = 0; i < knownLevels.length; i++)
{
if (name == knownLevels[i].name)
return knownLevels[i];
}
try
{
int num = Integer.parseInt(name);
for (int i = 0; i < knownLevels.length; i++)
if (num == knownLevels[i].value)
return knownLevels[i];
}
catch (NumberFormatException _)
{
}
String msg = "Not the name of a standard logging level: \"" + name + "\"";
throw new IllegalArgumentException(msg);
}
/**
* Checks whether this Level's integer value is equal to that of
* another object.
*
* @return <code>true</code> if <code>other</code> is an instance of
* <code>java.util.logging.Level</code> and has the same integer
* value, <code>false</code> otherwise.
*/
public boolean equals(Object other)
{
if (!(other instanceof Level))
return false;
return value == ((Level) other).value;
}
/**
* Returns a hash code for this Level which is based on its numeric
* value.
*/
public int hashCode()
{
return value;
}
/**
* Determines whether or not this Level is one of the standard
* levels specified in the Logging API.
*
* <p>This method is package-private because it is not part
* of the logging API specification. However, an XMLFormatter
* is supposed to emit the numeric value for a custom log
* level, but the name for a pre-defined level. It seems
* cleaner to put this method to Level than to write some
* procedural code for XMLFormatter.
*
* @return <code>true</code> if this Level is a standard level,
* <code>false</code> otherwise.
*/
final boolean isStandardLevel()
{
for (int i = 0; i < knownLevels.length; i++)
if (knownLevels[i] == this)
return true;
return false;
}
}

View file

@ -1,672 +0,0 @@
/* LogRecord.java --
A class for the state associated with individual logging events
Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.util.logging;
import java.util.ResourceBundle;
/**
* A <code>LogRecord</code> contains the state for an individual
* event to be logged.
*
* <p>As soon as a LogRecord instance has been handed over to the
* logging framework, applications should not manipulate it anymore.
*
* @author Sascha Brawer (brawer@acm.org)
*/
public class LogRecord
implements java.io.Serializable
{
/**
* The severity level of this <code>LogRecord</code>.
*/
private Level level;
/**
* The sequence number of this <code>LogRecord</code>.
*/
private long sequenceNumber;
/**
* The name of the class that issued the logging request, or
* <code>null</code> if this information could not be obtained.
*/
private String sourceClassName;
/**
* The name of the method that issued the logging request, or
* <code>null</code> if this information could not be obtained.
*/
private String sourceMethodName;
/**
* The message for this <code>LogRecord</code> before
* any localization or formatting.
*/
private String message;
/**
* An identifier for the thread in which this <code>LogRecord</code>
* was created. The identifier is not necessarily related to any
* thread identifiers used by the operating system.
*/
private int threadID;
/**
* The time when this <code>LogRecord</code> was created,
* in milliseconds since the beginning of January 1, 1970.
*/
private long millis;
/**
* The Throwable associated with this <code>LogRecord</code>, or
* <code>null</code> if the logged event is not related to an
* exception or error.
*/
private Throwable thrown;
/**
* The name of the logger where this <code>LogRecord</code> has
* originated, or <code>null</code> if this <code>LogRecord</code>
* does not originate from a <code>Logger</code>.
*/
private String loggerName;
/**
* The name of the resource bundle used for localizing log messages,
* or <code>null</code> if no bundle has been specified.
*/
private String resourceBundleName;
private transient Object[] parameters;
private transient ResourceBundle bundle;
/**
* Constructs a <code>LogRecord</code> given a severity level and
* an unlocalized message text. In addition, the sequence number,
* creation time (as returned by <code>getMillis()</code>) and
* thread ID are assigned. All other properties are set to
* <code>null</code>.
*
* @param level the severity level, for example <code>Level.WARNING</code>.
*
* @param message the message text (which will be used as key
* for looking up the localized message text
* if a resource bundle has been associated).
*/
public LogRecord(Level level, String message)
{
this.level = level;
this.message = message;
this.millis = System.currentTimeMillis();
/* A subclass of java.lang.Thread could override hashCode(),
* in which case the result would not be guaranteed anymore
* to be unique among all threads. While System.identityHashCode
* is not necessarily unique either, it at least cannot be
* overridden by user code. However, is might be a good idea
* to use something better for generating thread IDs.
*/
this.threadID = System.identityHashCode(Thread.currentThread());
sequenceNumber = allocateSeqNum();
}
/**
* Determined with the serialver tool of the Sun J2SE 1.4.
*/
static final long serialVersionUID = 5372048053134512534L;
private void readObject(java.io.ObjectInputStream in)
throws java.io.IOException, java.lang.ClassNotFoundException
{
in.defaultReadObject();
/* We assume that future versions will be downwards compatible,
* so we can ignore the versions.
*/
byte majorVersion = in.readByte();
byte minorVersion = in.readByte();
int numParams = in.readInt();
if (numParams >= 0)
{
parameters = new Object[numParams];
for (int i = 0; i < numParams; i++)
parameters[i] = in.readObject();
}
}
/**
* @serialData The default fields, followed by a major byte version
* number, followed by a minor byte version number, followed by
* information about the log record parameters. If
* <code>parameters</code> is <code>null</code>, the integer -1 is
* written, otherwise the length of the <code>parameters</code>
* array (which can be zero), followed by the result of calling
* {@link Object#toString() toString()} on the parameter (or
* <code>null</code> if the parameter is <code>null</code>).
*
* <p><strong>Specification Note:</strong> The Javadoc for the
* Sun reference implementation does not specify the version
* number. FIXME: Reverse-engineer the JDK and file a bug
* report with Sun, asking for amendment of the specification.
*/
private void writeObject(java.io.ObjectOutputStream out)
throws java.io.IOException
{
out.defaultWriteObject();
/* Major, minor version number: The Javadoc for J2SE1.4 does not
* specify the values.
*/
out.writeByte(0);
out.writeByte(0);
if (parameters == null)
out.writeInt(-1);
else
{
out.writeInt(parameters.length);
for (int i = 0; i < parameters.length; i++)
{
if (parameters[i] == null)
out.writeObject(null);
else
out.writeObject(parameters[i].toString());
}
}
}
/**
* Returns the name of the logger where this <code>LogRecord</code>
* has originated.
*
* @return the name of the source {@link Logger}, or
* <code>null</code> if this <code>LogRecord</code>
* does not originate from a <code>Logger</code>.
*/
public String getLoggerName()
{
return loggerName;
}
/**
* Sets the name of the logger where this <code>LogRecord</code>
* has originated.
*
* <p>As soon as a <code>LogRecord</code> has been handed over
* to the logging framework, applications should not modify it
* anymore. Therefore, this method should only be called on
* freshly constructed LogRecords.
*
* @param name the name of the source logger, or <code>null</code> to
* indicate that this <code>LogRecord</code> does not
* originate from a <code>Logger</code>.
*/
public void setLoggerName(String name)
{
loggerName = name;
}
/**
* Returns the resource bundle that is used when the message
* of this <code>LogRecord</code> needs to be localized.
*
* @return the resource bundle used for localization,
* or <code>null</code> if this message does not need
* to be localized.
*/
public ResourceBundle getResourceBundle()
{
return bundle;
}
/**
* Sets the resource bundle that is used when the message
* of this <code>LogRecord</code> needs to be localized.
*
* <p>As soon as a <code>LogRecord</code> has been handed over
* to the logging framework, applications should not modify it
* anymore. Therefore, this method should only be called on
* freshly constructed LogRecords.
*
* @param bundle the resource bundle to be used, or
* <code>null</code> to indicate that this
* message does not need to be localized.
*/
public void setResourceBundle(ResourceBundle bundle)
{
this.bundle = bundle;
/* FIXME: Is there a way to infer the name
* of a resource bundle from a ResourceBundle object?
*/
this.resourceBundleName = null;
}
/**
* Returns the name of the resource bundle that is used when the
* message of this <code>LogRecord</code> needs to be localized.
*
* @return the name of the resource bundle used for localization,
* or <code>null</code> if this message does not need
* to be localized.
*/
public String getResourceBundleName()
{
return resourceBundleName;
}
/**
* Sets the name of the resource bundle that is used when the
* message of this <code>LogRecord</code> needs to be localized.
*
* <p>As soon as a <code>LogRecord</code> has been handed over
* to the logging framework, applications should not modify it
* anymore. Therefore, this method should only be called on
* freshly constructed LogRecords.
*
* @param name the name of the resource bundle to be used, or
* <code>null</code> to indicate that this message
* does not need to be localized.
*/
public void setResourceBundleName(String name)
{
resourceBundleName = name;
bundle = null;
try
{
if (resourceBundleName != null)
bundle = ResourceBundle.getBundle(resourceBundleName);
}
catch (java.util.MissingResourceException _)
{
}
}
/**
* Returns the level of the LogRecord.
*
* <p>Applications should be aware of the possibility that the
* result is not necessarily one of the standard logging levels,
* since the logging framework allows to create custom subclasses
* of <code>java.util.logging.Level</code>. Therefore, filters
* should perform checks like <code>theRecord.getLevel().intValue()
* == Level.INFO.intValue()</code> instead of <code>theRecord.getLevel()
* == Level.INFO</code>.
*/
public Level getLevel()
{
return level;
}
/**
* Sets the severity level of this <code>LogRecord</code> to a new
* value.
*
* <p>As soon as a <code>LogRecord</code> has been handed over
* to the logging framework, applications should not modify it
* anymore. Therefore, this method should only be called on
* freshly constructed LogRecords.
*
* @param level the new severity level, for example
* <code>Level.WARNING</code>.
*/
public void setLevel(Level level)
{
this.level = level;
}
/**
* The last used sequence number for any LogRecord.
*/
private static long lastSeqNum;
/**
* Allocates a sequence number for a new LogRecord. This class
* method is only called by the LogRecord constructor.
*/
private static synchronized long allocateSeqNum()
{
lastSeqNum += 1;
return lastSeqNum;
}
/**
* Returns the sequence number of this <code>LogRecord</code>.
*/
public long getSequenceNumber()
{
return sequenceNumber;
}
/**
* Sets the sequence number of this <code>LogRecord</code> to a new
* value.
*
* <p>As soon as a <code>LogRecord</code> has been handed over
* to the logging framework, applications should not modify it
* anymore. Therefore, this method should only be called on
* freshly constructed LogRecords.
*
* @param seqNum the new sequence number.
*/
public void setSequenceNumber(long seqNum)
{
this.sequenceNumber = seqNum;
}
/**
* Returns the name of the class where the event being logged
* has had its origin. This information can be passed as
* parameter to some logging calls, and in certain cases, the
* logging framework tries to determine an approximation
* (which may or may not be accurate).
*
* @return the name of the class that issued the logging request,
* or <code>null</code> if this information could not
* be obtained.
*/
public String getSourceClassName()
{
if (sourceClassName != null)
return sourceClassName;
/* FIXME: Should infer this information from the call stack. */
return null;
}
/**
* Sets the name of the class where the event being logged
* has had its origin.
*
* <p>As soon as a <code>LogRecord</code> has been handed over
* to the logging framework, applications should not modify it
* anymore. Therefore, this method should only be called on
* freshly constructed LogRecords.
*
* @param sourceClassName the name of the class that issued the
* logging request, or <code>null</code> to indicate that
* this information could not be obtained.
*/
public void setSourceClassName(String sourceClassName)
{
this.sourceClassName = sourceClassName;
}
/**
* Returns the name of the method where the event being logged
* has had its origin. This information can be passed as
* parameter to some logging calls, and in certain cases, the
* logging framework tries to determine an approximation
* (which may or may not be accurate).
*
* @return the name of the method that issued the logging request,
* or <code>null</code> if this information could not
* be obtained.
*/
public String getSourceMethodName()
{
if (sourceMethodName != null)
return sourceMethodName;
/* FIXME: Should infer this information from the call stack. */
return null;
}
/**
* Sets the name of the method where the event being logged
* has had its origin.
*
* <p>As soon as a <code>LogRecord</code> has been handed over
* to the logging framework, applications should not modify it
* anymore. Therefore, this method should only be called on
* freshly constructed LogRecords.
*
* @param sourceMethodName the name of the method that issued the
* logging request, or <code>null</code> to indicate that
* this information could not be obtained.
*/
public void setSourceMethodName(String sourceMethodName)
{
this.sourceMethodName = sourceMethodName;
}
/**
* Returns the message for this <code>LogRecord</code> before
* any localization or parameter substitution.
*
* <p>A {@link Logger} will try to localize the message
* if a resource bundle has been associated with this
* <code>LogRecord</code>. In this case, the logger will call
* <code>getMessage()</code> and use the result as the key
* for looking up the localized message in the bundle.
* If no bundle has been associated, or if the result of
* <code>getMessage()</code> is not a valid key in the
* bundle, the logger will use the raw message text as
* returned by this method.
*
* @return the message text, or <code>null</code> if there
* is no message text.
*/
public String getMessage()
{
return message;
}
/**
* Sets the message for this <code>LogRecord</code>.
*
* <p>A <code>Logger</code> will try to localize the message
* if a resource bundle has been associated with this
* <code>LogRecord</code>. In this case, the logger will call
* <code>getMessage()</code> and use the result as the key
* for looking up the localized message in the bundle.
* If no bundle has been associated, or if the result of
* <code>getMessage()</code> is not a valid key in the
* bundle, the logger will use the raw message text as
* returned by this method.
*
* <p>It is possible to set the message to either an empty String or
* <code>null</code>, although this does not make the the message
* very helpful to human users.
*
* @param message the message text (which will be used as key
* for looking up the localized message text
* if a resource bundle has been associated).
*/
public void setMessage(String message)
{
this.message = message;
}
/**
* Returns the parameters to the log message.
*
* @return the parameters to the message, or <code>null</code> if
* the message has no parameters.
*/
public Object[] getParameters()
{
return parameters;
}
/**
* Sets the parameters to the log message.
*
* <p>As soon as a <code>LogRecord</code> has been handed over
* to the logging framework, applications should not modify it
* anymore. Therefore, this method should only be called on
* freshly constructed LogRecords.
*
* @param parameters the parameters to the message, or <code>null</code>
* to indicate that the message has no parameters.
*/
public void setParameters(Object[] parameters)
{
this.parameters = parameters;
}
/**
* Returns an identifier for the thread in which this
* <code>LogRecord</code> was created. The identifier is not
* necessarily related to any thread identifiers used by the
* operating system.
*
* @return an identifier for the source thread.
*/
public int getThreadID()
{
return threadID;
}
/**
* Sets the identifier indicating in which thread this
* <code>LogRecord</code> was created. The identifier is not
* necessarily related to any thread identifiers used by the
* operating system.
*
* <p>As soon as a <code>LogRecord</code> has been handed over
* to the logging framework, applications should not modify it
* anymore. Therefore, this method should only be called on
* freshly constructed LogRecords.
*
* @param threadID the identifier for the source thread.
*/
public void setThreadID(int threadID)
{
this.threadID = threadID;
}
/**
* Returns the time when this <code>LogRecord</code> was created.
*
* @return the time of creation in milliseconds since the beginning
* of January 1, 1970.
*/
public long getMillis()
{
return millis;
}
/**
* Sets the time when this <code>LogRecord</code> was created.
*
* <p>As soon as a <code>LogRecord</code> has been handed over
* to the logging framework, applications should not modify it
* anymore. Therefore, this method should only be called on
* freshly constructed LogRecords.
*
* @param millis the time of creation in milliseconds since the
* beginning of January 1, 1970.
*/
public void setMillis(long millis)
{
this.millis = millis;
}
/**
* Returns the Throwable associated with this <code>LogRecord</code>,
* or <code>null</code> if the logged event is not related to an exception
* or error.
*/
public Throwable getThrown()
{
return thrown;
}
/**
* Associates this <code>LogRecord</code> with an exception or error.
*
* <p>As soon as a <code>LogRecord</code> has been handed over
* to the logging framework, applications should not modify it
* anymore. Therefore, this method should only be called on
* freshly constructed LogRecords.
*
* @param thrown the exception or error to associate with, or
* <code>null</code> if this <code>LogRecord</code>
* should be made unrelated to an exception or error.
*/
public void setThrown(Throwable thrown)
{
this.thrown = thrown;
}
}

View file

@ -1,73 +0,0 @@
/* LoggingPermission.java -- a class for logging permissions.
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.util.logging;
public final class LoggingPermission
extends java.security.BasicPermission
{
/**
* Creates a new LoggingPermission.
*
* @param name the name of the permission, which must be "control".
*
* @param actions the list of actions for the permission, which
* must be either <code>null</code> or an empty
* string.
*
* @exception IllegalArgumentException if <code>name</code>
* is not "control", or <code>actions</code> is
* neither <code>null</code> nor empty.
*/
public LoggingPermission(String name, String actions)
{
super("control", "");
if (!"control".equals(name))
{
throw new IllegalArgumentException(
"name of LoggingPermission must be \"control\"");
}
if ((actions != null) && (actions.length() != 0))
{
throw new IllegalArgumentException(
"actions of LoggingPermissions must be null or empty");
}
}
}

View file

@ -1,345 +0,0 @@
/* MemoryHandler.java -- a class for buffering log messages in a memory buffer
Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.util.logging;
/**
* A <code>MemoryHandler</code> maintains a circular buffer of
* log records.
*
* <p><strong>Configuration:</strong> Values of the subsequent
* <code>LogManager</code> properties are taken into consideration
* when a <code>MemoryHandler</code> is initialized.
* If a property is not defined, or if it has an invalid
* value, a default is taken without an exception being thrown.
*
* <ul>
* <li><code>java.util.MemoryHandler.level</code> - specifies
* the initial severity level threshold. Default value:
* <code>Level.ALL</code>.</li>
* <li><code>java.util.MemoryHandler.filter</code> - specifies
* the name of a Filter class. Default value: No Filter.</li>
* <li><code>java.util.MemoryHandler.size</code> - specifies the
* maximum number of log records that are kept in the circular
* buffer. Default value: 1000.</li>
* <li><code>java.util.MemoryHandler.push</code> - specifies the
* <code>pushLevel</code>. Default value:
* <code>Level.SEVERE</code>.</li>
* <li><code>java.util.MemoryHandler.target</code> - specifies the
* name of a subclass of {@link Handler} that will be used as the
* target handler. There is no default value for this property;
* if it is not set, the no-argument MemoryHandler constructor
* will throw an exception.</li>
* </ul>
*
* @author Sascha Brawer (brawer@acm.org)
*/
public class MemoryHandler
extends Handler
{
/**
* The storage area used for buffering the unpushed log records in
* memory.
*/
private final LogRecord[] buffer;
/**
* The current position in the circular buffer. For a new
* MemoryHandler, or immediately after {@link #push()} was called,
* the value of this variable is zero. Each call to {@link
* #publish(LogRecord)} will store the published LogRecord into
* <code>buffer[position]</code> before position is incremented by
* one. If position becomes greater than the size of the buffer, it
* is reset to zero.
*/
private int position;
/**
* The number of log records which have been published, but not
* pushed yet to the target handler.
*/
private int numPublished;
/**
* The push level threshold for this <code>Handler</code>. When a
* record is published whose severity level is greater than or equal
* to the <code>pushLevel</code> of this <code>MemoryHandler</code>,
* the {@link #push()} method will be invoked for pushing the buffer
* contents to the target <code>Handler</code>.
*/
private Level pushLevel;
/**
* The Handler to which log records are forwarded for actual
* publication.
*/
private final Handler target;
/**
* Constructs a <code>MemoryHandler</code> for keeping a circular
* buffer of LogRecords; the initial configuration is determined by
* the <code>LogManager</code> properties described above.
*/
public MemoryHandler()
{
this((Handler) LogManager.getInstanceProperty(
"java.util.logging.MemoryHandler.target",
Handler.class, /* default */ null),
LogManager.getIntPropertyClamped(
"java.util.logging.MemoryHandler.size",
/* default */ 1000,
/* minimum value */ 1,
/* maximum value */ Integer.MAX_VALUE),
LogManager.getLevelProperty(
"java.util.logging.MemoryHandler.push",
/* default push level */ Level.SEVERE));
}
/**
* Constructs a <code>MemoryHandler</code> for keeping a circular
* buffer of LogRecords, given some parameters. The values of the
* other parameters are taken from LogManager properties, as
* described above.
*
* @param target the target handler that will receive those
* log records that are passed on for publication.
*
* @param size the number of log records that are kept in the buffer.
* The value must be a at least one.
*
* @param pushLevel the push level threshold for this
* <code>MemoryHandler</code>. When a record is published whose
* severity level is greater than or equal to
* <code>pushLevel</code>, the {@link #push()} method will be
* invoked in order to push the bufffer contents to
* <code>target</code>.
*
* @throws java.lang.IllegalArgumentException if <code>size</code>
* is negative or zero. The GNU implementation also throws
* an IllegalArgumentException if <code>target</code> or
* <code>pushLevel</code> are <code>null</code>, but the
* API specification does not prescribe what should happen
* in those cases.
*/
public MemoryHandler(Handler target, int size, Level pushLevel)
{
if ((target == null) || (size <= 0) || (pushLevel == null))
throw new IllegalArgumentException();
buffer = new LogRecord[size];
this.pushLevel = pushLevel;
this.target = target;
setLevel(LogManager.getLevelProperty(
"java.util.logging.MemoryHandler.level",
/* default value */ Level.ALL));
setFilter((Filter) LogManager.getInstanceProperty(
"java.util.logging.MemoryHandler.filter",
/* must be instance of */ Filter.class,
/* default value */ null));
}
/**
* Stores a <code>LogRecord</code> in a fixed-size circular buffer,
* provided the record passes all tests for being loggable. If the
* buffer is full, the oldest record will be discarded.
*
* <p>If the record has a severity level which is greater than or
* equal to the <code>pushLevel</code> of this
* <code>MemoryHandler</code>, the {@link #push()} method will be
* invoked for pushing the buffer contents to the target
* <code>Handler</code>.
*
* <p>Most applications do not need to call this method directly.
* Instead, they will use use a {@link Logger}, which will create
* LogRecords and distribute them to registered handlers.
*
* @param record the log event to be published.
*/
public void publish(LogRecord record)
{
if (!isLoggable(record))
return;
buffer[position] = record;
position = (position + 1) % buffer.length;
numPublished = numPublished + 1;
if (record.getLevel().intValue() >= pushLevel.intValue())
push();
}
/**
* Pushes the contents of the memory buffer to the target
* <code>Handler</code> and clears the buffer. Note that
* the target handler will discard those records that do
* not satisfy its own severity level threshold, or that are
* not considered loggable by an installed {@link Filter}.
*
* <p>In case of an I/O failure, the {@link ErrorManager} of the
* target <code>Handler</code> will be notified, but the caller of
* this method will not receive an exception.
*/
public void push()
{
int i;
if (numPublished < buffer.length)
{
for (i = 0; i < position; i++)
target.publish(buffer[i]);
}
else
{
for (i = position; i < buffer.length; i++)
target.publish(buffer[i]);
for (i = 0; i < position; i++)
target.publish(buffer[i]);
}
numPublished = 0;
position = 0;
}
/**
* Forces any data that may have been buffered by the target
* <code>Handler</code> to the underlying output device, but
* does <em>not</em> push the contents of the circular memory
* buffer to the target handler.
*
* <p>In case of an I/O failure, the {@link ErrorManager} of the
* target <code>Handler</code> will be notified, but the caller of
* this method will not receive an exception.
*
* @see #push()
*/
public void flush()
{
target.flush();
}
/**
* Closes this <code>MemoryHandler</code> and its associated target
* handler, discarding the contents of the memory buffer. However,
* any data that may have been buffered by the target
* <code>Handler</code> is forced to the underlying output device.
*
* <p>As soon as <code>close</code> has been called,
* a <code>Handler</code> should not be used anymore. Attempts
* to publish log records, to flush buffers, or to modify the
* <code>Handler</code> in any other way may throw runtime
* exceptions after calling <code>close</code>.</p>
*
* <p>In case of an I/O failure, the <code>ErrorManager</code> of
* the associated target <code>Handler</code> will be informed, but
* the caller of this method will not receive an exception.</p>
*
* @throws SecurityException if a security manager exists and
* the caller is not granted the permission to control
* the logging infrastructure.
*
* @see #push()
*/
public void close()
throws SecurityException
{
push();
/* This will check for LoggingPermission("control"). If the
* current security context does not grant this permission,
* push() has been executed, but this does not impose a
* security risk.
*/
target.close();
}
/**
* Returns the push level threshold for this <code>Handler</code>.
* When a record is published whose severity level is greater
* than or equal to the <code>pushLevel</code> of this
* <code>MemoryHandler</code>, the {@link #push()} method will be
* invoked for pushing the buffer contents to the target
* <code>Handler</code>.
*
* @return the push level threshold for automatic pushing.
*/
public Level getPushLevel()
{
return pushLevel;
}
/**
* Sets the push level threshold for this <code>Handler</code>.
* When a record is published whose severity level is greater
* than or equal to the <code>pushLevel</code> of this
* <code>MemoryHandler</code>, the {@link #push()} method will be
* invoked for pushing the buffer contents to the target
* <code>Handler</code>.
*
* @param pushLevel the push level threshold for automatic pushing.
*
* @exception SecurityException if a security manager exists and
* the caller is not granted the permission to control
* the logging infrastructure.
*
* @exception NullPointerException if <code>pushLevel</code> is
* <code>null</code>.
*/
public void setPushLevel(Level pushLevel)
{
LogManager.getLogManager().checkAccess();
/* Throws a NullPointerException if pushLevel is null. */
pushLevel.getClass();
this.pushLevel = pushLevel;
}
}

View file

@ -1,119 +0,0 @@
/* SimpleFormatter.java --
A class for formatting log records into short human-readable messages
Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.util.logging;
import java.text.DateFormat;
import java.util.Date;
/**
* A <code>SimpleFormatter</code> formats log records into
* short human-readable messages, typically one or two lines.
*
* @author Sascha Brawer (brawer@acm.org)
*/
public class SimpleFormatter
extends Formatter
{
/**
* Constructs a SimpleFormatter.
*/
public SimpleFormatter()
{
}
/**
* An instance of a DateFormatter that is used for formatting
* the time of a log record into a human-readable string,
* according to the rules of the current locale. The value
* is set after the first invocation of format, since it is
* common that a JVM will instantiate a SimpleFormatter without
* ever using it.
*/
private DateFormat dateFormat;
/**
* The character sequence that is used to separate lines in the
* generated stream. Somewhat surprisingly, the Sun J2SE 1.4
* reference implementation always uses UNIX line endings, even on
* platforms that have different line ending conventions (i.e.,
* DOS). The GNU implementation does not replicate this bug.
*
* @see Sun bug parade, bug #4462871,
* "java.util.logging.SimpleFormatter uses hard-coded line separator".
*/
static final String lineSep = System.getProperty("line.separator");
/**
* Formats a log record into a String.
*
* @param the log record to be formatted.
*
* @return a short human-readable message, typically one or two
* lines. Lines are separated using the default platform line
* separator.
*
* @throws NullPointerException if <code>record</code>
* is <code>null</code>.
*/
public String format(LogRecord record)
{
StringBuffer buf = new StringBuffer(180);
if (dateFormat == null)
dateFormat = DateFormat.getDateTimeInstance();
buf.append(dateFormat.format(new Date(record.getMillis())));
buf.append(' ');
buf.append(record.getSourceClassName());
buf.append(' ');
buf.append(record.getSourceMethodName());
buf.append(lineSep);
buf.append(record.getLevel());
buf.append(": ");
buf.append(formatMessage(record));
buf.append(lineSep);
return buf.toString();
}
}

View file

@ -1,221 +0,0 @@
/* SocketHandler.java -- a class for publishing log messages to network sockets
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.util.logging;
/**
* A <code>SocketHandler</code> publishes log records to
* a TCP/IP socket.
*
* <p><strong>Configuration:</strong> Values of the subsequent
* <code>LogManager</code> properties are taken into consideration
* when a <code>SocketHandler</code> is initialized.
* If a property is not defined, or if it has an invalid
* value, a default is taken without an exception being thrown.
*
* <ul>
*
* <li><code>java.util.SocketHandler.level</code> - specifies
* the initial severity level threshold. Default value:
* <code>Level.ALL</code>.</li>
*
* <li><code>java.util.SocketHandler.filter</code> - specifies
* the name of a Filter class. Default value: No Filter.</li>
*
* <li><code>java.util.SocketHandler.formatter</code> - specifies
* the name of a Formatter class. Default value:
* <code>java.util.logging.XMLFormatter</code>.</li>
*
* <li><code>java.util.SocketHandler.encoding</code> - specifies
* the name of the character encoding. Default value:
* the default platform encoding.</li>
*
* <li><code>java.util.SocketHandler.host</code> - specifies
* the name of the host to which records are published.
* There is no default value for this property; if it is
* not set, the SocketHandler constructor will throw
* an exception.</li>
*
* <li><code>java.util.SocketHandler.port</code> - specifies
* the TCP/IP port to which records are published.
* There is no default value for this property; if it is
* not set, the SocketHandler constructor will throw
* an exception.</li>
*
* </ul>
*
* @author Sascha Brawer (brawer@acm.org)
*/
public class SocketHandler
extends StreamHandler
{
/**
* Constructs a <code>SocketHandler</code> that publishes log
* records to a TCP/IP socket. Tthe initial configuration is
* determined by the <code>LogManager</code> properties described
* above.
*
* @throws java.io.IOException if the connection to the specified
* network host and port cannot be established.
*
* @throws java.lang.IllegalArgumentException if either the
* <code>java.util.logging.SocketHandler.host</code>
* or <code>java.util.logging.SocketHandler.port</code>
* LogManager properties is not defined, or specifies
* an invalid value.
*/
public SocketHandler()
throws java.io.IOException
{
this(LogManager.getLogManager().getProperty("java.util.logging.SocketHandler.host"),
getPortNumber());
}
/**
* Constructs a <code>SocketHandler</code> that publishes log
* records to a TCP/IP socket. With the exception of the internet
* host and port, the initial configuration is determined by the
* <code>LogManager</code> properties described above.
*
* @param host the Internet host to which log records will be
* forwarded.
*
* @param port the port at the host which will accept a request
* for a TCP/IP connection.
*
* @throws java.io.IOException if the connection to the specified
* network host and port cannot be established.
*
* @throws java.lang.IllegalArgumentException if either
* <code>host</code> or <code>port</code> specify
* an invalid value.
*/
public SocketHandler(String host, int port)
throws java.io.IOException
{
super(createSocket(host, port),
"java.util.logging.SocketHandler",
/* default level */ Level.ALL,
/* formatter */ null,
/* default formatter */ XMLFormatter.class);
}
/**
* Retrieves the port number from the java.util.logging.SocketHandler.port
* LogManager property.
*
* @throws IllegalArgumentException if the property is not defined or
* does not specify an integer value.
*/
private static int getPortNumber()
{
try {
return Integer.parseInt(LogManager.getLogManager().getProperty("java.util.logging.SocketHandler.port"));
} catch (Exception ex) {
throw new IllegalArgumentException();
}
}
/**
* Creates an OutputStream for publishing log records to an Internet
* host and port. This private method is a helper for use by the
* constructor of SocketHandler.
*
* @param host the Internet host to which log records will be
* forwarded.
*
* @param port the port at the host which will accept a request
* for a TCP/IP connection.
*
* @throws java.io.IOException if the connection to the specified
* network host and port cannot be established.
*
* @throws java.lang.IllegalArgumentException if either
* <code>host</code> or <code>port</code> specify
* an invalid value.
*/
private static java.io.OutputStream createSocket(String host, int port)
throws java.io.IOException, java.lang.IllegalArgumentException
{
java.net.Socket socket;
if ((host == null) || (port < 1))
throw new IllegalArgumentException();
socket = new java.net.Socket(host, port);
socket.shutdownInput();
/* The architecture of the logging framework provides replaceable
* formatters. Because these formatters perform their task by
* returning one single String for each LogRecord to be formatted,
* there is no need to buffer.
*/
socket.setTcpNoDelay(true);
return socket.getOutputStream();
}
/**
* Publishes a <code>LogRecord</code> to the network socket,
* provided the record passes all tests for being loggable.
* In addition, all data that may have been buffered will
* be forced to the network stream.
*
* <p>Most applications do not need to call this method directly.
* Instead, they will use a {@link Logger} instance, which will
* create LogRecords and distribute them to registered handlers.
*
* <p>In case of an I/O failure, the <code>ErrorManager</code>
* of this <code>SocketHandler</code> will be informed, but the caller
* of this method will not receive an exception.
*
* @param record the log event to be published.
*/
public void publish(LogRecord record)
{
super.publish(record);
flush();
}
}

View file

@ -1,521 +0,0 @@
/* StreamHandler.java --
A class for publishing log messages to instances of java.io.OutputStream
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.util.logging;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
/**
* A <code>StreamHandler</code> publishes <code>LogRecords</code> to
* a instances of <code>java.io.OutputStream</code>.
*
* @author Sascha Brawer (brawer@acm.org)
*/
public class StreamHandler
extends Handler
{
private OutputStream out;
private Writer writer;
/**
* Indicates the current state of this StreamHandler. The value
* should be one of STATE_FRESH, STATE_PUBLISHED, or STATE_CLOSED.
*/
private int streamState = STATE_FRESH;
/**
* streamState having this value indicates that the StreamHandler
* has been created, but the publish(LogRecord) method has not been
* called yet. If the StreamHandler has been constructed without an
* OutputStream, writer will be null, otherwise it is set to a
* freshly created OutputStreamWriter.
*/
private static final int STATE_FRESH = 0;
/**
* streamState having this value indicates that the publish(LocRecord)
* method has been called at least once.
*/
private static final int STATE_PUBLISHED = 1;
/**
* streamState having this value indicates that the close() method
* has been called.
*/
private static final int STATE_CLOSED = 2;
/**
* Creates a <code>StreamHandler</code> without an output stream.
* Subclasses can later use {@link
* #setOutputStream(java.io.OutputStream)} to associate an output
* stream with this StreamHandler.
*/
public StreamHandler()
{
this(null, null);
}
/**
* Creates a <code>StreamHandler</code> that formats log messages
* with the specified Formatter and publishes them to the specified
* output stream.
*
* @param out the output stream to which the formatted log messages
* are published.
*
* @param formatter the <code>Formatter</code> that will be used
* to format log messages.
*/
public StreamHandler(OutputStream out, Formatter formatter)
{
this(out, "java.util.logging.StreamHandler", Level.INFO,
formatter, SimpleFormatter.class);
}
StreamHandler(
OutputStream out,
String propertyPrefix,
Level defaultLevel,
Formatter formatter, Class defaultFormatterClass)
{
this.level = LogManager.getLevelProperty(propertyPrefix + ".level",
defaultLevel);
this.filter = (Filter) LogManager.getInstanceProperty(
propertyPrefix + ".filter",
/* must be instance of */ Filter.class,
/* default: new instance of */ null);
if (formatter != null)
this.formatter = formatter;
else
this.formatter = (Formatter) LogManager.getInstanceProperty(
propertyPrefix + ".formatter",
/* must be instance of */ Formatter.class,
/* default: new instance of */ defaultFormatterClass);
try
{
String enc = LogManager.getLogManager().getProperty(propertyPrefix
+ ".encoding");
/* make sure enc actually is a valid encoding */
if ((enc != null) && (enc.length() > 0))
new String(new byte[0], enc);
this.encoding = enc;
}
catch (Exception _)
{
}
if (out != null)
{
try
{
changeWriter(out, getEncoding());
}
catch (UnsupportedEncodingException uex)
{
/* This should never happen, since the validity of the encoding
* name has been checked above.
*/
throw new RuntimeException(uex.getMessage());
}
}
}
private void checkOpen()
{
if (streamState == STATE_CLOSED)
throw new IllegalStateException(this.toString() + " has been closed");
}
private void checkFresh()
{
checkOpen();
if (streamState != STATE_FRESH)
throw new IllegalStateException("some log records have been published to " + this);
}
private void changeWriter(OutputStream out, String encoding)
throws UnsupportedEncodingException
{
OutputStreamWriter writer;
/* The logging API says that a null encoding means the default
* platform encoding. However, java.io.OutputStreamWriter needs
* another constructor for the default platform encoding,
* passing null would throw an exception.
*/
if (encoding == null)
writer = new OutputStreamWriter(out);
else
writer = new OutputStreamWriter(out, encoding);
/* Closing the stream has side effects -- do this only after
* creating a new writer has been successful.
*/
if ((streamState != STATE_FRESH) || (this.writer != null))
close();
this.writer = writer;
this.out = out;
this.encoding = encoding;
streamState = STATE_FRESH;
}
/**
* Sets the character encoding which this handler uses for publishing
* log records. The encoding of a <code>StreamHandler</code> must be
* set before any log records have been published.
*
* @param encoding the name of a character encoding, or <code>null</code>
* for the default encoding.
*
* @throws SecurityException if a security manager exists and
* the caller is not granted the permission to control the
* the logging infrastructure.
*
* @exception IllegalStateException if any log records have been
* published to this <code>StreamHandler</code> before. Please
* be aware that this is a pecularity of the GNU implementation.
* While the API specification indicates that it is an error
* if the encoding is set after records have been published,
* it does not mandate any specific behavior for that case.
*/
public void setEncoding(String encoding)
throws SecurityException, UnsupportedEncodingException
{
/* The inherited implementation first checks whether the invoking
* code indeed has the permission to control the logging infra-
* structure, and throws a SecurityException if this was not the
* case.
*
* Next, it verifies that the encoding is supported and throws
* an UnsupportedEncodingExcpetion otherwise. Finally, it remembers
* the name of the encoding.
*/
super.setEncoding(encoding);
checkFresh();
/* If out is null, setEncoding is being called before an output
* stream has been set. In that case, we need to check that the
* encoding is valid, and remember it if this is the case. Since
* this is exactly what the inherited implementation of
* Handler.setEncoding does, we can delegate.
*/
if (out != null)
{
/* The logging API says that a null encoding means the default
* platform encoding. However, java.io.OutputStreamWriter needs
* another constructor for the default platform encoding, passing
* null would throw an exception.
*/
if (encoding == null)
writer = new OutputStreamWriter(out);
else
writer = new OutputStreamWriter(out, encoding);
}
}
/**
* Changes the output stream to which this handler publishes
* logging records.
*
* @throws SecurityException if a security manager exists and
* the caller is not granted the permission to control
* the logging infrastructure.
*
* @throws NullPointerException if <code>out</code>
* is <code>null</code>.
*/
protected void setOutputStream(OutputStream out)
throws SecurityException
{
LogManager.getLogManager().checkAccess();
/* Throw a NullPointerException if out is null. */
out.getClass();
try
{
changeWriter(out, getEncoding());
}
catch (UnsupportedEncodingException ex)
{
/* This seems quite unlikely to happen, unless the underlying
* implementation of java.io.OutputStreamWriter changes its
* mind (at runtime) about the set of supported character
* encodings.
*/
throw new RuntimeException(ex.getMessage());
}
}
/**
* Publishes a <code>LogRecord</code> to the associated output
* stream, provided the record passes all tests for being loggable.
* The <code>StreamHandler</code> will localize the message of the
* log record and substitute any message parameters.
*
* <p>Most applications do not need to call this method directly.
* Instead, they will use use a {@link Logger}, which will create
* LogRecords and distribute them to registered handlers.
*
* <p>In case of an I/O failure, the <code>ErrorManager</code>
* of this <code>Handler</code> will be informed, but the caller
* of this method will not receive an exception.
*
* <p>If a log record is being published to a
* <code>StreamHandler</code> that has been closed earlier, the Sun
* J2SE 1.4 reference can be observed to silently ignore the
* call. The GNU implementation, however, intentionally behaves
* differently by informing the <code>ErrorManager</code> associated
* with this <code>StreamHandler</code>. Since the condition
* indicates a programming error, the programmer should be
* informed. It also seems extremely unlikely that any application
* would depend on the exact behavior in this rather obscure,
* erroneous case -- especially since the API specification does not
* prescribe what is supposed to happen.
*
* @param record the log event to be published.
*/
public void publish(LogRecord record)
{
String formattedMessage;
if (!isLoggable(record))
return;
if (streamState == STATE_FRESH)
{
try
{
writer.write(formatter.getHead(this));
}
catch (java.io.IOException ex)
{
reportError(null, ex, ErrorManager.WRITE_FAILURE);
return;
}
catch (Exception ex)
{
reportError(null, ex, ErrorManager.GENERIC_FAILURE);
return;
}
streamState = STATE_PUBLISHED;
}
try
{
formattedMessage = formatter.format(record);
}
catch (Exception ex)
{
reportError(null, ex, ErrorManager.FORMAT_FAILURE);
return;
}
try
{
writer.write(formattedMessage);
}
catch (Exception ex)
{
reportError(null, ex, ErrorManager.WRITE_FAILURE);
}
}
/**
* Checks whether or not a <code>LogRecord</code> would be logged
* if it was passed to this <code>StreamHandler</code> for publication.
*
* <p>The <code>StreamHandler</code> implementation first checks
* whether a writer is present and the handler's level is greater
* than or equal to the severity level threshold. In a second step,
* if a {@link Filter} has been installed, its {@link
* Filter#isLoggable(LogRecord) isLoggable} method is
* invoked. Subclasses of <code>StreamHandler</code> can override
* this method to impose their own constraints.
*
* @param record the <code>LogRecord</code> to be checked.
*
* @return <code>true</code> if <code>record</code> would
* be published by {@link #publish(LogRecord) publish},
* <code>false</code> if it would be discarded.
*
* @see #setLevel(Level)
* @see #setFilter(Filter)
* @see Filter#isLoggable(LogRecord)
*
* @throws NullPointerException if <code>record</code> is
* <code>null</code>. */
public boolean isLoggable(LogRecord record)
{
return (writer != null) && super.isLoggable(record);
}
/**
* Forces any data that may have been buffered to the underlying
* output device.
*
* <p>In case of an I/O failure, the <code>ErrorManager</code>
* of this <code>Handler</code> will be informed, but the caller
* of this method will not receive an exception.
*
* <p>If a <code>StreamHandler</code> that has been closed earlier
* is closed a second time, the Sun J2SE 1.4 reference can be
* observed to silently ignore the call. The GNU implementation,
* however, intentionally behaves differently by informing the
* <code>ErrorManager</code> associated with this
* <code>StreamHandler</code>. Since the condition indicates a
* programming error, the programmer should be informed. It also
* seems extremely unlikely that any application would depend on the
* exact behavior in this rather obscure, erroneous case --
* especially since the API specification does not prescribe what is
* supposed to happen.
*/
public void flush()
{
try
{
checkOpen();
if (writer != null)
writer.flush();
}
catch (Exception ex)
{
reportError(null, ex, ErrorManager.FLUSH_FAILURE);
}
}
/**
* Closes this <code>StreamHandler</code> after having forced any
* data that may have been buffered to the underlying output
* device.
*
* <p>As soon as <code>close</code> has been called,
* a <code>Handler</code> should not be used anymore. Attempts
* to publish log records, to flush buffers, or to modify the
* <code>Handler</code> in any other way may throw runtime
* exceptions after calling <code>close</code>.</p>
*
* <p>In case of an I/O failure, the <code>ErrorManager</code>
* of this <code>Handler</code> will be informed, but the caller
* of this method will not receive an exception.</p>
*
* <p>If a <code>StreamHandler</code> that has been closed earlier
* is closed a second time, the Sun J2SE 1.4 reference can be
* observed to silently ignore the call. The GNU implementation,
* however, intentionally behaves differently by informing the
* <code>ErrorManager</code> associated with this
* <code>StreamHandler</code>. Since the condition indicates a
* programming error, the programmer should be informed. It also
* seems extremely unlikely that any application would depend on the
* exact behavior in this rather obscure, erroneous case --
* especially since the API specification does not prescribe what is
* supposed to happen.
*
* @throws SecurityException if a security manager exists and
* the caller is not granted the permission to control
* the logging infrastructure.
*/
public void close()
throws SecurityException
{
LogManager.getLogManager().checkAccess();
try
{
/* Although flush also calls checkOpen, it catches
* any exceptions and reports them to the ErrorManager
* as flush failures. However, we want to report
* a closed stream as a close failure, not as a
* flush failure here. Therefore, we call checkOpen()
* before flush().
*/
checkOpen();
flush();
if (writer != null)
{
if (formatter != null)
{
/* Even if the StreamHandler has never published a record,
* it emits head and tail upon closing. An earlier version
* of the GNU Classpath implementation did not emitted
* anything. However, this had caused XML log files to be
* entirely empty instead of containing no log records.
*/
if (streamState == STATE_FRESH)
writer.write(formatter.getHead(this));
if (streamState != STATE_CLOSED)
writer.write(formatter.getTail(this));
}
streamState = STATE_CLOSED;
writer.close();
}
}
catch (Exception ex)
{
reportError(null, ex, ErrorManager.CLOSE_FAILURE);
}
}
}

View file

@ -1,387 +0,0 @@
/* XMLFormatter.java --
A class for formatting log messages into a standard XML format
Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.util.logging;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.ResourceBundle;
/**
* An <code>XMLFormatter</code> formats LogRecords into
* a standard XML format.
*
* @author Sascha Brawer (brawer@acm.org)
*/
public class XMLFormatter
extends Formatter
{
/**
* Constructs a new XMLFormatter.
*/
public XMLFormatter()
{
}
/**
* The character sequence that is used to separate lines in the
* generated XML stream. Somewhat surprisingly, the Sun J2SE 1.4
* reference implementation always uses UNIX line endings, even on
* platforms that have different line ending conventions (i.e.,
* DOS). The GNU Classpath implementation does not replicates this
* bug.
*
* See also the Sun bug parade, bug #4462871,
* "java.util.logging.SimpleFormatter uses hard-coded line separator".
*/
private static final String lineSep = SimpleFormatter.lineSep;
/**
* A DateFormat for emitting time in the ISO 8601 format.
* Since the API specification of SimpleDateFormat does not talk
* about its thread-safety, we cannot share a singleton instance.
*/
private final SimpleDateFormat iso8601
= new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
/**
* Appends a line consisting of indentation, opening element tag,
* element content, closing element tag and line separator to
* a StringBuffer, provided that the element content is
* actually existing.
*
* @param buf the StringBuffer to which the line will be appended.
*
* @param indent the indentation level.
*
* @param tag the element tag name, for instance <code>method</code>.
*
* @param content the element content, or <code>null</code> to
* have no output whatsoever appended to <code>buf</code>.
*/
private static void appendTag(StringBuffer buf, int indent,
String tag, String content)
{
int i;
if (content == null)
return;
for (i = 0; i < indent * 2; i++)
buf.append(' ');
buf.append("<");
buf.append(tag);
buf.append('>');
/* Append the content, but escape for XML by replacing
* '&', '<', '>' and all non-ASCII characters with
* appropriate escape sequences.
* The Sun J2SE 1.4 reference implementation does not
* escape non-ASCII characters. This is a bug in their
* implementation which has been reported in the Java
* bug parade as bug number (FIXME: Insert number here).
*/
for (i = 0; i < content.length(); i++)
{
char c = content.charAt(i);
switch (c)
{
case '&':
buf.append("&amp;");
break;
case '<':
buf.append("&lt;");
break;
case '>':
buf.append("&gt;");
break;
default:
if (((c >= 0x20) && (c <= 0x7e))
|| (c == /* line feed */ 10)
|| (c == /* carriage return */ 13))
buf.append(c);
else
{
buf.append("&#");
buf.append((int) c);
buf.append(';');
}
break;
} /* switch (c) */
} /* for i */
buf.append("</");
buf.append(tag);
buf.append(">");
buf.append(lineSep);
}
/**
* Appends a line consisting of indentation, opening element tag,
* numeric element content, closing element tag and line separator
* to a StringBuffer.
*
* @param buf the StringBuffer to which the line will be appended.
*
* @param indent the indentation level.
*
* @param tag the element tag name, for instance <code>method</code>.
*
* @param content the element content.
*/
private static void appendTag(StringBuffer buf, int indent,
String tag, long content)
{
appendTag(buf, indent, tag, Long.toString(content));
}
public String format(LogRecord record)
{
StringBuffer buf = new StringBuffer(400);
Level level = record.getLevel();
long millis = record.getMillis();
Object[] params = record.getParameters();
ResourceBundle bundle = record.getResourceBundle();
String message;
buf.append("<record>");
buf.append(lineSep);
appendTag(buf, 1, "date", iso8601.format(new Date(millis)));
appendTag(buf, 1, "millis", record.getMillis());
appendTag(buf, 1, "sequence", record.getSequenceNumber());
appendTag(buf, 1, "logger", record.getLoggerName());
if (level.isStandardLevel())
appendTag(buf, 1, "level", level.toString());
else
appendTag(buf, 1, "level", level.intValue());
appendTag(buf, 1, "class", record.getSourceClassName());
appendTag(buf, 1, "method", record.getSourceMethodName());
appendTag(buf, 1, "thread", record.getThreadID());
/* The Sun J2SE 1.4 reference implementation does not emit the
* message in localized form. This is in violation of the API
* specification. The GNU Classpath implementation intentionally
* replicates the buggy behavior of the Sun implementation, as
* different log files might be a big nuisance to users.
*/
try
{
record.setResourceBundle(null);
message = formatMessage(record);
}
finally
{
record.setResourceBundle(bundle);
}
appendTag(buf, 1, "message", message);
/* The Sun J2SE 1.4 reference implementation does not
* emit key, catalog and param tags. This is in violation
* of the API specification. The Classpath implementation
* intentionally replicates the buggy behavior of the
* Sun implementation, as different log files might be
* a big nuisance to users.
*
* FIXME: File a bug report with Sun. Insert bug number here.
*
*
* key = record.getMessage();
* if (key == null)
* key = "";
*
* if ((bundle != null) && !key.equals(message))
* {
* appendTag(buf, 1, "key", key);
* appendTag(buf, 1, "catalog", record.getResourceBundleName());
* }
*
* if (params != null)
* {
* for (int i = 0; i < params.length; i++)
* appendTag(buf, 1, "param", params[i].toString());
* }
*/
/* FIXME: We have no way to obtain the stacktrace before free JVMs
* support the corresponding method in java.lang.Throwable. Well,
* it would be possible to parse the output of printStackTrace,
* but this would be pretty kludgy. Instead, we postpose the
* implementation until Throwable has made progress.
*/
Throwable thrown = record.getThrown();
if (thrown != null)
{
buf.append(" <exception>");
buf.append(lineSep);
/* The API specification is not clear about what exactly
* goes into the XML record for a thrown exception: It
* could be the result of getMessage(), getLocalizedMessage(),
* or toString(). Therefore, it was necessary to write a
* Mauve testlet and run it with the Sun J2SE 1.4 reference
* implementation. It turned out that the we need to call
* toString().
*
* FIXME: File a bug report with Sun, asking for clearer
* specs.
*/
appendTag(buf, 2, "message", thrown.toString());
/* FIXME: The Logging DTD specifies:
*
* <!ELEMENT exception (message?, frame+)>
*
* However, java.lang.Throwable.getStackTrace() is
* allowed to return an empty array. So, what frame should
* be emitted for an empty stack trace? We probably
* should file a bug report with Sun, asking for the DTD
* to be changed.
*/
buf.append(" </exception>");
buf.append(lineSep);
}
buf.append("</record>");
buf.append(lineSep);
return buf.toString();
}
/**
* Returns a string that handlers are supposed to emit before
* the first log record. The base implementation returns an
* empty string, but subclasses such as {@link XMLFormatter}
* override this method in order to provide a suitable header.
*
* @return a string for the header.
*
* @param handler the handler which will prepend the returned
* string in front of the first log record. This method
* will inspect certain properties of the handler, for
* example its encoding, in order to construct the header.
*/
public String getHead(Handler h)
{
StringBuffer buf;
String encoding;
buf = new StringBuffer(80);
buf.append("<?xml version=\"1.0\" encoding=\"");
encoding = h.getEncoding();
/* file.encoding is a system property with the Sun JVM, indicating
* the platform-default file encoding. Unfortunately, the API
* specification for java.lang.System.getProperties() does not
* list this property.
*/
if (encoding == null)
encoding = System.getProperty("file.encoding");
/* Since file.encoding is not listed with the API specification of
* java.lang.System.getProperties(), there might be some VMs that
* do not define this system property. Therefore, we use UTF-8 as
* a reasonable default. Please note that if the platform encoding
* uses the same codepoints as US-ASCII for the US-ASCII character
* set (e.g, 65 for A), it does not matter whether we emit the
* wrong encoding into the XML header -- the GNU Classpath will
* emit XML escape sequences like &#1234; for any non-ASCII
* character. Virtually all character encodings use the same code
* points as US-ASCII for ASCII characters. Probably, EBCDIC is
* the only exception.
*/
if (encoding == null)
encoding = "UTF-8";
/* On Windows XP localized for Swiss German (this is one of
* my [Sascha Brawer's] test machines), the default encoding
* has the canonical name "windows-1252". The "historical" name
* of this encoding is "Cp1252" (see the Javadoc for the class
* java.nio.charset.Charset for the distinction). Now, that class
* does have a method for mapping historical to canonical encoding
* names. However, if we used it here, we would be come dependent
* on java.nio.*, which was only introduced with J2SE 1.4.
* Thus, we do this little hack here. As soon as Classpath supports
* java.nio.charset.CharSet, this hack should be replaced by
* code that correctly canonicalizes the encoding name.
*/
if ((encoding.length() > 2) && encoding.startsWith("Cp"))
encoding = "windows-" + encoding.substring(2);
buf.append(encoding);
buf.append("\" standalone=\"no\"?>");
buf.append(lineSep);
/* SYSTEM is not a fully qualified URL so that validating
* XML parsers do not need to connect to the Internet in
* order to read in a log file. See also the Sun Bug Parade,
* bug #4372790, "Logging APIs: need to use relative URL for XML
* doctype".
*/
buf.append("<!DOCTYPE log SYSTEM \"logger.dtd\">");
buf.append(lineSep);
buf.append("<log>");
buf.append(lineSep);
return buf.toString();
}
public String getTail(Handler h)
{
return "</log>" + lineSep;
}
}