From 2d0c9050c37f33240921ea92a0f82320687e7998 Mon Sep 17 00:00:00 2001 From: Michael Koch Date: Sat, 21 Jun 2003 10:31:55 +0000 Subject: LogRecord.java, [...]: New files from classpath. 2003-06-21 Michael Koch * java/util/logging/LogRecord.java, java/util/logging/Logger.java, java/util/logging/SocketHandler.java, java/util/logging/SimpleFormatter.java, java/util/logging/Formatter.java, java/util/logging/ErrorManager.java, java/util/logging/Handler.java, java/util/logging/FileHandler.java, java/util/logging/LogManager.java, java/util/logging/Level.java, java/util/logging/ConsoleHandler.java, java/util/logging/StreamHandler.java, java/util/logging/LoggingPermission.java, java/util/logging/Filter.java, java/util/logging/MemoryHandler.java, java/util/logging/XMLFormatter.java: New files from classpath. From-SVN: r68295 --- libjava/java/util/logging/FileHandler.java | 509 +++++++++++++++++++++++++++++ 1 file changed, 509 insertions(+) create mode 100644 libjava/java/util/logging/FileHandler.java (limited to 'libjava/java/util/logging/FileHandler.java') diff --git a/libjava/java/util/logging/FileHandler.java b/libjava/java/util/logging/FileHandler.java new file mode 100644 index 00000000000..b9f61109d3b --- /dev/null +++ b/libjava/java/util/logging/FileHandler.java @@ -0,0 +1,509 @@ +/* FileHandler.java + -- a class for publishing log messages to log files + +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., 59 Temple Place, Suite 330, Boston, MA +02111-1307 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.IOException; +import java.io.File; +import java.io.FileOutputStream; + +/** + * A FileHandler 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. + * + *

Configuration: Values of the subsequent + * LogManager properties are taken into consideration + * when a FileHandler is initialized. If a property is + * not defined, or if it has an invalid value, a default is taken + * without an exception being thrown. + * + *

+ * + *

File Name Patterns: + * The name and location and log files are specified with pattern + * strings. The handler will replace the following character sequences + * when opening log files: + * + *

+ * + *

If the pattern string does not contain %g and + * count is greater than one, the handler will append + * the string .%g to the specified pattern. + * + *

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 %u, the handler will append + * the string .%u to the specified pattern. This + * step is performed after any generation number has been + * appended. + * + *

Examples for the GNU platform: + * + *

+ * + * @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 file name patterns + * for details. + */ + private final String pattern; + + + /** + * Indicates whether the handler will append log records to existing + * files (true), or whether the handler will clear log files + * upon switching to them (false). + */ + private final boolean append; + + + /** + * Constructs a FileHandler, 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 FileHandler 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 append 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 file name patterns for details. + * If pattern is null, the value is + * taken from the {@link LogManager LogManager} configuration + * property + * java.util.logging.FileHandler.pattern. + * However, this is a pecularity of the GNU implementation, + * and Sun's API specification does not mention what behavior + * is to be expected for null. 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 (true), or whether the + * handler will clear log files upon switching to them + * (false). + * + * @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. + *

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 "/" by the value of the + * system property "file.separator", "%t" + * by the value of the system property + * "java.io.tmpdir", "%h" by the value of + * the system property "user.home", "%g" + * by the value of generation, "%u" by the + * value of uniqueNumber, and "%%" by a + * single percent character. If pattern does + * not contain the sequence "%g", + * the value of generation will be appended to + * the result. + * + * @throws NullPointerException if one of the system properties + * "file.separator", + * "java.io.tmpdir", or + * "user.home" has no value and the + * corresponding escape sequence appears in + * pattern. + */ + 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. + */ + } +} -- cgit v1.2.3