summaryrefslogtreecommitdiffstats
path: root/logging/src/main/java
diff options
context:
space:
mode:
authorPeter Hallam <peterhal@google.com>2010-04-26 12:53:37 -0700
committerPeter Hallam <peterhal@google.com>2010-04-27 16:26:27 -0700
commitcec4dd4b1d33f78997603d0f89c0d0e56e64dbcd (patch)
treee71d43da21749bfeb4524b0adec05c91d1f89a5f /logging/src/main/java
parentf205f06be1ce65f132be1b7c850675086f26c0f7 (diff)
downloadlibcore-cec4dd4b1d33f78997603d0f89c0d0e56e64dbcd.zip
libcore-cec4dd4b1d33f78997603d0f89c0d0e56e64dbcd.tar.gz
libcore-cec4dd4b1d33f78997603d0f89c0d0e56e64dbcd.tar.bz2
merge more modules into luni
Diffstat (limited to 'logging/src/main/java')
-rw-r--r--logging/src/main/java/java/util/logging/ConsoleHandler.java72
-rw-r--r--logging/src/main/java/java/util/logging/ErrorManager.java107
-rw-r--r--logging/src/main/java/java/util/logging/FileHandler.java621
-rw-r--r--logging/src/main/java/java/util/logging/Filter.java35
-rw-r--r--logging/src/main/java/java/util/logging/Formatter.java118
-rw-r--r--logging/src/main/java/java/util/logging/Handler.java396
-rw-r--r--logging/src/main/java/java/util/logging/Level.java361
-rw-r--r--logging/src/main/java/java/util/logging/LogManager.java614
-rw-r--r--logging/src/main/java/java/util/logging/LogRecord.java507
-rw-r--r--logging/src/main/java/java/util/logging/Logger.java1414
-rw-r--r--logging/src/main/java/java/util/logging/LoggingMXBean.java82
-rw-r--r--logging/src/main/java/java/util/logging/LoggingPermission.java59
-rw-r--r--logging/src/main/java/java/util/logging/MemoryHandler.java280
-rw-r--r--logging/src/main/java/java/util/logging/SimpleFormatter.java76
-rw-r--r--logging/src/main/java/java/util/logging/SocketHandler.java167
-rw-r--r--logging/src/main/java/java/util/logging/StreamHandler.java340
-rw-r--r--logging/src/main/java/java/util/logging/XMLFormatter.java213
-rw-r--r--logging/src/main/java/java/util/logging/logging.properties65
-rw-r--r--logging/src/main/java/java/util/logging/package.html9
19 files changed, 0 insertions, 5536 deletions
diff --git a/logging/src/main/java/java/util/logging/ConsoleHandler.java b/logging/src/main/java/java/util/logging/ConsoleHandler.java
deleted file mode 100644
index ef365ca..0000000
--- a/logging/src/main/java/java/util/logging/ConsoleHandler.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.logging;
-
-/**
- * A handler that writes log messages to the standard output stream
- * {@code System.err}.
- * <p>
- * This handler reads the following properties from the log manager to
- * initialize itself:
- * <ul>
- * <li>java.util.logging.ConsoleHandler.level specifies the logging level,
- * defaults to {@code Level.INFO} if this property is not found or has an
- * invalid value.
- * <li>java.util.logging.ConsoleHandler.filter specifies the name of the filter
- * class to be associated with this handler, defaults to {@code null} if this
- * property is not found or has an invalid value.
- * <li>java.util.logging.ConsoleHandler.formatter specifies the name of the
- * formatter class to be associated with this handler, defaults to
- * {@code java.util.logging.SimpleFormatter} if this property is not found or
- * has an invalid value.
- * <li>java.util.logging.ConsoleHandler.encoding specifies the encoding this
- * handler will use to encode log messages, defaults to {@code null} if this
- * property is not found or has an invalid value.
- * </ul>
- * <p>
- * This class is not thread-safe.
- */
-public class ConsoleHandler extends StreamHandler {
-
- /**
- * Constructs a {@code ConsoleHandler} object.
- */
- public ConsoleHandler() {
- super(System.err);
- }
-
- /**
- * Closes this handler. The {@code System.err} is flushed but not closed.
- */
- @Override
- public void close() {
- super.close(false);
- }
-
- /**
- * Logs a record if necessary. A flush operation will be done.
- *
- * @param record
- * the log record to be logged.
- */
- @Override
- public void publish(LogRecord record) {
- super.publish(record);
- super.flush();
- }
-}
diff --git a/logging/src/main/java/java/util/logging/ErrorManager.java b/logging/src/main/java/java/util/logging/ErrorManager.java
deleted file mode 100644
index 6570fa7..0000000
--- a/logging/src/main/java/java/util/logging/ErrorManager.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.logging;
-
-/**
- * An error reporting facility for {@link Handler} implementations to record any
- * error that may happen during logging. {@code Handlers} should report errors
- * to an {@code ErrorManager}, instead of throwing exceptions, which would
- * interfere with the log issuer's execution.
- */
-public class ErrorManager {
-
- /**
- * The error code indicating a failure that does not fit in any of the
- * specific types of failures that follow.
- */
- public static final int GENERIC_FAILURE = 0;
-
- /**
- * The error code indicating a failure when writing to an output stream.
- */
- public static final int WRITE_FAILURE = 1;
-
- /**
- * The error code indicating a failure when flushing an output stream.
- */
- public static final int FLUSH_FAILURE = 2;
-
- /**
- * The error code indicating a failure when closing an output stream.
- */
- public static final int CLOSE_FAILURE = 3;
-
- /**
- * The error code indicating a failure when opening an output stream.
- */
- public static final int OPEN_FAILURE = 4;
-
- /**
- * The error code indicating a failure when formatting the error messages.
- */
- public static final int FORMAT_FAILURE = 5;
-
- @SuppressWarnings("nls")
- private static final String[] FAILURES = new String[] { "GENERIC_FAILURE",
- "WRITE_FAILURE", "FLUSH_FAILURE", "CLOSE_FAILURE", "OPEN_FAILURE",
- "FORMAT_FAILURE" };
-
- /**
- * An indicator for determining if the error manager has been called at
- * least once before.
- */
- private boolean called;
-
- /**
- * Constructs an instance of {@code ErrorManager}.
- */
- public ErrorManager() {
- super();
- }
-
- /**
- * Reports an error using the given message, exception and error code. This
- * implementation will write out the message to {@link System#err} on the
- * first call and all subsequent calls are ignored. A subclass of this class
- * should override this method.
- *
- * @param message
- * the error message, which may be {@code null}.
- * @param exception
- * the exception associated with the error, which may be
- * {@code null}.
- * @param errorCode
- * the error code that identifies the type of error; see the
- * constant fields of this class for possible values.
- */
- public void error(String message, Exception exception, int errorCode) {
- synchronized (this) {
- if (called) {
- return;
- }
- called = true;
- }
- System.err.println(this.getClass().getName() + ": " + FAILURES[errorCode]);
- if (message != null) {
- System.err.println("Error message - " + message);
- }
- if (exception != null) {
- System.err.println("Exception - " + exception);
- }
- }
-}
diff --git a/logging/src/main/java/java/util/logging/FileHandler.java b/logging/src/main/java/java/util/logging/FileHandler.java
deleted file mode 100644
index 3d61d7d..0000000
--- a/logging/src/main/java/java/util/logging/FileHandler.java
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.logging;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.channels.FileChannel;
-import java.nio.channels.FileLock;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Hashtable;
-
-/**
- * A {@code FileHandler} writes logging records into a specified file or a
- * rotating set of files.
- * <p>
- * When a set of files is used and a given amount of data has been written to
- * one file, then this file is closed and another file is opened. The name of
- * these files are generated by given name pattern, see below for details.
- * When the files have all been filled the Handler returns to the first and goes
- * through the set again.
- * <p>
- * By default, the I/O buffering mechanism is enabled, but when each log record
- * is complete, it is flushed out.
- * <p>
- * {@code XMLFormatter} is the default formatter for {@code FileHandler}.
- * <p>
- * {@code FileHandler} reads the following {@code LogManager} properties for
- * initialization; if a property is not defined or has an invalid value, a
- * default value is used.
- * <ul>
- * <li>java.util.logging.FileHandler.append specifies whether this
- * {@code FileHandler} should append onto existing files, defaults to
- * {@code false}.</li>
- * <li>java.util.logging.FileHandler.count specifies how many output files to
- * rotate, defaults to 1.</li>
- * <li>java.util.logging.FileHandler.filter specifies the {@code Filter} class
- * name, defaults to no {@code Filter}.</li>
- * <li>java.util.logging.FileHandler.formatter specifies the {@code Formatter}
- * class, defaults to {@code java.util.logging.XMLFormatter}.</li>
- * <li>java.util.logging.FileHandler.encoding specifies the character set
- * encoding name, defaults to the default platform encoding.</li>
- * <li>java.util.logging.FileHandler.level specifies the level for this
- * {@code Handler}, defaults to {@code Level.ALL}.</li>
- * <li>java.util.logging.FileHandler.limit specifies the maximum number of
- * bytes to write to any one file, defaults to zero, which means no limit.</li>
- * <li>java.util.logging.FileHandler.pattern specifies name pattern for the
- * output files. See below for details. Defaults to "%h/java%u.log".</li>
- * </ul>
- * <p>
- * Name pattern is a string that may include some special substrings, which will
- * be replaced to generate output files:
- * <ul>
- * <li>"/" represents the local pathname separator</li>
- * <li>"%g" represents the generation number to distinguish rotated logs</li>
- * <li>"%h" represents the home directory of the current user, which is
- * specified by "user.home" system property</li>
- * <li>"%t" represents the system's temporary directory</li>
- * <li>"%u" represents a unique number to resolve conflicts</li>
- * <li>"%%" represents the percent sign character '%'</li>
- * </ul>
- * <p>
- * Normally, the generation numbers are not larger than the given file count and
- * follow the sequence 0, 1, 2.... If the file count is larger than one, but the
- * generation field("%g") has not been specified in the pattern, then the
- * generation number after a dot will be added to the end of the file name.
- * <p>
- * The "%u" unique field is used to avoid conflicts and is set to 0 at first. If
- * one {@code FileHandler} tries to open the filename which is currently in use
- * by another process, it will repeatedly increment the unique number field and
- * try again. If the "%u" component has not been included in the file name
- * pattern and some contention on a file does occur, then a unique numerical
- * value will be added to the end of the filename in question immediately to the
- * right of a dot. The generation of unique IDs for avoiding conflicts is only
- * guaranteed to work reliably when using a local disk file system.
- */
-public class FileHandler extends StreamHandler {
-
- private static final String LCK_EXT = ".lck"; //$NON-NLS-1$
-
- private static final int DEFAULT_COUNT = 1;
-
- private static final int DEFAULT_LIMIT = 0;
-
- private static final boolean DEFAULT_APPEND = false;
-
- private static final String DEFAULT_PATTERN = "%h/java%u.log"; //$NON-NLS-1$
-
- // maintain all file locks hold by this process
- private static final Hashtable<String, FileLock> allLocks = new Hashtable<String, FileLock>();
-
- // the count of files which the output cycle through
- private int count;
-
- // the size limitation in byte of log file
- private int limit;
-
- // whether the FileHandler should open a existing file for output in append
- // mode
- private boolean append;
-
- // the pattern for output file name
- private String pattern;
-
- // maintain a LogManager instance for convenience
- private LogManager manager;
-
- // output stream, which can measure the output file length
- private MeasureOutputStream output;
-
- // used output file
- private File[] files;
-
- // output file lock
- FileLock lock = null;
-
- // current output file name
- String fileName = null;
-
- // current unique ID
- int uniqueID = -1;
-
- /**
- * Construct a {@code FileHandler} using {@code LogManager} properties or
- * their default value.
- *
- * @throws IOException
- * if any I/O error occurs.
- * @throws SecurityException
- * if a security manager exists and it determines that the
- * caller does not have the required permissions to control this
- * handler; required permissions include
- * {@code LogPermission("control")},
- * {@code FilePermission("write")} etc.
- */
- public FileHandler() throws IOException {
- init(null, null, null, null);
- }
-
- // init properties
- private void init(String p, Boolean a, Integer l, Integer c)
- throws IOException {
- // check access
- manager = LogManager.getLogManager();
- manager.checkAccess();
- initProperties(p, a, l, c);
- initOutputFiles();
- }
-
- private void initOutputFiles() throws FileNotFoundException, IOException {
- while (true) {
- // try to find a unique file which is not locked by other process
- uniqueID++;
- // FIXME: improve performance here
- for (int generation = 0; generation < count; generation++) {
- // cache all file names for rotation use
- files[generation] = new File(parseFileName(generation));
- }
- fileName = files[0].getAbsolutePath();
- synchronized (allLocks) {
- /*
- * if current process has held lock for this fileName continue
- * to find next file
- */
- if (null != allLocks.get(fileName)) {
- continue;
- }
- if (files[0].exists()
- && (!append || files[0].length() >= limit)) {
- for (int i = count - 1; i > 0; i--) {
- if (files[i].exists()) {
- files[i].delete();
- }
- files[i - 1].renameTo(files[i]);
- }
- }
- FileOutputStream fileStream = new FileOutputStream(fileName
- + LCK_EXT);
- FileChannel channel = fileStream.getChannel();
- /*
- * if lock is unsupported and IOException thrown, just let the
- * IOException throws out and exit otherwise it will go into an
- * undead cycle
- */
- lock = channel.tryLock();
- if (null == lock) {
- try {
- fileStream.close();
- } catch (Exception e) {
- // ignore
- }
- continue;
- }
- allLocks.put(fileName, lock);
- break;
- }
- }
- output = new MeasureOutputStream(new BufferedOutputStream(
- new FileOutputStream(fileName, append)), files[0].length());
- setOutputStream(output);
- }
-
- @SuppressWarnings("nls")
- private void initProperties(String p, Boolean a, Integer l, Integer c) {
- super.initProperties("ALL", null, "java.util.logging.XMLFormatter",
- null);
- String className = this.getClass().getName();
- pattern = (null == p) ? getStringProperty(className + ".pattern",
- DEFAULT_PATTERN) : p;
- if (pattern == null || pattern.isEmpty()) {
- throw new NullPointerException("Pattern cannot be empty or null");
- }
- append = (null == a) ? getBooleanProperty(className + ".append",
- DEFAULT_APPEND) : a.booleanValue();
- count = (null == c) ? getIntProperty(className + ".count",
- DEFAULT_COUNT) : c.intValue();
- limit = (null == l) ? getIntProperty(className + ".limit",
- DEFAULT_LIMIT) : l.intValue();
- count = count < 1 ? DEFAULT_COUNT : count;
- limit = limit < 0 ? DEFAULT_LIMIT : limit;
- files = new File[count];
- }
-
- void findNextGeneration() {
- super.close();
- for (int i = count - 1; i > 0; i--) {
- if (files[i].exists()) {
- files[i].delete();
- }
- files[i - 1].renameTo(files[i]);
- }
- try {
- output = new MeasureOutputStream(new BufferedOutputStream(
- new FileOutputStream(files[0])));
- } catch (FileNotFoundException e1) {
- this.getErrorManager().error("Error opening log file", e1, ErrorManager.OPEN_FAILURE);
- }
- setOutputStream(output);
- }
-
- /**
- * Transform the pattern to the valid file name, replacing any patterns, and
- * applying generation and uniqueID if present.
- *
- * @param gen
- * generation of this file
- * @return transformed filename ready for use.
- */
- private String parseFileName(int gen) {
- int cur = 0;
- int next = 0;
- boolean hasUniqueID = false;
- boolean hasGeneration = false;
-
- // TODO privilege code?
-
- String tempPath = System.getProperty("java.io.tmpdir"); //$NON-NLS-1$
- boolean tempPathHasSepEnd = (tempPath == null ? false : tempPath
- .endsWith(File.separator));
-
- String homePath = System.getProperty("user.home"); //$NON-NLS-1$
- boolean homePathHasSepEnd = (homePath == null ? false : homePath
- .endsWith(File.separator));
-
- StringBuilder sb = new StringBuilder();
- pattern = pattern.replace('/', File.separatorChar);
-
- char[] value = pattern.toCharArray();
- while ((next = pattern.indexOf('%', cur)) >= 0) {
- if (++next < pattern.length()) {
- switch (value[next]) {
- case 'g':
- sb.append(value, cur, next - cur - 1).append(gen);
- hasGeneration = true;
- break;
- case 'u':
- sb.append(value, cur, next - cur - 1).append(uniqueID);
- hasUniqueID = true;
- break;
- case 't':
- /*
- * we should probably try to do something cute here like
- * lookahead for adjacent '/'
- */
- sb.append(value, cur, next - cur - 1).append(tempPath);
- if (!tempPathHasSepEnd) {
- sb.append(File.separator);
- }
- break;
- case 'h':
- sb.append(value, cur, next - cur - 1).append(homePath);
- if (!homePathHasSepEnd) {
- sb.append(File.separator);
- }
- break;
- case '%':
- sb.append(value, cur, next - cur - 1).append('%');
- break;
- default:
- sb.append(value, cur, next - cur);
- }
- cur = ++next;
- } else {
- // fail silently
- }
- }
-
- sb.append(value, cur, value.length - cur);
-
- if (!hasGeneration && count > 1) {
- sb.append(".").append(gen); //$NON-NLS-1$
- }
-
- if (!hasUniqueID && uniqueID > 0) {
- sb.append(".").append(uniqueID); //$NON-NLS-1$
- }
-
- return sb.toString();
- }
-
- // get boolean LogManager property, if invalid value got, using default
- // value
- private boolean getBooleanProperty(String key, boolean defaultValue) {
- String property = manager.getProperty(key);
- if (null == property) {
- return defaultValue;
- }
- boolean result = defaultValue;
- if ("true".equalsIgnoreCase(property)) { //$NON-NLS-1$
- result = true;
- } else if ("false".equalsIgnoreCase(property)) { //$NON-NLS-1$
- result = false;
- }
- return result;
- }
-
- // get String LogManager property, if invalid value got, using default value
- private String getStringProperty(String key, String defaultValue) {
- String property = manager.getProperty(key);
- return property == null ? defaultValue : property;
- }
-
- // get int LogManager property, if invalid value got, using default value
- private int getIntProperty(String key, int defaultValue) {
- String property = manager.getProperty(key);
- int result = defaultValue;
- if (null != property) {
- try {
- result = Integer.parseInt(property);
- } catch (Exception e) {
- // ignore
- }
- }
- return result;
- }
-
- /**
- * Constructs a new {@code FileHandler}. The given name pattern is used as
- * output filename, the file limit is set to zero (no limit), the file count
- * is set to one; the remaining configuration is done using
- * {@code LogManager} properties or their default values. This handler
- * writes to only one file with no size limit.
- *
- * @param pattern
- * the name pattern for the output file.
- * @throws IOException
- * if any I/O error occurs.
- * @throws SecurityException
- * if a security manager exists and it determines that the
- * caller does not have the required permissions to control this
- * handler; required permissions include
- * {@code LogPermission("control")},
- * {@code FilePermission("write")} etc.
- * @throws IllegalArgumentException
- * if the pattern is empty.
- * @throws NullPointerException
- * if the pattern is {@code null}.
- */
- public FileHandler(String pattern) throws IOException {
- if (pattern.isEmpty()) {
- throw new IllegalArgumentException("Pattern cannot be empty");
- }
- init(pattern, null, Integer.valueOf(DEFAULT_LIMIT), Integer.valueOf(DEFAULT_COUNT));
- }
-
- /**
- * Construct a new {@code FileHandler}. The given name pattern is used as
- * output filename, the file limit is set to zero (no limit), the file count
- * is initialized to one and the value of {@code append} becomes the new
- * instance's append mode. The remaining configuration is done using
- * {@code LogManager} properties. This handler writes to only one file
- * with no size limit.
- *
- * @param pattern
- * the name pattern for the output file.
- * @param append
- * the append mode.
- * @throws IOException
- * if any I/O error occurs.
- * @throws SecurityException
- * if a security manager exists and it determines that the
- * caller does not have the required permissions to control this
- * handler; required permissions include
- * {@code LogPermission("control")},
- * {@code FilePermission("write")} etc.
- * @throws IllegalArgumentException
- * if {@code pattern} is empty.
- * @throws NullPointerException
- * if {@code pattern} is {@code null}.
- */
- public FileHandler(String pattern, boolean append) throws IOException {
- if (pattern.isEmpty()) {
- throw new IllegalArgumentException("Pattern cannot be empty");
- }
- init(pattern, Boolean.valueOf(append), Integer.valueOf(DEFAULT_LIMIT),
- Integer.valueOf(DEFAULT_COUNT));
- }
-
- /**
- * Construct a new {@code FileHandler}. The given name pattern is used as
- * output filename, the maximum file size is set to {@code limit} and the
- * file count is initialized to {@code count}. The remaining configuration
- * is done using {@code LogManager} properties. This handler is configured
- * to write to a rotating set of count files, when the limit of bytes has
- * been written to one output file, another file will be opened instead.
- *
- * @param pattern
- * the name pattern for the output file.
- * @param limit
- * the data amount limit in bytes of one output file, can not be
- * negative.
- * @param count
- * the maximum number of files to use, can not be less than one.
- * @throws IOException
- * if any I/O error occurs.
- * @throws SecurityException
- * if a security manager exists and it determines that the
- * caller does not have the required permissions to control this
- * handler; required permissions include
- * {@code LogPermission("control")},
- * {@code FilePermission("write")} etc.
- * @throws IllegalArgumentException
- * if {@code pattern} is empty, {@code limit < 0} or
- * {@code count < 1}.
- * @throws NullPointerException
- * if {@code pattern} is {@code null}.
- */
- public FileHandler(String pattern, int limit, int count) throws IOException {
- if (pattern.isEmpty()) {
- throw new IllegalArgumentException("Pattern cannot be empty");
- }
- if (limit < 0 || count < 1) {
- throw new IllegalArgumentException("limit < 0 || count < 1");
- }
- init(pattern, null, Integer.valueOf(limit), Integer.valueOf(count));
- }
-
- /**
- * Construct a new {@code FileHandler}. The given name pattern is used as
- * output filename, the maximum file size is set to {@code limit}, the file
- * count is initialized to {@code count} and the append mode is set to
- * {@code append}. The remaining configuration is done using
- * {@code LogManager} properties. This handler is configured to write to a
- * rotating set of count files, when the limit of bytes has been written to
- * one output file, another file will be opened instead.
- *
- * @param pattern
- * the name pattern for the output file.
- * @param limit
- * the data amount limit in bytes of one output file, can not be
- * negative.
- * @param count
- * the maximum number of files to use, can not be less than one.
- * @param append
- * the append mode.
- * @throws IOException
- * if any I/O error occurs.
- * @throws SecurityException
- * if a security manager exists and it determines that the
- * caller does not have the required permissions to control this
- * handler; required permissions include
- * {@code LogPermission("control")},
- * {@code FilePermission("write")} etc.
- * @throws IllegalArgumentException
- * if {@code pattern} is empty, {@code limit < 0} or
- * {@code count < 1}.
- * @throws NullPointerException
- * if {@code pattern} is {@code null}.
- */
- public FileHandler(String pattern, int limit, int count, boolean append) throws IOException {
- if (pattern.isEmpty()) {
- throw new IllegalArgumentException("Pattern cannot be empty");
- }
- if (limit < 0 || count < 1) {
- throw new IllegalArgumentException("limit < 0 || count < 1");
- }
- init(pattern, Boolean.valueOf(append), Integer.valueOf(limit), Integer.valueOf(count));
- }
-
- /**
- * Flushes and closes all opened files.
- *
- * @throws SecurityException
- * if a security manager exists and it determines that the
- * caller does not have the required permissions to control this
- * handler; required permissions include
- * {@code LogPermission("control")},
- * {@code FilePermission("write")} etc.
- */
- @Override
- public void close() {
- // release locks
- super.close();
- allLocks.remove(fileName);
- try {
- FileChannel channel = lock.channel();
- lock.release();
- channel.close();
- File file = new File(fileName + LCK_EXT);
- file.delete();
- } catch (IOException e) {
- // ignore
- }
- }
-
- /**
- * Publish a {@code LogRecord}.
- *
- * @param record
- * the log record to publish.
- */
- @Override
- public synchronized void publish(LogRecord record) {
- super.publish(record);
- flush();
- if (limit > 0 && output.getLength() >= limit) {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- findNextGeneration();
- return null;
- }
- });
- }
- }
-
- /**
- * This output stream uses the decorator pattern to add measurement features
- * to OutputStream which can detect the total size(in bytes) of output, the
- * initial size can be set.
- */
- static class MeasureOutputStream extends OutputStream {
-
- OutputStream wrapped;
-
- long length;
-
- public MeasureOutputStream(OutputStream stream, long currentLength) {
- wrapped = stream;
- length = currentLength;
- }
-
- public MeasureOutputStream(OutputStream stream) {
- this(stream, 0);
- }
-
- @Override
- public void write(int oneByte) throws IOException {
- wrapped.write(oneByte);
- length++;
- }
-
- @Override
- public void write(byte[] bytes) throws IOException {
- wrapped.write(bytes);
- length += bytes.length;
- }
-
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- wrapped.write(b, off, len);
- length += len;
- }
-
- @Override
- public void close() throws IOException {
- wrapped.close();
- }
-
- @Override
- public void flush() throws IOException {
- wrapped.flush();
- }
-
- public long getLength() {
- return length;
- }
-
- public void setLength(long newLength) {
- length = newLength;
- }
- }
-}
diff --git a/logging/src/main/java/java/util/logging/Filter.java b/logging/src/main/java/java/util/logging/Filter.java
deleted file mode 100644
index f5dbd9f..0000000
--- a/logging/src/main/java/java/util/logging/Filter.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.logging;
-
-/**
- * A {@code Filter} provides a mechanism for exercising fine-grained control
- * over which records get logged.
- */
-public interface Filter {
-
- /**
- * Checks {@code record} to determine if it should be logged.
- *
- * @param record
- * the {@link LogRecord} to be checked.
- * @return {@code true} if the supplied log record needs to be logged,
- * {@code false} otherwise.
- */
- boolean isLoggable(LogRecord record);
-}
diff --git a/logging/src/main/java/java/util/logging/Formatter.java b/logging/src/main/java/java/util/logging/Formatter.java
deleted file mode 100644
index f9b0d25..0000000
--- a/logging/src/main/java/java/util/logging/Formatter.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.logging;
-
-import java.text.MessageFormat;
-import java.util.ResourceBundle;
-
-/**
- * {@code Formatter} objects are used to format {@link LogRecord} objects into a
- * string representation. Head and tail strings are sometimes used to wrap a set
- * of records. The {@code getHead} and {@code getTail} methods are used for this
- * purpose.
- */
-public abstract class Formatter {
-
- /**
- * Constructs a {@code Formatter} object.
- */
- protected Formatter() {
- super();
- }
-
- /**
- * Converts a {@link LogRecord} object into a string representation. The
- * resulted string is usually localized and includes the message field of
- * the record.
- *
- * @param r
- * the log record to be formatted into a string.
- * @return the formatted string.
- */
- public abstract String format(LogRecord r);
-
- /**
- * Formats a {@code LogRecord} object into a localized string
- * representation. This is a convenience method for subclasses of {@code
- * Formatter}.
- * <p>
- * The message string is firstly localized using the {@code ResourceBundle}
- * object associated with the supplied {@code LogRecord}.
- * <p>
- * Notice : if message contains "{0", then java.text.MessageFormat is used.
- * Otherwise no formatting is performed.
- *
- * @param r
- * the log record to be formatted.
- * @return the string resulted from the formatting.
- */
- public String formatMessage(LogRecord r) {
- String pattern = r.getMessage();
- ResourceBundle rb = null;
- // try to localize the message string first
- if (null != (rb = r.getResourceBundle())) {
- try {
- pattern = rb.getString(pattern);
- } catch (Exception e) {
- pattern = r.getMessage();
- }
- }
- if (null != pattern) {
- Object[] params = r.getParameters();
- /*
- * if the message contains "{0", use java.text.MessageFormat to
- * format the string
- */
- if (pattern.indexOf("{0") >= 0 && null != params //$NON-NLS-1$
- && params.length > 0) {
- try {
- pattern = MessageFormat.format(pattern, params);
- } catch (IllegalArgumentException e) {
- pattern = r.getMessage();
- }
- }
- }
- return pattern;
- }
-
- /**
- * Gets the head string used to wrap a set of log records. This base class
- * always returns an empty string.
- *
- * @param h
- * the target handler.
- * @return the head string used to wrap a set of log records, empty in this
- * implementation.
- */
- public String getHead(Handler h) {
- return ""; //$NON-NLS-1$
- }
-
- /**
- * Gets the tail string used to wrap a set of log records. This base class
- * always returns the empty string.
- *
- * @param h
- * the target handler.
- * @return the tail string used to wrap a set of log records, empty in this
- * implementation.
- */
- public String getTail(Handler h) {
- return ""; //$NON-NLS-1$
- }
-}
diff --git a/logging/src/main/java/java/util/logging/Handler.java b/logging/src/main/java/java/util/logging/Handler.java
deleted file mode 100644
index d1aaef2..0000000
--- a/logging/src/main/java/java/util/logging/Handler.java
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.logging;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.Charset;
-import java.security.AccessController;
-import java.security.PrivilegedExceptionAction;
-
-/**
- * A {@code Handler} object accepts a logging request and exports the desired
- * messages to a target, for example, a file, the console, etc. It can be
- * disabled by setting its logging level to {@code Level.OFF}.
- */
-public abstract class Handler {
-
- private static final Level DEFAULT_LEVEL = Level.ALL;
-
- // the error manager to report errors during logging
- private ErrorManager errorMan;
-
- // the character encoding used by this handler
- private String encoding;
-
- // the logging level
- private Level level;
-
- // the formatter used to export messages
- private Formatter formatter;
-
- // the filter used to filter undesired messages
- private Filter filter;
-
- // class name, used for property reading
- private String prefix;
-
- /**
- * Constructs a {@code Handler} object with a default error manager instance
- * {@code ErrorManager}, the default encoding, and the default logging
- * level {@code Level.ALL}. It has no filter and no formatter.
- */
- protected Handler() {
- this.errorMan = new ErrorManager();
- this.level = DEFAULT_LEVEL;
- this.encoding = null;
- this.filter = null;
- this.formatter = null;
- this.prefix = this.getClass().getName();
- }
-
- // get a instance from given class name, using Class.forName()
- private Object getDefaultInstance(String className) {
- Object result = null;
- if (null == className) {
- return result;
- }
- try {
- result = Class.forName(className).newInstance();
- } catch (Exception e) {
- // ignore
- }
- return result;
- }
-
- // get a instance from given class name, using context classloader
- private Object getCustomizeInstance(final String className)
- throws Exception {
- Class<?> c = AccessController
- .doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
- public Class<?> run() throws Exception {
- ClassLoader loader = Thread.currentThread()
- .getContextClassLoader();
- if (null == loader) {
- loader = ClassLoader.getSystemClassLoader();
- }
- return loader.loadClass(className);
- }
- });
- return c.newInstance();
- }
-
- // print error message in some format
- void printInvalidPropMessage(String key, String value, Exception e) {
- String msg = "Invalid property value for " + prefix + ":" + key + "/" + value;
- errorMan.error(msg, e, ErrorManager.GENERIC_FAILURE);
- }
-
- /**
- * init the common properties, including filter, level, formatter, and
- * encoding
- */
- void initProperties(String defaultLevel, String defaultFilter,
- String defaultFormatter, String defaultEncoding) {
- LogManager manager = LogManager.getLogManager();
-
- // set filter
- final String filterName = manager.getProperty(prefix + ".filter"); //$NON-NLS-1$
- if (null != filterName) {
- try {
- filter = (Filter) getCustomizeInstance(filterName);
- } catch (Exception e1) {
- printInvalidPropMessage("filter", filterName, e1); //$NON-NLS-1$
- filter = (Filter) getDefaultInstance(defaultFilter);
- }
- } else {
- filter = (Filter) getDefaultInstance(defaultFilter);
- }
-
- // set level
- String levelName = manager.getProperty(prefix + ".level"); //$NON-NLS-1$
- if (null != levelName) {
- try {
- level = Level.parse(levelName);
- } catch (Exception e) {
- printInvalidPropMessage("level", levelName, e); //$NON-NLS-1$
- level = Level.parse(defaultLevel);
- }
- } else {
- level = Level.parse(defaultLevel);
- }
-
- // set formatter
- final String formatterName = manager.getProperty(prefix + ".formatter"); //$NON-NLS-1$
- if (null != formatterName) {
- try {
- formatter = (Formatter) getCustomizeInstance(formatterName);
- } catch (Exception e) {
- printInvalidPropMessage("formatter", formatterName, e); //$NON-NLS-1$
- formatter = (Formatter) getDefaultInstance(defaultFormatter);
- }
- } else {
- formatter = (Formatter) getDefaultInstance(defaultFormatter);
- }
-
- // set encoding
- final String encodingName = manager.getProperty(prefix + ".encoding"); //$NON-NLS-1$
- try {
- internalSetEncoding(encodingName);
- } catch (UnsupportedEncodingException e) {
- printInvalidPropMessage("encoding", encodingName, e); //$NON-NLS-1$
- }
- }
-
- /**
- * Closes this handler. A flush operation will be performed and all the
- * associated resources will be freed. Client applications should not use
- * this handler after closing it.
- *
- * @throws SecurityException
- * if a security manager determines that the caller does not
- * have the required permission.
- */
- public abstract void close();
-
- /**
- * Flushes any buffered output.
- */
- public abstract void flush();
-
- /**
- * Accepts a logging request and sends it to the the target.
- *
- * @param record
- * the log record to be logged; {@code null} records are ignored.
- */
- public abstract void publish(LogRecord record);
-
- /**
- * Gets the character encoding used by this handler, {@code null} for
- * default encoding.
- *
- * @return the character encoding used by this handler.
- */
- public String getEncoding() {
- return this.encoding;
- }
-
- /**
- * Gets the error manager used by this handler to report errors during
- * logging.
- *
- * @return the error manager used by this handler.
- * @throws SecurityException
- * if a security manager determines that the caller does not
- * have the required permission.
- */
- public ErrorManager getErrorManager() {
- LogManager.getLogManager().checkAccess();
- return this.errorMan;
- }
-
- /**
- * Gets the filter used by this handler.
- *
- * @return the filter used by this handler (possibly {@code null}).
- */
- public Filter getFilter() {
- return this.filter;
- }
-
- /**
- * Gets the formatter used by this handler to format the logging messages.
- *
- * @return the formatter used by this handler (possibly {@code null}).
- */
- public Formatter getFormatter() {
- return this.formatter;
- }
-
- /**
- * Gets the logging level of this handler, records with levels lower than
- * this value will be dropped.
- *
- * @return the logging level of this handler.
- */
- public Level getLevel() {
- return this.level;
- }
-
- /**
- * Determines whether the supplied log record needs to be logged. The
- * logging levels will be checked as well as the filter.
- *
- * @param record
- * the log record to be checked.
- * @return {@code true} if the supplied log record needs to be logged,
- * otherwise {@code false}.
- */
- public boolean isLoggable(LogRecord record) {
- if (null == record) {
- throw new NullPointerException();
- }
- if (this.level.intValue() == Level.OFF.intValue()) {
- return false;
- } else if (record.getLevel().intValue() >= this.level.intValue()) {
- return null == this.filter || this.filter.isLoggable(record);
- }
- return false;
- }
-
- /**
- * Reports an error to the error manager associated with this handler,
- * {@code ErrorManager} is used for that purpose. No security checks are
- * done, therefore this is compatible with environments where the caller
- * is non-privileged.
- *
- * @param msg
- * the error message, may be {@code null}.
- * @param ex
- * the associated exception, may be {@code null}.
- * @param code
- * an {@code ErrorManager} error code.
- */
- protected void reportError(String msg, Exception ex, int code) {
- this.errorMan.error(msg, ex, code);
- }
-
- /**
- * Sets the character encoding used by this handler. A {@code null} value
- * indicates the use of the default encoding. This internal method does
- * not check security.
- *
- * @param newEncoding
- * the character encoding to set.
- * @throws UnsupportedEncodingException
- * if the specified encoding is not supported by the runtime.
- */
- void internalSetEncoding(String newEncoding) throws UnsupportedEncodingException {
- // accepts "null" because it indicates using default encoding
- if (newEncoding == null) {
- this.encoding = null;
- } else {
- if (Charset.isSupported(newEncoding)) {
- this.encoding = newEncoding;
- } else {
- throw new UnsupportedEncodingException(newEncoding);
- }
- }
- }
-
- /**
- * Sets the character encoding used by this handler, {@code null} indicates
- * a default encoding.
- *
- * @param encoding
- * the character encoding to set.
- * @throws SecurityException
- * if a security manager determines that the caller does not
- * have the required permission.
- * @throws UnsupportedEncodingException
- * if the specified encoding is not supported by the runtime.
- */
- public void setEncoding(String encoding) throws SecurityException,
- UnsupportedEncodingException {
- LogManager.getLogManager().checkAccess();
- internalSetEncoding(encoding);
- }
-
- /**
- * Sets the error manager for this handler.
- *
- * @param em
- * the error manager to set.
- * @throws NullPointerException
- * if {@code em} is {@code null}.
- * @throws SecurityException
- * if a security manager determines that the caller does not
- * have the required permission.
- */
- public void setErrorManager(ErrorManager em) {
- LogManager.getLogManager().checkAccess();
- if (null == em) {
- throw new NullPointerException();
- }
- this.errorMan = em;
- }
-
- /**
- * Sets the filter to be used by this handler.
- *
- * @param newFilter
- * the filter to set, may be {@code null}.
- * @throws SecurityException
- * if a security manager determines that the caller does not
- * have the required permission.
- */
- public void setFilter(Filter newFilter) {
- LogManager.getLogManager().checkAccess();
- this.filter = newFilter;
- }
-
- /**
- * Sets the formatter to be used by this handler. This internal method does
- * not check security.
- *
- * @param newFormatter
- * the formatter to set.
- */
- void internalSetFormatter(Formatter newFormatter) {
- if (null == newFormatter) {
- throw new NullPointerException();
- }
- this.formatter = newFormatter;
- }
-
- /**
- * Sets the formatter to be used by this handler.
- *
- * @param newFormatter
- * the formatter to set.
- * @throws NullPointerException
- * if {@code newFormatter} is {@code null}.
- * @throws SecurityException
- * if a security manager determines that the caller does not
- * have the required permission.
- */
- public void setFormatter(Formatter newFormatter) {
- LogManager.getLogManager().checkAccess();
- internalSetFormatter(newFormatter);
- }
-
- /**
- * Sets the logging level of the messages logged by this handler, levels
- * lower than this value will be dropped.
- *
- * @param newLevel
- * the logging level to set.
- * @throws NullPointerException
- * if {@code newLevel} is {@code null}.
- * @throws SecurityException
- * if a security manager determines that the caller does not
- * have the required permission.
- */
- public void setLevel(Level newLevel) {
- if (null == newLevel) {
- throw new NullPointerException();
- }
- LogManager.getLogManager().checkAccess();
- this.level = newLevel;
- }
-}
diff --git a/logging/src/main/java/java/util/logging/Level.java b/logging/src/main/java/java/util/logging/Level.java
deleted file mode 100644
index 2c7ac53..0000000
--- a/logging/src/main/java/java/util/logging/Level.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.logging;
-
-import dalvik.system.VMStack;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-/**
- * {@code Level} objects are used to indicate the level of logging. There are a
- * set of predefined logging levels, each associated with an integer value.
- * Enabling a certain logging level also enables all logging levels with larger
- * values.
- * <p>
- * The predefined levels in ascending order are FINEST, FINER, FINE, CONFIG,
- * INFO, WARNING, SEVERE. There are two additional predefined levels, which are
- * ALL and OFF. ALL indicates logging all messages, and OFF indicates logging no
- * messages.
- */
-public class Level implements Serializable {
-
- private static final long serialVersionUID = -8176160795706313070L;
-
- private static final List<Level> levels = new ArrayList<Level>(9);
-
- /**
- * The OFF level provides no logging messages.
- */
- public static final Level OFF = new Level("OFF", Integer.MAX_VALUE); //$NON-NLS-1$
-
- /**
- * The SEVERE level provides severe failure messages.
- */
- public static final Level SEVERE = new Level("SEVERE", 1000); //$NON-NLS-1$
-
- /**
- * The WARNING level provides warnings.
- */
- public static final Level WARNING = new Level("WARNING", 900); //$NON-NLS-1$
-
- /**
- * The INFO level provides informative messages.
- */
- public static final Level INFO = new Level("INFO", 800); //$NON-NLS-1$
-
- /**
- * The CONFIG level provides static configuration messages.
- */
- public static final Level CONFIG = new Level("CONFIG", 700); //$NON-NLS-1$
-
- /**
- * The FINE level provides tracing messages.
- */
- public static final Level FINE = new Level("FINE", 500); //$NON-NLS-1$
-
- /**
- * The FINER level provides more detailed tracing messages.
- */
- public static final Level FINER = new Level("FINER", 400); //$NON-NLS-1$
-
- /**
- * The FINEST level provides highly detailed tracing messages.
- */
- public static final Level FINEST = new Level("FINEST", 300); //$NON-NLS-1$
-
- /**
- * The ALL level provides all logging messages.
- */
- public static final Level ALL = new Level("ALL", Integer.MIN_VALUE); //$NON-NLS-1$
-
- /**
- * Parses a level name into a {@code Level} object.
- *
- * @param name
- * the name of the desired {@code level}, which cannot be
- * {@code null}.
- * @return the level with the specified name.
- * @throws NullPointerException
- * if {@code name} is {@code null}.
- * @throws IllegalArgumentException
- * if {@code name} is not valid.
- */
- public static Level parse(String name) throws IllegalArgumentException {
- if (name == null) {
- throw new NullPointerException("name == null");
- }
-
- boolean isNameAnInt;
- int nameAsInt;
- try {
- nameAsInt = Integer.parseInt(name);
- isNameAnInt = true;
- } catch (NumberFormatException e) {
- nameAsInt = 0;
- isNameAnInt = false;
- }
-
- synchronized (levels) {
- for (Level level : levels) {
- if (name.equals(level.getName())) {
- return level;
- }
- }
-
- if (isNameAnInt) {
- /*
- * Loop through levels a second time, so that the returned
- * instance will be passed on the order of construction.
- */
- for (Level level : levels) {
- if (nameAsInt == level.intValue()) {
- return level;
- }
- }
- }
- }
-
- if (!isNameAnInt) {
- throw new IllegalArgumentException("Cannot parse name '" + name + "'");
- }
-
- return new Level(name, nameAsInt);
- }
-
- /**
- * The name of this Level.
- *
- * @serial
- */
- private final String name;
-
- /**
- * The integer value indicating the level.
- *
- * @serial
- */
- private final int value;
-
- /**
- * The name of the resource bundle used to localize the level name.
- *
- * @serial
- */
- private final String resourceBundleName;
-
- /**
- * The resource bundle associated with this level, used to localize the
- * level name.
- */
- private transient ResourceBundle rb;
-
- /**
- * Constructs an instance of {@code Level} taking the supplied name and
- * level value.
- *
- * @param name
- * the name of the level.
- * @param level
- * an integer value indicating the level.
- * @throws NullPointerException
- * if {@code name} is {@code null}.
- */
- protected Level(String name, int level) {
- this(name, level, null);
- }
-
- /**
- * Constructs an instance of {@code Level} taking the supplied name, level
- * value and resource bundle name.
- *
- * @param name
- * the name of the level.
- * @param level
- * an integer value indicating the level.
- * @param resourceBundleName
- * the name of the resource bundle to use.
- * @throws NullPointerException
- * if {@code name} is {@code null}.
- */
- protected Level(String name, int level, String resourceBundleName) {
- if (name == null) {
- throw new NullPointerException("name == null");
- }
- this.name = name;
- this.value = level;
- this.resourceBundleName = resourceBundleName;
- if (resourceBundleName != null) {
- try {
- rb = ResourceBundle.getBundle(resourceBundleName,
- // BEGIN android-changed
- Locale.getDefault(), VMStack.getCallingClassLoader());
- // BEGIN android-changed
- } catch (MissingResourceException e) {
- rb = null;
- }
- }
- synchronized (levels) {
- levels.add(this);
- }
- }
-
- /**
- * Gets the name of this level.
- *
- * @return this level's name.
- */
- public String getName() {
- return this.name;
- }
-
- /**
- * Gets the name of the resource bundle associated with this level.
- *
- * @return the name of this level's resource bundle.
- */
- public String getResourceBundleName() {
- return this.resourceBundleName;
- }
-
- /**
- * Gets the integer value indicating this level.
- *
- * @return this level's integer value.
- */
- public final int intValue() {
- return this.value;
- }
-
- /**
- * Serialization helper method to maintain singletons and add any new
- * levels.
- *
- * @return the resolved instance.
- */
- private Object readResolve() {
- synchronized (levels) {
- for (Level level : levels) {
- if (value != level.value) {
- continue;
- }
- if (!name.equals(level.name)) {
- continue;
- }
- if (resourceBundleName == level.resourceBundleName) {
- return level;
- } else if (resourceBundleName != null
- && resourceBundleName.equals(level.resourceBundleName)) {
- return level;
- }
- }
- // This is a new value, so add it.
- levels.add(this);
- return this;
- }
- }
-
- /**
- * Serialization helper to setup transient resource bundle instance.
- *
- * @param in
- * the input stream to read the instance data from.
- * @throws IOException
- * if an IO error occurs.
- * @throws ClassNotFoundException
- * if a class is not found.
- */
- private void readObject(ObjectInputStream in) throws IOException,
- ClassNotFoundException {
- in.defaultReadObject();
- if (resourceBundleName != null) {
- try {
- rb = ResourceBundle.getBundle(resourceBundleName);
- } catch (MissingResourceException e) {
- rb = null;
- }
- }
- }
-
- /**
- * Gets the localized name of this level. The default locale is used. If no
- * resource bundle is associated with this level then the original level
- * name is returned.
- *
- * @return the localized name of this level.
- */
- public String getLocalizedName() {
- if (rb == null) {
- return name;
- }
-
- try {
- return rb.getString(name);
- } catch (MissingResourceException e) {
- return name;
- }
- }
-
- /**
- * Compares two {@code Level} objects for equality. They are considered to
- * be equal if they have the same level value.
- *
- * @param o
- * the other object to compare this level to.
- * @return {@code true} if this object equals to the supplied object,
- * {@code false} otherwise.
- */
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
-
- if (!(o instanceof Level)) {
- return false;
- }
-
- return ((Level) o).intValue() == this.value;
- }
-
- /**
- * Returns the hash code of this {@code Level} object.
- *
- * @return this level's hash code.
- */
- @Override
- public int hashCode() {
- return this.value;
- }
-
- /**
- * Returns the string representation of this {@code Level} object. In
- * this case, it is the level's name.
- *
- * @return the string representation of this level.
- */
- @Override
- public final String toString() {
- return this.name;
- }
-}
diff --git a/logging/src/main/java/java/util/logging/LogManager.java b/logging/src/main/java/java/util/logging/LogManager.java
deleted file mode 100644
index c07f6bf..0000000
--- a/logging/src/main/java/java/util/logging/LogManager.java
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.logging;
-
-// BEGIN android-note
-// this file contains cleaned up documentation and style for contribution
-// upstream.
-// javax.management support (MBeans) has been dropped.
-// END android-note
-
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Properties;
-import java.util.StringTokenizer;
-
-/**
- * {@code LogManager} is used to maintain configuration properties of the
- * logging framework, and to manage a hierarchical namespace of all named
- * {@code Logger} objects.
- * <p>
- * There is only one global {@code LogManager} instance in the
- * application, which can be get by calling static method
- * {@link #getLogManager()}. This instance is created and
- * initialized during class initialization and cannot be changed.
- * <p>
- * The {@code LogManager} class can be specified by
- * java.util.logging.manager system property, if the property is unavailable or
- * invalid, the default class {@link java.util.logging.LogManager} will
- * be used.
- * <p>
- * On initialization, {@code LogManager} reads its configuration from a
- * properties file, which by default is the "lib/logging.properties" in the JRE
- * directory.
- * <p>
- * However, two optional system properties can be used to customize the initial
- * configuration process of {@code LogManager}.
- * <ul>
- * <li>"java.util.logging.config.class"</li>
- * <li>"java.util.logging.config.file"</li>
- * </ul>
- * <p>
- * These two properties can be set in three ways, by the Preferences API, by the
- * "java" command line property definitions, or by system property definitions
- * passed to JNI_CreateJavaVM.
- * <p>
- * The "java.util.logging.config.class" should specifies a class name. If it is
- * set, this given class will be loaded and instantiated during
- * {@code LogManager} initialization, so that this object's default
- * constructor can read the initial configuration and define properties for
- * {@code LogManager}.
- * <p>
- * If "java.util.logging.config.class" property is not set, or it is invalid, or
- * some exception is thrown during the instantiation, then the
- * "java.util.logging.config.file" system property can be used to specify a
- * properties file. The {@code LogManager} will read initial
- * configuration from this file.
- * <p>
- * If neither of these properties is defined, or some exception is thrown
- * during these two properties using, the {@code LogManager} will read
- * its initial configuration from default properties file, as described above.
- * <p>
- * The global logging properties may include:
- * <ul>
- * <li>"handlers". This property's values should be a list of class names for
- * handler classes separated by whitespace, these classes must be subclasses of
- * {@code Handler} and each must have a default constructor, these
- * classes will be loaded, instantiated and registered as handlers on the root
- * {@code Logger} (the {@code Logger} named ""). These
- * {@code Handler}s maybe initialized lazily.</li>
- * <li>"config". The property defines a list of class names separated by
- * whitespace. Each class must have a default constructor, in which it can
- * update the logging configuration, such as levels, handlers, or filters for
- * some logger, etc. These classes will be loaded and instantiated during
- * {@code LogManager} configuration</li>
- * </ul>
- * <p>
- * This class, together with any handler and configuration classes associated
- * with it, <b>must</b> be loaded from the system classpath when
- * {@code LogManager} configuration occurs.
- * <p>
- * Besides global properties, the properties for loggers and Handlers can be
- * specified in the property files. The names of these properties will start
- * with the complete dot separated names for the handlers or loggers.
- * <p>
- * In the {@code LogManager}'s hierarchical namespace,
- * {@code Loggers} are organized based on their dot separated names. For
- * example, "x.y.z" is child of "x.y".
- * <p>
- * Levels for {@code Loggers} can be defined by properties whose name end
- * with ".level". Thus "alogger.level" defines a level for the logger named as
- * "alogger" and for all its children in the naming hierarchy. Log levels
- * properties are read and applied in the same order as they are specified in
- * the property file. The root logger's level can be defined by the property
- * named as ".level".
- * <p>
- * This class is thread safe. It is an error to synchronize on a
- * {@code LogManager} while synchronized on a {@code Logger}.
- */
-public class LogManager {
-
- /** The line separator of the underlying OS. */
- private static final String lineSeparator = getPrivilegedSystemProperty("line.separator");
-
- /** The shared logging permission. */
- private static final LoggingPermission perm = new LoggingPermission("control", null);
-
- /** The singleton instance. */
- static LogManager manager;
-
- /**
- * The {@code String} value of the {@link LoggingMXBean}'s ObjectName.
- */
- public static final String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging";
-
- /**
- * Get the {@code LoggingMXBean} instance. this implementation always throws
- * an UnsupportedOperationException.
- *
- * @return the {@code LoggingMXBean} instance
- */
- public static LoggingMXBean getLoggingMXBean() {
- throw new UnsupportedOperationException();
- }
-
- // FIXME: use weak reference to avoid heap memory leak
- private Hashtable<String, Logger> loggers;
-
- /** The configuration properties */
- private Properties props;
-
- /** the property change listener */
- private PropertyChangeSupport listeners;
-
- static {
- // init LogManager singleton instance
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- String className = System.getProperty("java.util.logging.manager");
-
- if (null != className) {
- manager = (LogManager) getInstanceByClass(className);
- }
- if (null == manager) {
- manager = new LogManager();
- }
-
- // read configuration
- try {
- manager.readConfiguration();
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- // if global logger has been initialized, set root as its parent
- Logger root = new Logger("", null);
- root.setLevel(Level.INFO);
- Logger.global.setParent(root);
-
- manager.addLogger(root);
- manager.addLogger(Logger.global);
- return null;
- }
- });
- }
-
- /**
- * Default constructor. This is not public because there should be only one
- * {@code LogManager} instance, which can be get by
- * {@code LogManager.getLogManager()}. This is protected so that
- * application can subclass the object.
- */
- protected LogManager() {
- loggers = new Hashtable<String, Logger>();
- props = new Properties();
- listeners = new PropertyChangeSupport(this);
- // add shutdown hook to ensure that the associated resource will be
- // freed when JVM exits
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- public Void run() {
- Runtime.getRuntime().addShutdownHook(new Thread() {
- @Override
- public void run() {
- reset();
- }
- });
- return null;
- }
- });
- }
-
- /*
- * Package private utilities Returns the line separator of the underlying
- * OS.
- */
- static String getSystemLineSeparator() {
- return lineSeparator;
- }
-
- /**
- * Check that the caller has {@code LoggingPermission("control")} so
- * that it is trusted to modify the configuration for logging framework. If
- * the check passes, just return, otherwise {@code SecurityException}
- * will be thrown.
- *
- * @throws SecurityException
- * if there is a security manager in operation and the invoker
- * of this method does not have the required security permission
- * {@code LoggingPermission("control")}
- */
- public void checkAccess() {
- if (null != System.getSecurityManager()) {
- System.getSecurityManager().checkPermission(perm);
- }
- }
-
- /**
- * Add a given logger into the hierarchical namespace. The
- * {@code Logger.addLogger()} factory methods call this method to add newly
- * created Logger. This returns false if a logger with the given name has
- * existed in the namespace
- * <p>
- * Note that the {@code LogManager} may only retain weak references to
- * registered loggers. In order to prevent {@code Logger} objects from being
- * unexpectedly garbage collected it is necessary for <i>applications</i>
- * to maintain references to them.
- * </p>
- *
- * @param logger
- * the logger to be added.
- * @return true if the given logger is added into the namespace
- * successfully, false if the given logger exists in the namespace.
- */
- public synchronized boolean addLogger(Logger logger) {
- String name = logger.getName();
- if (null != loggers.get(name)) {
- return false;
- }
- addToFamilyTree(logger, name);
- loggers.put(name, logger);
- logger.setManager(this);
- return true;
- }
-
- private void addToFamilyTree(Logger logger, String name) {
- Logger parent = null;
- // find parent
- int lastSeparator;
- String parentName = name;
- while ((lastSeparator = parentName.lastIndexOf('.')) != -1) {
- parentName = parentName.substring(0, lastSeparator);
- parent = loggers.get(parentName);
- if (parent != null) {
- setParent(logger, parent);
- break;
- } else if (getProperty(parentName + ".level") != null ||
- getProperty(parentName + ".handlers") != null) {
- parent = Logger.getLogger(parentName);
- setParent(logger, parent);
- break;
- }
- }
- if (parent == null && null != (parent = loggers.get(""))) {
- setParent(logger, parent);
- }
-
- // find children
- // TODO: performance can be improved here?
- String nameDot = name + '.';
- Collection<Logger> allLoggers = loggers.values();
- for (final Logger child : allLoggers) {
- Logger oldParent = child.getParent();
- if (parent == oldParent
- && (name.length() == 0 || child.getName().startsWith(
- nameDot))) {
- final Logger thisLogger = logger;
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- child.setParent(thisLogger);
- return null;
- }
- });
- if (null != oldParent) {
- // -- remove from old parent as the parent has been changed
- oldParent.children.remove(child);
- }
- }
- }
- }
-
- /**
- * Get the logger with the given name.
- *
- * @param name
- * name of logger
- * @return logger with given name, or {@code null} if nothing is found.
- */
- public synchronized Logger getLogger(String name) {
- return loggers.get(name);
- }
-
- /**
- * Get a {@code Enumeration} of all registered logger names.
- *
- * @return enumeration of registered logger names
- */
- public synchronized Enumeration<String> getLoggerNames() {
- return loggers.keys();
- }
-
- /**
- * Get the global {@code LogManager} instance.
- *
- * @return the global {@code LogManager} instance
- */
- public static LogManager getLogManager() {
- return manager;
- }
-
- /**
- * Get the value of property with given name.
- *
- * @param name
- * the name of property
- * @return the value of property
- */
- public String getProperty(String name) {
- return props.getProperty(name);
- }
-
- /**
- * Re-initialize the properties and configuration. The initialization
- * process is same as the {@code LogManager} instantiation.
- * <p>
- * Notice : No {@code PropertyChangeEvent} are fired.
- * </p>
- *
- * @throws IOException
- * if any IO related problems happened.
- * @throws SecurityException
- * if security manager exists and it determines that caller does
- * not have the required permissions to perform this action.
- */
- public void readConfiguration() throws IOException {
- // check config class
- String configClassName = System.getProperty("java.util.logging.config.class");
- if (null == configClassName
- || null == getInstanceByClass(configClassName)) {
- // if config class failed, check config file
- String configFile = System.getProperty("java.util.logging.config.file");
-
- if (null == configFile) {
- // if cannot find configFile, use default logging.properties
- configFile = System.getProperty("java.home") + File.separator + "lib" +
- File.separator + "logging.properties";
- }
-
- InputStream input = null;
- try {
- // BEGIN android-removed
- // input = new BufferedInputStream(new FileInputStream(configFile));
- // END android-removed
-
- // BEGIN android-added
- try {
- input = new BufferedInputStream(new FileInputStream(configFile));
- } catch (Exception ex) {
- // consult fixed resource as a last resort
- input = new BufferedInputStream(
- getClass().getResourceAsStream("logging.properties"));
- }
- // END android-added
- readConfiguration(input);
- } finally {
- if (input != null) {
- try {
- input.close();
- } catch (Exception e) {// ignore
- }
- }
- }
- }
- }
-
- // use privilege code to get system property
- static String getPrivilegedSystemProperty(final String key) {
- return AccessController.doPrivileged(new PrivilegedAction<String>() {
- public String run() {
- return System.getProperty(key);
- }
- });
- }
-
- // use SystemClassLoader to load class from system classpath
- static Object getInstanceByClass(final String className) {
- try {
- Class<?> clazz = ClassLoader.getSystemClassLoader().loadClass(className);
- return clazz.newInstance();
- } catch (Exception e) {
- try {
- Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
- return clazz.newInstance();
- } catch (Exception innerE) {
- System.err.println("Loading class '" + className + "' failed");
- System.err.println(innerE);
- return null;
- }
- }
-
- }
-
- // actual initialization process from a given input stream
- private synchronized void readConfigurationImpl(InputStream ins)
- throws IOException {
- reset();
- props.load(ins);
-
- // The RI treats the root logger as special. For compatibility, always
- // update the root logger's handlers.
- Logger root = loggers.get("");
- if (root != null) {
- root.setManager(this);
- }
-
- // parse property "config" and apply setting
- String configs = props.getProperty("config");
- if (null != configs) {
- StringTokenizer st = new StringTokenizer(configs, " ");
- while (st.hasMoreTokens()) {
- String configerName = st.nextToken();
- getInstanceByClass(configerName);
- }
- }
-
- // set levels for logger
- Collection<Logger> allLoggers = loggers.values();
- for (Logger logger : allLoggers) {
- String property = props.getProperty(logger.getName() + ".level");
- if (null != property) {
- logger.setLevel(Level.parse(property));
- }
- }
- listeners.firePropertyChange(null, null, null);
- }
-
- /**
- * Re-initialize the properties and configuration from the given
- * {@code InputStream}
- * <p>
- * Notice : No {@code PropertyChangeEvent} are fired.
- * </p>
- *
- * @param ins
- * the input stream
- * @throws IOException
- * if any IO related problems happened.
- * @throws SecurityException
- * if security manager exists and it determines that caller does
- * not have the required permissions to perform this action.
- */
- public void readConfiguration(InputStream ins) throws IOException {
- checkAccess();
- readConfigurationImpl(ins);
- }
-
- /**
- * Reset configuration.
- * <p>
- * All handlers are closed and removed from any named loggers. All loggers'
- * level is set to null, except the root logger's level is set to
- * {@code Level.INFO}.
- * </p>
- *
- * @throws SecurityException
- * if security manager exists and it determines that caller does
- * not have the required permissions to perform this action.
- */
- public synchronized void reset() {
- checkAccess();
- props = new Properties();
- Enumeration<String> names = getLoggerNames();
- while (names.hasMoreElements()) {
- String name = names.nextElement();
- Logger logger = getLogger(name);
- if (logger != null) {
- logger.reset();
- }
- }
- Logger root = loggers.get("");
- if (null != root) {
- root.setLevel(Level.INFO);
- }
- }
-
- /**
- * Add a {@code PropertyChangeListener}, which will be invoked when
- * the properties are reread.
- *
- * @param l
- * the {@code PropertyChangeListener} to be added.
- * @throws SecurityException
- * if security manager exists and it determines that caller does
- * not have the required permissions to perform this action.
- */
- public void addPropertyChangeListener(PropertyChangeListener l) {
- if (l == null) {
- throw new NullPointerException();
- }
- checkAccess();
- listeners.addPropertyChangeListener(l);
- }
-
- /**
- * Remove a {@code PropertyChangeListener}, do nothing if the given
- * listener is not found.
- *
- * @param l
- * the {@code PropertyChangeListener} to be removed.
- * @throws SecurityException
- * if security manager exists and it determines that caller does
- * not have the required permissions to perform this action.
- */
- public void removePropertyChangeListener(PropertyChangeListener l) {
- checkAccess();
- listeners.removePropertyChangeListener(l);
- }
-
- /**
- * Returns a named logger associated with the supplied resource bundle.
- *
- * @param resourceBundleName the resource bundle to associate, or null for
- * no associated resource bundle.
- */
- synchronized Logger getOrCreate(String name, String resourceBundleName) {
- Logger result = getLogger(name);
- if (result == null) {
- result = new Logger(name, resourceBundleName);
- addLogger(result);
- }
- return result;
- }
-
-
- /**
- * Sets the parent of this logger in the namespace. Callers must first
- * {@link #checkAccess() check security}.
- *
- * @param newParent
- * the parent logger to set.
- */
- synchronized void setParent(Logger logger, Logger newParent) {
- logger.parent = newParent;
-
- if (logger.levelObjVal == null) {
- setLevelRecursively(logger, null);
- }
- newParent.children.add(logger);
- logger.updateDalvikLogHandler(); // android-only
- }
-
- /**
- * Sets the level on {@code logger} to {@code newLevel}. Any child loggers
- * currently inheriting their level from {@code logger} will be updated
- * recursively.
- *
- * @param newLevel the new minimum logging threshold. If null, the logger's
- * parent level will be used; or {@code Level.INFO} for loggers with no
- * parent.
- */
- synchronized void setLevelRecursively(Logger logger, Level newLevel) {
- int previous = logger.levelIntVal;
- logger.levelObjVal = newLevel;
-
- if (newLevel == null) {
- logger.levelIntVal = logger.parent != null
- ? logger.parent.levelIntVal
- : Level.INFO.intValue();
- } else {
- logger.levelIntVal = newLevel.intValue();
- }
-
- if (previous != logger.levelIntVal) {
- for (Logger child : logger.children) {
- if (child.levelObjVal == null) {
- setLevelRecursively(child, null);
- }
- }
- }
- }
-}
diff --git a/logging/src/main/java/java/util/logging/LogRecord.java b/logging/src/main/java/java/util/logging/LogRecord.java
deleted file mode 100644
index d4466bf..0000000
--- a/logging/src/main/java/java/util/logging/LogRecord.java
+++ /dev/null
@@ -1,507 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.logging;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-/**
- * A {@code LogRecord} object represents a logging request. It is passed between
- * the logging framework and individual logging handlers. Client applications
- * should not modify a {@code LogRecord} object that has been passed into the
- * logging framework.
- * <p>
- * The {@code LogRecord} class will infer the source method name and source
- * class name the first time they are accessed if the client application didn't
- * specify them explicitly. This automatic inference is based on the analysis of
- * the call stack and is not guaranteed to be precise. Client applications
- * should force the initialization of these two fields by calling
- * {@code getSourceClassName} or {@code getSourceMethodName} if they expect to
- * use them after passing the {@code LogRecord} object to another thread or
- * transmitting it over RMI.
- */
-public class LogRecord implements Serializable {
-
- private static final long serialVersionUID = 5372048053134512534L;
-
- // The major byte used in serialization.
- private static final int MAJOR = 1;
-
- // The minor byte used in serialization.
- private static final int MINOR = 4;
-
- // Store the current value for the sequence number.
- private static long currentSequenceNumber = 0;
-
- // Store the id for each thread.
- private static ThreadLocal<Integer> currentThreadId = new ThreadLocal<Integer>();
-
- // The base id as the starting point for thread ID allocation.
- private static int initThreadId = 0;
-
- /**
- * The logging level.
- *
- * @serial
- */
- private Level level;
-
- /**
- * The sequence number.
- *
- * @serial
- */
- private long sequenceNumber;
-
- /**
- * The name of the class that issued the logging call.
- *
- * @serial
- */
- private String sourceClassName;
-
- /**
- * The name of the method that issued the logging call.
- *
- * @serial
- */
- private String sourceMethodName;
-
- /**
- * The original message text.
- *
- * @serial
- */
- private String message;
-
- /**
- * The ID of the thread that issued the logging call.
- *
- * @serial
- */
- private int threadID;
-
- /**
- * The time that the event occurred, in milliseconds since 1970.
- *
- * @serial
- */
- private long millis;
-
- /**
- * The associated {@code Throwable} object if any.
- *
- * @serial
- */
- private Throwable thrown;
-
- /**
- * The name of the source logger.
- *
- * @serial
- */
- private String loggerName;
-
- /**
- * The name of the resource bundle used to localize the log message.
- *
- * @serial
- */
- private String resourceBundleName;
-
- // The associated resource bundle if any.
- private transient ResourceBundle resourceBundle;
-
- // The parameters.
- private transient Object[] parameters;
-
- // If the source method and source class has been initialized
- private transient boolean sourceInited;
-
- /**
- * Constructs a {@code LogRecord} object using the supplied the logging
- * level and message. The millis property is set to the current time. The
- * sequence property is set to a new unique value, allocated in increasing
- * order within the virtual machine. The thread ID is set to a unique value
- * for the current thread. All other properties are set to {@code null}.
- *
- * @param level
- * the logging level, may not be {@code null}.
- * @param msg
- * the raw message.
- * @throws NullPointerException
- * if {@code level} is {@code null}.
- */
- public LogRecord(Level level, String msg) {
- if (level == null) {
- throw new NullPointerException("level == null");
- }
- this.level = level;
- this.message = msg;
- this.millis = System.currentTimeMillis();
-
- synchronized (LogRecord.class) {
- this.sequenceNumber = currentSequenceNumber++;
- Integer id = currentThreadId.get();
- if (null == id) {
- this.threadID = initThreadId;
- currentThreadId.set(Integer.valueOf(initThreadId++));
- } else {
- this.threadID = id.intValue();
- }
- }
-
- this.sourceClassName = null;
- this.sourceMethodName = null;
- this.loggerName = null;
- this.parameters = null;
- this.resourceBundle = null;
- this.resourceBundleName = null;
- this.thrown = null;
- }
-
- /**
- * Gets the logging level.
- *
- * @return the logging level.
- */
- public Level getLevel() {
- return level;
- }
-
- /**
- * Sets the logging level.
- *
- * @param level
- * the level to set.
- * @throws NullPointerException
- * if {@code level} is {@code null}.
- */
- public void setLevel(Level level) {
- if (level == null) {
- throw new NullPointerException("level == null");
- }
- this.level = level;
- }
-
- /**
- * Gets the name of the logger.
- *
- * @return the logger name.
- */
- public String getLoggerName() {
- return loggerName;
- }
-
- /**
- * Sets the name of the logger.
- *
- * @param loggerName
- * the logger name to set.
- */
- public void setLoggerName(String loggerName) {
- this.loggerName = loggerName;
- }
-
- /**
- * Gets the raw message.
- *
- * @return the raw message, may be {@code null}.
- */
- public String getMessage() {
- return message;
- }
-
- /**
- * Sets the raw message. When this record is formatted by a logger that has
- * a localization resource bundle that contains an entry for {@code message},
- * then the raw message is replaced with its localized version.
- *
- * @param message
- * the raw message to set, may be {@code null}.
- */
- public void setMessage(String message) {
- this.message = message;
- }
-
- /**
- * Gets the time when this event occurred, in milliseconds since 1970.
- *
- * @return the time when this event occurred, in milliseconds since 1970.
- */
- public long getMillis() {
- return millis;
- }
-
- /**
- * Sets the time when this event occurred, in milliseconds since 1970.
- *
- * @param millis
- * the time when this event occurred, in milliseconds since 1970.
- */
- public void setMillis(long millis) {
- this.millis = millis;
- }
-
- /**
- * Gets the parameters.
- *
- * @return the array of parameters or {@code null} if there are no
- * parameters.
- */
- public Object[] getParameters() {
- return parameters;
- }
-
- /**
- * Sets the parameters.
- *
- * @param parameters
- * the array of parameters to set, may be {@code null}.
- */
- public void setParameters(Object[] parameters) {
- this.parameters = parameters;
- }
-
- /**
- * Gets the resource bundle used to localize the raw message during
- * formatting.
- *
- * @return the associated resource bundle, {@code null} if none is
- * available or the message is not localizable.
- */
- public ResourceBundle getResourceBundle() {
- return resourceBundle;
- }
-
- /**
- * Sets the resource bundle used to localize the raw message during
- * formatting.
- *
- * @param resourceBundle
- * the resource bundle to set, may be {@code null}.
- */
- public void setResourceBundle(ResourceBundle resourceBundle) {
- this.resourceBundle = resourceBundle;
- }
-
- /**
- * Gets the name of the resource bundle.
- *
- * @return the name of the resource bundle, {@code null} if none is
- * available or the message is not localizable.
- */
- public String getResourceBundleName() {
- return resourceBundleName;
- }
-
- /**
- * Sets the name of the resource bundle.
- *
- * @param resourceBundleName
- * the name of the resource bundle to set.
- */
- public void setResourceBundleName(String resourceBundleName) {
- this.resourceBundleName = resourceBundleName;
- }
-
- /**
- * Gets the sequence number.
- *
- * @return the sequence number.
- */
- public long getSequenceNumber() {
- return sequenceNumber;
- }
-
- /**
- * Sets the sequence number. It is usually not necessary to call this method
- * to change the sequence number because the number is allocated when this
- * instance is constructed.
- *
- * @param sequenceNumber
- * the sequence number to set.
- */
- public void setSequenceNumber(long sequenceNumber) {
- this.sequenceNumber = sequenceNumber;
- }
-
- /**
- * Gets the name of the class that is the source of this log record. This
- * information can be changed, may be {@code null} and is untrusted.
- *
- * @return the name of the source class of this log record (possiblity {@code null})
- */
- public String getSourceClassName() {
- initSource();
- return sourceClassName;
- }
-
- /*
- * Init the sourceClass and sourceMethod fields.
- */
- private void initSource() {
- // BEGIN android-changed
- if (sourceInited) {
- return;
- }
-
- boolean sawLogger = false;
- for (StackTraceElement element : new Throwable().getStackTrace()) {
- String current = element.getClassName();
- if (current.startsWith(Logger.class.getName())) {
- sawLogger = true;
- } else if (sawLogger) {
- this.sourceClassName = element.getClassName();
- this.sourceMethodName = element.getMethodName();
- break;
- }
- }
-
- sourceInited = true;
- // END android-changed
- }
-
- /**
- * Sets the name of the class that is the source of this log record.
- *
- * @param sourceClassName
- * the name of the source class of this log record, may be
- * {@code null}.
- */
- public void setSourceClassName(String sourceClassName) {
- sourceInited = true;
- this.sourceClassName = sourceClassName;
- }
-
- /**
- * Gets the name of the method that is the source of this log record.
- *
- * @return the name of the source method of this log record.
- */
- public String getSourceMethodName() {
- initSource();
- return sourceMethodName;
- }
-
- /**
- * Sets the name of the method that is the source of this log record.
- *
- * @param sourceMethodName
- * the name of the source method of this log record, may be
- * {@code null}.
- */
- public void setSourceMethodName(String sourceMethodName) {
- sourceInited = true;
- this.sourceMethodName = sourceMethodName;
- }
-
- /**
- * Gets a unique ID of the thread originating the log record. Every thread
- * becomes a different ID.
- * <p>
- * Notice : the ID doesn't necessary map the OS thread ID
- * </p>
- *
- * @return the ID of the thread originating this log record.
- */
- public int getThreadID() {
- return threadID;
- }
-
- /**
- * Sets the ID of the thread originating this log record.
- *
- * @param threadID
- * the new ID of the thread originating this log record.
- */
- public void setThreadID(int threadID) {
- this.threadID = threadID;
- }
-
- /**
- * Gets the {@code Throwable} object associated with this log record.
- *
- * @return the {@code Throwable} object associated with this log record.
- */
- public Throwable getThrown() {
- return thrown;
- }
-
- /**
- * Sets the {@code Throwable} object associated with this log record.
- *
- * @param thrown
- * the new {@code Throwable} object to associate with this log
- * record.
- */
- public void setThrown(Throwable thrown) {
- this.thrown = thrown;
- }
-
- /*
- * Customized serialization.
- */
- private void writeObject(ObjectOutputStream out) throws IOException {
- out.defaultWriteObject();
- out.writeByte(MAJOR);
- out.writeByte(MINOR);
- if (null == parameters) {
- out.writeInt(-1);
- } else {
- out.writeInt(parameters.length);
- for (Object element : parameters) {
- out.writeObject(null == element ? null : element.toString());
- }
- }
- }
-
- /*
- * Customized deserialization.
- */
- private void readObject(ObjectInputStream in) throws IOException,
- ClassNotFoundException {
- in.defaultReadObject();
- byte major = in.readByte();
- byte minor = in.readByte();
- // only check MAJOR version
- if (major != MAJOR) {
- throw new IOException("Different version " + Byte.valueOf(major) + "." + Byte.valueOf(minor));
- }
-
- int length = in.readInt();
- if (length >= 0) {
- parameters = new Object[length];
- for (int i = 0; i < parameters.length; i++) {
- parameters[i] = in.readObject();
- }
- }
- if (null != resourceBundleName) {
- try {
- resourceBundle = Logger.loadResourceBundle(resourceBundleName);
- } catch (MissingResourceException e) {
- // Cannot find the specified resource bundle
- resourceBundle = null;
- }
- }
- }
-}
diff --git a/logging/src/main/java/java/util/logging/Logger.java b/logging/src/main/java/java/util/logging/Logger.java
deleted file mode 100644
index 8271022..0000000
--- a/logging/src/main/java/java/util/logging/Logger.java
+++ /dev/null
@@ -1,1414 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.logging;
-
-// BEGIN android-note
-// this file contains cleaned up documentation and style for contribution
-// upstream
-// It also contains Android-specific optimizations that aren't appropriate for
-// general purpose platforms
-// END android-note
-
-import dalvik.system.DalvikLogHandler;
-import dalvik.system.DalvikLogging;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/**
- * Loggers are used to log records to a variety of destinations such as log files or
- * the console. They use instances of {@link Handler} to actually do the destination-specific
- * operations.
- *
- * <p>Client applications can get named loggers by calling the {@code getLogger}
- * methods. They can also get anonymous loggers by calling the
- * {@code getAnonymousLogger} methods. Named loggers are organized in a
- * namespace hierarchy managed by a log manager. The naming convention is
- * usually the Java package naming convention. Anonymous loggers do not belong to any namespace.
- *
- * <p>Developers should use named loggers to enable logging to be controlled on a
- * per-{@code Logger} granularity. The recommended idiom is to create and assign the logger to
- * a {@code static final} field. This ensures that there's always a strong reference to the logger,
- * preventing it from being garbage collected. In particular, {@link LogManager#addLogger(Logger)}
- * will <i>not</i> keep your logger live.
- *
- * <p>Loggers "inherit" log level setting from their parent if their own level is
- * set to {@code null}. This is also true for the resource bundle. The logger's
- * resource bundle is used to localize the log messages if no resource bundle
- * name is given when a log method is called. If {@code getUseParentHandlers()}
- * returns {@code true}, loggers also inherit their parent's handlers. In this
- * context, "inherit" only means that "behavior" is inherited. The internal
- * field values will not change, for example, {@code getLevel()} still returns
- * {@code null}.
- * <p>
- * When loading a given resource bundle, the logger first tries to use the
- * context {@code ClassLoader}. If that fails, it tries the system {@code ClassLoader}. And if
- * that still fails, it searches up the class stack and uses each class's
- * {@code ClassLoader} to try to locate the resource bundle.
- * <p>
- * Some log methods accept log requests that do not specify the source class and
- * source method. In these cases, the logging framework will automatically infer
- * the calling class and method, but this is not guaranteed to be accurate.
- * <p>
- * Once a {@code LogRecord} object has been passed into the logging framework,
- * it is owned by the logging framework and the client applications should not
- * use it any longer.
- * <p>
- * All methods of this class are thread-safe.
- *
- * @see LogManager
- */
-public class Logger {
-
- // BEGIN android-only
- /** A handler for use when no handler optimization is possible. */
- private static final DalvikLogHandler GENERAL_LOG_HANDLER = new DalvikLogHandler() {
- public void publish(Logger source, String tag, Level level, String message) {
- LogRecord record = new LogRecord(level, message);
- record.setLoggerName(source.name);
- source.setResourceBundle(record);
- source.log(record);
- }
- };
- // END android-only
-
- /**
- * The name of the global logger. Before using this, see the discussion of how to use
- * {@code Logger} in the class documentation.
- * @since 1.6
- * @hide
- */
- public static final String GLOBAL_LOGGER_NAME = "global";
-
- /**
- * The global logger is provided as convenience for casual use.
- * @deprecated deadlock-prone. Use {@code Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)} as
- * a direct replacement, but see the discussion of how to use {@code Logger} in the class
- * documentation.
- */
- @Deprecated
- public final static Logger global = new Logger(GLOBAL_LOGGER_NAME, null);
-
- /**
- * When converting the concurrent collection of handlers to an array, we
- * always pass a zero-length array to avoid size miscalculations. Passing
- * properly-sized arrays is non-atomic, and risks a null element in the
- * result.
- */
- private static final Handler[] EMPTY_HANDLERS_ARRAY = new Handler[0];
-
- /** The name of this logger. */
- private volatile String name;
-
- /** The parent logger of this logger. */
- Logger parent;
-
- /** The logging level of this logger, or null if none is set. */
- volatile Level levelObjVal;
-
- /**
- * The effective logging level of this logger. In order of preference this
- * is the first applicable of:
- * <ol>
- * <li>the int value of this logger's {@link #levelObjVal}
- * <li>the logging level of the parent
- * <li>the default level ({@link Level#INFO})
- * </ol>
- */
- volatile int levelIntVal = Level.INFO.intValue();
-
- /** The filter. */
- private Filter filter;
-
- /**
- * The resource bundle used to localize logging messages. If null, no
- * localization will be performed.
- */
- private volatile String resourceBundleName;
-
- /** The loaded resource bundle according to the specified name. */
- private volatile ResourceBundle resourceBundle;
-
- /**
- * The handlers attached to this logger. Eagerly initialized and
- * concurrently modified.
- */
- private final List<Handler> handlers = new CopyOnWriteArrayList<Handler>();
-
- /** True to notify the parent's handlers of each log message. */
- private boolean notifyParentHandlers = true;
-
- /**
- * Indicates whether this logger is named. Only {@link #getAnonymousLogger
- * anonymous loggers} are unnamed.
- */
- private boolean isNamed = true;
-
- /**
- * Child loggers. Should be accessed only while synchronized on {@code
- * LogManager.getLogManager()}.
- */
- final List<Logger> children = new ArrayList<Logger>();
-
- // BEGIN android-only
- /** the tag used for optimized logging. Derived from the logger name. */
- private final String androidTag;
-
- /** Handler delegate for either optimized or standard logging. */
- private volatile DalvikLogHandler dalvikLogHandler = GENERAL_LOG_HANDLER;
-
- /**
- * We've optimized for the common case: logging to a single handler that
- * implements {@link DalvikLogHandler}. This is how Android framework
- * applications are configured by default.
- *
- * <p>This optimization has been measured to show a 2.75x improvement in
- * throughput in the common case: 154ns vs. 56ns per message on a Cortex-A8.
- * Direct use of {@code android.util.Log} takes 29ns per message.
- *
- * <p>Each time the handler configuration changes, either directly or
- * indirectly, it's necessary to either turn on or off this optimization.
- * When the optimization is off, {@link #dalvikLogHandler} is assigned to
- * {@link #GENERAL_LOG_HANDLER} which can satisfy arbitrary configuration.
- * When the optimization is possible, {@link #dalvikLogHandler} is assigned
- * to the user's efficient implementation. In pratice this is usually the
- * {@code com.android.internal.logging.AndroidHandler}.
- */
- void updateDalvikLogHandler() {
- DalvikLogHandler newLogHandler = GENERAL_LOG_HANDLER;
-
- Logger parent = this.parent;
-
- if (getClass() != Logger.class) {
- /*
- * Do nothing. Subclasses aren't eligible for the optimization
- * because they may override methods like getHandlers() or
- * log(LogRecord).
- */
-
- } else if (parent == null) {
- // we use an iterator rather than size()+get() for safe concurrency
- Iterator<Handler> h = handlers.iterator();
- if (h.hasNext()) {
- Handler firstHandler = h.next();
- if (!h.hasNext() && firstHandler instanceof DalvikLogHandler) {
- /*
- * At this point, we're eligible for the optimization. We've
- * satisfied these constraints:
- * 1. This is not a subclass of logger
- * 2. This is a root logger (no parent)
- * 3. There is exactly one handler installed
- * 4. That handler is a DalvikLogHandler
- */
- newLogHandler = (DalvikLogHandler) firstHandler;
- }
- }
- } else if (handlers.isEmpty() && notifyParentHandlers) {
- /*
- * At this point, we're eligible for the optimization if our parent
- * logger is eligible. We've satisfied these constraints:
- * 1. This is not a subclass of logger
- * 2. our parent exists
- * 3. we have no handlers of our own
- * 4. we notify our parent's handlers
- */
- newLogHandler = parent.dalvikLogHandler;
- }
-
- if (newLogHandler == this.dalvikLogHandler) {
- return;
- }
-
- this.dalvikLogHandler = newLogHandler;
-
- for (Logger logger : children) {
- logger.updateDalvikLogHandler();
- }
- }
- // END android-only
-
- /**
- * Constructs a {@code Logger} object with the supplied name and resource
- * bundle name; {@code notifiyParentHandlers} is set to {@code true}.
- * <p>
- * Notice : Loggers use a naming hierarchy. Thus "z.x.y" is a child of "z.x".
- *
- * @param name
- * the name of this logger, may be {@code null} for anonymous
- * loggers.
- * @param resourceBundleName
- * the name of the resource bundle used to localize logging
- * messages, may be {@code null}.
- * @throws MissingResourceException
- * if the specified resource bundle can not be loaded.
- */
- protected Logger(String name, String resourceBundleName) {
- this.name = name;
- initResourceBundle(resourceBundleName);
- // BEGIN android-only
- this.androidTag = DalvikLogging.loggerNameToTag(name);
- updateDalvikLogHandler();
- // END android-only
- }
-
- /**
- * Load the specified resource bundle, use privileged code.
- *
- * @param resourceBundleName
- * the name of the resource bundle to load, cannot be {@code null}.
- * @return the loaded resource bundle.
- * @throws MissingResourceException
- * if the specified resource bundle can not be loaded.
- */
- static ResourceBundle loadResourceBundle(String resourceBundleName) {
- // try context class loader to load the resource
- ClassLoader cl = AccessController
- .doPrivileged(new PrivilegedAction<ClassLoader>() {
- public ClassLoader run() {
- return Thread.currentThread().getContextClassLoader();
- }
- });
- if (cl != null) {
- try {
- return ResourceBundle.getBundle(resourceBundleName, Locale
- .getDefault(), cl);
- } catch (MissingResourceException e) {
- // Failed to load using context classloader, ignore
- }
- }
- // try system class loader to load the resource
- cl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
- public ClassLoader run() {
- return ClassLoader.getSystemClassLoader();
- }
- });
- if (cl != null) {
- try {
- return ResourceBundle.getBundle(resourceBundleName, Locale
- .getDefault(), cl);
- } catch (MissingResourceException e) {
- // Failed to load using system classloader, ignore
- }
- }
- // try all class loaders up the class stack
- final Class<?>[] classes = AccessController
- .doPrivileged(new PrivilegedAction<Class<?>[]>() {
- public Class<?>[] run() {
- return (new PrivateSecurityManager())
- .privateGetClassContext();
- }
- });
- // the first class, which is PrivateSecurityManager, is skipped
- for (int i = 1; i < classes.length; i++) {
- final int index = i;
- try {
- cl = AccessController
- .doPrivileged(new PrivilegedAction<ClassLoader>() {
- public ClassLoader run() {
- return classes[index].getClassLoader();
- }
- });
- if (cl == null) {
- continue;
- }
- return ResourceBundle.getBundle(resourceBundleName, Locale
- .getDefault(), cl);
- } catch (MissingResourceException e) {
- // Failed to load using the current class's classloader, ignore
- }
- }
- throw new MissingResourceException("Failed to load the specified resource bundle \"" +
- resourceBundleName + "\"", resourceBundleName, null);
- }
-
- /**
- * Gets an anonymous logger to use internally in a thread. Anonymous loggers
- * are not registered in the log manager's namespace. No security checks
- * will be performed when updating an anonymous logger's control settings.
- * <p>
- * The anonymous loggers' parent is set to be the root logger. This way it
- * inherits the default logging level and handlers from the root logger.
- *
- * @return a new instance of anonymous logger.
- */
- public static Logger getAnonymousLogger() {
- return getAnonymousLogger(null);
- }
-
- /**
- * Gets an anonymous logger to use internally in a thread. Anonymous loggers
- * are not registered in the log manager's namespace. No security checks
- * will be performed when updating an anonymous logger's control settings.
- * <p>
- * The anonymous loggers' parent is set to be the root logger. This way it
- * inherits default logging level and handlers from the root logger.
- *
- * @param resourceBundleName
- * the name of the resource bundle used to localize log messages.
- * @return a new instance of anonymous logger.
- * @throws MissingResourceException
- * if the specified resource bundle can not be loaded.
- */
- public static Logger getAnonymousLogger(String resourceBundleName) {
- Logger result = new Logger(null, resourceBundleName);
- result.isNamed = false;
- LogManager logManager = LogManager.getLogManager();
- logManager.setParent(result, logManager.getLogger(""));
- return result;
- }
-
- /**
- * Initializes this logger's resource bundle.
- *
- * @throws IllegalArgumentException if this logger's resource bundle already
- * exists and is different from the resource bundle specified.
- */
- private synchronized void initResourceBundle(String resourceBundleName) {
- String current = this.resourceBundleName;
-
- if (current != null) {
- if (current.equals(resourceBundleName)) {
- return;
- } else {
- throw new IllegalArgumentException("Resource bundle name '" + resourceBundleName + "' is inconsistent with the existing '" + current + "'");
- }
- }
-
- if (resourceBundleName != null) {
- this.resourceBundle = loadResourceBundle(resourceBundleName);
- this.resourceBundleName = resourceBundleName;
- }
- }
-
- /**
- * Gets a named logger. The returned logger may already exist or may be
- * newly created. In the latter case, its level will be set to the
- * configured level according to the {@code LogManager}'s properties.
- *
- * @param name
- * the name of the logger to get, cannot be {@code null}.
- * @return a named logger.
- * @throws MissingResourceException
- * If the specified resource bundle can not be loaded.
- */
- public static Logger getLogger(String name) {
- return LogManager.getLogManager().getOrCreate(name, null);
- }
-
- /**
- * Gets a named logger associated with the supplied resource bundle. The
- * resource bundle will be used to localize logging messages.
- *
- * @param name
- * the name of the logger to get, cannot be {@code null}.
- * @param resourceBundleName
- * the name of the resource bundle, may be {@code null}.
- * @throws IllegalArgumentException
- * if the logger identified by {@code name} is associated with a
- * resource bundle and its name is not equal to
- * {@code resourceBundleName}.
- * @throws MissingResourceException
- * if the name of the resource bundle cannot be found.
- * @return a named logger.
- */
- public static Logger getLogger(String name, String resourceBundleName) {
- Logger result = LogManager.getLogManager()
- .getOrCreate(name, resourceBundleName);
- result.initResourceBundle(resourceBundleName);
- return result;
- }
-
- /**
- * Adds a handler to this logger. The {@code name} will be fed with log
- * records received by this logger.
- *
- * @param handler
- * the handler object to add, cannot be {@code null}.
- * @throws SecurityException
- * if a security manager determines that the caller does not
- * have the required permission.
- */
- public void addHandler(Handler handler) {
- if (handler == null) {
- throw new NullPointerException("handler == null");
- }
- // Anonymous loggers can always add handlers
- if (this.isNamed) {
- LogManager.getLogManager().checkAccess();
- }
- this.handlers.add(handler);
- updateDalvikLogHandler(); // android-only
- }
-
- /**
- * Set the logger's manager and initializes its configuration from the
- * manager's properties.
- */
- @SuppressWarnings("nls")
- void setManager(LogManager manager) {
- String levelProperty = manager.getProperty(name + ".level");
- if (levelProperty != null) {
- try {
- manager.setLevelRecursively(Logger.this, Level.parse(levelProperty));
- } catch (IllegalArgumentException invalidLevel) {
- invalidLevel.printStackTrace();
- }
- }
-
- String handlersPropertyName = "".equals(name) ? "handlers" : name + ".handlers";
- String handlersProperty = manager.getProperty(handlersPropertyName);
- if (handlersProperty != null) {
- for (String handlerName : handlersProperty.split(",|\\s")) {
- if (handlerName.equals("")) {
- continue;
- }
-
- final Handler handler;
- try {
- handler = (Handler) LogManager.getInstanceByClass(handlerName);
- } catch (Exception invalidHandlerName) {
- invalidHandlerName.printStackTrace();
- continue;
- }
-
- try {
- String level = manager.getProperty(handlerName + ".level");
- if (level != null) {
- handler.setLevel(Level.parse(level));
- }
- } catch (Exception invalidLevel) {
- invalidLevel.printStackTrace();
- }
-
- handlers.add(handler);
- }
- }
-
- updateDalvikLogHandler(); // android-only
- }
-
- /**
- * Gets all the handlers associated with this logger.
- *
- * @return an array of all the handlers associated with this logger.
- */
- public Handler[] getHandlers() {
- return handlers.toArray(EMPTY_HANDLERS_ARRAY);
- }
-
- /**
- * Removes a handler from this logger. If the specified handler does not
- * exist then this method has no effect.
- *
- * @param handler
- * the handler to be removed.
- * @throws SecurityException
- * if a security manager determines that the caller does not
- * have the required permission.
- */
- public void removeHandler(Handler handler) {
- // Anonymous loggers can always remove handlers
- if (this.isNamed) {
- LogManager.getLogManager().checkAccess();
- }
- if (handler == null) {
- return;
- }
- this.handlers.remove(handler);
- updateDalvikLogHandler(); // android-only
- }
-
- /**
- * Gets the filter used by this logger.
- *
- * @return the filter used by this logger, may be {@code null}.
- */
- public Filter getFilter() {
- return this.filter;
- }
-
- /**
- * Sets the filter used by this logger.
- *
- * @param newFilter
- * the filter to set, may be {@code null}.
- * @throws SecurityException
- * if a security manager determines that the caller does not
- * have the required permission.
- */
- public void setFilter(Filter newFilter) {
- // Anonymous loggers can always set the filter
- if (this.isNamed) {
- LogManager.getLogManager().checkAccess();
- }
- filter = newFilter;
- }
-
- /**
- * Gets the logging level of this logger. A {@code null} level indicates
- * that this logger inherits its parent's level.
- *
- * @return the logging level of this logger.
- */
- public Level getLevel() {
- return levelObjVal;
- }
-
- /**
- * Sets the logging level for this logger. A {@code null} level indicates
- * that this logger will inherit its parent's level.
- *
- * @param newLevel
- * the logging level to set.
- * @throws SecurityException
- * if a security manager determines that the caller does not
- * have the required permission.
- */
- public void setLevel(Level newLevel) {
- // Anonymous loggers can always set the level
- LogManager logManager = LogManager.getLogManager();
- if (this.isNamed) {
- logManager.checkAccess();
- }
- logManager.setLevelRecursively(this, newLevel);
- }
-
- /**
- * Gets the flag which indicates whether to use the handlers of this
- * logger's parent to publish incoming log records, potentially recursively
- * up the namespace.
- *
- * @return {@code true} if set to use parent's handlers, {@code false}
- * otherwise.
- */
- public boolean getUseParentHandlers() {
- return this.notifyParentHandlers;
- }
-
- /**
- * Sets the flag which indicates whether to use the handlers of this
- * logger's parent, potentially recursively up the namespace.
- *
- * @param notifyParentHandlers
- * the new flag indicating whether to use the parent's handlers.
- * @throws SecurityException
- * if a security manager determines that the caller does not
- * have the required permission.
- */
- public void setUseParentHandlers(boolean notifyParentHandlers) {
- // Anonymous loggers can always set the useParentHandlers flag
- if (this.isNamed) {
- LogManager.getLogManager().checkAccess();
- }
- this.notifyParentHandlers = notifyParentHandlers;
- updateDalvikLogHandler(); // android-only
- }
-
- /**
- * Gets the nearest parent of this logger in the namespace, a {@code null}
- * value will be returned if called on the root logger.
- *
- * @return the parent of this logger in the namespace.
- */
- public Logger getParent() {
- return parent;
- }
-
- /**
- * Sets the parent of this logger in the namespace. This method should be
- * used by the {@code LogManager} object only.
- *
- * @param parent
- * the parent logger to set.
- * @throws SecurityException
- * if a security manager determines that the caller does not
- * have the required permission.
- */
- public void setParent(Logger parent) {
- if (parent == null) {
- throw new NullPointerException("parent == null");
- }
-
- // even anonymous loggers are checked
- LogManager logManager = LogManager.getLogManager();
- logManager.checkAccess();
- logManager.setParent(this, parent);
- }
-
- /**
- * Gets the name of this logger, {@code null} for anonymous loggers.
- *
- * @return the name of this logger.
- */
- public String getName() {
- return this.name;
- }
-
- /**
- * Gets the loaded resource bundle used by this logger to localize logging
- * messages. If the value is {@code null}, the parent's resource bundle will be
- * inherited.
- *
- * @return the loaded resource bundle used by this logger.
- */
- public ResourceBundle getResourceBundle() {
- return this.resourceBundle;
- }
-
- /**
- * Gets the name of the loaded resource bundle used by this logger to
- * localize logging messages. If the value is {@code null}, the parent's resource
- * bundle name will be inherited.
- *
- * @return the name of the loaded resource bundle used by this logger.
- */
- public String getResourceBundleName() {
- return this.resourceBundleName;
- }
-
- /**
- * This method is for compatibility. Tests written to the reference
- * implementation API imply that the isLoggable() method is not called
- * directly. This behavior is important because subclass may override
- * isLoggable() method, so that affect the result of log methods.
- */
- private boolean internalIsLoggable(Level l) {
- int effectiveLevel = levelIntVal;
- if (effectiveLevel == Level.OFF.intValue()) {
- // always return false if the effective level is off
- return false;
- }
- return l.intValue() >= effectiveLevel;
- }
-
- /**
- * Determines whether this logger will actually log messages of the
- * specified level. The effective level used to do the determination may be
- * inherited from its parent. The default level is {@code Level.INFO}.
- *
- * @param l
- * the level to check.
- * @return {@code true} if this logger will actually log this level,
- * otherwise {@code false}.
- */
- public boolean isLoggable(Level l) {
- return internalIsLoggable(l);
- }
-
- /**
- * Sets the resource bundle and its name for a supplied LogRecord object.
- * This method first tries to use this logger's resource bundle if any,
- * otherwise try to inherit from this logger's parent, recursively up the
- * namespace.
- */
- private void setResourceBundle(LogRecord record) {
- for (Logger p = this; p != null; p = p.parent) {
- String resourceBundleName = p.resourceBundleName;
- if (resourceBundleName != null) {
- record.setResourceBundle(p.resourceBundle);
- record.setResourceBundleName(resourceBundleName);
- return;
- }
- }
- }
-
- /**
- * Logs a message indicating that a method has been entered. A log record
- * with log level {@code Level.FINER}, log message "ENTRY", the specified
- * source class name and source method name is submitted for logging.
- *
- * @param sourceClass
- * the calling class name.
- * @param sourceMethod
- * the method name.
- */
- public void entering(String sourceClass, String sourceMethod) {
- if (!internalIsLoggable(Level.FINER)) {
- return;
- }
-
- LogRecord record = new LogRecord(Level.FINER, "ENTRY"); //$NON-NLS-1$
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- setResourceBundle(record);
- log(record);
- }
-
- /**
- * Logs a message indicating that a method has been entered. A log record
- * with log level {@code Level.FINER}, log message "ENTRY", the specified
- * source class name, source method name and one parameter is submitted for
- * logging.
- *
- * @param sourceClass
- * the source class name.
- * @param sourceMethod
- * the source method name.
- * @param param
- * the parameter for the method call.
- */
- public void entering(String sourceClass, String sourceMethod, Object param) {
- if (!internalIsLoggable(Level.FINER)) {
- return;
- }
-
- LogRecord record = new LogRecord(Level.FINER, "ENTRY" + " {0}"); //$NON-NLS-1$ //$NON-NLS-2$
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setParameters(new Object[] { param });
- setResourceBundle(record);
- log(record);
- }
-
- /**
- * Logs a message indicating that a method has been entered. A log record
- * with log level {@code Level.FINER}, log message "ENTRY", the specified
- * source class name, source method name and array of parameters is
- * submitted for logging.
- *
- * @param sourceClass
- * the source class name.
- * @param sourceMethod
- * the source method name.
- * @param params
- * an array of parameters for the method call.
- */
- @SuppressWarnings("nls")
- public void entering(String sourceClass, String sourceMethod,
- Object[] params) {
- if (!internalIsLoggable(Level.FINER)) {
- return;
- }
-
- String msg = "ENTRY";
- if (params != null) {
- StringBuilder msgBuffer = new StringBuilder("ENTRY");
- for (int i = 0; i < params.length; i++) {
- msgBuffer.append(" {").append(i).append("}");
- }
- msg = msgBuffer.toString();
- }
- LogRecord record = new LogRecord(Level.FINER, msg);
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setParameters(params);
- setResourceBundle(record);
- log(record);
- }
-
- /**
- * Logs a message indicating that a method is exited. A log record with log
- * level {@code Level.FINER}, log message "RETURN", the specified source
- * class name and source method name is submitted for logging.
- *
- * @param sourceClass
- * the calling class name.
- * @param sourceMethod
- * the method name.
- */
- public void exiting(String sourceClass, String sourceMethod) {
- if (!internalIsLoggable(Level.FINER)) {
- return;
- }
-
- LogRecord record = new LogRecord(Level.FINER, "RETURN"); //$NON-NLS-1$
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- setResourceBundle(record);
- log(record);
- }
-
- /**
- * Logs a message indicating that a method is exited. A log record with log
- * level {@code Level.FINER}, log message "RETURN", the specified source
- * class name, source method name and return value is submitted for logging.
- *
- * @param sourceClass
- * the source class name.
- * @param sourceMethod
- * the source method name.
- * @param result
- * the return value of the method call.
- */
- public void exiting(String sourceClass, String sourceMethod, Object result) {
- if (!internalIsLoggable(Level.FINER)) {
- return;
- }
-
- LogRecord record = new LogRecord(Level.FINER, "RETURN" + " {0}"); //$NON-NLS-1$ //$NON-NLS-2$
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setParameters(new Object[] { result });
- setResourceBundle(record);
- log(record);
- }
-
- /**
- * Logs a message indicating that an exception is thrown. A log record with
- * log level {@code Level.FINER}, log message "THROW", the specified source
- * class name, source method name and the {@code Throwable} object is
- * submitted for logging.
- *
- * @param sourceClass
- * the source class name.
- * @param sourceMethod
- * the source method name.
- * @param thrown
- * the {@code Throwable} object.
- */
- public void throwing(String sourceClass, String sourceMethod,
- Throwable thrown) {
- if (!internalIsLoggable(Level.FINER)) {
- return;
- }
-
- LogRecord record = new LogRecord(Level.FINER, "THROW"); //$NON-NLS-1$
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setThrown(thrown);
- setResourceBundle(record);
- log(record);
- }
-
- /**
- * Logs a message of level {@code Level.SEVERE}; the message is transmitted
- * to all subscribed handlers.
- *
- * @param msg
- * the message to log.
- */
- public void severe(String msg) {
- log(Level.SEVERE, msg);
- }
-
- /**
- * Logs a message of level {@code Level.WARNING}; the message is
- * transmitted to all subscribed handlers.
- *
- * @param msg
- * the message to log.
- */
- public void warning(String msg) {
- log(Level.WARNING, msg);
- }
-
- /**
- * Logs a message of level {@code Level.INFO}; the message is transmitted
- * to all subscribed handlers.
- *
- * @param msg
- * the message to log.
- */
- public void info(String msg) {
- log(Level.INFO, msg);
- }
-
- /**
- * Logs a message of level {@code Level.CONFIG}; the message is transmitted
- * to all subscribed handlers.
- *
- * @param msg
- * the message to log.
- */
- public void config(String msg) {
- log(Level.CONFIG, msg);
- }
-
- /**
- * Logs a message of level {@code Level.FINE}; the message is transmitted
- * to all subscribed handlers.
- *
- * @param msg
- * the message to log.
- */
- public void fine(String msg) {
- log(Level.FINE, msg);
- }
-
- /**
- * Logs a message of level {@code Level.FINER}; the message is transmitted
- * to all subscribed handlers.
- *
- * @param msg
- * the message to log.
- */
- public void finer(String msg) {
- log(Level.FINER, msg);
- }
-
- /**
- * Logs a message of level {@code Level.FINEST}; the message is transmitted
- * to all subscribed handlers.
- *
- * @param msg
- * the message to log.
- */
- public void finest(String msg) {
- log(Level.FINEST, msg);
- }
-
- /**
- * Logs a message of the specified level. The message is transmitted to all
- * subscribed handlers.
- *
- * @param logLevel
- * the level of the specified message.
- * @param msg
- * the message to log.
- */
- public void log(Level logLevel, String msg) {
- if (!internalIsLoggable(logLevel)) {
- return;
- }
-
- // BEGIN android-only
- dalvikLogHandler.publish(this, androidTag, logLevel, msg);
- // END android-only
- }
-
- /**
- * Logs a message of the specified level with the supplied parameter. The
- * message is then transmitted to all subscribed handlers.
- *
- * @param logLevel
- * the level of the given message.
- * @param msg
- * the message to log.
- * @param param
- * the parameter associated with the event that is logged.
- */
- public void log(Level logLevel, String msg, Object param) {
- if (!internalIsLoggable(logLevel)) {
- return;
- }
-
- LogRecord record = new LogRecord(logLevel, msg);
- record.setLoggerName(this.name);
- record.setParameters(new Object[] { param });
- setResourceBundle(record);
- log(record);
- }
-
- /**
- * Logs a message of the specified level with the supplied parameter array.
- * The message is then transmitted to all subscribed handlers.
- *
- * @param logLevel
- * the level of the given message
- * @param msg
- * the message to log.
- * @param params
- * the parameter array associated with the event that is logged.
- */
- public void log(Level logLevel, String msg, Object[] params) {
- if (!internalIsLoggable(logLevel)) {
- return;
- }
-
- LogRecord record = new LogRecord(logLevel, msg);
- record.setLoggerName(this.name);
- record.setParameters(params);
- setResourceBundle(record);
- log(record);
- }
-
- /**
- * Logs a message of the specified level with the supplied {@code Throwable}
- * object. The message is then transmitted to all subscribed handlers.
- *
- * @param logLevel
- * the level of the given message.
- * @param msg
- * the message to log.
- * @param thrown
- * the {@code Throwable} object associated with the event that is
- * logged.
- */
- public void log(Level logLevel, String msg, Throwable thrown) {
- if (!internalIsLoggable(logLevel)) {
- return;
- }
-
- LogRecord record = new LogRecord(logLevel, msg);
- record.setLoggerName(this.name);
- record.setThrown(thrown);
- setResourceBundle(record);
- log(record);
- }
-
- /**
- * Logs a given log record. Only records with a logging level that is equal
- * or greater than this logger's level will be submitted to this logger's
- * handlers for logging. If {@code getUseParentHandlers()} returns {@code
- * true}, the log record will also be submitted to the handlers of this
- * logger's parent, potentially recursively up the namespace.
- * <p>
- * Since all other log methods call this method to actually perform the
- * logging action, subclasses of this class can override this method to
- * catch all logging activities.
- * </p>
- *
- * @param record
- * the log record to be logged.
- */
- public void log(LogRecord record) {
- if (!internalIsLoggable(record.getLevel())) {
- return;
- }
-
- // apply the filter if any
- Filter f = filter;
- if (f != null && !f.isLoggable(record)) {
- return;
- }
-
- /*
- * call the handlers of this logger, throw any exception that occurs
- */
- Handler[] allHandlers = getHandlers();
- for (Handler element : allHandlers) {
- element.publish(record);
- }
- // call the parent's handlers if set useParentHandlers
- Logger temp = this;
- Logger theParent = temp.parent;
- while (theParent != null && temp.getUseParentHandlers()) {
- Handler[] ha = theParent.getHandlers();
- for (Handler element : ha) {
- element.publish(record);
- }
- temp = theParent;
- theParent = temp.parent;
- }
- }
-
- /**
- * Logs a message of the given level with the specified source class name
- * and source method name.
- *
- * @param logLevel
- * the level of the given message.
- * @param sourceClass
- * the source class name.
- * @param sourceMethod
- * the source method name.
- * @param msg
- * the message to be logged.
- */
- public void logp(Level logLevel, String sourceClass, String sourceMethod,
- String msg) {
- if (!internalIsLoggable(logLevel)) {
- return;
- }
-
- LogRecord record = new LogRecord(logLevel, msg);
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- setResourceBundle(record);
- log(record);
- }
-
- /**
- * Logs a message of the given level with the specified source class name,
- * source method name and parameter.
- *
- * @param logLevel
- * the level of the given message
- * @param sourceClass
- * the source class name
- * @param sourceMethod
- * the source method name
- * @param msg
- * the message to be logged
- * @param param
- * the parameter associated with the event that is logged.
- */
- public void logp(Level logLevel, String sourceClass, String sourceMethod,
- String msg, Object param) {
- if (!internalIsLoggable(logLevel)) {
- return;
- }
-
- LogRecord record = new LogRecord(logLevel, msg);
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setParameters(new Object[] { param });
- setResourceBundle(record);
- log(record);
- }
-
- /**
- * Logs a message of the given level with the specified source class name,
- * source method name and parameter array.
- *
- * @param logLevel
- * the level of the given message.
- * @param sourceClass
- * the source class name.
- * @param sourceMethod
- * the source method name.
- * @param msg
- * the message to be logged.
- * @param params
- * the parameter array associated with the event that is logged.
- */
- public void logp(Level logLevel, String sourceClass, String sourceMethod,
- String msg, Object[] params) {
- if (!internalIsLoggable(logLevel)) {
- return;
- }
-
- LogRecord record = new LogRecord(logLevel, msg);
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setParameters(params);
- setResourceBundle(record);
- log(record);
- }
-
- /**
- * Logs a message of the given level with the specified source class name,
- * source method name and {@code Throwable} object.
- *
- * @param logLevel
- * the level of the given message.
- * @param sourceClass
- * the source class name.
- * @param sourceMethod
- * the source method name.
- * @param msg
- * the message to be logged.
- * @param thrown
- * the {@code Throwable} object.
- */
- public void logp(Level logLevel, String sourceClass, String sourceMethod,
- String msg, Throwable thrown) {
- if (!internalIsLoggable(logLevel)) {
- return;
- }
-
- LogRecord record = new LogRecord(logLevel, msg);
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setThrown(thrown);
- setResourceBundle(record);
- log(record);
- }
-
- /**
- * Logs a message of the given level with the specified source class name
- * and source method name, using the given resource bundle to localize the
- * message. If {@code bundleName} is null, the empty string or not valid then
- * the message is not localized.
- *
- * @param logLevel
- * the level of the given message.
- * @param sourceClass
- * the source class name.
- * @param sourceMethod
- * the source method name.
- * @param bundleName
- * the name of the resource bundle used to localize the message.
- * @param msg
- * the message to be logged.
- */
- public void logrb(Level logLevel, String sourceClass, String sourceMethod,
- String bundleName, String msg) {
- if (!internalIsLoggable(logLevel)) {
- return;
- }
-
- LogRecord record = new LogRecord(logLevel, msg);
- if (bundleName != null) {
- try {
- record.setResourceBundle(loadResourceBundle(bundleName));
- } catch (MissingResourceException e) {
- // ignore
- }
- record.setResourceBundleName(bundleName);
- }
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- log(record);
- }
-
- /**
- * Logs a message of the given level with the specified source class name,
- * source method name and parameter, using the given resource bundle to
- * localize the message. If {@code bundleName} is null, the empty string
- * or not valid then the message is not localized.
- *
- * @param logLevel
- * the level of the given message.
- * @param sourceClass
- * the source class name.
- * @param sourceMethod
- * the source method name.
- * @param bundleName
- * the name of the resource bundle used to localize the message.
- * @param msg
- * the message to be logged.
- * @param param
- * the parameter associated with the event that is logged.
- */
- public void logrb(Level logLevel, String sourceClass, String sourceMethod,
- String bundleName, String msg, Object param) {
- if (!internalIsLoggable(logLevel)) {
- return;
- }
-
- LogRecord record = new LogRecord(logLevel, msg);
- if (bundleName != null) {
- try {
- record.setResourceBundle(loadResourceBundle(bundleName));
- } catch (MissingResourceException e) {
- // ignore
- }
- record.setResourceBundleName(bundleName);
- }
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setParameters(new Object[] { param });
- log(record);
- }
-
- /**
- * Logs a message of the given level with the specified source class name,
- * source method name and parameter array, using the given resource bundle
- * to localize the message. If {@code bundleName} is null, the empty string
- * or not valid then the message is not localized.
- *
- * @param logLevel
- * the level of the given message.
- * @param sourceClass
- * the source class name.
- * @param sourceMethod
- * the source method name.
- * @param bundleName
- * the name of the resource bundle used to localize the message.
- * @param msg
- * the message to be logged.
- * @param params
- * the parameter array associated with the event that is logged.
- */
- public void logrb(Level logLevel, String sourceClass, String sourceMethod,
- String bundleName, String msg, Object[] params) {
- if (!internalIsLoggable(logLevel)) {
- return;
- }
-
- LogRecord record = new LogRecord(logLevel, msg);
- if (bundleName != null) {
- try {
- record.setResourceBundle(loadResourceBundle(bundleName));
- } catch (MissingResourceException e) {
- // ignore
- }
- record.setResourceBundleName(bundleName);
- }
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setParameters(params);
- log(record);
- }
-
- /**
- * Logs a message of the given level with the specified source class name,
- * source method name and {@code Throwable} object, using the given resource
- * bundle to localize the message. If {@code bundleName} is null, the empty
- * string or not valid then the message is not localized.
- *
- * @param logLevel
- * the level of the given message
- * @param sourceClass
- * the source class name
- * @param sourceMethod
- * the source method name
- * @param bundleName
- * the name of the resource bundle used to localize the message.
- * @param msg
- * the message to be logged.
- * @param thrown
- * the {@code Throwable} object.
- */
- public void logrb(Level logLevel, String sourceClass, String sourceMethod,
- String bundleName, String msg, Throwable thrown) {
- if (!internalIsLoggable(logLevel)) {
- return;
- }
-
- LogRecord record = new LogRecord(logLevel, msg);
- if (bundleName != null) {
- try {
- record.setResourceBundle(loadResourceBundle(bundleName));
- } catch (MissingResourceException e) {
- // ignore
- }
- record.setResourceBundleName(bundleName);
- }
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setThrown(thrown);
- log(record);
- }
-
- /*
- * This security manager is used to access the class context.
- */
- static class PrivateSecurityManager extends SecurityManager {
- public Class<?>[] privateGetClassContext() {
- return super.getClassContext();
- }
- }
-
- void reset() {
- levelObjVal = null;
- levelIntVal = Level.INFO.intValue();
-
- for (Handler handler : handlers) {
- try {
- if (handlers.remove(handler)) {
- handler.close();
- }
- } catch (Exception ignored) {
- }
- }
-
- updateDalvikLogHandler(); // android-only
- }
-}
diff --git a/logging/src/main/java/java/util/logging/LoggingMXBean.java b/logging/src/main/java/java/util/logging/LoggingMXBean.java
deleted file mode 100644
index 18cc4cc..0000000
--- a/logging/src/main/java/java/util/logging/LoggingMXBean.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.logging;
-
-import java.util.List;
-
-/**
- * {@code LoggingMXBean} is the management interface for the logging sub-system.
- * <p>
- * The ObjectName for identifying the {@code LoggingMXBean} in a bean server is
- * {@link LogManager#LOGGING_MXBEAN_NAME}.
- * </p>
- *
- * @since 1.5
- */
-public interface LoggingMXBean {
-
- /**
- * Gets the string value of the logging level of a logger. An empty string
- * is returned when the logger's level is defined by its parent. A
- * {@code null} is returned if the specified logger does not exist.
- *
- * @param loggerName
- * the name of the logger lookup.
- * @return a {@code String} if the logger is found, otherwise {@code null}.
- * @see Level#getName()
- */
- String getLoggerLevel(String loggerName);
-
- /**
- * Gets a list of all currently registered logger names. This is performed
- * using the {@link LogManager#getLoggerNames()}.
- *
- * @return a list of logger names.
- */
- List<String> getLoggerNames();
-
- /**
- * Gets the name of the parent logger of a logger. If the logger doesn't
- * exist then {@code null} is returned. If the logger is the root logger,
- * then an empty {@code String} is returned.
- *
- * @param loggerName
- * the name of the logger to lookup.
- * @return a {@code String} if the logger was found, otherwise {@code null}.
- */
- String getParentLoggerName(String loggerName);
-
- /**
- * Sets the log level of a logger. LevelName set to {@code null} means the
- * level is inherited from the nearest non-null ancestor.
- *
- * @param loggerName
- * the name of the logger to set the level on, which must not be
- * {@code null}.
- * @param levelName
- * the level to set on the logger, which may be {@code null}.
- * @throws IllegalArgumentException
- * if {@code loggerName} is not a registered logger or if
- * {@code levelName} is not null and not valid.
- * @throws SecurityException
- * if a security manager exists and the caller doesn't have
- * LoggingPermission("control").
- * @see Level#parse(String)
- */
- void setLoggerLevel(String loggerName, String levelName);
-}
diff --git a/logging/src/main/java/java/util/logging/LoggingPermission.java b/logging/src/main/java/java/util/logging/LoggingPermission.java
deleted file mode 100644
index 5ca9cc9..0000000
--- a/logging/src/main/java/java/util/logging/LoggingPermission.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.logging;
-
-import java.io.Serializable;
-import java.security.BasicPermission;
-import java.security.Guard;
-
-/**
- * The permission required to control the logging when run with a
- * {@code SecurityManager}.
- */
-public final class LoggingPermission extends BasicPermission implements Guard,
- Serializable {
-
- // for serialization compatibility with J2SE 1.4.2
- private static final long serialVersionUID = 63564341580231582L;
-
- /**
- * Constructs a {@code LoggingPermission} object required to control the
- * logging. The {@code SecurityManager} checks the permissions.
- * <p>
- * {@code LoggingPermission} objects are created by the security policy code
- * and depends on the security policy file, therefore programmers shouldn't
- * normally use them directly.
- * </p>
- *
- * @param name
- * currently must be "control".
- * @param actions
- * currently must be either {@code null} or the empty string.
- * @throws IllegalArgumentException
- * if name null or different from {@code string} control.
- */
- public LoggingPermission(String name, String actions) {
- super(name, actions);
- if (!"control".equals(name)) {
- throw new IllegalArgumentException("name must be \"control\"");
- }
- if (actions != null && !actions.isEmpty()) {
- throw new IllegalArgumentException("actions != null && !actions.isEmpty()");
- }
- }
-}
diff --git a/logging/src/main/java/java/util/logging/MemoryHandler.java b/logging/src/main/java/java/util/logging/MemoryHandler.java
deleted file mode 100644
index c1b36c8..0000000
--- a/logging/src/main/java/java/util/logging/MemoryHandler.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.logging;
-
-import java.security.AccessController;
-import java.security.PrivilegedExceptionAction;
-
-/**
- * A {@code Handler} put the description of log events into a cycled memory
- * buffer.
- * <p>
- * Mostly this {@code MemoryHandler} just puts the given {@code LogRecord} into
- * the internal buffer and doesn't perform any formatting or any other process.
- * When the buffer is full, the earliest buffered records will be discarded.
- * <p>
- * Every {@code MemoryHandler} has a target handler, and push action can be
- * triggered so that all buffered records will be output to the target handler
- * and normally the latter will publish the records. After the push action, the
- * buffer will be cleared.
- * <p>
- * The push method can be called directly, but will also be called automatically
- * if a new <code>LogRecord</code> is added that has a level greater than or
- * equal to than the value defined for the property
- * java.util.logging.MemoryHandler.push.
- * <p>
- * {@code MemoryHandler} will read following {@code LogManager} properties for
- * initialization, if given properties are not defined or has invalid values,
- * default value will be used.
- * <ul>
- * <li>java.util.logging.MemoryHandler.filter specifies the {@code Filter}
- * class name, defaults to no {@code Filter}.</li>
- * <li>java.util.logging.MemoryHandler.level specifies the level for this
- * {@code Handler}, defaults to {@code Level.ALL}.</li>
- * <li>java.util.logging.MemoryHandler.push specifies the push level, defaults
- * to level.SEVERE.</li>
- * <li>java.util.logging.MemoryHandler.size specifies the buffer size in number
- * of {@code LogRecord}, defaults to 1000.</li>
- * <li>java.util.logging.MemoryHandler.target specifies the class of the target
- * {@code Handler}, no default value, which means this property must be
- * specified either by property setting or by constructor.</li>
- * </ul>
- */
-public class MemoryHandler extends Handler {
-
- // default maximum buffered number of LogRecord
- private static final int DEFAULT_SIZE = 1000;
-
- // target handler
- private Handler target;
-
- // buffer size
- private int size = DEFAULT_SIZE;
-
- // push level
- private Level push = Level.SEVERE;
-
- // LogManager instance for convenience
- private final LogManager manager = LogManager.getLogManager();
-
- // buffer
- private LogRecord[] buffer;
-
- // current position in buffer
- private int cursor;
-
- /**
- * Default constructor, construct and init a {@code MemoryHandler} using
- * {@code LogManager} properties or default values.
- *
- * @throws RuntimeException
- * if property value are invalid and no default value could be
- * used.
- */
- public MemoryHandler() {
- super();
- String className = this.getClass().getName();
- // init target
- final String targetName = manager.getProperty(className + ".target");
- try {
- Class<?> targetClass = AccessController
- .doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
- public Class<?> run() throws Exception {
- ClassLoader loader = Thread.currentThread()
- .getContextClassLoader();
- if (loader == null) {
- loader = ClassLoader.getSystemClassLoader();
- }
- return loader.loadClass(targetName);
- }
- });
- target = (Handler) targetClass.newInstance();
- } catch (Exception e) {
- throw new RuntimeException("Cannot load target handler '" + targetName + "'");
- }
- // init size
- String sizeString = manager.getProperty(className + ".size");
- if (null != sizeString) {
- try {
- size = Integer.parseInt(sizeString);
- if (size <= 0) {
- size = DEFAULT_SIZE;
- }
- } catch (Exception e) {
- printInvalidPropMessage(className + ".size", sizeString, e);
- }
- }
- // init push level
- String pushName = manager.getProperty(className + ".push");
- if (null != pushName) {
- try {
- push = Level.parse(pushName);
- } catch (Exception e) {
- printInvalidPropMessage(className + ".push", pushName, e);
- }
- }
- // init other properties which are common for all Handler
- initProperties("ALL", null, "java.util.logging.SimpleFormatter", null);
- buffer = new LogRecord[size];
- }
-
- /**
- * Construct and init a {@code MemoryHandler} using given target, size and
- * push level, other properties using {@code LogManager} properties or
- * default values.
- *
- * @param target
- * the given {@code Handler} to output
- * @param size
- * the maximum number of buffered {@code LogRecord}, greater than
- * zero
- * @param pushLevel
- * the push level
- * @throws IllegalArgumentException
- * if {@code size <= 0}
- * @throws RuntimeException
- * if property value are invalid and no default value could be
- * used.
- */
- public MemoryHandler(Handler target, int size, Level pushLevel) {
- if (size <= 0) {
- throw new IllegalArgumentException("size <= 0");
- }
- target.getLevel();
- pushLevel.intValue();
- this.target = target;
- this.size = size;
- this.push = pushLevel;
- initProperties("ALL", null, "java.util.logging.SimpleFormatter", null);
- buffer = new LogRecord[size];
- }
-
- /**
- * Close this handler and target handler, free all associated resources.
- *
- * @throws SecurityException
- * if security manager exists and it determines that caller does
- * not have the required permissions to control this handler.
- */
- @Override
- public void close() {
- manager.checkAccess();
- target.close();
- setLevel(Level.OFF);
- }
-
- /**
- * Call target handler to flush any buffered output. Note that this doesn't
- * cause this {@code MemoryHandler} to push.
- */
- @Override
- public void flush() {
- target.flush();
- }
-
- /**
- * Put a given {@code LogRecord} into internal buffer. If given record is
- * not loggable, just return. Otherwise it is stored in the buffer.
- * Furthermore if the record's level is not less than the push level, the
- * push action is triggered to output all the buffered records to the target
- * handler, and the target handler will publish them.
- *
- * @param record
- * the log record
- */
- @Override
- public synchronized void publish(LogRecord record) {
- if (!isLoggable(record)) {
- return;
- }
- if (cursor >= size) {
- cursor = 0;
- }
- buffer[cursor++] = record;
- if (record.getLevel().intValue() >= push.intValue()) {
- push();
- }
- return;
- }
-
- /**
- * Return the push level.
- *
- * @return the push level
- */
- public Level getPushLevel() {
- return push;
- }
-
- /**
- * Check if given {@code LogRecord} would be put into this
- * {@code MemoryHandler}'s internal buffer.
- * <p>
- * The given {@code LogRecord} is loggable if and only if it has appropriate
- * level and it pass any associated filter's check.
- * <p>
- * Note that the push level is not used for this check.
- *
- * @param record
- * the given {@code LogRecord}
- * @return the given {@code LogRecord} if it should be logged, {@code false}
- * if {@code LogRecord} is {@code null}.
- */
- @Override
- public boolean isLoggable(LogRecord record) {
- return super.isLoggable(record);
- }
-
- /**
- * Triggers a push action to output all buffered records to the target handler,
- * and the target handler will publish them. Then the buffer is cleared.
- */
- public void push() {
- for (int i = cursor; i < size; i++) {
- if (null != buffer[i]) {
- target.publish(buffer[i]);
- }
- buffer[i] = null;
- }
- for (int i = 0; i < cursor; i++) {
- if (null != buffer[i]) {
- target.publish(buffer[i]);
- }
- buffer[i] = null;
- }
- cursor = 0;
- }
-
- /**
- * Set the push level. The push level is used to check the push action
- * triggering. When a new {@code LogRecord} is put into the internal
- * buffer and its level is not less than the push level, the push action
- * will be triggered. Note that set new push level won't trigger push action.
- *
- * @param newLevel
- * the new level to set.
- * @throws SecurityException
- * if security manager exists and it determines that caller
- * does not have the required permissions to control this handler.
- */
- public void setPushLevel(Level newLevel) {
- manager.checkAccess();
- newLevel.intValue();
- this.push = newLevel;
- }
-}
diff --git a/logging/src/main/java/java/util/logging/SimpleFormatter.java b/logging/src/main/java/java/util/logging/SimpleFormatter.java
deleted file mode 100644
index def4ad3..0000000
--- a/logging/src/main/java/java/util/logging/SimpleFormatter.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.logging;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.text.MessageFormat;
-import java.util.Date;
-
-/**
- * {@code SimpleFormatter} can be used to print a summary of the information
- * contained in a {@code LogRecord} object in a human readable format.
- */
-public class SimpleFormatter extends Formatter {
- /**
- * Constructs a new {@code SimpleFormatter}.
- */
- public SimpleFormatter() {
- super();
- }
-
- /**
- * Converts a {@link LogRecord} object into a human readable string
- * representation.
- *
- * @param r
- * the log record to be formatted into a string.
- * @return the formatted string.
- */
- @Override
- public String format(LogRecord r) {
- StringBuilder sb = new StringBuilder();
- sb.append(MessageFormat.format("{0, date} {0, time} ", //$NON-NLS-1$
- new Object[] { new Date(r.getMillis()) }));
- sb.append(r.getSourceClassName()).append(" "); //$NON-NLS-1$
- sb.append(r.getSourceMethodName()).append(
- LogManager.getSystemLineSeparator());
- sb.append(r.getLevel().getName()).append(": "); //$NON-NLS-1$
- sb.append(formatMessage(r)).append(LogManager.getSystemLineSeparator());
- if (null != r.getThrown()) {
- sb.append("Throwable occurred: "); //$NON-NLS-1$
- Throwable t = r.getThrown();
- PrintWriter pw = null;
- try {
- StringWriter sw = new StringWriter();
- pw = new PrintWriter(sw);
- t.printStackTrace(pw);
- sb.append(sw.toString());
- } finally {
- if (pw != null) {
- try {
- pw.close();
- } catch (Exception e) {
- // ignore
- }
- }
- }
- }
- return sb.toString();
- }
-}
diff --git a/logging/src/main/java/java/util/logging/SocketHandler.java b/logging/src/main/java/java/util/logging/SocketHandler.java
deleted file mode 100644
index fb854fe..0000000
--- a/logging/src/main/java/java/util/logging/SocketHandler.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.logging;
-
-import java.io.BufferedOutputStream;
-import java.io.IOException;
-import java.net.Socket;
-
-/**
- * A handler that writes log messages to a socket connection.
- * <p>
- * This handler reads the following properties from the log manager to
- * initialize itself:
- * <ul>
- * <li>java.util.logging.ConsoleHandler.level specifies the logging level,
- * defaults to {@code Level.ALL} if this property is not found or has an invalid
- * value.
- * <li>java.util.logging.SocketHandler.filter specifies the name of the filter
- * class to be associated with this handler, defaults to {@code null} if this
- * property is not found or has an invalid value.
- * <li>java.util.logging.SocketHandler.formatter specifies the name of the
- * formatter class to be associated with this handler, defaults to
- * {@code java.util.logging.XMLFormatter} if this property is not found or has
- * an invalid value.
- * <li>java.util.logging.SocketHandler.encoding specifies the encoding this
- * handler will use to encode log messages, defaults to {@code null} if this
- * property is not found or has an invalid value.
- * <li>java.util.logging.SocketHandler.host specifies the name of the host that
- * this handler should connect to. There's no default value for this property.
- * <li>java.util.logging.SocketHandler.encoding specifies the port number that
- * this handler should connect to. There's no default value for this property.
- * </ul>
- * <p>
- * This handler buffers the outgoing messages, but flushes each time a log
- * record has been published.
- * <p>
- * This class is not thread-safe.
- */
-public class SocketHandler extends StreamHandler {
-
- // default level
- private static final String DEFAULT_LEVEL = "ALL"; //$NON-NLS-1$
-
- // default formatter
- private static final String DEFAULT_FORMATTER = "java.util.logging.XMLFormatter"; //$NON-NLS-1$
-
- // the socket connection
- private Socket socket;
-
- /**
- * Constructs a {@code SocketHandler} object using the properties read by
- * the log manager, including the host name and port number. Default
- * formatting uses the XMLFormatter class and level is set to ALL.
- *
- * @throws IOException
- * if failed to connect to the specified host and port.
- * @throws IllegalArgumentException
- * if the host name or port number is illegal.
- * @throws SecurityException
- * if a security manager determines that the caller does not
- * have the required permission to control this handler.
- */
- public SocketHandler() throws IOException {
- super(DEFAULT_LEVEL, null, DEFAULT_FORMATTER, null);
- initSocket(LogManager.getLogManager().getProperty(
- "java.util.logging.SocketHandler.host"), LogManager //$NON-NLS-1$
- .getLogManager().getProperty(
- "java.util.logging.SocketHandler.port")); //$NON-NLS-1$
- }
-
- /**
- * Constructs a {@code SocketHandler} object using the specified host name
- * and port number together with other properties read by the log manager.
- * Default formatting uses the XMLFormatter class and level is set to ALL.
- *
- * @param host
- * the host name
- * @param port
- * the port number
- * @throws IOException
- * if failed to connect to the specified host and port.
- * @throws IllegalArgumentException
- * if the host name or port number is illegal.
- * @throws SecurityException
- * if a security manager determines that the caller does not
- * have the required permission to control this handler.
- */
- public SocketHandler(String host, int port) throws IOException {
- super(DEFAULT_LEVEL, null, DEFAULT_FORMATTER, null);
- initSocket(host, String.valueOf(port));
- }
-
- // Initialize the socket connection and prepare the output stream
- private void initSocket(String host, String port) throws IOException {
- // check the validity of the host name
- if (host == null || host.isEmpty()) {
- throw new IllegalArgumentException("host == null || host.isEmpty()");
- }
- // check the validity of the port number
- int p = 0;
- try {
- p = Integer.parseInt(port);
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("Illegal port argument");
- }
- if (p <= 0) {
- throw new IllegalArgumentException("Illegal port argument");
- }
- // establish the network connection
- try {
- this.socket = new Socket(host, p);
- } catch (IOException e) {
- getErrorManager().error("Failed to establish the network connection", e,
- ErrorManager.OPEN_FAILURE);
- throw e;
- }
- super.internalSetOutputStream(new BufferedOutputStream(this.socket.getOutputStream()));
- }
-
- /**
- * Closes this handler. The network connection to the host is also closed.
- *
- * @throws SecurityException
- * If a security manager determines that the caller does not
- * have the required permission to control this handler.
- */
- @Override
- public void close() {
- try {
- super.close();
- if (null != this.socket) {
- this.socket.close();
- this.socket = null;
- }
- } catch (Exception e) {
- getErrorManager().error("Exception occurred when closing the socket handler", e,
- ErrorManager.CLOSE_FAILURE);
- }
- }
-
- /**
- * Logs a record if necessary. A flush operation will be done afterwards.
- *
- * @param record
- * the log record to be logged.
- */
- @Override
- public void publish(LogRecord record) {
- super.publish(record);
- super.flush();
- }
-}
diff --git a/logging/src/main/java/java/util/logging/StreamHandler.java b/logging/src/main/java/java/util/logging/StreamHandler.java
deleted file mode 100644
index 2a67b98..0000000
--- a/logging/src/main/java/java/util/logging/StreamHandler.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.logging;
-
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-import java.io.Writer;
-
-/**
- * A {@code StreamHandler} object writes log messages to an output stream, that
- * is, objects of the class {@link java.io.OutputStream}.
- * <p>
- * A {@code StreamHandler} object reads the following properties from the log
- * manager to initialize itself. A default value will be used if a property is
- * not found or has an invalid value.
- * <ul>
- * <li>java.util.logging.StreamHandler.encoding specifies the encoding this
- * handler will use to encode log messages. Default is the encoding used by the
- * current platform.
- * <li>java.util.logging.StreamHandler.filter specifies the name of the filter
- * class to be associated with this handler. No <code>Filter</code> is used by
- * default.
- * <li>java.util.logging.StreamHandler.formatter specifies the name of the
- * formatter class to be associated with this handler. Default is
- * {@code java.util.logging.SimpleFormatter}.
- * <li>java.util.logging.StreamHandler.level specifies the logging level.
- * Defaults is {@code Level.INFO}.
- * </ul>
- * <p>
- * This class is not thread-safe.
- */
-public class StreamHandler extends Handler {
-
- // the output stream this handler writes to
- private OutputStream os;
-
- // the writer that writes to the output stream
- private Writer writer;
-
- // the flag indicating whether the writer has been initialized
- private boolean writerNotInitialized;
-
- /**
- * Constructs a {@code StreamHandler} object. The new stream handler
- * does not have an associated output stream.
- */
- public StreamHandler() {
- initProperties("INFO", null, "java.util.logging.SimpleFormatter", null);
- this.os = null;
- this.writer = null;
- this.writerNotInitialized = true;
- }
-
- /**
- * Constructs a {@code StreamHandler} object with the supplied output
- * stream. Default properties are read.
- *
- * @param os
- * the output stream this handler writes to.
- */
- StreamHandler(OutputStream os) {
- this();
- this.os = os;
- }
-
- /**
- * Constructs a {@code StreamHandler} object. The specified default values
- * will be used if the corresponding properties are not found in the log
- * manager's properties.
- */
- StreamHandler(String defaultLevel, String defaultFilter,
- String defaultFormatter, String defaultEncoding) {
- initProperties(defaultLevel, defaultFilter, defaultFormatter,
- defaultEncoding);
- this.os = null;
- this.writer = null;
- this.writerNotInitialized = true;
- }
-
- /**
- * Constructs a {@code StreamHandler} object with the supplied output stream
- * and formatter.
- *
- * @param os
- * the output stream this handler writes to.
- * @param formatter
- * the formatter this handler uses to format the output.
- * @throws NullPointerException
- * if {@code os} or {@code formatter} is {@code null}.
- */
- public StreamHandler(OutputStream os, Formatter formatter) {
- this();
- if (os == null) {
- throw new NullPointerException("os == null");
- }
- if (formatter == null) {
- throw new NullPointerException("formatter == null");
- }
- this.os = os;
- internalSetFormatter(formatter);
- }
-
- // initialize the writer
- private void initializeWriter() {
- this.writerNotInitialized = false;
- if (null == getEncoding()) {
- this.writer = new OutputStreamWriter(this.os);
- } else {
- try {
- this.writer = new OutputStreamWriter(this.os, getEncoding());
- } catch (UnsupportedEncodingException e) {
- /*
- * Should not happen because it's checked in
- * super.initProperties().
- */
- }
- }
- write(getFormatter().getHead(this));
- }
-
- // Write a string to the output stream.
- private void write(String s) {
- try {
- this.writer.write(s);
- } catch (Exception e) {
- getErrorManager().error("Exception occurred when writing to the output stream", e,
- ErrorManager.WRITE_FAILURE);
- }
- }
-
- /**
- * Sets the output stream this handler writes to. Note it does nothing else.
- *
- * @param newOs
- * the new output stream
- */
- void internalSetOutputStream(OutputStream newOs) {
- this.os = newOs;
- }
-
- /**
- * Sets the output stream this handler writes to. If there's an existing
- * output stream, the tail string of the associated formatter will be
- * written to it. Then it will be flushed, closed and replaced with
- * {@code os}.
- *
- * @param os
- * the new output stream.
- * @throws SecurityException
- * if a security manager determines that the caller does not
- * have the required permission.
- * @throws NullPointerException
- * if {@code os} is {@code null}.
- */
- protected void setOutputStream(OutputStream os) {
- if (null == os) {
- throw new NullPointerException();
- }
- LogManager.getLogManager().checkAccess();
- close(true);
- this.writer = null;
- this.os = os;
- this.writerNotInitialized = true;
- }
-
- /**
- * Sets the character encoding used by this handler. A {@code null} value
- * indicates that the default encoding should be used.
- *
- * @param encoding
- * the character encoding to set.
- * @throws SecurityException
- * if a security manager determines that the caller does not
- * have the required permission.
- * @throws UnsupportedEncodingException
- * if the specified encoding is not supported by the runtime.
- */
- @Override
- public void setEncoding(String encoding) throws SecurityException,
- UnsupportedEncodingException {
- // flush first before set new encoding
- this.flush();
- super.setEncoding(encoding);
- // renew writer only if the writer exists
- if (null != this.writer) {
- if (null == getEncoding()) {
- this.writer = new OutputStreamWriter(this.os);
- } else {
- try {
- this.writer = new OutputStreamWriter(this.os, getEncoding());
- } catch (UnsupportedEncodingException e) {
- /*
- * Should not happen because it's checked in
- * super.initProperties().
- */
- throw new AssertionError(e);
- }
- }
- }
- }
-
- /**
- * Closes this handler, but the underlying output stream is only closed if
- * {@code closeStream} is {@code true}. Security is not checked.
- *
- * @param closeStream
- * whether to close the underlying output stream.
- */
- void close(boolean closeStream) {
- if (null != this.os) {
- if (this.writerNotInitialized) {
- initializeWriter();
- }
- write(getFormatter().getTail(this));
- try {
- this.writer.flush();
- if (closeStream) {
- this.writer.close();
- this.writer = null;
- this.os = null;
- }
- } catch (Exception e) {
- getErrorManager().error("Exception occurred when closing the output stream", e,
- ErrorManager.CLOSE_FAILURE);
- }
- }
- }
-
- /**
- * Closes this handler. The tail string of the formatter associated with
- * this handler is written out. A flush operation and a subsequent close
- * operation is then performed upon the output stream. Client applications
- * should not use a handler after closing it.
- *
- * @throws SecurityException
- * if a security manager determines that the caller does not
- * have the required permission.
- */
- @Override
- public void close() {
- LogManager.getLogManager().checkAccess();
- close(true);
- }
-
- /**
- * Flushes any buffered output.
- */
- @Override
- public void flush() {
- if (null != this.os) {
- try {
- if (null != this.writer) {
- this.writer.flush();
- } else {
- this.os.flush();
- }
- } catch (Exception e) {
- getErrorManager().error("Exception occurred when flushing the output stream",
- e, ErrorManager.FLUSH_FAILURE);
- }
- }
- }
-
- /**
- * Accepts a logging request. The log record is formatted and written to the
- * output stream if the following three conditions are met:
- * <ul>
- * <li>the supplied log record has at least the required logging level;
- * <li>the supplied log record passes the filter associated with this
- * handler, if any;
- * <li>the output stream associated with this handler is not {@code null}.
- * </ul>
- * If it is the first time a log record is written out, the head string of
- * the formatter associated with this handler is written out first.
- *
- * @param record
- * the log record to be logged.
- */
- @Override
- public synchronized void publish(LogRecord record) {
- try {
- if (this.isLoggable(record)) {
- if (this.writerNotInitialized) {
- initializeWriter();
- }
- String msg = null;
- try {
- msg = getFormatter().format(record);
- } catch (Exception e) {
- getErrorManager().error("Exception occurred when formatting the log record",
- e, ErrorManager.FORMAT_FAILURE);
- }
- write(msg);
- }
- } catch (Exception e) {
- getErrorManager().error("Exception occurred when logging the record", e,
- ErrorManager.GENERIC_FAILURE);
- }
- }
-
- /**
- * Determines whether the supplied log record needs to be logged. The
- * logging levels are checked as well as the filter. The output stream of
- * this handler is also checked. If it is {@code null}, this method returns
- * {@code false}.
- * <p>
- * Notice : Case of no output stream will return {@code false}.
- *
- * @param record
- * the log record to be checked.
- * @return {@code true} if {@code record} needs to be logged, {@code false}
- * otherwise.
- */
- @Override
- public boolean isLoggable(LogRecord record) {
- if (null == record) {
- return false;
- }
- if (null != this.os && super.isLoggable(record)) {
- return true;
- }
- return false;
- }
-}
diff --git a/logging/src/main/java/java/util/logging/XMLFormatter.java b/logging/src/main/java/java/util/logging/XMLFormatter.java
deleted file mode 100644
index ff96813..0000000
--- a/logging/src/main/java/java/util/logging/XMLFormatter.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.util.logging;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.text.MessageFormat;
-import java.util.Date;
-import java.util.ResourceBundle;
-
-/**
- * Formatter to convert a {@link LogRecord} into an XML string. The DTD
- * specified in Appendix A to the Java Logging APIs specification is used.
- * {@code XMLFormatter} uses the output handler's encoding if it is specified,
- * otherwise the default platform encoding is used instead. UTF-8 is the
- * recommended encoding.
- */
-public class XMLFormatter extends Formatter {
-
- private static final String lineSeperator = LogManager
- .getSystemLineSeparator();
-
- private static final String indent = " "; //$NON-NLS-1$
-
- /**
- * Constructs a new {@code XMLFormatter}.
- */
- public XMLFormatter() {
- super();
- }
-
- /**
- * Converts a {@code LogRecord} into an XML string.
- *
- * @param r
- * the log record to be formatted.
- * @return the log record formatted as an XML string.
- */
- @SuppressWarnings("nls")
- @Override
- public String format(LogRecord r) {
- // call a method of LogRecord to ensure not null
- long time = r.getMillis();
- // format to date
- String date = MessageFormat.format("{0, date} {0, time}",
- new Object[] { new Date(time) });
-
- StringBuilder sb = new StringBuilder();
- sb.append(("<record>")).append(lineSeperator);
- sb.append(indent).append(("<date>")).append(date).append(("</date>"))
- .append(lineSeperator);
- sb.append(indent).append(("<millis>")).append(time).append(
- ("</millis>")).append(lineSeperator);
- sb.append(indent).append(("<sequence>")).append(r.getSequenceNumber())
- .append(("</sequence>")).append(lineSeperator);
- if (null != r.getLoggerName()) {
- sb.append(indent).append(("<logger>")).append(r.getLoggerName())
- .append(("</logger>")).append(lineSeperator);
- }
- sb.append(indent).append(("<level>")).append(r.getLevel().getName())
- .append(("</level>")).append(lineSeperator);
- if (null != r.getSourceClassName()) {
- sb.append(indent).append(("<class>"))
- .append(r.getSourceClassName()).append(("</class>"))
- .append(lineSeperator);
- }
- if (null != r.getSourceMethodName()) {
- sb.append(indent).append(("<method>")).append(
- r.getSourceMethodName()).append(("</method>")).append(
- lineSeperator);
- }
- sb.append(indent).append(("<thread>")).append(r.getThreadID()).append(
- ("</thread>")).append(lineSeperator);
- formatMessages(r, sb);
- Object[] params;
- if ((params = r.getParameters()) != null) {
- for (Object element : params) {
- sb.append(indent).append(("<param>")).append(element).append(
- ("</param>")).append(lineSeperator);
- }
- }
- formatThrowable(r, sb);
- sb.append(("</record>")).append(lineSeperator);
- return sb.toString();
- }
-
- @SuppressWarnings("nls")
- private void formatMessages(LogRecord r, StringBuilder sb) {
- // get localized message if has, but don't call Formatter.formatMessage
- // to parse pattern string
- ResourceBundle rb = r.getResourceBundle();
- String pattern = r.getMessage();
- if (null != rb && null != pattern) {
- String message;
- try {
- message = rb.getString(pattern);
- } catch (Exception e) {
- message = null;
- }
-
- if (message == null) {
- message = pattern;
- sb.append(indent).append(("<message>")).append(message).append(
- ("</message>")).append(lineSeperator);
- } else {
- sb.append(indent).append(("<message>")).append(message).append(
- ("</message>")).append(lineSeperator);
- sb.append(indent).append(("<key>")).append(pattern).append(
- ("</key>")).append(lineSeperator);
- sb.append(indent).append(("<catalog>")).append(
- r.getResourceBundleName()).append(("</catalog>"))
- .append(lineSeperator);
- }
- } else if (null != pattern) {
- sb.append(indent).append(("<message>")).append(pattern).append(
- ("</message>")).append(lineSeperator);
- } else {
- sb.append(indent).append(("<message/>"));
- }
- }
-
- @SuppressWarnings("nls")
- private void formatThrowable(LogRecord r, StringBuilder sb) {
- Throwable t;
- if ((t = r.getThrown()) != null) {
- sb.append(indent).append("<exception>").append(lineSeperator);
- sb.append(indent).append(indent).append("<message>").append(
- t.toString()).append("</message>").append(lineSeperator);
- // format throwable's stack trace
- StackTraceElement[] elements = t.getStackTrace();
- for (StackTraceElement e : elements) {
- sb.append(indent).append(indent).append("<frame>").append(
- lineSeperator);
- sb.append(indent).append(indent).append(indent).append(
- "<class>").append(e.getClassName()).append("</class>")
- .append(lineSeperator);
- sb.append(indent).append(indent).append(indent).append(
- "<method>").append(e.getMethodName()).append(
- "</method>").append(lineSeperator);
- sb.append(indent).append(indent).append(indent)
- .append("<line>").append(e.getLineNumber()).append(
- "</line>").append(lineSeperator);
- sb.append(indent).append(indent).append("</frame>").append(
- lineSeperator);
- }
- sb.append(indent).append("</exception>").append(lineSeperator);
- }
- }
-
- /**
- * Returns the header string for a set of log records formatted as XML
- * strings, using the output handler's encoding if it is defined, otherwise
- * using the default platform encoding.
- *
- * @param h
- * the output handler, may be {@code null}.
- * @return the header string for log records formatted as XML strings.
- */
- @SuppressWarnings("nls")
- @Override
- public String getHead(Handler h) {
- String encoding = null;
- if (null != h) {
- encoding = h.getEncoding();
- }
- if (null == encoding) {
- encoding = getSystemProperty("file.encoding");
- }
- StringBuilder sb = new StringBuilder();
- sb.append("<?xml version=\"1.0\" encoding=\"").append(encoding).append(
- "\" standalone=\"no\"?>").append(lineSeperator);
- sb.append("<!DOCTYPE log SYSTEM \"logger.dtd\">").append(lineSeperator);
- sb.append(("<log>"));
- return sb.toString();
- }
-
- /**
- * Returns the tail string for a set of log records formatted as XML
- * strings.
- *
- * @param h
- * the output handler, may be {@code null}.
- * @return the tail string for log records formatted as XML strings.
- */
- @Override
- public String getTail(Handler h) {
- return "</log>"; //$NON-NLS-1$
- }
-
- // use privilege code to get system property
- private static String getSystemProperty(final String key) {
- return AccessController.doPrivileged(new PrivilegedAction<String>() {
- public String run() {
- return System.getProperty(key);
- }
- });
- }
-}
diff --git a/logging/src/main/java/java/util/logging/logging.properties b/logging/src/main/java/java/util/logging/logging.properties
deleted file mode 100644
index f99fe3f..0000000
--- a/logging/src/main/java/java/util/logging/logging.properties
+++ /dev/null
@@ -1,65 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-#------------------------------------------------------------------------------
-# Default logging property file.
-# This file is used by java.util.logging package as default settings, users can
-# specify another file instead with java.util.logging.config.file system
-# property, this property can be set via the Preference API, or as VM arguments
-# passed to "java" command, or as property definition passed to JNI_CreateJavaVM.
-# You can refer to JavaDoc of java.util.logging package for more information
-# about this file.
-#------------------------------------------------------------------------------
-
-#------------------------------------------------------------------------------
-# Global settings
-#------------------------------------------------------------------------------
-
-# Specify default level for global logger, the event whose level is below won't
-# be logged. You can specify level for every logger, otherwise the level of parent
-# logger will be used. You can also set the level for every handler, as below for
-# java.util.logging.ConsoleHandler.
-.level=INFO
-
-# Specify handler classes list, these classes will be instantiated during the
-# logging framework initialization. The list should be white space separated.
-# For example, use the line below to add SocketHandler. Note that the handler
-# classes must be in the classpath.
-#
-# handlers=java.util.logging.ConsoleHandler java.util.logging.SocketHandler
-#
-handlers=java.util.logging.ConsoleHandler
-
-# Specify a class names list, these classes' default constructor will be executed
-# during logging package initialization, which may contain some code to set the
-# logging configuration. The list should be white space separated, and the
-# classes must be in the classpath.
-#
-# config=
-
-
-#------------------------------------------------------------------------------
-# Handler settings
-#------------------------------------------------------------------------------
-
-# The properties below are samples for handler settings.
-#java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
-#java.util.logging.ConsoleHandler.level=INFO
-#java.util.logging.FileHandler.limit=100000
-#java.util.logging.FileHandler.count=1
-#java.util.logging.FileHandler.formatter=java.util.logging.XMLFormatter
-#java.util.logging.FileHandler.pattern=%h/java%u.log
-
diff --git a/logging/src/main/java/java/util/logging/package.html b/logging/src/main/java/java/util/logging/package.html
deleted file mode 100644
index d7ed252..0000000
--- a/logging/src/main/java/java/util/logging/package.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
- <body>
- <p>
- This package allows to add logging to any application. It
- supports different levels of importance of a message that needs to be
- logged. The output written to the target can be filtered by this level.
- </p>
- </body>
-</html>