diff --git a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/ConsoleHandler.java b/jre_emul/android/libcore/luni/src/main/java/java/util/logging/ConsoleHandler.java
deleted file mode 100644
index 98b7b24af6..0000000000
--- a/jre_emul/android/libcore/luni/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}.
- *
- * This handler reads the following properties from the log manager to
- * initialize itself:
- *
- *
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.
- *
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.
- *
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.
- *
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.
- *
- *
- * 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/jre_emul/android/libcore/luni/src/main/java/java/util/logging/ErrorManager.java b/jre_emul/android/libcore/luni/src/main/java/java/util/logging/ErrorManager.java
deleted file mode 100644
index 877be0b7f8..0000000000
--- a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/ErrorManager.java
+++ /dev/null
@@ -1,105 +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;
-
- 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() {
- }
-
- /**
- * 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/jre_emul/android/libcore/luni/src/main/java/java/util/logging/Filter.java b/jre_emul/android/libcore/luni/src/main/java/java/util/logging/Filter.java
deleted file mode 100644
index c296ddbfc0..0000000000
--- a/jre_emul/android/libcore/luni/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/jre_emul/android/libcore/luni/src/main/java/java/util/logging/Formatter.java b/jre_emul/android/libcore/luni/src/main/java/java/util/logging/Formatter.java
deleted file mode 100644
index b18c2e924a..0000000000
--- a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/Formatter.java
+++ /dev/null
@@ -1,116 +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() {
- }
-
- /**
- * 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}.
- *
- * The message string is firstly localized using the {@code ResourceBundle}
- * object associated with the supplied {@code LogRecord}.
- *
- * 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 ((rb = r.getResourceBundle()) != null) {
- try {
- pattern = rb.getString(pattern);
- } catch (Exception e) {
- pattern = r.getMessage();
- }
- }
- if (pattern != null) {
- Object[] params = r.getParameters();
- /*
- * if the message contains "{0", use java.text.MessageFormat to
- * format the string
- */
- if (pattern.indexOf("{0") >= 0 && params != null && 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 "";
- }
-
- /**
- * 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 "";
- }
-}
diff --git a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/Handler.java b/jre_emul/android/libcore/luni/src/main/java/java/util/logging/Handler.java
deleted file mode 100644
index ae7288d528..0000000000
--- a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/Handler.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 java.io.UnsupportedEncodingException;
-import java.nio.charset.Charset;
-
-/**
- * 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 (className == null) {
- 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 {
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
- if (loader == null) {
- loader = ClassLoader.getSystemClassLoader();
- }
- Class> c = 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");
- if (filterName != null) {
- try {
- filter = (Filter) getCustomizeInstance(filterName);
- } catch (Exception e1) {
- printInvalidPropMessage("filter", filterName, e1);
- filter = (Filter) getDefaultInstance(defaultFilter);
- }
- } else {
- filter = (Filter) getDefaultInstance(defaultFilter);
- }
-
- // set level
- String levelName = manager.getProperty(prefix + ".level");
- if (levelName != null) {
- try {
- level = Level.parse(levelName);
- } catch (Exception e) {
- printInvalidPropMessage("level", levelName, e);
- level = Level.parse(defaultLevel);
- }
- } else {
- level = Level.parse(defaultLevel);
- }
-
- // set formatter
- final String formatterName = manager.getProperty(prefix + ".formatter");
- if (formatterName != null) {
- try {
- formatter = (Formatter) getCustomizeInstance(formatterName);
- } catch (Exception e) {
- printInvalidPropMessage("formatter", formatterName, e);
- formatter = (Formatter) getDefaultInstance(defaultFormatter);
- }
- } else {
- formatter = (Formatter) getDefaultInstance(defaultFormatter);
- }
-
- // set encoding
- final String encodingName = manager.getProperty(prefix + ".encoding");
- try {
- internalSetEncoding(encodingName);
- } catch (UnsupportedEncodingException e) {
- printInvalidPropMessage("encoding", encodingName, e);
- }
- }
-
- /**
- * 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.
- */
- 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.
- */
- 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 (record == null) {
- throw new NullPointerException("record == null");
- }
- if (this.level.intValue() == Level.OFF.intValue()) {
- return false;
- } else if (record.getLevel().intValue() >= this.level.intValue()) {
- return this.filter == null || 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.
- *
- * @throws UnsupportedEncodingException if {@code charsetName} is not supported.
- */
- public void setEncoding(String charsetName) throws UnsupportedEncodingException {
- LogManager.getLogManager().checkAccess();
- internalSetEncoding(charsetName);
- }
-
- /**
- * Sets the error manager for this handler.
- *
- * @param newErrorManager
- * the error manager to set.
- * @throws NullPointerException
- * if {@code em} is {@code null}.
- */
- public void setErrorManager(ErrorManager newErrorManager) {
- LogManager.getLogManager().checkAccess();
- if (newErrorManager == null) {
- throw new NullPointerException("newErrorManager == null");
- }
- this.errorMan = newErrorManager;
- }
-
- /**
- * Sets the filter to be used by this handler.
- *
- * @param newFilter
- * the filter to set, may be {@code null}.
- */
- 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 (newFormatter == null) {
- throw new NullPointerException("newFormatter == null");
- }
- 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}.
- */
- 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}.
- */
- public void setLevel(Level newLevel) {
- if (newLevel == null) {
- throw new NullPointerException("newLevel == null");
- }
- LogManager.getLogManager().checkAccess();
- this.level = newLevel;
- }
-}
diff --git a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/Level.java b/jre_emul/android/libcore/luni/src/main/java/java/util/logging/Level.java
deleted file mode 100644
index 6dc68359a3..0000000000
--- a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/Level.java
+++ /dev/null
@@ -1,357 +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.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-import libcore.util.Objects;
-
-/**
- * {@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.
- *
- * 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 levels = new ArrayList(9);
-
- /**
- * The OFF level provides no logging messages.
- */
- public static final Level OFF = new Level("OFF", Integer.MAX_VALUE);
-
- /**
- * The SEVERE level provides severe failure messages.
- */
- public static final Level SEVERE = new Level("SEVERE", 1000);
-
- /**
- * The WARNING level provides warnings.
- */
- public static final Level WARNING = new Level("WARNING", 900);
-
- /**
- * The INFO level provides informative messages.
- */
- public static final Level INFO = new Level("INFO", 800);
-
- /**
- * The CONFIG level provides static configuration messages.
- */
- public static final Level CONFIG = new Level("CONFIG", 700);
-
- /**
- * The FINE level provides tracing messages.
- */
- public static final Level FINE = new Level("FINE", 500);
-
- /**
- * The FINER level provides more detailed tracing messages.
- */
- public static final Level FINER = new Level("FINER", 400);
-
- /**
- * The FINEST level provides highly detailed tracing messages.
- */
- public static final Level FINEST = new Level("FINEST", 300);
-
- /**
- * The ALL level provides all logging messages.
- */
- public static final Level ALL = new Level("ALL", Integer.MIN_VALUE);
-
- /**
- * 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");
- }
-
- synchronized (levels) {
- for (Level level : levels) {
- if (name.equals(level.getName())) {
- return level;
- }
- }
- }
-
- boolean isNameAnInt;
- int nameAsInt;
- try {
- nameAsInt = Integer.parseInt(name);
- isNameAnInt = true;
- } catch (NumberFormatException e) {
- nameAsInt = 0;
- isNameAnInt = false;
- }
-
- if (isNameAnInt) {
- synchronized (levels) {
- /*
- * 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;
- }
- }
- }
- } else {
- 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,
- Locale.getDefault(), ClassLoader.getSystemClassLoader());
- } 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 (Objects.equal(resourceBundleName, 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/jre_emul/android/libcore/luni/src/main/java/java/util/logging/LogManager.java b/jre_emul/android/libcore/luni/src/main/java/java/util/logging/LogManager.java
deleted file mode 100644
index 3ee1752fa5..0000000000
--- a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/LogManager.java
+++ /dev/null
@@ -1,533 +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 com.google.j2objc.util.logging.IOSLogHandler;
-import java.beans.PropertyChangeListener;
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Properties;
-import java.util.StringTokenizer;
-import libcore.io.IoUtils;
-
-/*-[
-#include "java/io/IOException.h"
-]-*/
-
-/**
- * {@code LogManager} is used to maintain configuration properties of the
- * logging framework, and to manage a hierarchical namespace of all named
- * {@code Logger} objects.
- *
- * 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.
- *
- * 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.
- *
- * On initialization, {@code LogManager} reads its configuration from a
- * properties file, which by default is the "lib/logging.properties" in the JRE
- * directory.
- *
- * However, two optional system properties can be used to customize the initial
- * configuration process of {@code LogManager}.
- *
- *
"java.util.logging.config.class"
- *
"java.util.logging.config.file"
- *
- *
- * 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.
- *
- * 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}.
- *
- * 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.
- *
- * 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.
- *
- * The global logging properties may include:
- *
- *
"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.
- *
"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
- *
- *
- * This class, together with any handler and configuration classes associated
- * with it, must be loaded from the system classpath when
- * {@code LogManager} configuration occurs.
- *
- * 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.
- *
- * 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".
- *
- * 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".
- *
- * This class is thread safe. It is an error to synchronize on a
- * {@code LogManager} while synchronized on a {@code Logger}.
- */
-@SuppressWarnings("deprecation")
-public class LogManager {
-
- /** 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 loggers;
-
- /** The configuration properties */
- private Properties props;
-
- static { // init LogManager singleton instance
- String className = System.getProperty("java.util.logging.manager");
- if (className != null) {
- manager = (LogManager) getInstanceByClass(className);
- }
- if (manager == null) {
- manager = new LogManager();
- }
- checkConfiguration();
-
- // 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);
- }
-
- private static native void checkConfiguration() /*-[
- // To disable on iOS to improve startup performance, define
- // DISABLE_JAVA_LOG_CONFIGURATION to non-zero in project.
- #if !defined(DISABLE_JAVA_LOG_CONFIGURATION) || DISABLE_JAVA_LOG_CONFIGURATION == 0
- @try {
- [JavaUtilLoggingLogManager_manager readConfiguration];
- }
- @catch (JavaIoIOException *e) {
- [e printStackTrace];
- }
- #endif
- ]-*/;
-
- /**
- * 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();
- props = new Properties();
- // add shutdown hook to ensure that the associated resource will be
- // freed when JVM exits
- Runtime.getRuntime().addShutdownHook(new Thread() {
- @Override public void run() {
- reset();
- }
- });
- }
-
- /**
- * Does nothing.
- */
- public void checkAccess() {
- }
-
- /**
- * 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
- *
- * 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 applications
- * to maintain references to them.
- *
- *
- * @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 (loggers.get(name) != null) {
- 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 && (parent = loggers.get("")) != null) {
- setParent(logger, parent);
- }
-
- // find children
- // TODO: performance can be improved here?
- String nameDot = name + '.';
- Collection 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;
- child.setParent(thisLogger);
- if (oldParent != null) {
- // -- 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 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.
- *
- * Notice : No {@code PropertyChangeEvent} are fired.
- *
- *
- * @throws IOException
- * if any IO related problems happened.
- */
- public void readConfiguration() throws IOException {
- // check config class
- String configClassName = System.getProperty("java.util.logging.config.class");
- if (configClassName == null || getInstanceByClass(configClassName) == null) {
- // if config class failed, check config file
- String configFile = System.getProperty("java.util.logging.config.file");
-
- if (configFile == null) {
- // if cannot find configFile, use default logging.properties
- configFile = System.getProperty("java.home") + File.separator + "lib" +
- File.separator + "logging.properties";
- }
-
- InputStream input = null;
- try {
- if (new File(configFile).exists()) {
- input = new FileInputStream(configFile);
- } else {
- // fall back to using the built-in logging.properties file
- input = LogManager.class.getResourceAsStream("logging.properties");
- if (input == null) {
- input = new ByteArrayInputStream(
- IOSLogHandler.IOS_LOG_MANAGER_DEFAULTS.getBytes());
- }
- }
- readConfiguration(new BufferedInputStream(input));
- } finally {
- IoUtils.closeQuietly(input);
- }
- }
- }
-
- // 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 (configs != null) {
- StringTokenizer st = new StringTokenizer(configs, " ");
- while (st.hasMoreTokens()) {
- String configerName = st.nextToken();
- getInstanceByClass(configerName);
- }
- }
-
- // set levels for logger
- Collection allLoggers = loggers.values();
- for (Logger logger : allLoggers) {
- String property = props.getProperty(logger.getName() + ".level");
- if (property != null) {
- logger.setLevel(Level.parse(property));
- }
- }
- }
-
- /**
- * Re-initialize the properties and configuration from the given
- * {@code InputStream}
- *
- * Notice : No {@code PropertyChangeEvent} are fired.
- *
- *
- * @param ins
- * the input stream
- * @throws IOException
- * if any IO related problems happened.
- */
- public void readConfiguration(InputStream ins) throws IOException {
- checkAccess();
- readConfigurationImpl(ins);
- }
-
- /**
- * Reset configuration.
- *
- *
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}.
- */
- public synchronized void reset() {
- checkAccess();
- props = new Properties();
- Enumeration names = getLoggerNames();
- while (names.hasMoreElements()) {
- String name = names.nextElement();
- Logger logger = getLogger(name);
- if (logger != null) {
- logger.reset();
- }
- }
- Logger root = loggers.get("");
- if (root != null) {
- 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.
- */
- public void addPropertyChangeListener(PropertyChangeListener l) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Remove a {@code PropertyChangeListener}, do nothing if the given
- * listener is not found.
- *
- * @param l
- * the {@code PropertyChangeListener} to be removed.
- */
- public void removePropertyChangeListener(PropertyChangeListener l) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * 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);
- }
-
- /**
- * 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/jre_emul/android/libcore/luni/src/main/java/java/util/logging/LogRecord.java b/jre_emul/android/libcore/luni/src/main/java/java/util/logging/LogRecord.java
deleted file mode 100644
index 9944f20ff7..0000000000
--- a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/LogRecord.java
+++ /dev/null
@@ -1,505 +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.
- *
- * 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 currentThreadId = new ThreadLocal();
-
- // 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 sourceInitialized;
-
- /**
- * 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 VM. 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 (id == null) {
- 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() {
- if (sourceInitialized) {
- 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;
- }
- }
-
- sourceInitialized = true;
- }
-
- /**
- * 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) {
- sourceInitialized = 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) {
- sourceInitialized = true;
- this.sourceMethodName = sourceMethodName;
- }
-
- /**
- * Gets a unique ID of the thread originating the log record. Every thread
- * becomes a different ID.
- *
- * Notice : the ID doesn't necessary map the OS thread ID
- *
- *
- * @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 (parameters == null) {
- out.writeInt(-1);
- } else {
- out.writeInt(parameters.length);
- for (Object element : parameters) {
- out.writeObject((element == null) ? 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 (resourceBundleName != null) {
- try {
- resourceBundle = Logger.loadResourceBundle(resourceBundleName);
- } catch (MissingResourceException e) {
- // Cannot find the specified resource bundle
- resourceBundle = null;
- }
- }
- }
-}
diff --git a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/Logger.java b/jre_emul/android/libcore/luni/src/main/java/java/util/logging/Logger.java
deleted file mode 100644
index 8ed6c3d9d5..0000000000
--- a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/Logger.java
+++ /dev/null
@@ -1,1247 +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 com.google.j2objc.annotations.Weak;
-
-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.
- *
- *
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.
- *
- *
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 not keep your logger live.
- *
- *
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}.
- *
- * 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.
- *
- * 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.
- *
- * 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.
- *
- * All methods of this class are thread-safe.
- *
- * @see LogManager
- */
-public class Logger {
-
- /**
- * 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
- */
- public static final String GLOBAL_LOGGER_NAME = "global";
-
- /**
- * The global logger is provided as convenience for casual use.
- * @deprecated This is deadlock-prone. Use {@code Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)}
- * as a direct replacement, but read the discussion of how to use {@link Logger} in the class
- * documentation.
- */
- @Deprecated
- public static final 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. */
- @Weak
- 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:
- *
- *
the int value of this logger's {@link #levelObjVal}
- *
the logging level of the parent
- *
the default level ({@link Level#INFO})
- *
- */
- 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 handlers = new CopyOnWriteArrayList();
-
- /** 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 children = new ArrayList();
-
- /**
- * Constructs a {@code Logger} object with the supplied name and resource
- * bundle name; {@code notifiyParentHandlers} is set to {@code true}.
- *
- * 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);
- }
-
- /**
- * 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 = Thread.currentThread().getContextClassLoader();
- if (cl != null) {
- try {
- return ResourceBundle.getBundle(resourceBundleName, Locale.getDefault(), cl);
- } catch (MissingResourceException ignored) {
- // Failed to load using context class loader, ignore
- }
- }
- // try system class loader to load the resource
- cl = ClassLoader.getSystemClassLoader();
- if (cl != null) {
- try {
- return ResourceBundle.getBundle(resourceBundleName, Locale.getDefault(), cl);
- } catch (MissingResourceException ignored) {
- // Failed to load using system class loader, 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.
- *
- * 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.
- *
- * 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;
- }
-
- /**
- * Returns the global {@code Logger}.
- * @since 1.7
- */
- public static Logger getGlobal() {
- return global;
- }
-
- /**
- * 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}.
- */
- 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);
- }
-
- /**
- * Set the logger's manager and initializes its configuration from the
- * manager's properties.
- */
- 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 = name.isEmpty() ? "handlers" : name + ".handlers";
- String handlersProperty = manager.getProperty(handlersPropertyName);
- if (handlersProperty != null) {
- for (String handlerName : handlersProperty.split(",|\\s")) {
- if (handlerName.isEmpty()) {
- 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);
- }
- }
- }
-
- /**
- * 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.
- */
- 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);
- }
-
- /**
- * 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}.
- */
- 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.
- */
- 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.
- */
- public void setUseParentHandlers(boolean notifyParentHandlers) {
- // Anonymous loggers can always set the useParentHandlers flag
- if (this.isNamed) {
- LogManager.getLogManager().checkAccess();
- }
- this.notifyParentHandlers = notifyParentHandlers;
- }
-
- /**
- * 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.
- */
- 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");
- 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}");
- 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.
- */
- 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");
- 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}");
- 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");
- 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;
- }
-
- LogRecord record = new LogRecord(logLevel, msg);
- record.setLoggerName(this.name);
- setResourceBundle(record);
- log(record);
- }
-
- /**
- * 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.
- *
- * 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.
- *
- *
- * @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);
- }
-
- void reset() {
- levelObjVal = null;
- levelIntVal = Level.INFO.intValue();
-
- for (Handler handler : handlers) {
- try {
- if (handlers.remove(handler)) {
- handler.close();
- }
- } catch (Exception ignored) {
- }
- }
- }
-}
diff --git a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/LoggingMXBean.java b/jre_emul/android/libcore/luni/src/main/java/java/util/logging/LoggingMXBean.java
deleted file mode 100644
index a36a9d455a..0000000000
--- a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/LoggingMXBean.java
+++ /dev/null
@@ -1,79 +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.
- *
- * The ObjectName for identifying the {@code LoggingMXBean} in a bean server is
- * {@link LogManager#LOGGING_MXBEAN_NAME}.
- *
- *
- * @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 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.
- * @see Level#parse(String)
- */
- void setLoggerLevel(String loggerName, String levelName);
-}
diff --git a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/LoggingPermission.java b/jre_emul/android/libcore/luni/src/main/java/java/util/logging/LoggingPermission.java
deleted file mode 100644
index 3a55e26fe0..0000000000
--- a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/LoggingPermission.java
+++ /dev/null
@@ -1,34 +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;
-import java.security.Permission;
-
-/**
- * Legacy security code; do not use.
- */
-public final class LoggingPermission extends BasicPermission implements Guard, Serializable {
- public LoggingPermission(String name, String actions) { super("", ""); }
-
- @Override public String getActions() { return null; }
-
- @Override public boolean implies(Permission permission) { return true; }
-}
diff --git a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/MemoryHandler.java b/jre_emul/android/libcore/luni/src/main/java/java/util/logging/MemoryHandler.java
deleted file mode 100644
index d29b0efb6a..0000000000
--- a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/MemoryHandler.java
+++ /dev/null
@@ -1,261 +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 Handler} put the description of log events into a cycled memory
- * buffer.
- *
- * 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.
- *
- * 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.
- *
- * The push method can be called directly, but will also be called automatically
- * if a new LogRecord is added that has a level greater than or
- * equal to than the value defined for the property
- * java.util.logging.MemoryHandler.push.
- *
- * {@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.
- *
- *
java.util.logging.MemoryHandler.filter specifies the {@code Filter}
- * class name, defaults to no {@code Filter}.
- *
java.util.logging.MemoryHandler.level specifies the level for this
- * {@code Handler}, defaults to {@code Level.ALL}.
- *
java.util.logging.MemoryHandler.push specifies the push level, defaults
- * to level.SEVERE.
- *
java.util.logging.MemoryHandler.size specifies the buffer size in number
- * of {@code LogRecord}, defaults to 1000.
- *
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.
- *
- */
-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() {
- String className = this.getClass().getName();
- // init target
- final String targetName = manager.getProperty(className + ".target");
- try {
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
- if (loader == null) {
- loader = ClassLoader.getSystemClassLoader();
- }
- Class> targetClass = 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 (sizeString != null) {
- 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 (pushName != null) {
- 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.
- */
- @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 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.
- *
- * The given {@code LogRecord} is loggable if and only if it has appropriate
- * level and it pass any associated filter's check.
- *
- * 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 (buffer[i] != null) {
- target.publish(buffer[i]);
- }
- buffer[i] = null;
- }
- for (int i = 0; i < cursor; i++) {
- if (buffer[i] != null) {
- 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.
- */
- public void setPushLevel(Level newLevel) {
- manager.checkAccess();
- newLevel.intValue();
- this.push = newLevel;
- }
-}
diff --git a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/SimpleFormatter.java b/jre_emul/android/libcore/luni/src/main/java/java/util/logging/SimpleFormatter.java
deleted file mode 100644
index 22527e057d..0000000000
--- a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/SimpleFormatter.java
+++ /dev/null
@@ -1,69 +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;
-import libcore.io.IoUtils;
-
-/**
- * {@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() {
- }
-
- /**
- * 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} ",
- new Object[] { new Date(r.getMillis()) }));
- sb.append(r.getSourceClassName()).append(" ");
- sb.append(r.getSourceMethodName()).append(System.lineSeparator());
- sb.append(r.getLevel().getName()).append(": ");
- sb.append(formatMessage(r)).append(System.lineSeparator());
- if (r.getThrown() != null) {
- sb.append("Throwable occurred: ");
- Throwable t = r.getThrown();
- PrintWriter pw = null;
- try {
- StringWriter sw = new StringWriter();
- pw = new PrintWriter(sw);
- t.printStackTrace(pw);
- sb.append(sw.toString());
- } finally {
- IoUtils.closeQuietly(pw);
- }
- }
- return sb.toString();
- }
-}
diff --git a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/StreamHandler.java b/jre_emul/android/libcore/luni/src/main/java/java/util/logging/StreamHandler.java
deleted file mode 100644
index 4785f13fe3..0000000000
--- a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/StreamHandler.java
+++ /dev/null
@@ -1,326 +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}.
- *
- * 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.
- *
- *
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.
- *
java.util.logging.StreamHandler.filter specifies the name of the filter
- * class to be associated with this handler. No Filter is used by
- * default.
- *
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}.
- *
java.util.logging.StreamHandler.level specifies the logging level.
- * Defaults is {@code Level.INFO}.
- *
- *
- * 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 (getEncoding() == null) {
- 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 NullPointerException
- * if {@code os} is {@code null}.
- */
- protected void setOutputStream(OutputStream os) {
- if (os == null) {
- throw new NullPointerException("os == null");
- }
- 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.
- *
- * @throws UnsupportedEncodingException if {@code charsetName} is not supported.
- */
- @Override
- public void setEncoding(String charsetName) throws UnsupportedEncodingException {
- // Flush any existing data first.
- this.flush();
- super.setEncoding(charsetName);
- // renew writer only if the writer exists
- if (this.writer != null) {
- if (getEncoding() == null) {
- 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 (this.os != null) {
- 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.
- */
- @Override
- public void close() {
- LogManager.getLogManager().checkAccess();
- close(true);
- }
-
- /**
- * Flushes any buffered output.
- */
- @Override
- public void flush() {
- if (this.os != null) {
- try {
- if (this.writer != null) {
- 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:
- *
- *
the supplied log record has at least the required logging level;
- *
the supplied log record passes the filter associated with this
- * handler, if any;
- *
the output stream associated with this handler is not {@code null}.
- *
- * 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}.
- *
- * 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 (record == null) {
- return false;
- }
- if (this.os != null && super.isLoggable(record)) {
- return true;
- }
- return false;
- }
-}
diff --git a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/XMLFormatter.java b/jre_emul/android/libcore/luni/src/main/java/java/util/logging/XMLFormatter.java
deleted file mode 100644
index 0d80b3e57f..0000000000
--- a/jre_emul/android/libcore/luni/src/main/java/java/util/logging/XMLFormatter.java
+++ /dev/null
@@ -1,180 +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.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 indent = " ";
-
- /**
- * Constructs a new {@code XMLFormatter}.
- */
- public XMLFormatter() {
- }
-
- /**
- * 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.
- */
- @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) });
- String nl = System.lineSeparator();
-
- StringBuilder sb = new StringBuilder();
- sb.append("").append(nl);
- append(sb, 1, "date", date);
- append(sb, 1, "millis", time);
- append(sb, 1, "sequence", r.getSequenceNumber());
- if (r.getLoggerName() != null) {
- append(sb, 1, "logger", r.getLoggerName());
- }
- append(sb, 1, "level", r.getLevel().getName());
- if (r.getSourceClassName() != null) {
- append(sb, 1, "class", r.getSourceClassName());
- }
- if (r.getSourceMethodName() != null) {
- append(sb, 1, "method", r.getSourceMethodName());
- }
- append(sb, 1, "thread", r.getThreadID());
- formatMessages(r, sb);
- Object[] params = r.getParameters();
- if (params != null) {
- for (Object element : params) {
- append(sb, 1, "param", element);
- }
- }
- formatThrowable(r, sb);
- sb.append("").append(nl);
- return sb.toString();
- }
-
- 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 (rb != null && pattern != null) {
- String message;
- try {
- message = rb.getString(pattern);
- } catch (Exception e) {
- message = null;
- }
-
- if (message == null) {
- message = pattern;
- append(sb, 1, "message", message);
- } else {
- append(sb, 1, "message", message);
- append(sb, 1, "key", pattern);
- append(sb, 1, "catalog", r.getResourceBundleName());
- }
- } else if (pattern != null) {
- append(sb, 1, "message", pattern);
- } else {
- sb.append(indent).append("");
- }
- }
-
- private void formatThrowable(LogRecord r, StringBuilder sb) {
- Throwable t;
- if ((t = r.getThrown()) != null) {
- String nl = System.lineSeparator();
- sb.append(indent).append("").append(nl);
- append(sb, 2, "message", t.toString());
- // format throwable's stack trace
- StackTraceElement[] elements = t.getStackTrace();
- for (StackTraceElement e : elements) {
- sb.append(indent).append(indent).append("").append(nl);
- append(sb, 3, "class", e.getClassName());
- append(sb, 3, "method", e.getMethodName());
- append(sb, 3, "line", e.getLineNumber());
- sb.append(indent).append(indent).append("").append(nl);
- }
- sb.append(indent).append("").append(nl);
- }
- }
-
- private static void append(StringBuilder sb, int indentCount, String tag, Object value) {
- for (int i = 0; i < indentCount; ++i) {
- sb.append(indent);
- }
- sb.append("<").append(tag).append(">");
- sb.append(value);
- sb.append("").append(tag).append(">");
- sb.append(System.lineSeparator());
- }
-
- /**
- * 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.
- */
- @Override
- public String getHead(Handler h) {
- String encoding = null;
- if (h != null) {
- encoding = h.getEncoding();
- }
- if (encoding == null) {
- encoding = System.getProperty("file.encoding");
- }
- StringBuilder sb = new StringBuilder();
- sb.append("");
- sb.append(System.lineSeparator());
- sb.append("");
- sb.append(System.lineSeparator());
- sb.append("");
- 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 "";
- }
-}
diff --git a/jre_emul/android/platform/libcore/luni/src/main/java/java/util/logging/logging.properties b/jre_emul/android/platform/libcore/luni/src/main/java/java/util/logging/logging.properties
new file mode 100644
index 0000000000..f99fe3f050
--- /dev/null
+++ b/jre_emul/android/platform/libcore/luni/src/main/java/java/util/logging/logging.properties
@@ -0,0 +1,65 @@
+# 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/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldErrorManagerTest.java b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldErrorManagerTest.java
new file mode 100644
index 0000000000..d9ee1e4897
--- /dev/null
+++ b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldErrorManagerTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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 libcore.java.util.logging;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.logging.ErrorManager;
+import junit.framework.TestCase;
+
+public class OldErrorManagerTest extends TestCase {
+
+ private final PrintStream err = System.err;
+ private final PrintStream out = System.out;
+
+ public void tearDown() throws Exception{
+ System.setErr(err);
+ System.setOut(out);
+ super.tearDown();
+ }
+
+ public void test_errorCheck() {
+ ErrorManager em = new ErrorManager();
+ MockStream aos = new MockStream();
+ PrintStream st = new PrintStream(aos);
+ System.setErr(st);
+ System.setOut(st);
+ em.error("supertest", null, ErrorManager.GENERIC_FAILURE);
+ st.flush();
+ assertTrue("message appears (supertest)", aos.getWrittenData().indexOf("supertest") != -1);
+ }
+
+ public class MockStream extends ByteArrayOutputStream {
+
+ private StringBuffer linesWritten = new StringBuffer();
+
+ public void flush() {}
+ public void close() {}
+
+ @Override
+ public void write(byte[] buffer) {
+ linesWritten.append(new String(buffer));
+ }
+
+ @Override
+ public synchronized void write(byte[] buffer, int offset, int len) {
+ linesWritten.append(new String(buffer, offset, len));
+ }
+
+ public String getWrittenData() {return linesWritten.toString();}
+ }
+}
diff --git a/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldFileHandlerTest.java b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldFileHandlerTest.java
new file mode 100644
index 0000000000..785b2655b0
--- /dev/null
+++ b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldFileHandlerTest.java
@@ -0,0 +1,496 @@
+/*
+ * 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 libcore.java.util.logging;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Properties;
+import java.util.logging.FileHandler;
+import java.util.logging.Filter;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.LogRecord;
+import junit.framework.TestCase;
+
+public class OldFileHandlerTest extends TestCase {
+
+ static LogManager manager = LogManager.getLogManager();
+ final static Properties props = new Properties();
+ final static String className = OldFileHandlerTest.class.getName();
+ final static String SEP = File.separator;
+ String HOMEPATH;
+ String TEMPPATH;
+ FileHandler handler;
+ LogRecord r;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ manager.reset();
+
+ //initProp
+ props.clear();
+ props.put("java.util.logging.FileHandler.level", "FINE");
+ props.put("java.util.logging.FileHandler.filter", className
+ + "$MockFilter");
+ props.put("java.util.logging.FileHandler.formatter", className
+ + "$MockFormatter");
+ props.put("java.util.logging.FileHandler.encoding", "iso-8859-1");
+ // limit to only two message
+ props.put("java.util.logging.FileHandler.limit", "1000");
+ // rotation count is 2
+ props.put("java.util.logging.FileHandler.count", "2");
+ // using append mode
+ props.put("java.util.logging.FileHandler.append", "true");
+ props.put("java.util.logging.FileHandler.pattern",
+ "%t/log/java%u.test");
+
+ HOMEPATH = System.getProperty("user.home");
+ TEMPPATH = System.getProperty("java.io.tmpdir");
+
+ File file = new File(TEMPPATH + SEP + "log");
+ file.mkdir();
+ manager.readConfiguration(propertiesToInputStream(props));
+ handler = new FileHandler();
+ r = new LogRecord(Level.CONFIG, "msg");
+ }
+
+ protected void tearDown() throws Exception {
+ if (null != handler) {
+ handler.close();
+ }
+ reset(TEMPPATH + SEP + "log", "");
+ super.tearDown();
+ }
+
+ public static InputStream propertiesToInputStream(Properties p) throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ p.store(bos, "");
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ public void testFileHandler() throws Exception {
+ assertEquals("character encoding is non equal to actual value",
+ "iso-8859-1", handler.getEncoding());
+ assertNotNull("Filter is null", handler.getFilter());
+ assertNotNull("Formatter is null", handler.getFormatter());
+ assertEquals("is non equal to actual value", Level.FINE, handler
+ .getLevel());
+ assertNotNull("ErrorManager is null", handler.getErrorManager());
+ handler.publish(r);
+ handler.close();
+ // output 3 times, and all records left
+ // append mode is true
+ for (int i = 0; i < 3; i++) {
+ handler = new FileHandler();
+ handler.publish(r);
+ handler.close();
+ }
+ assertFileContent(TEMPPATH + SEP + "log", "java0.test.0",
+ new LogRecord[] { r, null, r, null, r, null, r },
+ new MockFormatter());
+ }
+
+ public void testFileHandler_1params() throws Exception {
+
+ handler = new FileHandler("%t/log/string");
+ assertEquals("character encoding is non equal to actual value",
+ "iso-8859-1", handler.getEncoding());
+ assertNotNull("Filter is null", handler.getFilter());
+ assertNotNull("Formatter is null", handler.getFormatter());
+ assertEquals("is non equal to actual value", Level.FINE, handler
+ .getLevel());
+ assertNotNull("ErrorManager is null", handler.getErrorManager());
+ handler.publish(r);
+ handler.close();
+
+ // output 3 times, and all records left
+ // append mode is true
+ for (int i = 0; i < 3; i++) {
+ handler = new FileHandler("%t/log/string");
+ handler.publish(r);
+ handler.close();
+ }
+ assertFileContent(TEMPPATH + SEP + "log", "/string", new LogRecord[] {
+ r, null, r, null, r, null, r }, new MockFormatter());
+
+ // test if unique ids not specified, it will append at the end
+ // no generation number is used
+ FileHandler h = new FileHandler("%t/log/string");
+ FileHandler h2 = new FileHandler("%t/log/string");
+ FileHandler h3 = new FileHandler("%t/log/string");
+ FileHandler h4 = new FileHandler("%t/log/string");
+ h.publish(r);
+ h2.publish(r);
+ h3.publish(r);
+ h4.publish(r);
+ h.close();
+ h2.close();
+ h3.close();
+ h4.close();
+ assertFileContent(TEMPPATH + SEP + "log", "string", h.getFormatter());
+ assertFileContent(TEMPPATH + SEP + "log", "string.1", h.getFormatter());
+ assertFileContent(TEMPPATH + SEP + "log", "string.2", h.getFormatter());
+ assertFileContent(TEMPPATH + SEP + "log", "string.3", h.getFormatter());
+
+ // default is append mode
+ FileHandler h6 = new FileHandler("%t/log/string%u.log");
+ h6.publish(r);
+ h6.close();
+ FileHandler h7 = new FileHandler("%t/log/string%u.log");
+ h7.publish(r);
+ h7.close();
+ try {
+ assertFileContent(TEMPPATH + SEP + "log", "string0.log", h
+ .getFormatter());
+ fail("should assertion failed");
+ } catch (Error e) {
+ }
+ File file = new File(TEMPPATH + SEP + "log");
+ assertTrue("length list of file is incorrect", file.list().length <= 2);
+
+ // test unique ids
+ FileHandler h8 = new FileHandler("%t/log/%ustring%u.log");
+ h8.publish(r);
+ FileHandler h9 = new FileHandler("%t/log/%ustring%u.log");
+ h9.publish(r);
+ h9.close();
+ h8.close();
+ assertFileContent(TEMPPATH + SEP + "log", "0string0.log", h
+ .getFormatter());
+ assertFileContent(TEMPPATH + SEP + "log", "1string1.log", h
+ .getFormatter());
+ file = new File(TEMPPATH + SEP + "log");
+ assertTrue("length list of file is incorrect", file.list().length <= 2);
+
+ try {
+ new FileHandler("");
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ public void testFileHandler_2params() throws Exception {
+ boolean append = false;
+ do {
+ append = !append;
+ handler = new FileHandler("%t/log/string", append);
+ assertEquals("character encoding is non equal to actual value",
+ "iso-8859-1", handler.getEncoding());
+ assertNotNull("Filter is null", handler.getFilter());
+ assertNotNull("Formatter is null", handler.getFormatter());
+ assertEquals("is non equal to actual value", Level.FINE, handler
+ .getLevel());
+ assertNotNull("ErrorManager is null", handler.getErrorManager());
+ handler.publish(r);
+ handler.close();
+ // output 3 times, and all records left
+ // append mode is true
+ for (int i = 0; i < 3; i++) {
+ handler = new FileHandler("%t/log/string", append);
+ handler.publish(r);
+ handler.close();
+ }
+ if (append) {
+ assertFileContent(TEMPPATH + SEP + "log", "/string",
+ new LogRecord[] { r, null, r, null, r, null, r },
+ new MockFormatter());
+ } else {
+ assertFileContent(TEMPPATH + SEP + "log", "/string",
+ new LogRecord[] { r }, new MockFormatter());
+ }
+ } while (append);
+
+ try {
+ new FileHandler("", true);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ public void testFileHandler_3params() throws Exception {
+ int limit = 120;
+ int count = 1;
+ handler = new FileHandler("%t/log/string", limit, count);
+ assertEquals("character encoding is non equal to actual value",
+ "iso-8859-1", handler.getEncoding());
+ assertNotNull("Filter is null", handler.getFilter());
+ assertNotNull("Formatter is null", handler.getFormatter());
+ assertEquals("is non equal to actual value", Level.FINE, handler
+ .getLevel());
+ assertNotNull("ErrorManager is null", handler.getErrorManager());
+ handler.publish(r);
+ handler.close();
+ // output 3 times, and all records left
+ // append mode is true
+ for (int i = 0; i < 3; i++) {
+ handler = new FileHandler("%t/log/string", limit, count);
+ handler.publish(r);
+ handler.close();
+ }
+ assertFileContent(TEMPPATH + SEP + "log", "/string", new LogRecord[] {
+ r, null, r, null, r, null, r }, new MockFormatter());
+
+ try {
+ new FileHandler("", limit, count);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new FileHandler("%t/log/string", -1, count);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new FileHandler("%t/log/string", limit, 0);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ public void testFileHandler_4params() throws Exception {
+ int limit = 120;
+ int count = 1;
+ boolean append = false;
+ do {
+ append = !append;
+ handler = new FileHandler("%t/log/string", limit, count, append);
+ assertEquals("character encoding is non equal to actual value",
+ "iso-8859-1", handler.getEncoding());
+ assertNotNull("Filter is null", handler.getFilter());
+ assertNotNull("Formatter is null", handler.getFormatter());
+ assertEquals("is non equal to actual value", Level.FINE, handler
+ .getLevel());
+ assertNotNull("ErrorManager is null", handler.getErrorManager());
+ handler.publish(r);
+ handler.close();
+ // output 3 times, and all records left
+ // append mode is true
+ for (int i = 0; i < 3; i++) {
+ handler = new FileHandler("%t/log/string", limit, count, append);
+ handler.publish(r);
+ handler.close();
+ }
+ if (append) {
+ assertFileContent(TEMPPATH + SEP + "log", "/string",
+ new LogRecord[] { r, null, r, null, r, null, r },
+ new MockFormatter());
+ } else {
+ assertFileContent(TEMPPATH + SEP + "log", "/string",
+ new LogRecord[] { r }, new MockFormatter());
+ }
+ } while (append);
+
+ try {
+ new FileHandler("", limit, count, true);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new FileHandler("%t/log/string", -1, count, false);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new FileHandler("%t/log/string", limit, 0, true);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ private void assertFileContent(String homepath, String filename,
+ Formatter formatter) throws Exception {
+ assertFileContent(homepath, filename, new LogRecord[] { r }, formatter);
+ }
+
+ private void assertFileContent(String homepath, String filename,
+ LogRecord[] lr, Formatter formatter) throws Exception {
+ handler.close();
+ String msg = "";
+ // if formatter is null, the file content should be empty
+ // else the message should be formatted given records
+ if (null != formatter) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(formatter.getHead(handler));
+ for (int i = 0; i < lr.length; i++) {
+ if (null == lr[i] && i < lr.length - 1) {
+ // if one record is null and is not the last record, means
+ // here is
+ // output completion point, should output tail, then output
+ // head
+ // (ready for next output)
+ sb.append(formatter.getTail(handler));
+ sb.append(formatter.getHead(handler));
+ } else {
+ sb.append(formatter.format(lr[i]));
+ }
+ }
+ sb.append(formatter.getTail(handler));
+ msg = sb.toString();
+ }
+ char[] chars = new char[msg.length()];
+ Reader reader = null;
+ try {
+ reader = new BufferedReader(new FileReader(homepath + SEP
+ + filename));
+ reader.read(chars);
+ assertEquals(msg, new String(chars));
+ // assert has reached the end of the file
+ assertEquals(-1, reader.read());
+ } finally {
+ try {
+ if (reader != null) {
+ reader.close();
+ }
+ } catch (Exception e) {
+ // don't care
+ }
+ reset(homepath, filename);
+ }
+ }
+
+ /**
+ * Does a cleanup of given file
+ */
+ private void reset(String homepath, String filename) {
+ File file;
+ try {
+ file = new File(homepath + SEP + filename);
+ if (file.isFile()) {
+ file.delete();
+ } else if (file.isDirectory()) {
+ File[] files = file.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ files[i].delete();
+ }
+ file.delete();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ try {
+ file = new File(homepath + SEP + filename + ".lck");
+ file.delete();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ // This test fails on RI. Doesn't parse special pattern \"%t/%h."
+ public void testInvalidParams() throws IOException {
+
+ // %t and %p parsing can add file separator automatically
+
+ // bad directory, IOException, append
+ try {
+ new FileHandler("%t/baddir/multi%g", true);
+ fail("should throw IO exception");
+ } catch (IOException e) {
+ }
+ File file = new File(TEMPPATH + SEP + "baddir" + SEP + "multi0");
+ assertFalse(file.exists());
+ try {
+ new FileHandler("%t/baddir/multi%g", false);
+ fail("should throw IO exception");
+ } catch (IOException e) {
+ }
+ file = new File(TEMPPATH + SEP + "baddir" + SEP + "multi0");
+ assertFalse(file.exists());
+
+ try {
+ new FileHandler("%t/baddir/multi%g", 12, 4);
+ fail("should throw IO exception");
+ } catch (IOException e) {
+ }
+ file = new File(TEMPPATH + SEP + "baddir" + SEP + "multi0");
+ assertFalse(file.exists());
+
+ try {
+ new FileHandler("%t/java%u", -1, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ public void testPublish() throws Exception {
+ LogRecord[] r = new LogRecord[] { new LogRecord(Level.CONFIG, "msg__"),
+ new LogRecord(Level.WARNING, "message"),
+ new LogRecord(Level.INFO, "message for"),
+ new LogRecord(Level.FINE, "message for test") };
+ for (int i = 0; i < r.length; i++) {
+ handler = new FileHandler("%t/log/stringPublish");
+ handler.publish(r[i]);
+ handler.close();
+ assertFileContent(TEMPPATH + SEP + "log", "stringPublish",
+ new LogRecord[] { r[i] }, handler.getFormatter());
+ }
+ }
+
+ public void testClose() throws Exception {
+ FileHandler h = new FileHandler("%t/log/stringPublish");
+ h.publish(r);
+ h.close();
+ assertFileContent(TEMPPATH + SEP + "log", "stringPublish", h
+ .getFormatter());
+ }
+
+ /*
+ * mock classes
+ */
+ public static class MockFilter implements Filter {
+ public boolean isLoggable(LogRecord record) {
+ return !record.getMessage().equals("false");
+ }
+ }
+
+ public static class MockFormatter extends Formatter {
+ public String format(LogRecord r) {
+ if (null == r) {
+ return "";
+ }
+ return r.getMessage() + " by MockFormatter\n";
+ }
+
+ public String getTail(Handler h) {
+ return "tail\n";
+ }
+
+ public String getHead(Handler h) {
+ return "head\n";
+ }
+ }
+}
diff --git a/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldFormatterTest.java b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldFormatterTest.java
new file mode 100644
index 0000000000..3bc1ede4a2
--- /dev/null
+++ b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldFormatterTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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 libcore.java.util.logging;
+
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.StreamHandler;
+import junit.framework.TestCase;
+
+public class OldFormatterTest extends TestCase {
+ static String MSG = "msg, pls. ignore it";
+
+ Formatter f = new MockFormatter();
+ LogRecord r = new LogRecord(Level.FINE, MSG);
+ Handler h;
+
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ h = new StreamHandler();
+ }
+
+ public void testFormatter() {
+ assertEquals("head string is not empty", "", f.getHead(null));
+ assertEquals("tail string is not empty", "", f.getTail(null));
+
+ }
+
+ public void testGetHead() {
+ assertEquals("head string is not empty", "", f.getHead(null));
+ assertEquals("head string is not empty", "", f.getHead(h));
+ h.publish(r);
+ assertEquals("head string is not empty", "", f.getHead(h));
+ }
+
+ public void testGetTail() {
+ assertEquals("tail string is not empty", "", f.getTail(null));
+ assertEquals("tail string is not empty", "", f.getTail(h));
+ h.publish(r);
+ assertEquals("tail string is not empty", "", f.getTail(h));
+ }
+
+ public void testFormatMessage() {
+ // The RI fails in this test because it uses a MessageFormat to format
+ // the message even though it doesn't contain "{0". The spec says that
+ // this would indicate that a MessageFormat should be used and else no
+ // formatting should be done.
+ String pattern = "pattern without 0 {1, number}";
+ r.setMessage(pattern);
+ assertEquals(pattern, f.formatMessage(r));
+ }
+
+ public static class MockFormatter extends Formatter {
+ public String format(LogRecord arg0) {
+ return "format";
+ }
+ }
+}
diff --git a/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldLevelTest.java b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldLevelTest.java
new file mode 100644
index 0000000000..3d0b31d74a
--- /dev/null
+++ b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldLevelTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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 libcore.java.util.logging;
+
+import java.io.Serializable;
+import java.util.logging.Level;
+import junit.framework.TestCase;
+
+public final class OldLevelTest extends TestCase {
+
+ public void testGetResourceBundleName() {
+ String bundleName = "bundles/java/util/logging/res";
+ Level l = new MockLevel("level1", 120);
+ assertNull("level's localization resource bundle name is not null", l
+ .getResourceBundleName());
+ l = new MockLevel("level1", 120, bundleName);
+ assertEquals("bundleName is non equal to actual value", bundleName, l
+ .getResourceBundleName());
+ l = new MockLevel("level1", 120, bundleName + "+abcdef");
+ assertEquals("bundleName is non equal to actual value", bundleName
+ + "+abcdef", l.getResourceBundleName());
+ }
+
+ /*
+ * test for method public final int intValue()
+ */
+ public void testIntValue() {
+ int value1 = 120;
+ Level l = new MockLevel("level1", value1);
+ assertEquals("integer value for this level is non equal to actual value",
+ value1, l.intValue());
+ }
+
+ public static class MockLevel extends Level implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ public MockLevel(String name, int value) {
+ super(name, value);
+ }
+
+ public MockLevel(String name, int value, String resourceBundleName) {
+ super(name, value, resourceBundleName);
+ }
+ }
+}
diff --git a/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldLogManagerTest.java b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldLogManagerTest.java
new file mode 100644
index 0000000000..e76c17831a
--- /dev/null
+++ b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldLogManagerTest.java
@@ -0,0 +1,255 @@
+/*
+ * 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 libcore.java.util.logging;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.logging.Handler;
+import java.util.logging.LogManager;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+import junit.framework.TestCase;
+
+public class OldLogManagerTest extends TestCase {
+
+ private static final String FOO = "LogManagerTestFoo";
+
+ LogManager mockManager;
+
+ LogManager manager = LogManager.getLogManager();
+
+ Properties props;
+
+ private static String className = OldLogManagerTest.class.getName();
+
+ static Handler handler = null;
+
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ mockManager = new MockLogManager();
+ handler = new MockHandler();
+ props = new Properties();
+ props.put("handlers", className + "$MockHandler " + className + "$MockHandler");
+ props.put("java.util.logging.FileHandler.pattern", "%h/java%u.log");
+ props.put("java.util.logging.FileHandler.limit", "50000");
+ props.put("java.util.logging.FileHandler.count", "5");
+ props.put("java.util.logging.FileHandler.formatter", "java.util.logging.XMLFormatter");
+ props.put(".level", "FINE");
+ props.put("java.util.logging.ConsoleHandler.level", "OFF");
+ props.put("java.util.logging.ConsoleHandler.formatter","java.util.logging.SimpleFormatter");
+ props.put("LogManagerTestFoo.handlers", "java.util.logging.ConsoleHandler");
+ props.put("LogManagerTestFoo.level", "WARNING");
+ }
+
+
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ handler = null;
+ }
+
+ public void testLogManager() {
+ class TestLogManager extends LogManager {
+ public TestLogManager() {
+ super();
+ }
+ }
+ TestLogManager tlm = new TestLogManager();
+ assertNotNull(tlm.toString());
+ }
+
+ /*
+ * test for method public Logger getLogger(String name)
+ * test covers following use cases:
+ * case 1: test default and valid value
+ * case 2: test throw NullPointerException
+ * case 3: test bad name
+ * case 4: check correct tested value
+ */
+
+ public void testGetLogger() throws Exception {
+
+ // case 1: test default and valid value
+ Logger log = new MockLogger(FOO, null);
+ Logger foo = mockManager.getLogger(FOO);
+ assertNull("Logger should be null", foo);
+ assertTrue("logger wasn't registered successfully", mockManager.addLogger(log));
+ foo = mockManager.getLogger(FOO);
+ assertSame("two loggers not refer to the same object", foo, log);
+ assertNull("logger foo should not haven parent", foo.getParent());
+
+ // case 2: test throw NullPointerException
+ try {
+ mockManager.getLogger(null);
+ fail("get null should throw NullPointerException");
+ } catch (NullPointerException e) {
+ }
+
+ // case 3: test bad name
+ assertNull("LogManager should not have logger with unforeseen name", mockManager
+ .getLogger("bad name"));
+
+ // case 4: check correct tested value
+ Enumeration enumar = mockManager.getLoggerNames();
+ int i = 0;
+ while (enumar.hasMoreElements()) {
+ String name = enumar.nextElement();
+ i++;
+ assertEquals("name logger should be equal to foreseen name", FOO, name);
+ }
+ assertEquals("LogManager should contain one element", 1, i);
+ }
+
+ /*
+ * test for method public Logger getLogger(String name)
+ */
+ public void testGetLogger_duplicateName() throws Exception {
+ // test duplicate name
+ // add logger with duplicate name has no effect
+ mockManager.reset();
+ Logger foo2 = new MockLogger(FOO, null);
+ Logger foo3 = new MockLogger(FOO, null);
+ mockManager.addLogger(foo2);
+ assertSame(foo2, mockManager.getLogger(FOO));
+ mockManager.addLogger(foo3);
+ assertSame(foo2, mockManager.getLogger(FOO));
+
+ Enumeration enumar2 = mockManager.getLoggerNames();
+ int i = 0;
+ while (enumar2.hasMoreElements()) {
+ enumar2.nextElement();
+ i++;
+ }
+ assertEquals(1, i);
+ }
+
+ /*
+ * test for method public Logger getLogger(String name)
+ */
+ public void testGetLogger_hierarchy() throws Exception {
+ // test hierarchy
+ Logger foo = new MockLogger("testGetLogger_hierachy.foo", null);
+ // but for non-mock LogManager, foo's parent should be root
+ assertTrue(manager.addLogger(foo));
+ assertSame(manager.getLogger(""), manager.getLogger("testGetLogger_hierachy.foo")
+ .getParent());
+ }
+
+ /*
+ * test for method public Logger getLogger(String name)
+ */
+ public void testGetLogger_nameSpace() throws Exception {
+ // test name with space
+ Logger foo = new MockLogger(FOO, null);
+ Logger fooBeforeSpace = new MockLogger(FOO + " ", null);
+ Logger fooAfterSpace = new MockLogger(" " + FOO, null);
+ Logger fooWithBothSpace = new MockLogger(" " + FOO + " ", null);
+ assertTrue(mockManager.addLogger(foo));
+ assertTrue(mockManager.addLogger(fooBeforeSpace));
+ assertTrue(mockManager.addLogger(fooAfterSpace));
+ assertTrue(mockManager.addLogger(fooWithBothSpace));
+
+ assertSame(foo, mockManager.getLogger(FOO));
+ assertSame(fooBeforeSpace, mockManager.getLogger(FOO + " "));
+ assertSame(fooAfterSpace, mockManager.getLogger(" " + FOO));
+ assertSame(fooWithBothSpace, mockManager.getLogger(" " + FOO + " "));
+ }
+
+ /*
+ * test for method public void checkAccess() throws SecurityException
+ */
+ public void testCheckAccess() {
+ try {
+ manager.checkAccess();
+ } catch (SecurityException e) {
+ fail("securityException should not be thrown");
+ }
+ }
+
+ public void testReadConfiguration() throws SecurityException,
+ IOException {
+
+ MockConfigLogManager lm = new MockConfigLogManager();
+ assertFalse(lm.isCalled);
+
+ lm.readConfiguration();
+ assertTrue(lm.isCalled);
+ }
+
+ public void testReadConfigurationInputStream_IOException_1parm() throws SecurityException {
+ try {
+ mockManager.readConfiguration(new MockInputStream());
+ fail("should throw IOException");
+ } catch (IOException expected) {
+ }
+ }
+
+ public static class MockInputStream extends InputStream {
+ @Override public int read() throws IOException {
+ throw new IOException();
+ }
+ }
+
+ public static class MockLogger extends Logger {
+ public MockLogger(String name, String rbName) {
+ super(name, rbName);
+ }
+ }
+
+ public static class MockLogManager extends LogManager {}
+
+ public static class MockConfigLogManager extends LogManager {
+ public boolean isCalled = false;
+
+ public void readConfiguration(InputStream ins) throws IOException {
+ isCalled = true;
+ super.readConfiguration(ins);
+ }
+ }
+
+ public static class MockHandler extends Handler {
+ static int number = 0;
+
+ public MockHandler() {
+ addNumber();
+ }
+
+ private synchronized void addNumber() {
+ number++;
+ }
+
+ public void close() {
+ minusNumber();
+ }
+
+ private synchronized void minusNumber() {
+ number--;
+ }
+
+ public void flush() {}
+
+ public void publish(LogRecord record) {}
+ }
+}
diff --git a/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldLogRecordTest.java b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldLogRecordTest.java
new file mode 100644
index 0000000000..27f4bc9894
--- /dev/null
+++ b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldLogRecordTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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 libcore.java.util.logging;
+
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import junit.framework.TestCase;
+
+public class OldLogRecordTest extends TestCase {
+
+ static final String MSG = "test msg, pls. ignore itb";
+
+ private LogRecord lr = new LogRecord(Level.CONFIG, MSG);
+
+ public void testGetSetTimeCheck() {
+ long before = lr.getMillis();
+ try {
+ Thread.sleep(2);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ LogRecord lr2 = new LogRecord(Level.CONFIG, "MSG2");
+ long after = lr2.getMillis();
+ assertTrue(after-before>0);
+ }
+
+ public void testGetSetLevelNormal() {
+ assertSame(lr.getLevel(), Level.CONFIG);
+ lr.setLevel(Level.ALL);
+ assertSame(lr.getLevel(), Level.ALL);
+ lr.setLevel(Level.FINEST);
+ assertSame(lr.getLevel(), Level.FINEST);
+ }
+
+ public void testGetSetThreadID_DifferentThread() {
+ lr.getThreadID();
+ // Create and start the thread
+ MockThread thread = new MockThread();
+ thread.start();
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ // Create and start the thread2
+ MockThread thread2 = new MockThread();
+ thread2.start();
+ try {
+ thread2.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ //All threadID must be different, based on the ThreadLocal.java ID
+ assertTrue(lr.getThreadID() != thread.lr.getThreadID());
+ assertTrue(lr.getThreadID() != thread2.lr.getThreadID());
+ assertTrue(thread.lr.getThreadID() != thread2.lr.getThreadID());
+ }
+
+ public class MockThread extends Thread {
+ public LogRecord lr = null; //will be update by the thread
+
+ public void run() {
+ update();
+ }
+
+ public synchronized void update(){
+ lr = new LogRecord(Level.CONFIG, "msg thread");
+ }
+ }
+}
diff --git a/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldLoggerTest.java b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldLoggerTest.java
new file mode 100644
index 0000000000..ad8ed217b2
--- /dev/null
+++ b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldLoggerTest.java
@@ -0,0 +1,230 @@
+/*
+ * 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 libcore.java.util.logging;
+
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.logging.Filter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+import junit.framework.TestCase;
+
+public class OldLoggerTest extends TestCase {
+ private final static String VALID_RESOURCE_BUNDLE = "bundles/java/util/logging/res";
+ private final static String INVALID_RESOURCE_BUNDLE = "impossible_not_existing";
+ private final static String VALID_KEY = "LOGGERTEST";
+ private final static String VALID_VALUE = "Test_ZH_CN";
+
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ LogManager.getLogManager().reset();
+ Locale.setDefault(new Locale("zh", "CN"));
+ }
+
+ @Override protected void tearDown() throws Exception {
+ LogManager.getLogManager().reset();
+ super.tearDown();
+ }
+
+ public void testGetLoggerWithRes_InvalidResourceBundle() {
+ assertNull(LogManager.getLogManager().getLogger(
+ "testMissingResourceException"));
+
+ assertNotNull(LogManager.getLogManager().getLogger(""));
+ // The root logger always exists TODO
+ try {
+ Logger.getLogger("", INVALID_RESOURCE_BUNDLE);
+ fail();
+ } catch (MissingResourceException expected) {
+ }
+ }
+
+ public void testGlobalLogger() {
+ assertNull(Logger.global.getFilter());
+ assertEquals(0, Logger.global.getHandlers().length);
+ assertNull(Logger.global.getLevel());
+ assertEquals("global", Logger.global.getName());
+ assertNull(Logger.global.getParent().getParent());
+ assertNull(Logger.global.getResourceBundle());
+ assertNull(Logger.global.getResourceBundleName());
+ assertTrue(Logger.global.getUseParentHandlers());
+ assertSame(Logger.global, Logger.getLogger("global"));
+ assertSame(Logger.global, LogManager.getLogManager().getLogger("global"));
+ assertSame(Logger.global, Logger.getGlobal());
+ }
+
+ public void testConstructor_Normal() {
+ MockLogger mlog = new MockLogger("myname", VALID_RESOURCE_BUNDLE);
+ assertNull(mlog.getFilter());
+ assertEquals(0, mlog.getHandlers().length);
+ assertNull(mlog.getLevel());
+ assertEquals("myname", mlog.getName());
+ assertNull(mlog.getParent());
+ ResourceBundle rb = mlog.getResourceBundle();
+ assertEquals(VALID_VALUE, rb.getString(VALID_KEY));
+ assertEquals(mlog.getResourceBundleName(), VALID_RESOURCE_BUNDLE);
+ assertTrue(mlog.getUseParentHandlers());
+ }
+
+ public void testConstructor_Null() {
+ MockLogger mlog = new MockLogger(null, null);
+ assertNull(mlog.getFilter());
+ assertEquals(0, mlog.getHandlers().length);
+ assertNull(mlog.getLevel());
+ assertNull(mlog.getName());
+ assertNull(mlog.getParent());
+ assertNull(mlog.getResourceBundle());
+ assertNull(mlog.getResourceBundleName());
+ assertTrue(mlog.getUseParentHandlers());
+ }
+
+ public void testConstructor_InvalidName() {
+ MockLogger mlog = new MockLogger("...#$%%^&&()-_+=!@~./,[]{};:'\\\"?|",
+ null);
+ assertEquals("...#$%%^&&()-_+=!@~./,[]{};:'\\\"?|", mlog.getName());
+ }
+
+ /*
+ * Test constructor with empty name.
+ */
+ public void testConstructor_EmptyName() {
+ MockLogger mlog = new MockLogger("", null);
+ assertEquals("", mlog.getName());
+ }
+
+ public void testConstructor_InvalidResourceBundle() {
+ try {
+ new MockLogger("testConstructor_InvalidResourceBundle",
+ INVALID_RESOURCE_BUNDLE);
+ fail("Should throw MissingResourceException!");
+ } catch (MissingResourceException expected) {
+ }
+ }
+
+ public void testGetLogger_Null() {
+ try {
+ Logger.getLogger(null, null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testGetLogger_WithParent() {
+ assertNull(LogManager.getLogManager().getLogger(
+ "testGetLogger_WithParent_ParentLogger"));
+
+ // get root of hierarchy
+ Logger root = Logger.getLogger("");
+ // create the parent logger
+ Logger pLog = Logger.getLogger("testGetLogger_WithParent_ParentLogger",
+ VALID_RESOURCE_BUNDLE);
+ pLog.setLevel(Level.CONFIG);
+ pLog.addHandler(new MockHandler());
+ pLog.setFilter(new MockFilter());
+ pLog.setUseParentHandlers(false);
+ // check root parent
+ assertEquals("testGetLogger_WithParent_ParentLogger", pLog.getName());
+ assertSame(pLog.getParent(), root);
+
+ // child part
+ assertNull(LogManager.getLogManager().getLogger(
+ "testGetLogger_WithParent_ParentLogger.child"));
+ // create the child logger
+ Logger child = Logger
+ .getLogger("testGetLogger_WithParent_ParentLogger.child");
+ assertNull(child.getFilter());
+ assertEquals(0, child.getHandlers().length);
+ assertNull(child.getLevel());
+ assertEquals("testGetLogger_WithParent_ParentLogger.child", child
+ .getName());
+ assertSame(child.getParent(), pLog);
+ assertNull(child.getResourceBundle());
+ assertNull(child.getResourceBundleName());
+ assertTrue(child.getUseParentHandlers());
+
+ // create not valid child
+ Logger notChild = Logger
+ .getLogger("testGetLogger_WithParent_ParentLogger1.child");
+ assertNull(notChild.getFilter());
+ assertEquals(0, notChild.getHandlers().length);
+ assertNull(notChild.getLevel());
+ assertEquals("testGetLogger_WithParent_ParentLogger1.child", notChild
+ .getName());
+ assertNotSame(notChild.getParent(), pLog);
+ assertNull(notChild.getResourceBundle());
+ assertNull(notChild.getResourceBundleName());
+ assertTrue(notChild.getUseParentHandlers());
+ // verify two level root.parent
+ assertEquals("testGetLogger_WithParent_ParentLogger.child", child
+ .getName());
+ assertSame(child.getParent().getParent(), root);
+
+
+ // create three level child
+ Logger childOfChild = Logger
+ .getLogger("testGetLogger_WithParent_ParentLogger.child.child");
+ assertNull(childOfChild.getFilter());
+ assertEquals(0, childOfChild.getHandlers().length);
+ assertSame(child.getParent().getParent(), root);
+ assertNull(childOfChild.getLevel());
+ assertEquals("testGetLogger_WithParent_ParentLogger.child.child",
+ childOfChild.getName());
+
+ assertSame(childOfChild.getParent(), child);
+ assertSame(childOfChild.getParent().getParent(), pLog);
+ assertSame(childOfChild.getParent().getParent().getParent(), root);
+ assertNull(childOfChild.getResourceBundle());
+ assertNull(childOfChild.getResourceBundleName());
+ assertTrue(childOfChild.getUseParentHandlers());
+
+ // abnormal case : lookup to root parent in a hierarchy without a logger
+ // parent created between
+ assertEquals("testGetLogger_WithParent_ParentLogger1.child", notChild
+ .getName());
+ assertSame(child.getParent().getParent(), root);
+ assertNotSame(child.getParent(), root);
+
+ // abnormal cases
+ assertNotSame(root.getParent(), root);
+ Logger twoDot = Logger.getLogger("..");
+ assertSame(twoDot.getParent(), root);
+
+ }
+
+ public static class MockLogger extends Logger {
+ public MockLogger(String name, String resourceBundleName) {
+ super(name, resourceBundleName);
+ }
+ }
+
+ public static class MockHandler extends Handler {
+ public void close() {}
+ public void flush() {}
+ public void publish(LogRecord record) {}
+ }
+
+ public static class MockFilter implements Filter {
+ public boolean isLoggable(LogRecord record) {
+ return false;
+ }
+ }
+}
diff --git a/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldMemoryHandlerTest.java b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldMemoryHandlerTest.java
new file mode 100644
index 0000000000..32770c40bb
--- /dev/null
+++ b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldMemoryHandlerTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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 libcore.java.util.logging;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+import java.util.logging.Filter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.LogRecord;
+import java.util.logging.MemoryHandler;
+import junit.framework.TestCase;
+
+public class OldMemoryHandlerTest extends TestCase {
+
+ final static LogManager manager = LogManager.getLogManager();
+ final static Properties props = new Properties();
+ final static String baseClassName = OldMemoryHandlerTest.class.getName();
+ MemoryHandler handler;
+
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ manager.reset();
+ initProps();
+ manager.readConfiguration(propertiesToInputStream(props));
+ handler = new MemoryHandler();
+ }
+
+ @Override protected void tearDown() throws Exception {
+ super.tearDown();
+ manager.readConfiguration();
+ props.clear();
+ }
+
+ public static InputStream propertiesToInputStream(Properties p) throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ p.store(bos, "");
+ return new ByteArrayInputStream(bos.toByteArray());
+ }
+
+ private void initProps() {
+ props.put("java.util.logging.MemoryHandler.level", "FINE");
+ props.put("java.util.logging.MemoryHandler.filter", baseClassName + "$MockFilter");
+ props.put("java.util.logging.MemoryHandler.size", "2");
+ props.put("java.util.logging.MemoryHandler.push", "WARNING");
+ props.put("java.util.logging.MemoryHandler.target", baseClassName + "$MockHandler");
+ props.put("java.util.logging.MemoryHandler.formatter", baseClassName + "$MockFormatter");
+ }
+
+ public void testIsLoggable() {
+ assertTrue(handler.isLoggable(new LogRecord(Level.INFO, "1")));
+ assertTrue(handler.isLoggable(new LogRecord(Level.WARNING, "2")));
+ assertTrue(handler.isLoggable(new LogRecord(Level.SEVERE, "3")));
+ }
+
+ public void testMemoryHandler() throws IOException {
+ assertNotNull("Filter should not be null", handler.getFilter());
+ assertNotNull("Formatter should not be null", handler.getFormatter());
+ assertNull("character encoding should be null", handler.getEncoding());
+ assertNotNull("ErrorManager should not be null", handler.getErrorManager());
+ assertEquals("Level should be FINE", Level.FINE, handler.getLevel());
+ assertEquals("Level should be WARNING", Level.WARNING, handler.getPushLevel());
+ }
+
+ public static class MockFilter implements Filter {
+ public boolean isLoggable(LogRecord record) {
+ return !record.getMessage().equals("false");
+ }
+ }
+
+ public static class MockHandler extends Handler {
+ public void close() {}
+ public void flush() {}
+ public void publish(LogRecord record) {}
+ }
+}
diff --git a/jre_emul/apache_harmony/classlib/modules/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTestResource.java b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldSimpleFormatterTest.java
similarity index 64%
rename from jre_emul/apache_harmony/classlib/modules/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTestResource.java
rename to jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldSimpleFormatterTest.java
index 5e06b70bd8..84be010824 100644
--- a/jre_emul/apache_harmony/classlib/modules/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTestResource.java
+++ b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldSimpleFormatterTest.java
@@ -1,13 +1,13 @@
-/*
+/*
* 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.
@@ -15,16 +15,17 @@
* limitations under the License.
*/
-package org.apache.harmony.logging.tests.java.util.logging;
+package libcore.java.util.logging;
-import java.util.ListResourceBundle;
+import java.util.logging.SimpleFormatter;
+import junit.framework.TestCase;
-public class LevelTestResource extends ListResourceBundle {
- public Object[][] getContents() {
- return contents;
- }
+public class OldSimpleFormatterTest extends TestCase {
+
+ SimpleFormatter sf = new SimpleFormatter();
- @SuppressWarnings("nls")
- static final Object[][] contents = { { "Level_error", "Name" },
- { "Localized", "Localized message" }, };
-}
\ No newline at end of file
+ public void testSimpleFormatter() {
+ assertEquals("Head for this SimpleFormatter should be empty", "", sf.getHead(null));
+ assertEquals("Tail for this SimpleFormatter should be empty", "", sf.getTail(null));
+ }
+}
diff --git a/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldXMLFormatterTest.java b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldXMLFormatterTest.java
new file mode 100644
index 0000000000..9897fa029c
--- /dev/null
+++ b/jre_emul/android/platform/libcore/luni/src/test/java/libcore/java/util/logging/OldXMLFormatterTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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 libcore.java.util.logging;
+
+import java.io.UnsupportedEncodingException;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.XMLFormatter;
+import junit.framework.TestCase;
+
+public final class OldXMLFormatterTest extends TestCase {
+
+ XMLFormatter formatter = null;
+ MockHandler handler = null;
+ LogRecord lr = null;
+
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ formatter = new XMLFormatter();
+ handler = new MockHandler();
+ lr = new LogRecord(Level.SEVERE, "pattern");
+ }
+
+ public void testXMLFormatter() throws SecurityException, UnsupportedEncodingException {
+ handler.setEncoding("UTF-8");
+
+ String result = formatter.getHead(handler);
+ int headPos = result
+ .indexOf("");
+ int dtdPos = result.indexOf("");
+ int rootPos = result.indexOf("");
+ assertTrue("head string position should be more or equal zero",
+ headPos >= 0);
+ assertTrue("dtd string position should be more head string position",
+ dtdPos > headPos);
+ assertTrue("root string position should be more dtd string position",
+ rootPos > dtdPos);
+
+ assertTrue("Tail string position should be more zero", formatter
+ .getTail(handler).indexOf("/log>") > 0);
+ }
+
+ public void testGetTail() {
+ assertEquals("Tail string with null handler should be equal expected value",
+ "", formatter.getTail(null).trim());
+ assertEquals("Tail string should be equal expected value", "",
+ formatter.getTail(handler).trim());
+ handler.publish(lr);
+ assertEquals("Tail string after publish() should be equal expected value",
+ "", formatter.getTail(handler).trim());
+ }
+
+ public static class MockHandler extends Handler {
+ public void close() {}
+ public void flush() {}
+ public void publish(LogRecord record) {}
+ }
+}
diff --git a/jre_emul/apache_harmony/classlib/modules/logging/src/test/resources/bundles/java/util/logging/res.properties b/jre_emul/android/platform/libcore/luni/src/test/resources/bundles/java/util/logging/res.properties
similarity index 100%
rename from jre_emul/apache_harmony/classlib/modules/logging/src/test/resources/bundles/java/util/logging/res.properties
rename to jre_emul/android/platform/libcore/luni/src/test/resources/bundles/java/util/logging/res.properties
diff --git a/jre_emul/apache_harmony/classlib/modules/logging/src/test/resources/bundles/java/util/logging/res2.properties b/jre_emul/android/platform/libcore/luni/src/test/resources/bundles/java/util/logging/res2.properties
similarity index 100%
rename from jre_emul/apache_harmony/classlib/modules/logging/src/test/resources/bundles/java/util/logging/res2.properties
rename to jre_emul/android/platform/libcore/luni/src/test/resources/bundles/java/util/logging/res2.properties
diff --git a/jre_emul/apache_harmony/classlib/modules/logging/src/test/resources/bundles/java/util/logging/res3.properties b/jre_emul/android/platform/libcore/luni/src/test/resources/bundles/java/util/logging/res3.properties
similarity index 100%
rename from jre_emul/apache_harmony/classlib/modules/logging/src/test/resources/bundles/java/util/logging/res3.properties
rename to jre_emul/android/platform/libcore/luni/src/test/resources/bundles/java/util/logging/res3.properties
diff --git a/jre_emul/apache_harmony/classlib/modules/logging/src/test/resources/bundles/java/util/logging/res_en_US.properties b/jre_emul/android/platform/libcore/luni/src/test/resources/bundles/java/util/logging/res_en_US.properties
similarity index 100%
rename from jre_emul/apache_harmony/classlib/modules/logging/src/test/resources/bundles/java/util/logging/res_en_US.properties
rename to jre_emul/android/platform/libcore/luni/src/test/resources/bundles/java/util/logging/res_en_US.properties
diff --git a/jre_emul/apache_harmony/classlib/modules/logging/src/test/resources/bundles/java/util/logging/res_zh_CN.properties b/jre_emul/android/platform/libcore/luni/src/test/resources/bundles/java/util/logging/res_zh_CN.properties
similarity index 100%
rename from jre_emul/apache_harmony/classlib/modules/logging/src/test/resources/bundles/java/util/logging/res_zh_CN.properties
rename to jre_emul/android/platform/libcore/luni/src/test/resources/bundles/java/util/logging/res_zh_CN.properties
diff --git a/jre_emul/apache_harmony/classlib/modules/logging/src/test/resources/config/java/util/logging/logging.config b/jre_emul/android/platform/libcore/luni/src/test/resources/config/java/util/logging/logging.config
similarity index 100%
rename from jre_emul/apache_harmony/classlib/modules/logging/src/test/resources/config/java/util/logging/logging.config
rename to jre_emul/android/platform/libcore/luni/src/test/resources/config/java/util/logging/logging.config
diff --git a/jre_emul/android/platform/libcore/luni/src/test/resources/config/java/util/logging/logging.properties b/jre_emul/android/platform/libcore/luni/src/test/resources/config/java/util/logging/logging.properties
new file mode 100644
index 0000000000..fa1d009698
--- /dev/null
+++ b/jre_emul/android/platform/libcore/luni/src/test/resources/config/java/util/logging/logging.properties
@@ -0,0 +1,3 @@
+handlers=libcore.java.util.logging.OldLogManagerTest$MockHandler java.util.logging.ConsoleHandler
+.level=ALL
+libcore.java.util.logging.OldLogManagerTest$MockHandler.level=OFF
\ No newline at end of file
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/util/logging/ConsoleHandler.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/util/logging/ConsoleHandler.java
new file mode 100644
index 0000000000..8cbff20010
--- /dev/null
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/util/logging/ConsoleHandler.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.util.logging;
+
+import java.io.*;
+import java.net.*;
+
+/**
+ * This Handler publishes log records to System.err.
+ * By default the SimpleFormatter is used to generate brief summaries.
+ *
+ * Configuration:
+ * By default each ConsoleHandler is initialized using the following
+ * LogManager configuration properties. If properties are not defined
+ * (or have invalid values) then the specified default values are used.
+ *
+ *
java.util.logging.ConsoleHandler.level
+ * specifies the default level for the Handler
+ * (defaults to Level.INFO).
+ *
java.util.logging.ConsoleHandler.filter
+ * specifies the name of a Filter class to use
+ * (defaults to no Filter).
+ *
java.util.logging.ConsoleHandler.formatter
+ * specifies the name of a Formatter class to use
+ * (defaults to java.util.logging.SimpleFormatter).
+ *
java.util.logging.ConsoleHandler.encoding
+ * the name of the character set encoding to use (defaults to
+ * the default platform encoding).
+ *
+ *
+ * @since 1.4
+ */
+
+public class ConsoleHandler extends StreamHandler {
+ // Private method to configure a ConsoleHandler from LogManager
+ // properties and/or default values as specified in the class
+ // javadoc.
+ private void configure() {
+ LogManager manager = LogManager.getLogManager();
+ String cname = getClass().getName();
+
+ setLevel(manager.getLevelProperty(cname +".level", Level.INFO));
+ setFilter(manager.getFilterProperty(cname +".filter", null));
+ setFormatter(manager.getFormatterProperty(cname +".formatter", new SimpleFormatter()));
+ try {
+ setEncoding(manager.getStringProperty(cname +".encoding", null));
+ } catch (Exception ex) {
+ try {
+ setEncoding(null);
+ } catch (Exception ex2) {
+ // doing a setEncoding with null should always work.
+ // assert false;
+ }
+ }
+ }
+
+ /**
+ * Create a ConsoleHandler for System.err.
+ *
+ * The ConsoleHandler is configured based on
+ * LogManager properties (or their default values).
+ *
+ */
+ public ConsoleHandler() {
+ sealed = false;
+ configure();
+ setOutputStream(System.err);
+ sealed = true;
+ }
+
+ /**
+ * Publish a LogRecord.
+ *
+ * The logging request was made initially to a Logger object,
+ * which initialized the LogRecord and forwarded it here.
+ *
+ * @param record description of the log event. A null record is
+ * silently ignored and is not published
+ */
+ public void publish(LogRecord record) {
+ super.publish(record);
+ flush();
+ }
+
+ /**
+ * Override StreamHandler.close to do a flush but not
+ * to close the output stream. That is, we do not
+ * close System.err.
+ */
+ public void close() {
+ flush();
+ }
+}
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/util/logging/ErrorManager.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/util/logging/ErrorManager.java
new file mode 100644
index 0000000000..1aaba4c7ab
--- /dev/null
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/util/logging/ErrorManager.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.util.logging;
+
+/**
+ * ErrorManager objects can be attached to Handlers to process
+ * any error that occurs on a Handler during Logging.
+ *
+ * When processing logging output, if a Handler encounters problems
+ * then rather than throwing an Exception back to the issuer of
+ * the logging call (who is unlikely to be interested) the Handler
+ * should call its associated ErrorManager.
+ */
+
+public class ErrorManager {
+ private boolean reported = false;
+
+ /*
+ * We declare standard error codes for important categories of errors.
+ */
+
+ /**
+ * GENERIC_FAILURE is used for failure that don't fit
+ * into one of the other categories.
+ */
+ public final static int GENERIC_FAILURE = 0;
+ /**
+ * WRITE_FAILURE is used when a write to an output stream fails.
+ */
+ public final static int WRITE_FAILURE = 1;
+ /**
+ * FLUSH_FAILURE is used when a flush to an output stream fails.
+ */
+ public final static int FLUSH_FAILURE = 2;
+ /**
+ * CLOSE_FAILURE is used when a close of an output stream fails.
+ */
+ public final static int CLOSE_FAILURE = 3;
+ /**
+ * OPEN_FAILURE is used when an open of an output stream fails.
+ */
+ public final static int OPEN_FAILURE = 4;
+ /**
+ * FORMAT_FAILURE is used when formatting fails for any reason.
+ */
+ public final static int FORMAT_FAILURE = 5;
+
+ /**
+ * The error method is called when a Handler failure occurs.
+ *
+ * This method may be overridden in subclasses. The default
+ * behavior in this base class is that the first call is
+ * reported to System.err, and subsequent calls are ignored.
+ *
+ * @param msg a descriptive string (may be null)
+ * @param ex an exception (may be null)
+ * @param code an error code defined in ErrorManager
+ */
+ public synchronized void error(String msg, Exception ex, int code) {
+ if (reported) {
+ // We only report the first error, to avoid clogging
+ // the screen.
+ return;
+ }
+ reported = true;
+ String text = "java.util.logging.ErrorManager: " + code;
+ if (msg != null) {
+ text = text + ": " + msg;
+ }
+ System.err.println(text);
+ if (ex != null) {
+ ex.printStackTrace();
+ }
+ }
+}
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/util/logging/FileHandler.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/util/logging/FileHandler.java
new file mode 100644
index 0000000000..57270a6d0d
--- /dev/null
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/util/logging/FileHandler.java
@@ -0,0 +1,635 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.util.logging;
+
+import java.io.*;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.security.*;
+
+/**
+ * Simple file logging Handler.
+ *
+ * The FileHandler can either write to a specified file,
+ * or it can write to a rotating set of files.
+ *
+ * For a rotating set of files, as each file reaches a given size
+ * limit, it is closed, rotated out, and a new file opened.
+ * Successively older files are named by adding "0", "1", "2",
+ * etc. into the base filename.
+ *
+ * By default buffering is enabled in the IO libraries but each log
+ * record is flushed out when it is complete.
+ *
+ * By default the XMLFormatter class is used for formatting.
+ *
+ * Configuration:
+ * By default each FileHandler is initialized using the following
+ * LogManager configuration properties. If properties are not defined
+ * (or have invalid values) then the specified default values are used.
+ *
+ *
java.util.logging.FileHandler.level
+ * specifies the default level for the Handler
+ * (defaults to Level.ALL).
+ *
java.util.logging.FileHandler.filter
+ * specifies the name of a Filter class to use
+ * (defaults to no Filter).
+ *
java.util.logging.FileHandler.formatter
+ * specifies the name of a Formatter class to use
+ * (defaults to java.util.logging.XMLFormatter)
+ *
java.util.logging.FileHandler.encoding
+ * the name of the character set encoding to use (defaults to
+ * the default platform encoding).
+ *
java.util.logging.FileHandler.limit
+ * specifies an approximate maximum amount to write (in bytes)
+ * to any one file. If this is zero, then there is no limit.
+ * (Defaults to no limit).
+ *
java.util.logging.FileHandler.count
+ * specifies how many output files to cycle through (defaults to 1).
+ *
java.util.logging.FileHandler.pattern
+ * specifies a pattern for generating the output file name. See
+ * below for details. (Defaults to "%h/java%u.log").
+ *
java.util.logging.FileHandler.append
+ * specifies whether the FileHandler should append onto
+ * any existing files (defaults to false).
+ *
+ *
+ *
+ * A pattern consists of a string that includes the following special
+ * components that will be replaced at runtime:
+ *
+ *
"/" the local pathname separator
+ *
"%t" the system temporary directory
+ *
"%h" the value of the "user.home" system property
+ *
"%g" the generation number to distinguish rotated logs
+ *
"%u" a unique number to resolve conflicts
+ *
"%%" translates to a single percent sign "%"
+ *
+ * If no "%g" field has been specified and the file count is greater
+ * than one, then the generation number will be added to the end of
+ * the generated filename, after a dot.
+ *
+ * Thus for example a pattern of "%t/java%g.log" with a count of 2
+ * would typically cause log files to be written on Solaris to
+ * /var/tmp/java0.log and /var/tmp/java1.log whereas on Windows 95 they
+ * would be typically written to C:\TEMP\java0.log and C:\TEMP\java1.log
+ *
+ * Generation numbers follow the sequence 0, 1, 2, etc.
+ *
+ * Normally the "%u" unique field is set to 0. However, if the FileHandler
+ * tries to open the filename and finds the file is currently in use by
+ * another process it will increment the unique number field and try
+ * again. This will be repeated until FileHandler finds a file name that
+ * is not currently in use. If there is a conflict and no "%u" field has
+ * been specified, it will be added at the end of the filename after a dot.
+ * (This will be after any automatically added generation number.)
+ *
+ * Thus if three processes were all trying to log to fred%u.%g.txt then
+ * they might end up using fred0.0.txt, fred1.0.txt, fred2.0.txt as
+ * the first file in their rotating sequences.
+ *
+ * Note that the use of unique ids to avoid conflicts is only guaranteed
+ * to work reliably when using a local disk file system.
+ *
+ * @since 1.4
+ */
+
+public class FileHandler extends StreamHandler {
+ private MeteredStream meter;
+ private boolean append;
+ private int limit; // zero => no limit.
+ private int count;
+ private String pattern;
+ private String lockFileName;
+ private FileOutputStream lockStream;
+ private File files[];
+ private static final int MAX_LOCKS = 100;
+ private static java.util.HashMap locks = new java.util.HashMap<>();
+
+ // A metered stream is a subclass of OutputStream that
+ // (a) forwards all its output to a target stream
+ // (b) keeps track of how many bytes have been written
+ private class MeteredStream extends OutputStream {
+ OutputStream out;
+ int written;
+
+ MeteredStream(OutputStream out, int written) {
+ this.out = out;
+ this.written = written;
+ }
+
+ public void write(int b) throws IOException {
+ out.write(b);
+ written++;
+ }
+
+ public void write(byte buff[]) throws IOException {
+ out.write(buff);
+ written += buff.length;
+ }
+
+ public void write(byte buff[], int off, int len) throws IOException {
+ out.write(buff,off,len);
+ written += len;
+ }
+
+ public void flush() throws IOException {
+ out.flush();
+ }
+
+ public void close() throws IOException {
+ out.close();
+ }
+ }
+
+ private void open(File fname, boolean append) throws IOException {
+ int len = 0;
+ if (append) {
+ len = (int)fname.length();
+ }
+ FileOutputStream fout = new FileOutputStream(fname.toString(), append);
+ BufferedOutputStream bout = new BufferedOutputStream(fout);
+ meter = new MeteredStream(bout, len);
+ setOutputStream(meter);
+ }
+
+ // Private method to configure a FileHandler from LogManager
+ // properties and/or default values as specified in the class
+ // javadoc.
+ private void configure() {
+ LogManager manager = LogManager.getLogManager();
+
+ String cname = getClass().getName();
+
+ pattern = manager.getStringProperty(cname + ".pattern", "%h/java%u.log");
+ limit = manager.getIntProperty(cname + ".limit", 0);
+ if (limit < 0) {
+ limit = 0;
+ }
+ count = manager.getIntProperty(cname + ".count", 1);
+ if (count <= 0) {
+ count = 1;
+ }
+ append = manager.getBooleanProperty(cname + ".append", false);
+ setLevel(manager.getLevelProperty(cname + ".level", Level.ALL));
+ setFilter(manager.getFilterProperty(cname + ".filter", null));
+ setFormatter(manager.getFormatterProperty(cname + ".formatter", new XMLFormatter()));
+ try {
+ setEncoding(manager.getStringProperty(cname +".encoding", null));
+ } catch (Exception ex) {
+ try {
+ setEncoding(null);
+ } catch (Exception ex2) {
+ // doing a setEncoding with null should always work.
+ // assert false;
+ }
+ }
+ }
+
+
+ /**
+ * Construct a default FileHandler. This will be configured
+ * entirely from LogManager properties (or their default values).
+ *
+ * @exception IOException if there are IO problems opening the files.
+ * @exception SecurityException if a security manager exists and if
+ * the caller does not have LoggingPermission("control")).
+ * @exception NullPointerException if pattern property is an empty String.
+ */
+ public FileHandler() throws IOException, SecurityException {
+ checkPermission();
+ configure();
+ openFiles();
+ }
+
+ /**
+ * Initialize a FileHandler to write to the given filename.
+ *
+ * The FileHandler is configured based on LogManager
+ * properties (or their default values) except that the given pattern
+ * argument is used as the filename pattern, the file limit is
+ * set to no limit, and the file count is set to one.
+ *
+ * There is no limit on the amount of data that may be written,
+ * so use this with care.
+ *
+ * @param pattern the name of the output file
+ * @exception IOException if there are IO problems opening the files.
+ * @exception SecurityException if a security manager exists and if
+ * the caller does not have LoggingPermission("control").
+ * @exception IllegalArgumentException if pattern is an empty string
+ */
+ public FileHandler(String pattern) throws IOException, SecurityException {
+ if (pattern.length() < 1 ) {
+ throw new IllegalArgumentException();
+ }
+ checkPermission();
+ configure();
+ this.pattern = pattern;
+ this.limit = 0;
+ this.count = 1;
+ openFiles();
+ }
+
+ /**
+ * Initialize a FileHandler to write to the given filename,
+ * with optional append.
+ *
+ * The FileHandler is configured based on LogManager
+ * properties (or their default values) except that the given pattern
+ * argument is used as the filename pattern, the file limit is
+ * set to no limit, the file count is set to one, and the append
+ * mode is set to the given append argument.
+ *
+ * There is no limit on the amount of data that may be written,
+ * so use this with care.
+ *
+ * @param pattern the name of the output file
+ * @param append specifies append mode
+ * @exception IOException if there are IO problems opening the files.
+ * @exception SecurityException if a security manager exists and if
+ * the caller does not have LoggingPermission("control").
+ * @exception IllegalArgumentException if pattern is an empty string
+ */
+ public FileHandler(String pattern, boolean append) throws IOException, SecurityException {
+ if (pattern.length() < 1 ) {
+ throw new IllegalArgumentException();
+ }
+ checkPermission();
+ configure();
+ this.pattern = pattern;
+ this.limit = 0;
+ this.count = 1;
+ this.append = append;
+ openFiles();
+ }
+
+ /**
+ * Initialize a FileHandler to write to a set of files. When
+ * (approximately) the given limit has been written to one file,
+ * another file will be opened. The output will cycle through a set
+ * of count files.
+ *
+ * The FileHandler is configured based on LogManager
+ * properties (or their default values) except that the given pattern
+ * argument is used as the filename pattern, the file limit is
+ * set to the limit argument, and the file count is set to the
+ * given count argument.
+ *
+ * The count must be at least 1.
+ *
+ * @param pattern the pattern for naming the output file
+ * @param limit the maximum number of bytes to write to any one file
+ * @param count the number of files to use
+ * @exception IOException if there are IO problems opening the files.
+ * @exception SecurityException if a security manager exists and if
+ * the caller does not have LoggingPermission("control").
+ * @exception IllegalArgumentException if limit < 0, or count < 1.
+ * @exception IllegalArgumentException if pattern is an empty string
+ */
+ public FileHandler(String pattern, int limit, int count)
+ throws IOException, SecurityException {
+ if (limit < 0 || count < 1 || pattern.length() < 1) {
+ throw new IllegalArgumentException();
+ }
+ checkPermission();
+ configure();
+ this.pattern = pattern;
+ this.limit = limit;
+ this.count = count;
+ openFiles();
+ }
+
+ /**
+ * Initialize a FileHandler to write to a set of files
+ * with optional append. When (approximately) the given limit has
+ * been written to one file, another file will be opened. The
+ * output will cycle through a set of count files.
+ *
+ * The FileHandler is configured based on LogManager
+ * properties (or their default values) except that the given pattern
+ * argument is used as the filename pattern, the file limit is
+ * set to the limit argument, and the file count is set to the
+ * given count argument, and the append mode is set to the given
+ * append argument.
+ *
+ * The count must be at least 1.
+ *
+ * @param pattern the pattern for naming the output file
+ * @param limit the maximum number of bytes to write to any one file
+ * @param count the number of files to use
+ * @param append specifies append mode
+ * @exception IOException if there are IO problems opening the files.
+ * @exception SecurityException if a security manager exists and if
+ * the caller does not have LoggingPermission("control").
+ * @exception IllegalArgumentException if limit < 0, or count < 1.
+ * @exception IllegalArgumentException if pattern is an empty string
+ *
+ */
+ public FileHandler(String pattern, int limit, int count, boolean append)
+ throws IOException, SecurityException {
+ if (limit < 0 || count < 1 || pattern.length() < 1) {
+ throw new IllegalArgumentException();
+ }
+ checkPermission();
+ configure();
+ this.pattern = pattern;
+ this.limit = limit;
+ this.count = count;
+ this.append = append;
+ openFiles();
+ }
+
+ // Private method to open the set of output files, based on the
+ // configured instance variables.
+ private void openFiles() throws IOException {
+ LogManager manager = LogManager.getLogManager();
+ manager.checkPermission();
+ if (count < 1) {
+ throw new IllegalArgumentException("file count = " + count);
+ }
+ if (limit < 0) {
+ limit = 0;
+ }
+
+ // We register our own ErrorManager during initialization
+ // so we can record exceptions.
+ InitializationErrorManager em = new InitializationErrorManager();
+ setErrorManager(em);
+
+ // Create a lock file. This grants us exclusive access
+ // to our set of output files, as long as we are alive.
+ int unique = -1;
+ for (;;) {
+ unique++;
+ if (unique > MAX_LOCKS) {
+ throw new IOException("Couldn't get lock for " + pattern);
+ }
+ // Generate a lock file name from the "unique" int.
+ lockFileName = generate(pattern, 0, unique).toString() + ".lck";
+ // Now try to lock that filename.
+ // Because some systems (e.g., Solaris) can only do file locks
+ // between processes (and not within a process), we first check
+ // if we ourself already have the file locked.
+ synchronized(locks) {
+ if (locks.get(lockFileName) != null) {
+ // We already own this lock, for a different FileHandler
+ // object. Try again.
+ continue;
+ }
+ FileChannel fc;
+ try {
+ lockStream = new FileOutputStream(lockFileName);
+ fc = lockStream.getChannel();
+ } catch (IOException ix) {
+ // We got an IOException while trying to open the file.
+ // Try the next file.
+ continue;
+ }
+ boolean available;
+ try {
+ available = fc.tryLock() != null;
+ // We got the lock OK.
+ } catch (IOException ix) {
+ // We got an IOException while trying to get the lock.
+ // This normally indicates that locking is not supported
+ // on the target directory. We have to proceed without
+ // getting a lock. Drop through.
+ available = true;
+ }
+ if (available) {
+ // We got the lock. Remember it.
+ locks.put(lockFileName, lockFileName);
+ break;
+ }
+
+ // We failed to get the lock. Try next file.
+ fc.close();
+ }
+ }
+
+ files = new File[count];
+ for (int i = 0; i < count; i++) {
+ files[i] = generate(pattern, i, unique);
+ }
+
+ // Create the initial log file.
+ if (append) {
+ open(files[0], true);
+ } else {
+ rotate();
+ }
+
+ // Did we detect any exceptions during initialization?
+ Exception ex = em.lastException;
+ if (ex != null) {
+ if (ex instanceof IOException) {
+ throw (IOException) ex;
+ } else if (ex instanceof SecurityException) {
+ throw (SecurityException) ex;
+ } else {
+ throw new IOException("Exception: " + ex);
+ }
+ }
+
+ // Install the normal default ErrorManager.
+ setErrorManager(new ErrorManager());
+ }
+
+ // Generate a filename from a pattern.
+ private File generate(String pattern, int generation, int unique) throws IOException {
+ File file = null;
+ String word = "";
+ int ix = 0;
+ boolean sawg = false;
+ boolean sawu = false;
+ while (ix < pattern.length()) {
+ char ch = pattern.charAt(ix);
+ ix++;
+ char ch2 = 0;
+ if (ix < pattern.length()) {
+ ch2 = Character.toLowerCase(pattern.charAt(ix));
+ }
+ if (ch == '/') {
+ if (file == null) {
+ file = new File(word);
+ } else {
+ file = new File(file, word);
+ }
+ word = "";
+ continue;
+ } else if (ch == '%') {
+ if (ch2 == 't') {
+ String tmpDir = System.getProperty("java.io.tmpdir");
+ if (tmpDir == null) {
+ tmpDir = System.getProperty("user.home");
+ }
+ file = new File(tmpDir);
+ ix++;
+ word = "";
+ continue;
+ } else if (ch2 == 'h') {
+ file = new File(System.getProperty("user.home"));
+ // Android-changed: Don't make a special exemption for setuid programs.
+ //
+ // if (isSetUID()) {
+ // // Ok, we are in a set UID program. For safety's sake
+ // // we disallow attempts to open files relative to %h.
+ // throw new IOException("can't use %h in set UID program");
+ // }
+ ix++;
+ word = "";
+ continue;
+ } else if (ch2 == 'g') {
+ word = word + generation;
+ sawg = true;
+ ix++;
+ continue;
+ } else if (ch2 == 'u') {
+ word = word + unique;
+ sawu = true;
+ ix++;
+ continue;
+ } else if (ch2 == '%') {
+ word = word + "%";
+ ix++;
+ continue;
+ }
+ }
+ word = word + ch;
+ }
+ if (count > 1 && !sawg) {
+ word = word + "." + generation;
+ }
+ if (unique > 0 && !sawu) {
+ word = word + "." + unique;
+ }
+ if (word.length() > 0) {
+ if (file == null) {
+ file = new File(word);
+ } else {
+ file = new File(file, word);
+ }
+ }
+ return file;
+ }
+
+ // Rotate the set of output files
+ private synchronized void rotate() {
+ Level oldLevel = getLevel();
+ setLevel(Level.OFF);
+
+ super.close();
+ for (int i = count-2; i >= 0; i--) {
+ File f1 = files[i];
+ File f2 = files[i+1];
+ if (f1.exists()) {
+ if (f2.exists()) {
+ f2.delete();
+ }
+ f1.renameTo(f2);
+ }
+ }
+ try {
+ open(files[0], false);
+ } catch (IOException ix) {
+ // We don't want to throw an exception here, but we
+ // report the exception to any registered ErrorManager.
+ reportError(null, ix, ErrorManager.OPEN_FAILURE);
+
+ }
+ setLevel(oldLevel);
+ }
+
+ /**
+ * Format and publish a LogRecord.
+ *
+ * @param record description of the log event. A null record is
+ * silently ignored and is not published
+ */
+ public synchronized void publish(LogRecord record) {
+ if (!isLoggable(record)) {
+ return;
+ }
+ super.publish(record);
+ flush();
+ if (limit > 0 && meter.written >= limit) {
+ // We performed access checks in the "init" method to make sure
+ // we are only initialized from trusted code. So we assume
+ // it is OK to write the target files, even if we are
+ // currently being called from untrusted code.
+ // So it is safe to raise privilege here.
+ /* J2ObjC removed.
+ AccessController.doPrivileged(new PrivilegedAction